Lap trinh C tren Window

166 76 0
Lap trinh C tren Window

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

NGƠN NGỮ LẬP TRÌNH LẬP TRÌNH C TRÊN WINDOWS LẬP TRÌNH C TRÊN WINDOWS Chƣơng TỔNG QUAN LẬP TRÌNH C TRÊN WINDOWS 1.1 MỞ ĐẦU Để lập trình Microsoft Windows®, cần nắm đặc điểm hệ điều hành Chương giới thiệu khái quát đặc điểm hệ điều hành Microsoft Windows, vấn đề liên quan đến lập trình ngơn ngữ C, đồng thời đưa chương trình mẫu làm sườn cho chương trình viết sau Trang CuuDuongThanCong.com https://fb.com/tailieudientucntt NGÔN NGỮ LẬP TRÌNH LẬP TRÌNH C TRÊN WINDOWS Trong phần đầu, tìm hiểu sơ lược lịch sử phát triển hệ điều hành Microsoft Windows® đặc điểm tảng Windows Phần trình bày khái niệm yêu cầu việc lập trình C Windows Ngồi ra, phần giới thiệu chế công cụ mà hệ điều hành cung cấp cho người lập trình hay người phát triển ứng dụng Windows Cuối chương phần xây dựng chương trình đơn giản Windows Chương trình xem khn mẫu chương trình ứng dụng điển hình, hầu hết đoạn chương trình viết minh họa sách lấy chương trình làm khung sườn để phát triển cho phù hợp với yêu cầu Thêm vào đó, số kiểu liệu định nghĩa Windows qui ước cách đặt tên biến giới thiệu phần Phần chi tiết chuyên sâu việc lập trình ngôn ngữ C môi trường Windows trình bày chương 1.2 HỆ ĐIỀU HÀNH MICROSOFT WINDOWS 1.2.1 Giới thiệu Giữa thập niên 80, cơng ty phần mềm máy tính Microsoft cơng bố phiên dòng hệ điều hành Windows Microsoft Windows® 1.0 Đây hệ điều hành dùng giao diện đồ họa khác với giao diện ký tự (text hay console) MS-DOS Tuy nhiên phải đến phiên thứ hai (Windows 2.0 - tháng 11 năm 1987) có bước cải tiến đáng kể, mở rộng giao tiếp bàn phím thiết bị chuột giao diện đồ họa (GUI-Graphic User Interface) trình đơn (menu) hộp thoại (dialog) Trong phiên Windows yêu cầu vi xử lý Intel 8086 hay 8088 chạy real-mode để truy xuất megabyte nhớ Tháng năm 1990, Microsoft công bố phiên Windows 3.0 Sự thay đổi lớn phiên Windows 3.0 hỗ trợ protected-mode 16 bit vi xử lý 286, 386, 486 Intel Sự thay đổi cho phép ứng dụng Windows truy xuất 16 megabyte nhớ Tiếp bước với phát triển phiên Windows 3.1 đời năm 1992, Microsoft đưa công nghệ Font TrueType, âm nhạc (multimedia), liên kết nhúng đối tượng (OLE- Object Linking and Embedding), đưa hộp thoại chung chuẩn hóa Trong phát triển mạnh mẽ thập niên 90, Microsoft cơng bố tiếp dòng hệ điều hành Windows với ứng dụng công nghệ (1993) Hệ điều hành lấy tên Windows® NT® (Windows New Technology), phiên hệ điều hành Windows hỗ trợ 32 bit cho xử lý 386, 486 Pentium Trong hệ điều hành ứng dụng phải truy xuất nhớ với địa 32-bit tập lệnh hay thị 32-bit Ngoài Windows NT thiết kế để chạy vi xử lý (CPU) khác ngồi Intel chạy máy trạm (workstation) Hệ điều hành Windows 95 công bố năm 1995 hệ điều hành 32-bit cho Intel 386 trở sau Tuy thiếu tính bảo mật Windows NT việc thích nghi với máy trạm công nghệ RISC, bù lại hệ điều hành yêu cầu phần cứng không cao Song song với phát triển phần mềm cơng nghệ phần cứng phát triển không Để tận dụng sức mạnh phần cứng hệ Windows ngày hoàn thiện Như Windows 98 phát triển từ Window 95 có nhiều cải thiện hiệu làm việc, hỗ trợ thiết bị phần cứng tốt hơn, cuối việc tích hợp chặt chẽ với Internet Word Wide Web Trang CuuDuongThanCong.com https://fb.com/tailieudientucntt NGƠN NGỮ LẬP TRÌNH LẬP TRÌNH C TRÊN WINDOWS Windows 2000 hệ điều hành xem ổn định tốt dòng Windows, phiên tăng cường tính bảo mật thích hợp mội trường mạng giao diện đẹp 1.2.2 Đặc điểm chung hệ điều hành Microsoft Windows Windows hệ điều hành sử dụng giao tiếp người dùng đồ họa (GUI), hay gọi hệ điều hành trực quan (Visual interface) GUI sử dụng đồ họa dựa hình ảnh nhị phân (Bitmapped video display) Do tận dụng tài ngun thực hình, cung cấp mơi trường giàu tính trực quan sinh động Windows không đơn điệu MS-DOS (hay số hệ điều hành giao diện console) mà hình sử dụng để thể chuỗi ký tự, người dùng gõ từ bàn phím (keyboard) hay để xuất thông tin dạng văn Trong giao diện người dùng đồ họa, hình giao tiếp với người sử dụng đa dạng hơn, người dùng nhập liệu thông qua chuột cách nhấn vào nút nhấn (button) hôp chọn (combo box)…thiết bị nhập, bàn phím thiết bị chuột (mouse device) Thiết bị chuột thiết bị định vị hình, sử dụng thiết bị chuột người dùng nhập liệu cách trực quan cách kích hoạt nút lệnh, hay làm việc với đối tượng đồ họa liên quan đến tọa độ hình Để giao tiếp môi trường đồ họa, Windows đưa số thành phần gọi điều khiển chung (common control), điều khiển chung đối tượng đưa vào hộp thoại để giao tiếp với người dùng Bao gồm : hộp văn (text box), nút nhấn (button), nút chọn (check box), hộp danh sách (list box), hộp chọn (combo box)… Thật ứng dụng Windows khơng phải q phức tạp chúng có hình thức chung Chương trình ứng dụng thuờng chiếm phạm vi hình chữ nhật hình gọi cửa sổ Trên cửa sổ tiêu đề (title bar) Các chức chương trình liệt kê thực đơn lựa chọn chương trình (menu) , hay xuất dạng trực quan công cụ (toolbar) Các công cụ chứa chức sử dụng thường xuyên thực đơn để giảm thời gian cho người dùng phải mở thực đơn chọn Thông thường cần lấy thông tin hay cung cấp thông tin cho người dùng ứng dụng đưa hộp thoại, hộp thoại chứa điều khiển chung để giao tiếp với người dùng Windows tạo số hộp thoại chuẩn Open Files, số hộp thoại tương tự Windows hệ điều hành đa nhiệm, tùy thuộc vào nhớ mà ta chạy nhiều ứng dụng lúc, đồng thời chuyển qua lại ứng dụng thực thi chúng Trong phiên Windows® 98 NT® trở sau, chương trình ứng dụng tự thân chúng chia thành nhiều tiểu trình (thread) để xử lý với tốc độ xử lý nhanh tạo cảm giác chương trình ứng dụng chạy đồng thời với Trong Windows, chương trình ứng dụng thực thi chia sẻ thủ tục mà Windows cung cấp sẵn, tập tin cung cấp thủ tục gọi thư viện liên kết động (Dynamic Link Libraries - DLL) Windows có chế liên kết chương trình ứng dụng với thủ tực cung cấp thư viện liên kết động Khả tương thích Windows cao Các chương trình ứng dụng viết cho Windows khơng truy xuất trực tiếp phần cứng thiết bị đồ hoạ hình máy in Mà thay vào đó, hệ điều hành cung cấp ngơn ngữ lập trình đồ họa (gọi Giao tiếp thiết bị đồ hoạ - Graphic Device Interface - GDI) cho phép hiển thị đối tượng đồ họa cách dễ dàng Nhờ ứng dụng viết cho Windows chạy với thiết bị hình Trang CuuDuongThanCong.com https://fb.com/tailieudientucntt NGƠN NGỮ LẬP TRÌNH LẬP TRÌNH C TRÊN WINDOWS hay máy in, miễn cài đặt trình điều khiển thiết bị hỗ trợ cho Windows Chương trình ứng dụng khơng quan tâm đến kiểu thiết bị kết nối với hệ thống Như giới thiệu phần khái niệm liên kết động thành phần quan trọng Windows, xem hạt nhân hệ điều hành, thân Windows tập thư viện liên kết động Windows cung cấp nhiều hàm cho chương trình ứng dụng để cài đặt giao diện người dùng hiển thị văn hay đồ họa hình Những hàm cài đặt thư viện liên kết động hay gọi DLL Đó tập tin có dạng phần mở rộng *.DLL hay *.EXE, hầu hết chứa thư mục \Windows\System, \Windows\system32 Windows® 98 thư mục \WinNT\System, \WinNT\System32 Windows® NT® Trong phiên sau này, hệ thống liên kết động tạo nhiều, nhiên, hầu hết hàm gọi thư viện phân thành đơn vị sau: Kernel, User, GDI Kernel cung cấp hàm thủ tục mà hạt nhân hệ điều hành truyền thống quản lý, quản lý nhớ, xuất nhập tập tin tác vụ Thư viện cài đặt tập tin KRNL386.EXE 16 bit KERNEL32.DLL 32 bit User quản lý giao diện người dùng, cài đặt tất khung cửa sổ mức luận lý Thư viện User cài đặt tập tin USER.EXE 16 bit USER32.DLL 32 bit GDI cung cấp toàn giao diện thiết bị đồ hoạ (Graphics Device Interface), cho phép chương trình ứng dụng hiển thị văn đồ hoạ thiết bị xuất phần cứng hình máy in Trong Windows 98, thư viện liên kết động chứa khoảng vài ngàn hàm, hàm có tên đặc tả, ví dụ CreateWindow, hàm dùng để tạo cửa sổ cho ứng dụng Khi sử dụng hàm mà Windows cung cấp cho ứng dụng phải khai báo tập tin tiêu đề h hay hpp (header file) Trong chương trình Windows, có khác biệt ta gọi hàm thư viện C hàm Windows hay thư viện liên kết động cung cấp Đó biên dịch mã máy, hàm thư viện C liên kết thành mã chương trình Trong hàm Windows gọi chương trình cần dùng đến khơng liên kết vào chương trình Để thực lời gọi chương trình Windows *.EXE ln chứa tham chiếu đến thư viện liên kết động khác mà cần dùng Khi đó, chương trình Windows nạp vào nhớ tạo trỏ tham chiếu đến hàm thư viện DLL mà chương trình dùng, thư viện chưa nạp vào nhớ trước nạp 1.3 LẬP TRÌNH TRÊN MICROSOFT WINDOWS 1.3.1 Đặc điểm chung Windows hệ điều hành đồ họa trực quan, dó tài nguyên hệ thống cung cấp đa dạng đòi hỏi người lập trình phải nghiên cứu nhiều để phát hay mạnh hệ điều hành Theo mục đích tiếp cận nhà lập trình ứng dụng Windows phải thân thiện với người dùng thông qua giao diện đồ họa sẵn có Windows Về lý thuyết người dùng làm việc với ứng dụng Windows làm việc với ứng dụng khác Nhưng thực tế để sử dụng ứng dụng cho đạt hiệu Trang CuuDuongThanCong.com https://fb.com/tailieudientucntt NGƠN NGỮ LẬP TRÌNH LẬP TRÌNH C TRÊN WINDOWS cao Windows cần phải có số huấn luyện trợ giúp hay tối thiểu phải cho biết chương trình ứng dụng làm việc Đa số ứng dụng Windows có chung giao diện tương tác với người dùng giống Ví dụ ứng dụng Windows đa số có thực đơn chứa mục : File, Edit, Tool, Help… Và hộp thoại thường chứa phần tử điều khiển chung : Edit Control, Button Control, Checkbox… 1.3.2 Sự khác biệt với lập trình MS-DOS Khi bước vào lập trình Windows đa số người học lạ lẫm, người làm việc với MS-DOS Do MS-DOS hệ điều hành đơn nhiệm giao tiếp qua giao diện console Nên viết chương trình khơng phức tạp Còn Windows người lập trình làm việc với cơng cụ lập trình đồ họa đa dạng với cách xử lý đa nhiệm, đa luồng Windows Vì việc lập trình Windows giúp cho người lập trình đỡ nhàm chán với giao diện console MS-DOS Việc cố gắng phát huy sức mạnh tài nguyên Windows làm cho ứng dụng mạnh mẽ, đa dạng, thân thiện, dễ sử dụng 1.3.3 Một số yêu cầu ngƣời lập trình Điều trước tiên người học lập trình C Windows phải biết lập trình C, sách khơng có tham vọng hướng dẫn người học thơng thạo lập trình C Windows mà chưa qua lớp huấn luyện C Tuy nhiên, không thiết phải hồn tồn thơng thạo C học lập trình Windows Để lập trình Windows ngồi u cầu việc sử dụng cơng cụ lập trình, người học cần phải có Windows, tối thiểu dùng qua số ứng dụng Windows Thật yêu cầu khơng q khó khăn người học Windows quen thuộc với người, người mà sử dụng máy tính Ngồi u cầu trên, đơi người lập trình Windows cần có khiếu thẩm mỹ, cách trình bày hình ảnh, điều khiển hộp thoại tốt làm cho ứng dụng tiện lợi, rõ ràng, thân thiện với người dùng 1.3.4 Bộ cơng cụ giao diện lập trình ứng dụng API Hệ điều hành Windows cung cấp hàng trăm hàm ứng dụng sử dụng truy cập tài nguyên hệ thống Những hàm gọi giao diện lập trình ứng dụng API (Application Programming Interface) Những hàm chứa thư viện liên kết động DLL hệ thống Nhờ có cấu trúc động ứng dụng truy cập đến hàm Khi biên dịch chương trình, đến đoạn mã gọi hàm API chương trình dịch không thêm mã hàm vào mã thực thi mà thêm tên DLL chứa hàm tên hàm Do mã hàm API thực tế khơng sử dụng xây dựng chương trình, thêm vào chương trình nạp vào nhớ để thực thi Trong API có số hàm có chức trì độc lập thiết bị đồ họa, hàm gọi giao diện thiết bị đồ họa GDI (Graphics Device Interface) Do độc lập thiết bị nên hàm GDI cho phép ứng dụng làm việc tốt với nhiều kiểu thiết bị đồ họa khác 1.3.5 Cơ chế thơng điệp Trang CuuDuongThanCong.com https://fb.com/tailieudientucntt NGƠN NGỮ LẬP TRÌNH LẬP TRÌNH C TRÊN WINDOWS Khơng giống ứng dụng chạy MS-DOS, ứng dụng Win32® xử lý theo kiện (event - driven), theo chế ứng dụng viết liên tục chờ cho hệ điều hành truyền liệu nhập vào Hệ thống đảm nhiệm việc truyền tất liệu nhập ứng dụng vào cửa sổ khác ứng dụng Mỗi cửa sổ có riêng hàm gọi hàm xử lý cửa sổ thường đặt tên WndProc, hệ thống gọi hàm có liệu nhập truyền đến cửa sổ, hàm xử lý liệu nhập trả quyền điều khiển cho hệ thống Hệ thống truyền liệu nhập vào thủ tục xử lý cửa sổ thơng qua hình thức gọi thông điệp (message) Thông điệp phát sinh từ ứng dụng hệ thống Hệ thống phát sinh thơng điệp có kiện nhập vào (input even), ví dụ người dùng nhấn phím, di chuyển thiết bị chuột, hay kích vào điều khiển (control) cuộn,… Ngoài hệ thống phát sinh thông điệp để phản ứng lại thay đổi hệ thống ứng dụng mang đến, điều xảy ứng dụng làm cạn kiệt tài nguyên hay ứng dụng tự thay đổi kích thước cửa sổ Một ứng dụng phát sinh thơng điệp cần yêu cầu cửa sổ thực nhiệm vụ hay dùng để thơng tin cửa sổ Hệ thống gởi thông điệp vào thủ tục xử lý cửa sổ với bốn tham số: định danh cửa sổ, định danh thông điệp, hai tham số lại gọi tham số thông điệp (message parameters) Định danh cửa sổ xác định cửa sổ mà thông điệp định Hệ thống dùng định danh để xác định cần phải gởi thông điệp đến thủ tục xử lý cửa sổ Định danh thông điệp số thể mục đích thơng điệp Khi thủ tục xử lý cửa sổ nhận thơng điệp dùng định danh để biết hình thức cần thực Ví dụ, thơng điệp truyền đến thủ tục cửa sổ có định danh WM_PAINT có ý nghĩa cửa sổ vùng làm việc thay đổi cần phải vẽ lại vùng Tham số thơng điệp lưu giá trị hay vị trí liệu, dùng thủ tục cửa sổ xử lý thông điệp Tham số phụ thuộc vào loại thơng điệp truyền đến, số nguyên, tập bit dùng làm cờ hiệu, hay trỏ đến cấu trúc liệu đó,… Khi thơng điệp khơng cần dùng đến tham số hệ thống thiết lập tham số có giá trị NULL Một thủ tục cửa sổ phải kiểm tra xem với loại thông điệp cần dùng tham số để định cách sử dụng tham số Có hai loại thơng điệp : Thông điệp định nghĩa hệ thống (system-defined messages) : Dạng thông điệp hệ thống định nghĩa cho cửa sổ, điều khiển, tài nguyên khác hệ thống Thường bắt đầu với tiền tố sau : WM_xxx, LB_xxx, CB_xxx,… Thông điệp định nghĩa ứng dụng (application-defined message) : Một ứng dụng tạo riêng thơng điệp để sử dụng cửa sổ hay truyền thông tin cửa sổ ứng dụng Nếu ứng dụng định nghĩa thơng điệp riêng thủ tục cửa sổ nhận thông điệp phải cung cấp hàm xử lý tương ứng Trang CuuDuongThanCong.com https://fb.com/tailieudientucntt NGƠN NGỮ LẬP TRÌNH LẬP TRÌNH C TRÊN WINDOWS Đối với thơng điệp hệ thống, cung cấp giá trị định danh từ 0x0000 đến 0x03FF, ứng dụng khơng định nghĩa thơng điệp có giá trị khoảng Thông điệp ứng dụng định nghĩa có giá trị định danh từ 0x0400 đến 0x7FFF Lộ trình thơng điệp từ lúc gởi đến lúc xử lý có hai dạng sau: Thơng điệp gởi vào hàng đợi thông điệp để chờ xử lý (queue message): bao gồm kiểu thông điệp phát sinh từ bàn phím, chuột thơng điệp : WM_MOUSEMOVE, WM_LBUTTONDOWN, WM_KEYDOWN, WM_CHAR Thông điệp gởi trực tiếp đến thủ tục xử lý không qua hàng đợi (nonqueue message), bao gồm thông điệp thời gian, thông điệp vẽ, thơng điệp WM_TIMER, WM_PAINT, WM_QUIT Xử lý thơng điệp : Một ứng dụng phải xóa xử lý thông điệp gởi tới hàng đợi ứng dụng Đối với ứng dụng đơn tiểu trình sử dụng vòng lặp thơng điệp (message loop) hàm WinMain để nhận thông điệp từ hàng đợi gởi tới thủ tục xử lý cửa sổ tương ứng Với ứng dụng nhiều tiểu trình tiểu trình có tạo cửa sổ có vòng lặp thơng điệp để xử lý thơng điệp cửa sổ tiểu trình 1.4 CÁCH VIẾT MỘT ỨNG DỤNG TRÊN MICROSOFT WINDOWS 1.4.1 Các thành phần tạo nên ứng dụng 1.4.1.1 Cửa sổ Trong ứng dụng đồ họa 32-bit, cửa sổ (window) vùng hình chữ nhật hình, nơi mà ứng dụng hiển thị thông tin nhận thông tin vào từ người sử dụng Do vậy, nhiệm vụ ứng dụng đồ họa 32-bit tạo cửa sổ Một cửa sổ chia sẻ hình với cửa sổ khác ứng dụng hay ứng dụng khác Chỉ cửa sổ thời điểm nhận thông tin nhập từ người dùng Người sử dụng dùng bàn phím, thiết bị chuột hay thiết bị nhập liệu khác để tương tác với cửa sổ ứng dụng Tất cửa sổ tạo từ cấu trúc cung cấp sẵn gọi lớp cửa sổ (window class) Cấu trúc tập mô tả thuộc tính mà hệ thống dùng khn mẫu để tạo nên cửa sổ Mỗi cửa sổ phải thành viên lớp cửa sổ Tất lớp cửa sổ xử lý riêng biệt 1.4.1.2 Hộp thoại điều khiển Hộp thoại (Dialog) dùng để tương tác với người dùng chương trình ứng dụng Một hộp thoại thường chứa nhiều khiển ô nhập văn (edit text), nút bấm (button), ghi (static control), hộp danh sách (list box)… ➢ Nút bấm (button): gồm có Push Button dùng kích hoạt thao tác, Check Box dùng để chọn hai trạng thái (TRUE hay FALSE), Radio Button giống Check Box nhóm Radio Button phải chọn loại trừ ➢ Chú thích (static): dùng để chứa ghi hộp thoại, ngồi nội dung thay đổi q trình sử dụng hộp thoại Trang CuuDuongThanCong.com https://fb.com/tailieudientucntt NGƠN NGỮ LẬP TRÌNH LẬP TRÌNH C TRÊN WINDOWS ➢ Hộp liệt kê (list box): Chọn hay nhiều liệu liệt kê danh sách, hộp chứa nhiều dòng hộp khơng hiển thị hết mẫu thơng tin phải kèm theo cuộn (scroll bar) ➢ Ô nhập văn (edit text): Dùng nhập văn bản, có nhiều dòng thường kèm theo cuộn ➢ Thanh cuộn (scroll bar): việc dùng kèm với list box hay edit box cuộn sử dụng độc lập nhằm tạo thước đo… ➢ Thực đơn (menu): danh sách chứa thao tác với định danh mà người dùng chọn Hầu hết ứng dụng có cửa sổ khơng thể thiếu thực đơn ➢ Thanh công cụ (toolbar): dạng menu chứa thao tác cần thiết dạng biểu tượng đặc trưng Ngồi nhiều điều khiển mà cơng cụ lập trình cung cấp cho người lập trình hay tự họ tạo dựa thành phần cung cấp sẵn 1.4.1.3 Ứng dụng điển hình Windows 1.4.1.4 Các kiểu tập tin để xây dựng ứng dụng Windows Chƣơng trình nguồn Tương tự chương trình C chuẩn, bao gồm tập tin tiêu đề (header) chứa tập tin *.h, *.hpp Còn mã nguồn (source code) chứa tập tin *.c hay *.cpp Tập tin định nghĩa Tập tin có phần mở rộng *.def, dùng định nghĩa điều khiển chương trình tạo viết ứng dụng tạo DLL, ngồi dùng để khai báo vùng nhớ heap chạy chương trình Lúc trước vấn đề tương thích với Windows 3.1 nên tập tin thường dùng, ngày chúng dùng đến Các file chứa tài nguyên ứng dụng ● Các file *.ico biểu tượng (icon) dùng chương trình Thơng thường cơng cụ lập trình Windows có tool để tạo ảnh ● Con trỏ chuột ứng dụng vẽ lại dạng biểu tượng lưu đĩa với dạng file *.cur ● Các file dạng ảnh bitmap dùng để minh họa lưu dạng file *.bmp ● Tập tin tài nguyên *.rc phần khai báo tài nguyên thực đơn, hộp thoại, định danh đến tập tin dạng *.ico, *.cur, *.bmp, 1.4.1.5 Các kiểu liệu Các kiểu liệu Windows thường định nghĩa nhờ toán tử typedef tập tin windows.h hay tập tin khác Thông thường tập tin định nghĩa Microsoft viết công ty viết trình biên dịch C tạo ra, thiết phải tương thích với hệ điều hành Windows 98, hay NT dựa kiến trúc 32-bit Một vài kiểu liệu có tên viết tắt dễ hiểu UINT liệu thường dùng mà đơn giản kiểu unsigned int, Windows 9x kiểu có kích thước 32-bit Đối với kiểu chuỗi có kiểu PSTR kiểu trỏ đến chuỗi tương tự char* Trang CuuDuongThanCong.com https://fb.com/tailieudientucntt NGƠN NGỮ LẬP TRÌNH LẬP TRÌNH C TRÊN WINDOWS Tuy nhiên, có số kiểu khái báo tên thiếu rõ ràng WPARAM LPARAM Tên đặt có nguồn ngốc lịch sử sâu xa Khi hệ điều hành Windows 16-bit tham số thứ hàm WndProc khai báo kiểu WORD, với kích thước 16-bit , tham số thứ có kiểu LONG 32-bit Đây lý người ta thêm tiến tố "W", "L" vào từ "PARAM" Tuy nhiên, phiên Windows 32-bit, WPARAM định nghĩa UINT LPARAM định nghĩa kiểu LONG, hai tham số có giá trị 32-bit Điều nhầm lẫn WORD giá trị 16-bit Window 98 Trong thủ tục xử lý cửa sổ WndProc giá trị trả kiểu LRESULT Kiểu đơn giản định nghĩa kiểu LONG Ngồi ra, có kiểu thường xun dùng kiểu HANDLE số nguyên 32-bit sử dụng kiểu định danh Có nhiều kiểu định danh thiết tất phải có kích thước với HANDLE Bảng sau mô tả số kiểu liệu mới: Kiể Ý nghĩa HA Số nguyên 32-bit, định danh HW Số nguyên 32-bit, định danh BY Giá trị 8-bit không dấu WO Số nguyên 16-bit không dấu DW Số nguyên 32-bit không dấu UIN Số nguyên không dấu 32-bit LO long 32-bit BO Bool u NDLE ND TE RD ORD T NG OL Trang CuuDuongThanCong.com https://fb.com/tailieudientucntt NGÔN NGỮ LẬP TRÌNH LẬP TRÌNH C TRÊN WINDOWS LPS Con trỏ chuỗi LPC Hằng trỏ chuỗi WP 32-bit TR STR ARAM LP 32-bit ARAM BST Giá trị 32-bit trỏ đến kí tự LP Con trỏ 32-bit đến kiểu khơng xác định R VOID Giống LPSTR chuyển sang dạng Unicode LPT STR DBCS Giống LPCTSTR chuyển sang dạng Unicode LPC TSTR DBCS Bảng 1.1 Mô tả kiểu liệu 1.4.2 Khuôn mẫu chung tạo ứng dụng Một ứng dụng đơn giản Windows bao gồm có hai hàm WinMain xử lý cửa sổ WinProc Do hai hàm quan trọng khơng thể thiếu ứng dụng Windows Hàm WinMain thực chức sau : ● Định nghĩa lớp cửa sổ ứng dụng ● Đăng ký lớp cửa sổ vừa định nghĩa ● Tạo thể cửa sổ lớp cho ● Hiển thị cửa sổ ● Khởi động chu trình xử lý thơng điệp Hàm xử lý WinProc có chức xử lý tất thơng điệp có liên quan đến cửa sổ Trang 10 CuuDuongThanCong.com https://fb.com/tailieudientucntt NGƠN NGỮ LẬP TRÌNH LẬP TRÌNH C TRÊN WINDOWS bSuccess = VirtualFree( lpvBase, // địa sở khối nhớ dwPages*PAGESIZE, // số byte trang cấp phát MEM_DECOMMIT); // hình thức khử xác nhận /* Cuối cùng, giải phóng tồn vùng nhớ (để dành) */ if (bSuccess) { bSuccess = VirtualFree( lpvBase, // địa sở khối nhớ 0, // giải phóng tồn khối nhớ MEM_RELEASE); // giải phóng (hồn tồn) } } INT PageFaultExceptionFilter(DWORD dwCode) { LPVOID lpvResult; /* Nếu xuất lỗi ngoại lệ, chương trình */ if (dwCode != EXCEPTION_ACCESS_VIOLATION) { printf("exception code = %d\n", dwCode); return EXCEPTION_EXECUTE_HANDLER; } printf("page fault\n"); /* Nếu trang để dành dùng */ if (dwPages >= PAGELIMIT) { printf("out of pages\n"); return EXCEPTION_EXECUTE_HANDLER; } /* Ngược lại, cấp phát xác nhận trang khác */ lpvResult = VirtualAlloc( (LPVOID) lpNxtPage, // cấp phát trang PAGESIZE, // số byte kích thuớc trang MEM_COMMIT, // cấp phát xác nhận trang PAGE_READWRITE); // truy cập đọc-ghi if (lpvResult == NULL ) { printf("VirtualAlloc failed\n"); return EXCEPTION_EXECUTE_HANDLER; Trang 152 CuuDuongThanCong.com https://fb.com/tailieudientucntt NGƠN NGỮ LẬP TRÌNH LẬP TRÌNH C TRÊN WINDOWS } /* Tăng trang đếm, chuyển lpNxtPage đến trang tiếp */ dwPages++; lpNxtPage += PAGESIZE; /* Tiếp tục thực nơi lỗi trang xuất */ return EXCEPTION_CONTINUE_EXECUTION; } Đoạn chương trình thực thao tác tạo trang "lính canh" Trang cung cấp cảnh báo truy cập trang vùng nhớ Điều hữu ích cho ứng dụng cần quản lý mở rộng cấu trúc liệu động Để tạo trang “lính canh”, ta thiết lập cờ PAGE_GUARD hàm VirtualAlloc Cờ dùng kết hợp với tất cờ khác, trừ cờ PAGE_NOACCESS Nếu chương trình truy cập trang "lính canh", hệ thống phát sinh lỗi ngoại lệ STATUS_GUARD_PAGE (0x80000001) Hệ thống xoá cờ PAGE_GUARD, loại bỏ tình trạng "lính canh" trang vùng nhớ Hệ thống không ngừng truy cập trang vùng nhớ với lỗi ngoại lệ STATUS_GUARD_PAGE Nếu lỗi ngoại lệ xuất suốt dịch vụ hệ thống, dịch vụ trả giá trị xác định lỗi Nếu sau ta truy cập lại trang (mà chưa thiết lập lại tình trạng "lính canh"), khơng xảy lỗi ngoại lệ Chương trình sau minh họa cách thực trang lính canh, tượng xuất lỗi dịch vụ hệ thống : #include #include #include int main() { LPVOID lpvAddr; DWORD cbSize; BOOL vLock; LPVOID commit; cbSize = 512; // Vùng nhớ cần cấp phát /* Gọi hàm cấp phát */ lpvAddr=VirtualAlloc(NULL,cbSize,MEM_RESERVE, PAGE_NOACCESS); if(lpvAddr == NULL) { fprintf(stdout,"VirtualAlloc failed on RESERVE with %ld\n", GetLastError()); } /* Cấp phát xác nhận vùng nhớ */ commit = VirtualAlloc(NULL,cbSize,MEM_COMMIT, Trang 153 CuuDuongThanCong.com https://fb.com/tailieudientucntt NGƠN NGỮ LẬP TRÌNH LẬP TRÌNH C TRÊN WINDOWS PAGE_READONLY|PAGE_GUARD); if(commit == NULL) { fprintf(stderr,"VirtualAlloc failed on COMMIT with %ld\n", GetLastError()); } else { fprintf(stderr,"Committed %lu bytes at address %lp\n", cbSize,commit); } /* Khoá vùng nhớ xác nhận */ vLock = VirtualLock(commit,cbSize); if(!vLock) { fprintf(stderr,"Cannot lock at %lp, error = %lu\n", commit, GetLastError()); } else fprintf(stderr,"Lock Achieved at %lp\n",commit); /* Khoá vùng nhớ lần */ vLock = VirtualLock(commit,cbSize); if(!vLock) { fprintf(stderr,"Cannot get 2nd lock at %lp, error = %lu\n", commit, GetLastError()); } else fprintf(stderr,"2nd Lock Achieved at %lp\n",commit); } Chương trình cho kết tương tự kết sau : Committed 512 bytes at address 003F0000 Cannot lock at 003F0000, error = 0x80000001 2nd Lock Achieved at 003F0000 Chú ý : Lần khoá thứ thất bại, tạo lỗi ngoại lệ STATUS_GUARD_PAGE Tuy nhiên, lần khố thứ hai, hàm thực thành cơng, hệ thống loại bỏ tình trạng "lính canh" trang 7.3 XỬ LÝ TẬP TIN Trang 154 CuuDuongThanCong.com https://fb.com/tailieudientucntt NGÔN NGỮ LẬP TRÌNH LẬP TRÌNH C TRÊN WINDOWS Tập tin đơn vị lưu trữ để máy tính phân biệt khối thơng tin khác nhau, lưu trữ thiết bị lưu trữ phụ đĩa, băng từ, tổ chức theo nhóm gọi thư mục Để xử lý tập tin, ta dùng hàm C chuẩn fopen, fclose, fread, fwrite, fseek, … môi trường Windows Các hàm hỗ trợ thư viện stdio.h Chúng ta không bàn hàm Trong phần này, tìm hiểu hàm thao tác tập tin Win32® cho phép ứng dụng tạo, mở, cập nhật xoá tập tin, tìm hiểu thơng số hệ thống tập tin 7.3.1 Tạo mở tập tin Win32® API cung cấp hàm CreateFile để tạo tập tin mở tập tin có sẵn HANDLE CreateFile(LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile); Trường lpFileName trỏ đến chuỗi ký tự zero xác định tên tập tin cần mở tạo Trường dwDesiredAccess xác định cách thức truy cập đối tượng Một ứng dụng thực truy cập đọc, ghi, đọc-ghi, sử dụng hay kết hợp giá trị sau : Giá trị Xác định truy vấn thiết bị đến đối tượng Một ứng dụng truy vấn thuộc tính thiết bị mà không cần phải truy cập thiết bị GENERIC_R Xác lập hình thức truy cập đọc Dữ liệu đọc từ tập tin, đồng thời dịch chuyển trỏ tập tin Để truy cập đọc-ghi, ta kết hợp với cờ GENERIC_WRITE GENERIC_ Xác lập hình thức truy cập ghi Dữ liệu ghi vào tập tin, đồng thời dịch chuyển trỏ Để truy cập đọcghi, ta kết hợp với cờ GENERIC_READ EAD WRITE Ý nghĩa Bảng 7.4 Trường dwDesiredAccess xác định cách truy cập đối tượng Trường dwShareMode thiết lập bit cờ xác định cách chia sẻ đối tượng (tập tin) Nếu dwShareMode 0, đối tượng khơng thể chia sẻ Khi đó, ta thao tác đối tượng đóng handle Để chia sẻ đối tượng, ta kết hợp cờ sau : Trang 155 CuuDuongThanCong.com https://fb.com/tailieudientucntt NGƠN NGỮ LẬP TRÌNH LẬP TRÌNH C TRÊN WINDOWS FILE_SHARE_D Sử dụng Windows NT : Thao tác đối tượng thực yêu cầu truy cập xoá FILE_SHARE_R Thao tác đối tượng thực yêu cầu truy cập đọc FILE_SHARE_ Thao tác đối tượng thực yêu cầu truy cập ghi ELETE EAD WRITE Bảng 7.5 Trường dwShareMode xác định cách chia sẻ đối tượng Trường lpSecurityAttributes trỏ đến cấu trúc SECURITY_ATTRIBUTES xác định handle đối tượng có chuyển cho tiến trình hay khơng Ở không dùng, thiết lập giá trị NULL Trường dwCreationDisposition xác lập thao tác tạo tập tin hay mở tập tin có Dùng giá trị sau : Tạo tập tin Hàm thất bại tập tin CREATE_NEW có CREATE_ALW AYS Tạo tập tin Nếu tập tin tồn tại, hàm tạo chồng lên, đồng thời xoá thuộc tính hành tập tin Mở tập tin Hàm thất bại tập tin chưa có sẵn OPEN_EXISTIN G OPEN_ALWAY Mở tập tin có sẵn Nếu tập tin chưa tồn tại, hàm tạo tập tin sử dụng cờ CREATE_NEW TRUNCATE_EX Mở tập tin Khi mở, hệ thống khởi tạo kích thước tập tin lại byte Tiến trình gọi cần mở tập tin nhật với dạng truy cập GENERIC_WRITE Hàm thất bại không tồn tập tin S ISTING Bảng 7.6 Trường dwCreationDisposition xác lập thao tác tập tin Trường dwFlagsAndAttributes xác định thuộc tính cờ cho tập tin Ta kết hợp thuộc tính sau : FILE_ATTRIBUTE_ARCHIVE Tập tin archive Ứng dụng dùng thuộc tính để Trang 156 CuuDuongThanCong.com https://fb.com/tailieudientucntt NGƠN NGỮ LẬP TRÌNH LẬP TRÌNH C TRÊN WINDOWS đánh dấu tập tin lưu loại bỏ FILE_ATTRIBUTE_HIDDEN Tập tin ẩn Không hiển thị danh sách tập tin thông thường thư mục FILE_ATTRIBUTE_NORMAL Tập tin thuộc tính khác Thuộc tính thường dùng FILE_ATTRIBUTE_OFFLINE Dữ liệu tập tin khơng có sẵn Dữ liệu định di chuyển vật lý vào vùng lưu trữ offline FILE_ATTRIBUTE_READONLY Tập tin đọc Ứng dụng khơng thể ghi xố liệu tập tin FILE_ATTRIBUTE_SYSTEM Tập tin phần hệ điều hành, sử dụng đặc biệt hệ thống FILE_ATTRIBUTE_TEMPORARY Tập tin dùng cho vùng lưu trữ tạm Sau ứng dụng kết thúc, tập tin xóa Bảng 7.7 Trường dwFlagsAndAttributes xác định thuộc tính cờ cho tập tin Các cờ xác định tập tin phức tạp, không bàn kỹ Trường cuối hTemplateFile xác định handle truy cập GENERAL_READ đến tập tin tạm Tập tin tạm có vai trò hỗ trợ thuộc tính tập tin thuộc tính mở rộng cho tập tin tạo Trong Windows 95, giá trị hTemplateFile cần gán NULL Nếu thành công hàm trả handle tập tin xác định Ngược lại, giá trị trả INVALID_HANDLE_VALUE Lưu ý, việc thiết lập giá trị dwDesiredAccess cho phép ứng dụng truy vấn thuộc tính thiết bị mà không thực truy cập thiết bị Điều hữu dụng, ví dụ trường hợp ứng dụng muốn xác định kích thước định dạng ổ đĩa mềm mà khơng cần phải có đĩa ổ đĩa Khi tạo tập tin, hàm CreateFile thực chức sau: ● Kết hợp cờ thuộc tính tập tin xác định cờ dwFlagsAndAttributes với giá trị FILE_ATTRIBUTE_ARCHIVE ● Thiết lập kích thước tập tin ● Chép thuộc tính mở rộng tập tin tạm vào tập tin biến hTemplateFile xác định Khi mở tập tin có sẵn, hàm CreateFile thực chức sau : Trang 157 CuuDuongThanCong.com https://fb.com/tailieudientucntt NGƠN NGỮ LẬP TRÌNH LẬP TRÌNH C TRÊN WINDOWS ● Kết hợp cờ xác định dwFlagsAndAttributes với thuộc tính tập tin có Hàm CreateFile bỏ qua thuộc tính tập tin xác định cờ dwFlagsAndAttributes ● Thiết lập kích thước tập tin dựa vào giá trị dwCreationDisposition ● Bỏ qua giá trị biến hTemplateFile Nếu hàm tạo tập tin ổ đĩa mềm khơng có đĩa mềm, CD-ROM khơng có đĩa CD, hệ thống đưa hộp thoại thông điệp (message box) yêu cầu người dùng đưa đĩa mềm đĩa CD vào Để hệ thống không thực thao tác trên, cần thiết lập giá trị uMode hàm SetErrorMode SEM_FAILCRITICALERRORS UINT SetErrorMode(UINT uMode); Trong ví dụ sau, hàm CreateFile mở tập tin có để đọc : HANDLE hFile; hFile = CreateFile("MYFILE.TXT", // mở tập tin MYFILE.TXT GENERIC_READ, // mở để đọc FILE_SHARE_READ, // chia sẻ để đọc NULL, // không bảo mật OPEN_EXISTING, // mở tập tin có FILE_ATTRIBUTE_NORMAL, //Tập tin thường NULL); // khơng có tính tạm if (hFile == INVALID_HANDLE_VALUE) { ErrorHandler("Could not open file."); // lỗi xử lý } Để xố tập tin trên, trước hết ta đóng tập tin lại CloseHandle(hFile); DeleteFile("MYFILE.TXT"); Trong ví dụ sau, hàm tạo tập tin mở chế độ ghi HANDLE hFile; hFile = CreateFile("MYFILE.TXT", // tập tin MYFILE.TXT GENERIC_WRITE, // tạo để ghi 0, // không chia sẻ NULL, // không bảo mật CREATE_ALWAYS, // ghi chồng có FILE_ATTRIBUTE_NORMAL | // tập tin bình thường FILE_FLAG_OVERLAPPED, // khơng đồng I/O NULL); // khơng thuộc tính tạm if (hFile == INVALID_HANDLE_VALUE) { Trang 158 CuuDuongThanCong.com https://fb.com/tailieudientucntt NGƠN NGỮ LẬP TRÌNH LẬP TRÌNH C TRÊN WINDOWS ErrorHandler("Could not open file."); // lỗi xử lý } 7.3.2 Tạo tập tin tạm Các ứng dụng nhận tập tin cho tập tin tạm cách sử dụng hàm GetTempFileName Để xác định đường dẫn đến thư mục chứa tập tin tạm tạo, ta dùng hàm GetTempPath Hàm GetTempFileName tạo tên tập tin tạm Tên tập tin đầy đủ gồm đường dẫn nối với chuỗi ký tự số thập lục phân thể tên tập tin, phần mở rộng TMP UINT GetTempFileName(LPCTSTR lpPathName, LPCTSTR lpPrefixString, UINT uUnique, LPTSTR lpTempFileName); Trường lpPathName trỏ đến chuỗi ký tự (kết thúc ký tự NULL) xác định đường dẫn tập tin, dùng ký tự ANSI Nếu trường NULL, hàm thất bại Trường lpPrefixString trỏ đến chuỗi ký tự (kết thúc ký tự NULL) Hàm sử dụng ký tự chuỗi phần tiền tố tập tin Các ký tự sử dụng phải ky tự ANSI Trường uUnique xác định số nguyên không dấu (mà) hàm chuyển thành chuỗi ký tự thập lục phân sử dụng việc tạo tập tin tạm Trường lpTempFileName trỏ đến vùng nhớ đệm chứa tên tập tin tạm Trường chuỗi ký tự kết thúc NULL ký tự ANSI Độ dài vùng nhớ đệm xác định giá trị MAX_PATH thư mục tương ứng Tập tin tạo có dạng sau : path\preuuuu.TMP Trong path đường dẫn, xác định giá trị lpPathName; pre ký tự đầu chuỗi lpPrefixString; uuuu giá trị thập lục phân uUnique Khi thoát khỏi hệ điều hành (tắt máy chẳng hạn), tập tin tạm tạo hàm tự động bị xoá Để tránh lỗi chuyển chuỗi ANSI, ứng dụng cần gọi hàm CreateFile trước để tạo tập tin tạm Nếu giá trị uUnique 0, hàm GetTempFileName xác lập số dựa thời điểm hệ thống Nếu tập tin có, hệ thống tự tăng lên số có tên Nếu thực thành công, hàm trả số xác định trường uUnique Ngược lại, giá trị trả Để thu nhận đường dẫn tập tin tạm, ta dùng hàm GetTempPath DWORD GetTempPath(DWORD nBufferLength, LPTSTR lpBuffer); Trường nBufferlength xác định kích thước vùng đệm chuỗi ký tự xác định lpBuffer Trường lpBuffer trỏ đến vùng đệm nhận chuỗi ký tự xác định đường dẫn tập tin tạm Chuỗi ký tự kết thức ký tự „\‟, ví dụ : C:\TEMP\ Trang 159 CuuDuongThanCong.com https://fb.com/tailieudientucntt NGƠN NGỮ LẬP TRÌNH LẬP TRÌNH C TRÊN WINDOWS Nếu thành công, hàm trả độ lớn xác định kích thước chuỗi zero Nếu giá trị trả lớn nBufferLength, giá trị trả kích thước vùng đệm cần để chứa đường dẫn Ngược lại, giá trị trả hàm thất bại 7.3.3 Sao chép di chuyển tập tin Để chép (copy) tập tin, ta cần mở chế độ đọc Sau dùng hàm CopyFile để chép vào tập tin BOOL CopyFile(LPCTSTR lpExistingFileName, LPCTSTR lpNewFileName, BOOL bFailIfExists); Trường lpExistingFileName lpNewFileName trỏ đến chuỗi (kết thúc NULL) xác định tên tập tin có tên tập tin Trường bFialIfExists xác định cách tạo tập tin với tên Nếu trường thiết lập TRUE, tập tin có tên lpNewFileName tồn tại, hàm thất bại Nếu trường thiết lập FALSE tập tin tồn tại, hàm tạo tập tin chồng lên tập tin cũ Nếu thành công, hàm trả giá trị khác Ngược lại, giá trị trả Để di chuyển (move) tập tin, trước hết cần phải đóng tập tin lại (nếu mở) Ta dùng hàm MoveFile Hàm thực thao tác đổi tên tập tin hay thư mục (bao gồm tập tin thư mục) BOOL MoveFile(LPCTSTR lpExistingFileName, LPCTSTR lpNewFileName); Hai trường trỏ đến tên tập tin (thư mục) có tên tập tin (thư mục) Tên tập tin (thư mục) cần phải chưa có đường dẫn Tên tập tin hệ thống hay ổ đĩa khác, tên thư mục phải ổ đĩa với thư mục cũ Nếu thành công, giá trị trả khác Ngược lại, giá trị trả Ví dụ sau minh họa việc tạo sử dụng tập tin tạm để copy tập tin Đầu tiên ứng dụng mở tập tin ORIGINAL.TXT cách sử dụng hàm CreateFile Sau ứng dụng sử dụng hàm GetTempFileName CreateFile để tạo tập tin tạm Ứng dụng đọc khối 4K liệu vào vùng đệm, chuyển nội dung vùng đệm sang chữ hoa, viết chúng xuống tập tin tạm Sau chuyển toàn tập tin sang tập tin tạm, ta đổi tập tin tạm thành ALLCAPS.TXT cách dùng hàm MoveFile HANDLE hFile; HANDLE hTempFile; DWORD dwBytesRead, dwBytesWritten, dwPos; char szTempName[MAX_PATH]; char buffer[4096]; /* Mở tập tin có sẵn */ hFile = CreateFile("ORIGINAL.TXT", // tên tập tin GENERIC_READ, // mở để đọc 0, // không chia sẻ NULL, // không bảo mật OPEN_EXISTING, // tập tin có sẵn FILE_ATTRIBUTE_NORMAL, // tập tin thơng thường Trang 160 CuuDuongThanCong.com https://fb.com/tailieudientucntt NGƠN NGỮ LẬP TRÌNH LẬP TRÌNH C TRÊN WINDOWS NULL); // khơng thuộc tính tạm if (hFile == INVALID_HANDLE_VALUE) { ErrorHandler("Could not open file."); // xử lý lỗi } /* Tạo tập tin tạm */ GetTempFileName("\\TEMP", // thư mục chứa tập tin tạm "NEW", // phần đầu tập tin tạm 0, // tạo tên szTempName); // vùng đệm tên hTempFile = CreateFile((LPTSTR) szTempName, // tên tập tin GENERIC_READ | GENERIC_WRITE, // mở dạng đọc-ghi 0, // không chia sẻ NULL, // không bảo mật CREATE_ALWAYS, // tạo chồng tập tin có FILE_ATTRIBUTE_NORMAL, // tập tin thơng thường NULL); // khơng thuộc tính tạm if (hTempFile == INVALID_HANDLE_VALUE) { ErrorHandler("Could not create temporary file."); } /* Đọc khối 4K vào vùng đệm Chuyển tất ký tự vùng đệm sang dạng chữ hoa Viết vùng đệm vào tập tin tạm */ { if (ReadFile(hFile, buffer, 4096, &dwBytesRead, NULL)) { CharUpperBuff(buffer, dwBytesRead); WriteFile(hTempFile, buffer, dwBytesRead, &dwBytesWritten, NULL); } } while (dwBytesRead == 4096); /* Đóng hai tập tin */ CloseHandle(hFile); CloseHandle(hTempFile); /* Chuyển tập tin tạm vào tập tin ALLCAPS.TXT */ if (!MoveFile(szTempName, "ALLCAPS.TXT")) { ErrorHandler("Could not move temp file."); } Trang 161 CuuDuongThanCong.com https://fb.com/tailieudientucntt NGÔN NGỮ LẬP TRÌNH LẬP TRÌNH C TRÊN WINDOWS Hàm CloseHandle đóng tập tin mở Xem phần 7.3.6 7.3.4 Đọc ghi liệu vào tập tin Mỗi tập tin mở có trỏ tập tin xác định byte đọc ghi Khi tập tin mở lần đầu tiên, hệ thống thiết lập trỏ tập tin vị trí đầu tập tin Mỗi đọc ghi vào byte, trỏ tập tin tự động dịch chuyển Để thay đổi vị trí này, ta dùng hàm SetFilePointer DWORD SetFilePointer(HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod); Trường hFile handle tập tin chứa trỏ tập tin cần di chuyển Handle cần tạo dạng truy cập GENERIC_READ GENERIC_WRITE Trường lDistanceToMove lpDistanceToMoveHigh xác định số byte trỏ cần dịch chuyển Nếu lpDistanceToMoveHigh NULL, 32-bit thấp lDistanceToMove xác định số byte cần di dời trỏ Ngược lại, hai trường thiết lập giá trị 64-bit (không dấu) thể số byte cần di dời trỏ Trường dwMoveMethod xác định điểm gốc mà trỏ cần di dời Nếu trường FILE_BEGIN, điểm gốc điểm (byte thứ 0) tập tin Nếu FILE_CURRENT, điểm gốc vị trí trỏ Và FILE_END xác định điểm gốc vị trí cuối tập tin Nếu thành công, lpDistanceToMoveHigh NULL, giá trị trả DWORD thấp trỏ tập tin Nếu lpDistanceToMoveHigh khác NULL, hàm trả DWORD thấp trỏ tập tin, trỏ trường đến DWORD cao trỏ tập tin Nếu hàm thất bại lpDistanceToMoveHigh NULL, giá trị trả 0xFFFFFFFF Để biết thêm thông tin lỗi, ta dùng hàm GetLastError Nếu hàm trả 0xFFFFFFFF lpDistanceToMoveHigh, hàm thành công thất bại, cần phải gọi hàm GetLastError để xác định Đoạn chương trình sau trình bày vấn đề : /* Trường hợp 1: Gọi hàm với lpDistanceToMoveHigh == NULL */ /* Cố gắng di chuyển trỏ tập tin hFile đoạn */ dwPtr = SetFilePointer(hFile, lDistance, NULL, FILE_BEGIN); if (dwPtr == 0xFFFFFFFF) // Kiểm tra thất bại { dwError = GetLastError() ; // Nhận mã lỗi // Xử lý lỗi } // Cuối phần xử lý lỗi /* Trường hợp 2: Gọi hàm với lpDistanceToMoveHigh != NULL */ /* Cố gắng di chuyển trỏ tập tin hFile đoạn dài */ dwPtrLow = SetFilePointer(hFile, lDistLow, & lDistHigh, FILE_BEGIN); /* Kiểm tra thất bại */ if (dwPtrLow==0xFFFFFFFF&&(dwError=GetLastError())!=NO_ERROR) { Trang 162 CuuDuongThanCong.com https://fb.com/tailieudientucntt NGƠN NGỮ LẬP TRÌNH LẬP TRÌNH C TRÊN WINDOWS // Xử lý lỗi // } // Cuối phần xử lý lỗi Để di chuyển tiến, ta thiết lập độ dịch chuyển giá trị dương Ngược lại, thiết lập giá trị âm để di chuyển lùi trỏ tập tin Nếu giá trị trỏ tập tin sau dịch chuyển âm, hàm thất bại, mã lỗi mà hàm GetlastError trả ERROR_NEGATIVE_SEEK Nếu muốn di chuyển trỏ đến cuối tập tin để ghi tiếp, ta dùng hàm SetEndOfFile BOOL SetEndOfFile(HANDLE hFile); Trường hFile handle tập tin cần di chuyển trỏ đến cuối tập tin cần tạo với dạng truy cập GENERAL_WRITE Nếu thành công, hàm trả giá trị khác Ngược lại, giá trị trả Hàm ReadFile đọc liệu từ tập tin, từ điểm xác định trỏ tập tin Sau đọc, trỏ tập tin dịch chuyển đoạn ứng với số byte thật đọc Tương tự, để ghi vào tập tin ta dùng hàm WriteFile BOOL ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped); BOOL WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped); Handle tập tin hFile cần tạo với dạng truy cập GENERAL_READ GENERAL_WRITE Trường lpBuffer trỏ đến vùng nhớ đệm nhận liệu đọc từ tập tin, hay chứa liệu cần ghi Trường nNumberOfBytesToRead xác định số byte cần đọc Trường lpNumberOfBytesRead trỏ đến byte đọc Hàm ReadFile thiết lập giá trị trước thực thao tác khác để kiểm tra lỗi Trường nNumberOfBytesToWrite xác định số byte cần ghi Nếu trường 0, hàm không ghi liệu, gọi thực Trường lpNumberOfBytesWritten xác định số byte ghi được, trường hàm WriteFile thiết lập trước thực thao tác khác để kiểm tra lỗi Cuối cùng, trường lpOverlapped trỏ đến cấu trúc OVERLAPPED Nếu tập tin mở với cờ FILE_FLAG_OVERLAPPED, giá trị phải khác NULL Để đơn giản ta thiết lập giá trị NULL, hàm đọc (ghi) tập tin từ vị trí trỏ hàm trả kết sau đọc (ghi) xong Hàm ReadFile dừng với số lý sau : thao tác ghi hoàn tất cuối đường ống ghi, đọc hết số byte yêu cầu, xảy lỗi đọc Nếu thành công, hàm trả giá trị khác Ngược lại, giá trị trả 7.3.5 Khoá mở khoá tập tin Trang 163 CuuDuongThanCong.com https://fb.com/tailieudientucntt NGƠN NGỮ LẬP TRÌNH LẬP TRÌNH C TRÊN WINDOWS Mặc dù hệ thống cho phép nhiều ứng dụng mở ghi vào tập tin, ứng dụng không nên thực song song Để ngăn chặn ứng dụng khác ghi vào phần liệu mình, ta sử dụng hàm LockFile Để mở khố tập tin, cho phép ứng dụng khác truy cập vùng liệu, ta dùng hàm UnlockFile BOOL LockFile(HANDLE hFile, DWORD dwFileOffsetLow, DWORD dwFileOffsetHigh, DWORD nNumberOfBytesToLockLow, DWORD nNumberOfBytesToLockHigh); BOOL UnlockFile(HANDLE hFile, DWORD dwFileOffsetLow, DWORD dwFileOffsetHigh, DWORD nNumberOfBytesToUnlockLow, DWORD nNumberOfBytesToUnlockHigh); Trường hFile handle tập tin mở dạng GENERAL_READ GENERAL_WRITE, hai Trường dwFileOffsetLow dwFileOffsetHigh xác định word thấp cao byte offset cần khoá hay mở khoá Trường nNumberofBytesToLockLow (nNumberofBytesTo UnlockLow) nNumberOfBytesToLockHigh (nNumberOf BytesToUnlockHigh) xác định word thấp cao độ dài khoảng byte cần khố hay mở khóa Nếu thành công, hàm trả giá trị khác Ngược lại, giá trị trả Ví dụ sau nối tập tin vào tập tin khác Ứng dụng sử dụng hàm CreateFile mở tập tin ONE.TXT để đọc, TWO.TXT để viết Sau ứng dụng nối phần liệu tập tin ONE.TXT vào cuối tập tin TWO.TXT cách đọc (dùng hàm ReadFile) ghi (dùng hàm WriteFile) khối 4K liệu Trước viết vào tập tin thứ hai, ứng dụng dịch chuyển trỏ đến cuối tập tin cách dùng hàm SetFilePointer, sau khóa vùng cần ghi dùng hàm LockFile Sau thực thao tác ghi xong, ta mở khoá, dùng hàm UnlockFile, để ứng dụng khác sử dụng tập tin HANDLE hFile; HANDLE hAppend; DWORD dwBytesRead, dwBytesWritten, dwPos; char buff[4096]; /* Mở tập tin có */ hFile = CreateFile("ONE.TXT", // mở tập tin ONE.TXT GENERIC_READ, // mở để đọc 0, // không chia sẻ NULL, // không bảo mật OPEN_EXISTING, // mở tập tin tồn FILE_ATTRIBUTE_NORMAL, // tập tin bình thường NULL); // khơng có thuộc tính tạm if (hFile == INVALID_HANDLE_VALUE) { ErrorHandler("Could not open ONE."); // xử lý lỗi Trang 164 CuuDuongThanCong.com https://fb.com/tailieudientucntt NGÔN NGỮ LẬP TRÌNH LẬP TRÌNH C TRÊN WINDOWS } /* Mở tập tin có Nếu chưa có, tạo tập tin */ hAppend = CreateFile("TWO.TXT", // mở tập tin TWO.TXT GENERIC_WRITE, // mở để ghi 0, // không chia sẻ NULL, // không bảo mật OPEN_ALWAYS, // mở tập tin cũ tạo FILE_ATTRIBUTE_NORMAL, // tập tin bình thường NULL); // khơng có thuộc tính tạm if (hAppend == INVALID_HANDLE_VALUE) { ErrorHandler("Could not open TWO."); // xử lý lỗi } /* Nối tập tin thứ vào cuối tập tin thứ hai Khoá tập tin thứ hai để ngăn chặn tiến trình khác truy cập ghi Mở khoá sau ghi xong */ { if (ReadFile(hFile, buff, 4096, &dwBytesRead, NULL)) { dwPos= SetFilePointer(hAppend, 0, NULL, FILE_END); LockFile(hAppend, dwPos, 0, dwPos+dwBytesRead, 0); WriteFile(hAppend, buff, dwBytesRead, &dwBytesWritten, NULL); UnlockFile(hAppend, dwPos, 0, dwPos+dwBytesRead, 0); } } while (dwBytesRead == 4096); /* Đóng hai tập tin */ CloseHandle(hFile); CloseHandle(hAppend); 7.3.6 Đóng xố tập tin Để sử dụng hiệu tài nguyên hệ thống, ứng dụng cần đóng tập tin không cần dùng cách gọi hàm CloseHandle Nếu ứng dụng bị ngắt tập tin mở, hệ thống tự động đóng tập tin BOOL CloseHandle(HANDLE hObject); Nếu thành công, hàm trả giá trị khác Ngược lại, giá trị trả Để biết thông tin lỗi mở rộng, ta dùng hàm GetLastError Để xoá tập tin, ta dùng hàm DeleteFile Lưu ý tập tin cần phải đóng trước bị xóa BOOL DeleteFile(LPCTSTR lpFileName); Trang 165 CuuDuongThanCong.com https://fb.com/tailieudientucntt NGƠN NGỮ LẬP TRÌNH LẬP TRÌNH C TRÊN WINDOWS Trường lpFileName trỏ đến chuỗi (kết thúc ký tự NULL) xác định tập tin cần xoá Nếu thành công, hàm trả trị khác Ngược lại, giá trị trả Hàm thất bại tập tập tin cần xố khơng tồn Trong Windows NT, hàm khơng thể xố tập tin mở Tuy nhiên, Windows 95, tập tin mở bị xố 7.3.7 Xử lý thƣ mục Khi ứng dụng tạo tập tin mới, hệ điều hành thêm tập tin vào thư mục xác định Để tạo xoá thư mục, ta dùng hàm CreateDirectory RemoveDirectory BOOL CreateDirectory(LPCTSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecurityAttributes); BOOL RemoveDirectory(LPCTSTR lpPathName); Trường lpPathName trỏ đến chuỗi (kết thúc ký tự NULL) xác định đường dẫn thư mục cần tạo (hay cần xố) Kích thước chuỗi mặc định giới hạn cho đường dẫn MAX_PATH ký tự Trong trường hợp xoá thư mục, đường dẫn cần xác định thư mục thư mục rỗng Trường lpSecurityAttributes trỏ đến cấu trúc SECURITY_ATTRIBUTES chứa trường lpSecurityDescriptor xác định mô tả mật thư mục Để đơn giản, ta gán giá trị lpSecurityAttributes NULL, thư mục nhận giá trị mô tả mật mặc định Nếu thành công, hàm trả giá trị khác Ngược lại, giá trị trả Thư mục cuối đường dẫn sử dụng gọi thư mục hành Để xác định thư mục hành, ứng dụng gọi hàm GetCurrentDirectory Để thay đổi thư mục hành, ứng dụng gọi hàm SetCurrentDirectory DWORD GetCurrentDirectory(DWORD nBufferLength, LPTSTR lpBuffer); Trường nBufferLength xác định kích thước vùng đệm chuỗi ký tự thể thư mục hành Vùng đệm phải dài đủ để chứa ký tự NULL cuối chuỗi Trường lpBuffer chứa chuỗi ký tự Nếu thành công, hàm trả giá trị xác định số ký tự ghi vào vùng đệm, không chứa ký tự NULL Ngược lại, giá trị trả Nếu vùng đệm lpBuffer không đủ lớn, giá trị trả xác định kích thước cần thiết vùng đệm, gồm byte NULL đáng dấu kết thúc chuỗi BOOL SetCurrentDirectory(LPCTSTR lpPathName); Trường lpPathName trỏ đến chuỗi ký tự (kết thúc NULL) xác định đường dẫn Nếu thành công, hàm trả giá trị khác Ngược lại, giá trị trả Trang 166 CuuDuongThanCong.com https://fb.com/tailieudientucntt ... HDC hdc ; RECT rect ; hdc = GetDC (hwnd) ; GetClientRect (hwnd, &rect) ; if(iBrush==IDC_HS_BDIAGONAL) hbrush=CreateHatchBrush(HS_BDIAGONAL, crColor[iColor-IDC_BLACK]); if(iBrush == IDC_HS_CROSS)... Windows ph c tạp chúng c hình th c chung Chương trình ứng dụng thuờng chiếm phạm vi hình chữ nhật hình gọi c a sổ Trên c a sổ tiêu đề (title bar) C c ch c chương trình liệt kê th c đơn lựa chọn... WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon ( NULL, IDI_APPLICATION ); wndclass.hCursor = LoadCursor ( NULL, IDC_ARROW

Ngày đăng: 26/12/2019, 20:15

Tài liệu cùng người dùng

Tài liệu liên quan