Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 202 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
202
Dung lượng
1,4 MB
Nội dung
NGÔN NGỮ LẬP TRÌNH LẬP TRÌNH C TRÊN WINDOWS LẬP TRÌNH C TRÊN WINDOWS Trang NGÔN NGỮ LẬP TRÌNH Bách khoa Online: hutonline.net 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 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 Ngoà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 khuôn 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 Trang NGÔN NGỮ LẬP TRÌNH Bách khoa Online: hutonline.net LẬP TRÌNH C TRÊN WINDOWS 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 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 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 nguyên 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 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 Trang NGÔN NGỮ LẬP TRÌNH Bách khoa Online: hutonline.net LẬP TRÌNH C TRÊN WINDOWS 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 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 Trang NGÔN NGỮ LẬP TRÌNH Bách khoa Online: hutonline.net LẬP TRÌNH C TRÊN WINDOWS 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 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 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 Trang NGÔN NGỮ LẬP TRÌNH Bách khoa Online: hutonline.net LẬP TRÌNH C TRÊN WINDOWS Đ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 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 hoàn toàn thông thạo C học lập trình Windows Để lập trình Windows yê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 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 Ngoài yêu cầu trên, 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 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ổ Trang NGÔN NGỮ LẬP TRÌNH Bách khoa Online: hutonline.net LẬP TRÌNH C TRÊN WINDOWS 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 Đố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 Trang NGÔN NGỮ LẬP TRÌNH Bách khoa Online: hutonline.net LẬP TRÌNH C TRÊN WINDOWS 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 thoát 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 khuôn 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, nội dung thay đổi trình sử dụng hộp thoại ¾ 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 Trang NGÔN NGỮ LẬP TRÌNH Bách khoa Online: hutonline.net LẬP TRÌNH C TRÊN WINDOWS ¾ 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ổ 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 Ngoà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, 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 NGÔN NGỮ LẬP TRÌNH Bách khoa Online: hutonline.net 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 Ngoài ra, có kiểu thường xuyên 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ểu Ý nghĩa HANDLE Số nguyên 32-bit, định danh HWND Số nguyên 32-bit, định danh BYTE Giá trị 8-bit không dấu WORD Số nguyên 16-bit không dấu DWORD Số nguyên 32-bit không dấu UINT Số nguyên không dấu 32-bit LONG long 32-bit BOOL Bool LPSTR Con trỏ chuỗi LPCSTR Hằng trỏ chuỗi WPARAM 32-bit LPARAM 32-bit BSTR Giá trị 32-bit trỏ đến kí tự LPVOID Con trỏ 32-bit đến kiểu không xác định LPTSTR Giống LPSTR chuyển sang dạng Unicode DBCS Trang 10 NGÔN NGỮ LẬP TRÌNH Bách khoa Online: hutonline.net LẬP TRÌNH C TRÊN WINDOWS { 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 khoá 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 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); Trang 188 Bách khoa Online: hutonline.net LẬP TRÌNH C TRÊN WINDOWS NGÔN NGỮ LẬP TRÌNH 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ị Ý nghĩa 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_READ 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_WRITE 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 đọc-ghi, ta kết hợp với cờ GENERIC_READ 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 chia sẻ Khi đó, ta thao tác đối tượng đóng handle Để chia sẻ đối tượng, ta kết hợp cờ sau : FILE_SHARE_DELETE Sử dụng Windows NT : Thao tác đối tượng thực yêu cầu truy cập xoá FILE_SHARE_READ Thao tác đối tượng thực yêu cầu truy cập đọc FILE_SHARE_WRITE Thao tác đối tượng thực yêu cầu truy cập ghi 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 : Trang 189 NGÔN NGỮ LẬP TRÌNH Bách khoa Online: hutonline.net LẬP TRÌNH C TRÊN WINDOWS CREATE_NEW Tạo tập tin Hàm thất bại tập tin có CREATE_ALWAYS 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 OPEN_EXISTING Mở tập tin Hàm thất bại tập tin chưa có sẵn OPEN_ALWAYS 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_EXISTING 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 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 để đá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 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 ghi xoá 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 Trang 190 NGÔN NGỮ LẬP TRÌNH Bách khoa Online: hutonline.net LẬP TRÌNH C TRÊN WINDOWS 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 : • 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 đĩa mềm, CD-ROM đĩ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 Trang 191 NGÔN NGỮ LẬP TRÌNH Bách khoa Online: hutonline.net LẬP TRÌNH C TRÊN WINDOWS OPEN_EXISTING, // mở tập tin có FILE_ATTRIBUTE_NORMAL, //Tập tin thường NULL); // tính tạm if (hFile == INVALID_HANDLE_VALUE) { ErrorHandler("Could not open file."); // lỗi xử lý } Để xoá 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) { ErrorHandler("Could not open file."); // lỗi xử lý } 7.3.2 Tạo tập tin tạm Trang 192 NGÔN NGỮ LẬP TRÌNH Bách khoa Online: hutonline.net LẬP TRÌNH C TRÊN WINDOWS 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); Trang 193 NGÔN NGỮ LẬP TRÌNH Bách khoa Online: hutonline.net LẬP TRÌNH C TRÊN WINDOWS 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\ 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; Trang 194 NGÔN NGỮ LẬP TRÌNH Bách khoa Online: hutonline.net LẬP TRÌNH C TRÊN WINDOWS 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 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 Trang 195 NGÔN NGỮ LẬP TRÌNH Bách khoa Online: hutonline.net LẬP TRÌNH C TRÊN WINDOWS 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."); } 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 Trang 196 NGÔN NGỮ LẬP TRÌNH Bách khoa Online: hutonline.net LẬP TRÌNH C TRÊN WINDOWS 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 */ Trang 197 NGÔN NGỮ LẬP TRÌNH Bách khoa Online: hutonline.net LẬP TRÌNH C TRÊN WINDOWS if (dwPtrLow==0xFFFFFFFF&&(dwError=GetLastError())!=NO_ERROR) { // 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 Trang 198 NGÔN NGỮ LẬP TRÌNH Bách khoa Online: hutonline.net LẬP TRÌNH C TRÊN WINDOWS 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 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ở khoá 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 khoá 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; Trang 199 NGÔN NGỮ LẬP TRÌNH Bách khoa Online: hutonline.net LẬP TRÌNH C TRÊN WINDOWS 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); // thuộc tính tạm if (hFile == INVALID_HANDLE_VALUE) { ErrorHandler("Could not open ONE."); // xử lý lỗi } /* 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); // thuộc tính tạm if (hAppend == INVALID_HANDLE_VALUE) { ErrorHandler("Could not open TWO."); // xử lý lỗi } Trang 200 NGÔN NGỮ LẬP TRÌNH Bách khoa Online: hutonline.net LẬP TRÌNH C TRÊN WINDOWS /* 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 xoá 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); 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 Trang 201 NGÔN NGỮ LẬP TRÌNH Bách khoa Online: hutonline.net LẬP TRÌNH C TRÊN WINDOWS tập tin cần xoá không tồn Trong Windows NT, hàm xoá tập tin mở Tuy nhiên, Windows 95, tập tin mở bị xoá 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 xoá) 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 202