Bài giảng Lập trình Windows: Phần 1 - Đại học Hàng Hải
lượt xem 6
download
Bài giảng Lập trình Windows cung cấp các kiến thức cơ bản về lâp̣ trình trực quan trên hê ̣điều hành Windows, các kiến thức về truy cập và can thiệp vào các thành phần của hệ điều hành Windows. Nội dung bài giảng gồm có 7 chương và được chia thành 2 phần, phần 1 gồm chương 1 và chương 2, mời các bạn cùng tham khảo.
Bình luận(0) Đăng nhập để gửi bình luận!
Nội dung Text: Bài giảng Lập trình Windows: Phần 1 - Đại học Hàng Hải
- BỘ GIAO THÔNG VẬN TẢI TRƢỜNG ĐẠI HỌC HÀNG HẢI BỘ MÔN: KHOA HỌC MÁ Y TÍ NH KHOA: CÔNG NGHỆ THÔNG TIN BÀI GIẢNG LẬP TRÌNH WINDOWS TÊN HỌC PHẦN : Lập trình Windows MÃ HỌC PHẦN : 17214 TRÌNH ĐỘ ĐÀO TẠO : ĐẠI HỌC CHÍNH QUY DÙNG CHO SV NGÀNH : CÔNG NGHỆ THÔNG TIN HẢI PHÕNG - 2010
- Bài giảng môn học: Lâ ̣p trin ̀ h Windows Tên học phần: Lập trình Windows Loại học phần: 2 Bộ môn phụ trách giảng dạy: Khoa học Máy tính Khoa phụ trách: CNTT Mã học phần: 17214 Tổng số TC: 3 TS tiết Lý thuyết Thực hành/Xemina Tự học Bài tập lớn Đồ án môn học 60 30 30 0 0 0 Điều kiện tiên quyết: Sinh viên phải học xong các học phần sau mới đƣợc đăng ký học phần này: Lâ ̣p trình hƣớng đố i tƣơ ̣ng, Cấ u trúc dƣ̃ liê ̣u Mục tiêu của học phần: - Cung cấp các kiến thức cơ bản về lâ ̣p triǹ h trƣ̣c quan trên hê ̣ điề u hành Windows - Cung cấ p các kiế n thƣ́c về truy câ ̣p và can thiê ̣p vào các t hành phần của hệ điều hành Windows Nội dung chủ yếu Các kiến thức về thao tác với file và thƣ mục , cơ sở dƣ̃ liê ̣u registry , các luồng , tiế n trình, dịch vụ, các thƣ viện liên kết động và lập trình sockets trên Windows. Nội dung chi tiết của học phần: PHÂN PHỐI SỐ TIẾT TÊN CHƢƠNG MỤC TS LT TH/Xemina BT KT Chƣơng I. Các khái niệm cơ bản 3 0 0 0 1.1. Giới thiệu về môi trƣờng lâ ̣p triǹ h trên 1 Windows 1.1.1. Cở sở về hê ̣ điề u hành Windows 1.1.2. Các phiên bản của hê ̣ điề u hành Windows 1 1.1.3. Vai trò của Windows trên thi ̣trƣờng phầ n mề m 1.2. Thƣ viê ̣n Win32 và Win64 1 1.2.1. Win32 API 1.2.2. Win64 API 1.3. Giới thiê ̣u về bô ̣ công cu ̣ Visual Studio 2005 Chƣơng II. Hê ̣ thố ng file và thƣ mục 4 4 0 2.1. Truy câ ̣p và sƣ̉ du ̣ng hê ̣ thố ng file trên môi 2 2 trƣờng Windows 2.1.1. Hê ̣ thố ng file và thƣ mu ̣c của Windows 2.1.2. Các thao tác với file và thƣ mục trên Windows 2.1.3. Các vấn đề liên quan tới Unicode 1 1 2.2. Các ví dụ về thao tác với file 2.2.1. Tạo file và xử lý các lỗi liên quan i
- Bài giảng môn học: Lâ ̣p trin ̀ h Windows PHÂN PHỐI SỐ TIẾT TÊN CHƢƠNG MỤC TS LT TH/Xemina BT KT 2.2.2. Copy file 2.2.3. Hiể n thi ̣danh sách các file trong thƣ mu ̣c 1 1 hiê ̣n thời 2.3. Quản lý file và thƣ mục nâng cao 2.3.1. Con trỏ file 2.3.2. Truy câ ̣p tới các thuô ̣c tiń h của file và thƣ mu ̣c Chƣơng III. Hê ̣thố ng cơ sở dƣ̃ liêụ Registry 4 6 0 1 3.1. Khái niệm và vai trò của CSDL Registry 1 1 3.1.1. Các khóa, các hive 3.1.2. Các kiểu dữ liệu 3.2. Quản lý CSDL Registry 1 2 3.2.1. Thay đổ i khóa 3.2.2. Thêm mới khóa 3.2.3. Liê ̣t kê các khóa 3.3. Can thiê ̣p Windows qua Registry 2 3 3.3.1. Thay đổ i giao diê ̣n 3.3.2. Thay đổ i các thiế t lâ ̣p đố i với các ổ điã 3.3.3. Thay đổ i các thiế t lâ ̣p với ngƣời dùng 1 Chƣơng IV. Quản lý các tiến trình và luồng 4 6 0 1 4.1. Các tiến trình và luồng trên Windows 2 2 4.2. Các thao tác với tiến trình 4.2.1. Tạo tiến trình 4.2.2. Kế t thúc và thoát khỏi mô ̣t tiế n trình 4.2.3. Các thao tác với biến môi trƣờng của Windows 4.2.4. Ví dụ : Ghi nhâ ̣t ký thời gian thƣ̣c hiê ̣n của các tiến trình 1 2 4.3. Quản lý luồng (thread) trên Windows 4.3.1. Các khái niệm cơ bản 4.3.2. Mô hiǹ h Boss /Worker và các mô hiǹ h khác 4.3.3. Bô ̣ nhớ dành cho luồ ng 1 2 4.3.4. Độ ƣu tiên và các trạng thái của luồng 4.4. Mô ̣t số ví du ̣ về tiế n trình và luồ ng 1 4.4.1. Tìm kiếm song song với các tiến trình 4.4.2. Thuâ ̣t toán sắ p xế p trô ̣n bằ ng đa luồ ng Chƣơng V. Các dịch vụ của Windows 4 6 0 1 5.1. Tổ ng quan về dich ̣ vu ̣ trên Windows 1 2 5.2. Các thành phần của một dịch vụ 5.2.1. Hàm main() 5.2.2. Hàm ServiceMain() 5.2.3. Kiể m soát dich ̣ vu ̣ qua các Handler 5.3. Ví du: dịch vụ đơn giản trên Windows 1 2 ii
- Bài giảng môn học: Lâ ̣p trin ̀ h Windows PHÂN PHỐI SỐ TIẾT TÊN CHƢƠNG MỤC TS LT TH/Xemina BT KT 5.4. Quản lý các dịch vụ của Windows 2 2 5.4.1. Các phƣơng pháp kiểm soát các dịch vụ của Windows 5.4.2. Ví dụ : Điề u khiể n các dich ̣ vu ̣ của 1 Windows Chƣơng VI. Lâ ̣p trin ̀ h ma ̣ng với Sockets 4 4 0 0 6.1. Khái niệm sockets trên Windows 0,5 1 6.2. Các hàm sockets phía server 0,5 0,5 6.3. Các hàm sockets phía client 0,5 0,5 6.4. Ứng dụng mạng đơn giản 2 2 6.4.1. Phía server 6.4.2. Phía client 6.5. Windows Sockets 2.0 0,5 Chƣơng VII. Thƣ viêṇ liên kế t đô ̣ng 4 4 0 0 7.1. Khái niệm và ứng dụng của thƣ viện liên 1 0,5 kế t đô ̣ng 1 1 7.2. Hê ̣ thố ng thƣ viê ̣n DLL của Windows 2 2,5 7.3. Các bƣớc tạo một thƣ viện DLL 7.3.1. Tạo thƣ viê ̣n DLL 7.3.2. Viế t ƣ́ng du ̣ng go ̣i tới thƣ viê ̣n DLL Nhiệm vụ của sinh viên : Tham dự các buổi thuyết trình của giáo viên, tự học, tự làm bài tập do giáo viên giao, tham dự các bài kiểm tra định kỳ và cuối kỳ. Tài liệu học tập : - Lê Hƣ̃u Đa ̣t. Lập trình Windows. NXB Giáo du ̣c. - Charles Petzold. Programming Windows, fifth edition. Microsoft Press. 1998. - Johnson M. Hart. Windows System Programming Third Edition. Addison Wesley Professional. 2004. Hình thức và tiêu chuẩn đánh giá sinh viên: - Hình thức thi cuối kỳ : Thi vấn đáp. - Sinh viên phải đảm bảo các điều kiện theo Quy chế của Nhà trƣờng và của Bộ Thang điểm: Thang điểm chữ A, B, C, D, F Điểm đánh giá học phần: Z = 0,3X + 0,7Y. iii
- Bài giảng môn học: Lâ ̣p trin ̀ h Windows MỤC LỤC LỜI NÓI ĐẦU ............................................................................................................................ 1 CHƢƠNG 1: CÁC KHÁI NIỆM CƠ BẢN ............................................................................... 2 1. Giới thiệu về môi trƣờng lập trình Windows .................................................................. 2 1.1 Cơ sở về hệ điều hành Windows ............................................................................ 2 1.2 Các phiên bản của hệ điều hành Windows ............................................................. 2 1.3 Vai trò của Windows trên thị trƣờng phần mềm .................................................... 3 2. Thƣ viện Win32 và Win64 .............................................................................................. 3 2.1 Win32 API .............................................................................................................. 3 2.2 Win64 API .............................................................................................................. 4 3. Các bƣớc phát triển ứng dụng trên Windows .................................................................. 4 3.1 Chƣơng trình Win32 đơn giản nhất. ....................................................................... 4 3.2 Chƣơng trình cƣ̉a sổ đơn giản ................................................................................. 5 3.3 Quản lý các thông điệp ......................................................................................... 14 3.4 Vòng lặp xử lý thông điệp .................................................................................... 17 Bài tập: .............................................................................................................................. 20 CHƢƠNG 2: HỆ THỐNG FILE VÀ THƢ MỤC .................................................................... 21 1. Truy câ ̣p và sƣ̉ du ̣ng hê ̣ thố ng file trên môi trƣờng Windows ....................................... 21 2. Các ví dụ về thao tác với file ......................................................................................... 21 2.1 Serialization .......................................................................................................... 21 2.2 Cài đặt một lớp Serializable.................................................................................. 24 3. Quản lý file và thƣ mục nâng cao .................................................................................. 40 Bài tập: .............................................................................................................................. 40 CHƢƠNG 3: HỆ THỐNG CSDL REGISTRY ........................................................................ 41 1. Khái niệm và vai trò của CSDL Registry ...................................................................... 41 1.1 Các khóa, các hive ................................................................................................ 41 1.2 Các kiểu dữ liệu .................................................................................................... 42 2. Quản lý CSDL Registry ................................................................................................. 43 2.1 Thay đổ i khóa ....................................................................................................... 43 2.2 Thêm mới khóa ..................................................................................................... 43 2.3 Liê ̣t kê các khóa .................................................................................................... 44 3. Can thiê ̣p Windows qua Registry .................................................................................. 44 3.1 Thay đổ i giao diê ̣n ................................................................................................ 44 3.2 Thay đổ i các thiế t lâ ̣p đố i với các ổ điã ................................................................ 44 i
- Bài giảng môn học: Lâ ̣p trin ̀ h Windows 3.3 Thay đổ i các thiế t lâ ̣p với ngƣời dùng .................................................................. 44 Bài tập: .............................................................................................................................. 44 CHƢƠNG 4: QUẢN LÝ CÁC TIẾN TRÌNH VÀ LUỒNG .................................................... 45 1. Các tiến trình và luồng trên Windows ........................................................................... 45 2. Các thao tác với tiến trình ............................................................................................. 46 2.1. Tạo tiến trình ........................................................................................................ 46 2.2. Kế t thúc và thoát khỏi một tiến trình ................................................................... 47 2.3. Các thao tác với biến môi trƣờng của Windows .................................................. 47 2.4. Ví dụ: Ghi nhâ ̣t ký thời gian thƣ̣c hiê ̣n của các tiế n triǹ h .................................... 47 3. Quản lý luồng (thread) trên Windows ........................................................................... 49 3.1. Các khái niệm cơ bản ........................................................................................... 49 3.2. Mô hiǹ h Boss/Worker và các mô hiǹ h khác ........................................................ 49 3.3. Bô ̣ nhớ dành cho luồ ng ........................................................................................ 49 3.4. Độ ƣu tiên và các trạng thái của luồng ................................................................ 50 4. Mô ̣t số ví du ̣ về tiế n triǹ h và luồ ng ............................................................................... 50 4.1. Tìm kiếm song song với các tiến trình................................................................. 50 4.2. Thuâ ̣t toán sắ p xế p trô ̣n bằ ng đa luồ ng ................................................................ 52 Bài tập: .............................................................................................................................. 55 CHƢƠNG 5: CÁC DỊCH VỤ CỦA WINDOWS .................................................................... 56 1. Tổ ng quan về dich ̣ vu ̣ trên Windows ............................................................................. 56 2. Các thành phần của một dịch vụ ................................................................................... 56 2.1 Hàm main() ........................................................................................................... 56 2.2 Hàm ServiceMain()............................................................................................... 56 2.3 Kiể m soát dịch vụ qua các Handler ...................................................................... 56 3. Ví du: dịch vụ đơn giản trên Windows .......................................................................... 57 4. Quản lý các dịch vụ của Windows ................................................................................ 60 4.1 Các phƣơng pháp kiểm soát các dịch vụ của Windows ........................................ 60 4.2 Ví dụ : Điề u khiể n các dich ̣ vu ̣ của Windows ....................................................... 60 Bài tập: .............................................................................................................................. 64 CHƢƠNG 6: LẬP TRÌNH SOCKET ....................................................................................... 65 1. Khái niệm sockets trên Windows .................................................................................. 65 2. Các hàm sockets phía server.......................................................................................... 65 3. Các hàm sockets phía client .......................................................................................... 66 4. Ứng dụng mang đơn giản .............................................................................................. 66 ii
- Bài giảng môn học: Lâ ̣p trin ̀ h Windows 4.1 Phía server............................................................................................................. 66 4.2 Phía client ............................................................................................................. 72 5. Windows Sockets 2.0 .................................................................................................... 74 Bài tập: .............................................................................................................................. 74 CHƢƠNG 7: THƢ VIỆN LIÊN KẾT ĐỘNG ......................................................................... 75 7.1. Khái niệm và ứng dụng của thƣ viện liên kết động .................................................... 75 7.2. Hệ thống thƣ viện liên kết động của Windows .......................................................... 75 7.3. Các bƣớc tạo một thƣ viện DLL ................................................................................. 76 7.4. Chia sẻ bô ̣ nhớ giƣ̃a các thƣ viê ̣n liên kế t đô ̣ng .......................................................... 83 7.5. Các vấn đề khác về thƣ viện liên kết động ................................................................. 84 Bài tập: .............................................................................................................................. 85 TÀI LIỆU THAM KHẢO ........................................................................................................ 86 ĐỀ THI THAM KHẢO ............................................................................................................ 87 iii
- Bài giảng môn học: Lâ ̣p trin ̀ h Windows LỜI NÓI ĐẦU Hệ điều hành Windows của Microsoft là hệ điều hành đƣợc cài đặt nhiều nhất trên các máy PC hiện nay. Sự phổ biến của Windows và nền tảng phần cứng của Intel dẫn tới sự cần thiết phải có những hiểu biết sâu về chúng, đặc biệt đối với những lập trình viên. Mục đích của học phần này là cung cấp cho học viên một cái nhìn tổng quan, từ cơ bản tới chi tiết về các khía cạnh của lập trình trên hệ điều hành Windows, từ các chi tiết trong cấu trúc của một chƣơng trình tới các khái niệm cấp cao về tiến trình, luồng, xử lý song song, thƣ viện DLL, lập trình Socket, can thiệp vào cơ sở dữ liệu Registry .... Tài liệu này dựa trên những kinh nghiệm và nghiên cứu mà tác giả đã đúc rút, thu thập trong quá trình giảng dạy môn học Lập trình C trên Windows, cùng với sự tham khảo của các tài liệu của các đồng nghiệp , các tác giả trong và ngoài nƣớc , tƣ̀ điể n trƣ̣c tuyế n Wikipedia . Với bẩ y chƣơng đƣợc chia thành các chủ đề khác nhau từ các khái niê ̣m cơ bản cho tới các thao tác với hệ thống file, thƣ mục, hệ thống CSDL Registry, quản lý tiến trình và luồng, lập trình quản lý dịch vụ, lập trình socket, thƣ viện liên kết động DLL… hy vọng sẽ cung cấp cho các em sinh viên , các bạn độc giả một tài liệu bổ ích . Mặc dù đã rất cố gắng song vẫn không tránh khỏi một số thiếu sót , hy vọng sẽ đƣợc các bạn bè đồng nghiệp , các em sinh viên , các bạn độc giả góp ý chân thành để tôi có thể hoàn thiện hơn nữa tài liệu này. Xin gửi lời cảm ơn chân thành tới các bạn bè đồng nghiệp và Ban chủ nhiệm khoa Công nghệ Thông tin đã tạo điều kiện giúp đỡ để tài liệu này có thể hoàn thành. Hải phòng, tháng 06 năm 2010 Tác giả Nguyễn Hƣ̃u Tuân 1
- Bài giảng môn học: Lâ ̣p trin ̀ h Windows Chƣơng 1: Các khái niệm cơ bản Tài liệu này đƣợc biên soạn để cung cấp cho ngƣời ho ̣c những kiến thức cơ bản vế việc viết các chƣơng trình sử dụng giao diện lập trình API trên môi trƣờng Win32. Ngôn ngữ đƣợc sử dụng là ngôn ngữ C, hầu hết các trình biên dịch C++ hiện nay đều có thể dịch đƣợc các chƣơng trình mẫu trình bày trong tài liệu này. Hầu hết tất cả các thông tin đƣợc trình bày trong tài liệu này đều có thể ứng dụng cho bất cứ ngôn ngữ nào có thể truy cập các hàm API, chẳng hạn nhƣ Java, Assembly, và Visual Basic. Tài liệu này đƣợc biên soạn không phải để dạy các bạn độc giả lập trình bằng ngôn ngữ C, hoặc dạy chúng ta sử dụng bất cứ một trình biên dịch cụ thể nào (chẳng hạn nhƣ Borland C++, Visual C++, …) tuy nhiên trong phần phụ lục tôi sẽ dành một chút để cung cấp cho các bạn một số chú ý về một số trình biên dịch mà tôi đã sử dụng. 1. Giới thiệu về môi trƣờng lập trình Windows 1.1 Cơ sở về hệ điều hành Windows Hệ điều hành Windows là một hệ điều hành dành cho ngƣời dùng cuối (End User Operating System) với các tính năng cơ bản sau: đa nhiệm, giao diện đồ họa, plug and play và quan trọng nhất là Windows Interface Based - tức là giao diện các chƣơng trình chạy trên Windows đều có dạng các cửa sổ. 1.2 Các phiên bản của hệ điều hành Windows Do cách dùng tiếng Anh và việc hiểu tiếng Anh dẫn tới việc nhiều ngƣời hiểu về các phiên bản của hệ điều hành Windows chƣa chính xác. Ví dụ có bạn cho rằng Windows XP Professional Edition và Windows XP Home Edition là hai phiên bản khác nhau của hệ điều hành Windows. Thực ra nhƣ vậy vừa đúng lại vừa không đúng, đúng là Windows XP Professional Edition và Windows XP Home Edition là hai Edition khác nhau của cùng 1 Version Windows XP, có lẽ sai là vì hiểu từ Edition và Version sai. Version có nghĩa là một phiên bản, thƣờng đi kèm với các số hiệu của phiên bản (1.0, 1.2. … 5.0) và thƣờng là một thay đổi lớn đối với bản thân phần mềm, ví dụ nhƣ đối với Windows thì có 3 thay đổi lớn: thay đổi về kiến trúc nền tảng của hệ điều hành (tức là phần kernel của hệ điều hành), hai là cập nhật các bản vá (patch) cho các lỗi của phiên bản trƣớc đó đối với tất cả các phần của hệ điều hành, ba là các phần mới của hệ điều hành (có thể là các ứng dụng đi kèm hoặc hỗ trợ thêm các công nghệ mới, ví dụ nhƣ đối với Windows là chuẩn Wi-Fi, DVD, dot NET framework hay các ứng dụng nhƣ Windows Media Player, IE …). Còn Edition là ấn bản khác nhau của cùng một phiên bản, các Edition thƣờng gắn với các yếu tố về địa lý, ngôn ngữ khác nhau (ví dụ nhƣ Compact Edition nghĩa là bản rút gọn, Standard Edition là bản chuẩn, Ultimate Edition là bản có các tính năng cao cấp nhất …). Đối với hệ điều hành Windows các Edition khác nhau thƣờng phân biệt bởi các tính năng của chúng, do nhắm tới việc phục vụ các đối tƣợng khác nhau nên Microsoft bỏ đi một số tính năng không cần thiết và tăng thêm các tính năng mà đối tƣợng ngƣời dùng hay dùng ví dụ nhƣ bản Home Edition nhắm tới ngƣời dùng gia đình nên các tính năng đồ họa, video, âm thanh phải tốt, còn bản Professional nhắm tới các ngƣời dùng chuyên nghiệp có trình độ cao nên các tính năng hệ thống sẽ cao hơn. Windows có các phiên bản sau đây: Windows 1.01 Windows 2.03 2
- Bài giảng môn học: Lâ ̣p trin ̀ h Windows Windows 2.11 Windows 3.0 Windows 3.1x Windows For Workgroups 3.1 Windows NT 3.1 Windows For Workgroups 3.11 Windows 3.2 (released in Simplified Chinese only) Windows NT 3.5 Windows NT 3.51 Windows 95 Windows NT 4.0 Windows 98 Windows 98 SE Windows 2000 Windows Me Windows XP Windows XP 64-bit Edition 2003 Windows Server 2003 Windows XP Professional x64 Edition Windows Fundamentals for Legacy PCs Windows Vista Windows Home Server Windows Server 2008 Windows 7 Tất nhiên là mỗi Version trên lại có nhiều Edition khác nhau. Phần nhân (Kernel – Core) của hệ điều hành luôn là phần quan trọng nhất của một hệ điều hành. Đối với Windows nhân gồm 3 thành phần: các dịch vụ chạy ở mức nhân (kernel-mode service, để phân biệt với các dịch vụ chạy ở mức ứng dụng) gồm các thƣ viện chính của hệ điều hành, các thƣ viện thực hiện quản lý tiến trình, lập lịch, quản lý vào ra dữ liệu trên đĩa cứng, bộ nhớ. Phần 2 là các thƣ viện làm việc với các phần cứng ở mức chung, phần 3 là các Diver. 1.3 Vai trò của Windows trên thị trƣờng phần mềm Do sự thống trị của hãng Microsoft nói riêng và sự phổ biến gần nhƣ độc tôn của hệ điều hành Windows nói chung ở Việt Nam nên Windows đóng vai trò hết sức quan trọng trong việc phát triển phần mềm ở Việt Nam. Về bản chất các chƣơng trình đều phải thực hiện trên một nền tảng (platform) nhất định bao gồm các chi tiết từ phần cứng cho tới phần mềm, tuy nhiên đối với đa số ứng dụng, các lập trình viên cần quan tâm nhiều nhất tới hệ điều hành mà ứng dụng sẽ chạy. 2. Thƣ viện Win32 và Win64 2.1 Win32 API Win32 API hay thƣờng đƣợc viết tắt là Win32 là phiên bản 32 bit tƣơng ứng với hệ điều hành 32 bit của Windows. Win32 bao gồm các hàm đƣợc cài đặt của hệ thống, chẳng hạn nhƣ các hàm trong hệ thống Win16 bit, dƣới dạng các file thƣ viện DLL của hệ thống. Lõi (core) của Win32 là các file thƣ viện kernel32.dll, user32.dll và gdi32.dll. Win32 đầu tiên đƣợc đƣa ra cùng với hệ điều hành Windows NT. Phiên bản đầu tiên của Win32 đƣợc phát hành cùng với hệ điều hành Windows 95 (gọi là Win32c - compatible), và sau này chỉ còn là Win32. 3
- Bài giảng môn học: Lâ ̣p trin ̀ h Windows 2.2 Win64 API Win64 là phiên bản 64 bit của thƣ viện Win32, là một biến thể dành cho các nền tảng 64 bit của hệ điều hành Windows (ví dụ hiện tại là AMD64 và IA-64). Cả hai phiên bản 32 và 64 bit của một ứng dụng đều có thể đƣợc biên dịch từ một mã chƣơng trình chung, mặc dù có một số khác biệt trong hai phiên bản này. Sự khác nhau cơ bản của hai phiên bản là các con trỏ địa chỉ của Win32 là 32 bit, còn với Win64 là 64 bit. 3. Các bƣớc phát triển ứng dụng trên Windows 3.1 Chƣơng trình Win32 đơn giản nhất. Nếu bạn là một ngƣời mới bắt đầu lập trình trên môi trƣờng Win32 thì thao tác đầu tiên mà bạn cần phải làm đƣợc đó là dịch một chƣơng trình cơ bản trên môi trƣờng Windows. Hãy gõ đoạn chƣơng trình trên vào và nếu mọi thứ suôn sẻ bạn sẽ có một chƣơng trình đơn giản nhất (vô nghĩa) trong số các chƣơng trình mà bạn đã làm. Hãy nhớ là dịch chƣơng trình này theo kiểu dịch một chƣơng trình viết bằng ngôn ngữ C, không phải ngôn ngữ C++. Trong hầu hết các trƣờng hợp điều này đơn giản thực hiện bằng cách đổi phần tên mở rộng từ cpp thành c. Chẳng hạn bạn có thể đặt tên cho file chƣơng trình sau là test.c và bắt đầu làm việc. #include int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MessageBox(NULL, "Goodbye, cruel world!", "Note", MB_OK); return 0; } Nếu nhƣ chƣơng trình không làm việc bƣớc đầu tiên mà bạn cần làm là đọc tất cả các lỗi (error) mà chƣơng trình báo lên và nếu nhƣ bạn không hiểu ý nghĩa của chúng hãy tra trong bất cứ một quyển sách dạy lập trình hoặc các sách hƣớng dẫn đi kèm với trình biên dịch mà bạn đang sử dụng. Hãy chắc chắn là bạn có đầy đủ các file mà trình biên dịch yêu cầu. Thật không may là tôi không thể giúp nhiều trong trƣờng hợp này vì các lỗi phụ thuộc vào trình biên dịch và ngƣời sử dụng (trong việc gây lỗi cũng nhƣ sửa lỗi). Bạn có thể nhận đƣợc một vài cảnh báo từ trình biên dịch về việc chƣơng trình không sử dụng các tham số đƣợc cung cấp cùng với hàm WinMain(). Nhƣng không sao điều quan trọng là bạn dịch chƣơng trình thành công và có một chƣơng trình Win32 thực sự. Chúng ta sẽ phân tích các đoạn mã chƣơng trình kỹ càng hơn. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) WinMain() là hàm chính của một chƣơng trình trên môi trƣờng Windows giống nhƣ hàm main trên môi trƣờng DOS và UNIX. Đó là nơi các đoạn mã chƣơng trình sẽ đƣợc thực thi. Các tham số của hàm main gồm có: HINSTANCE hInstance 4
- Bài giảng môn học: Lâ ̣p trin ̀ h Windows Tham số này quản lý module chƣơng trình (file .exe trong bộ nhớ). Hệ điều hành sử dụng tham số này để quản lý chƣơng trình khi thực hiện. HINSTANCE hPrevInstance Luôn là NULL đối với các chƣơng trình Win32. LPSTR lpCmdLine Các tham số dòng lệnh của chƣơng trình đƣợc truyền dƣới dạng một xâu. Không bao gồm tên chƣơng trình. int nCmdShow Một số nguyên có thể truyền cho hàm ShowWindow(). Chúng ta sẽ bàn về tham số này sau. Tham số hInstance đƣợc dùng cho các công việc đại loại nhƣ nạp (load) các tài nguyên và bất cứ tác vụ nào khác đƣợc thực hiện theo kiểu từng module cơ bản. Một module là một file EXE hoặc file DLL đƣợc nạp vào chƣơng trình của bạn. Đối với hầu hết (không phải tất cả) các chƣơng trình đƣợc trình bày trong tài liệu này, chỉ có một module mà chúng ta cần quan tâm đó là file chƣơng trình (EXE). Các qui ƣớc gọi hàm WINAPI chỉ định qui ƣớc gọi hàm và đƣợc định nghĩa là _stdcall. Nếu nhƣ bạn không hiểu ý nghĩa của chúng thì cũng không cần bận tâm nhiều vì chúng không ảnh hƣởng tới tài liệu này chỉ cần nhớ là đây là một điều cần thiết (kiểu của hàm WinMain() là int, nhƣng kiểu gọi hàm là WINAPI). Các kiểu dữ liệu Win32. Các bạn sẽ thấy rằng rất nhiều từ khóa thông thƣờng hoặc các kiểu dữ liệu đều có các cách định nghĩa cụ thể trên môi trƣờng Windows, UINT là unsigned int, LPSTR là char *, vân vân. Việc chọn lựa sử dụng cách nào thực sự phụ thuộc vào bạn. Nếu bạn thích sử dụng char * hơn là LPSTR thì hãy sử dụng cách đó nhƣng cần phải kiểm soát đƣợc việc sử dụng của mình (cần nắm rõ các kiểu dữ liệu trƣớc khi thay chúng bằng một kiểu khác). Bạn chỉ cần nắm vững một số nguyên tắc và sẽ hiểu ý nghĩa của các tên này: LP là long pointer. Trên môi trƣờng Win32 phần long này không quan trọng và hoàn toàn có thể bỏ qua. Còn nếu bạn không hiểu con trỏ là gì thì có lẽ bạn nên học lại về C hoặc bỏ qua chúng và tiếp tục. Tiếp đến là LPCSTR: long pointer const là một hằng xâu, tức là một xâu không thể thay đối, ngoài ra giữa hai kiểu LPSTR và LPCSTR còn có thể có thêm một chữ T nhƣng nếu bạn không có ý định sử dụng các font Unicode trong chƣơng trình thì nó cũng chẳng có ý nghĩa gì đặc biệt. 3.2 Chƣơng trin ̀ h cƣ̉a sổ đơn giản Ví dụ: chƣơng triǹ h gồ m 1 cƣ̉a sổ đơn giản trên Windows Đôi khi mo ̣i ngƣời hỏi nhau trong khi ho ̣ chát với nhau bằ ng phầ n mề m IRC là “Làm thế nào để ta ̣o ra mô ̣t cƣ̉a sổ ?”. Tôi e rằ ng điề u này hoàn toàn không phải là mô ̣t điề u đơn giản. Không khó khi ba ̣n biế t miǹ h đang làm gì nhƣng có khá it́ nhƣ̃ng điề u ba ̣n cầ n biế t để tạo ra một cửa sổ , và những điều đó hoàn toàn có thể giải thích bằng một đoạn văn bản ngắn hoă ̣c khoảng mô ̣t vài phút chat bằ ng IRC. 5
- Bài giảng môn học: Lâ ̣p trin ̀ h Windows Tôi luôn muố n làm trƣớc và ho ̣c kỹ càng sa u vì thế ở đây tôi sẽ triǹ h bày đoa ̣n mã chƣơng trình ta ̣o ra mô ̣t cƣ̉a sổ trƣớc và giải thích sau: #include const char g_szClassName[] = "myWindowClass"; /* tên lớp cửa sổ */ // Step 4: the Window Procedure LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_CLOSE: DestroyWindow(hwnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: // để windows xử lý các thông điệp còn lại return DefWindowProc(hwnd, msg, wParam, lParam); } return 0; } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASSEX wc; HWND hwnd; MSG Msg; //Step 1: Registering the Window Class wc.cbSize = sizeof(WNDCLASSEX); 6
- Bài giảng môn học: Lâ ̣p trin ̀ h Windows wc.style = 0; wc.lpfnWndProc = WndProc; /* hàm xử lý thông điệp cửa sổ */ wc.cbClsExtra = 0;/* không cần thông tin thêm cho cửa sổ */ wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); /* màu nền */ /*wc.hbrBackground = GetStockObject(WHITE_BRUSH); màu nền trắng */ wc.lpszMenuName = NULL; /* không có hệ thống thực đơn */ wc.lpszClassName = g_szClassName; /* tên lớp cửa sổ */ wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); /* đăng ký lớp cửa sổ */ if(!RegisterClassEx(&wc)) { MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK); return 0; } // Step 2: Creating the Window // Tạo ra một thể nghiệm của lớp cửa sổ cho ứng dụng hwnd = CreateWindowEx( WS_EX_CLIENTEDGE, g_szClassName, "The title of my window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 240, 120, NULL, NULL, hInstance, NULL); if(hwnd == NULL) { MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK); 7
- Bài giảng môn học: Lâ ̣p trin ̀ h Windows return 0; } // Hiển thị cửa sổ ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd); // Step 3: The Message Loop // Step 3: Tạo vòng lặp xử lý thông điệp while(GetMessage(&Msg, NULL, 0, 0) > 0) { TranslateMessage(&Msg); DispatchMessage(&Msg); } return Msg.wParam; } Hình 1 – Cƣ̉a sổ của chƣơng trình khi chạy Đây có lẽ là mô ̣t chƣơng triǹ h windows đơn giản nhấ t mà ba ̣n có thể viế t và chƣ́c năng của chƣơng trình đơn giản là tạo ra một cửa sổ cũng rất đơn giản . Bạn nên gõ chƣơng trình và biên dich ̣ để cha ̣y thƣ̉ và haỹ đảm bảo là không có lỗi gì xảy ra . Bƣớc 1: Đăng ký (Registering) lớp cƣ̉a sổ (Window). Mô ̣t lớp cƣ̉a sổ (Window Class) chƣ́a các thông tin về kiể u cƣ̉a sổ , bao gồ m thủ tu ̣c Window của nó (thủ tục này kiểm soát cƣ̉a sổ khi nó đƣơ ̣c ta ̣o ra và đáp ƣ́ng la ̣i các sƣ̣ kiê ̣n ngƣời dùng tác đô ̣ng lên cƣ̉a sổ ), các icon lớn và nhỏ của cửa sổ, và màu nền của cửa sổ. Theo cách này bạn có thể đăng ký một lớp và sau đó tạo ra bao nhiêu cửa sổ tùy thích mà không cầ n chỉ rõ tấ t cả các thuô ̣c tính đó thêm mô ̣t lầ n nào nƣ̃a . Hầ u hế t các thuô ̣c tính mà ba ̣n thiế t lâ ̣p trong lớp cƣ̉a sổ (window) có thể thay đổi đƣợc theo một cách rất cơ bản (thổ mô ̣c) nế u nhƣ ba ̣n thích. Và cần chú ý là lớp cửa sổ này không liên quan gì tới khái niệm các lớp trong C++. const char g_szClassName[] = "myWindowClass"; Biế n trên lƣu tên của lớp cƣ̉a sổ của chúng ta , chúng ta sẽ sử dụng nó để đăng ký lớp cƣ̉a sổ của chúng ta với hê ̣ thố ng. 8
- Bài giảng môn học: Lâ ̣p trin ̀ h Windows WNDCLASSEX wc; wc.cbSize = sizeof(WNDCLASSEX); wc.style = 0; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wc.lpszMenuName = NULL; wc.lpszClassName = g_szClassName; wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); if(!RegisterClassEx(&wc)) { MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK); return 0; } Đó là đoa ̣n mã chƣơng triǹ h chúng ta sƣ̉ du ̣ng trong hàm WinMain() để đăng ký lớp cƣ̉a sổ của chúng ta . Chúng ta sẽ điền đầy đủ các thành viên của cấu trúc WNDCLASSEX và gọi tới hàm RegisterClassEx(). Các thành viên của cấu trúc ảnh hƣởng đến lớp cửa sổ gồm có: cbSize: kích thƣớc của cấu trúc style: Class Style (CS_*), để không nhầm lẫn với Window Style (WS_*). Thông thƣờng thuô ̣c tính này đƣơ ̣c gán bằ ng 0. lpfnWndProc: con trỏ trỏ tới thủ tu ̣c quản lý cƣ̉a sổ cho lớp cƣ̉a sổ này . cbClsExtra: Lƣơ ̣ng dƣ̃ liê ̣u thêm đƣơ ̣c cấ p phát trong bô ̣ nhớ cho mỗi cƣ̉a sổ thuô ̣c loa ̣i này. Thông thƣờng cũng đƣơ ̣c gán bằ ng 0. hInstance: Quản lý một thể nghiệm (instance) của ứng dụng (tham số đầ u tiên của hàm WinMain()). hIcon: Icon lớn (thƣờng là 32x32) hiể n thị khi chúng ta nhấn tổ hợp phím Alt+TAB. 9
- Bài giảng môn học: Lâ ̣p trin ̀ h Windows hCursor: Con trỏ sẽ xuấ t hiê ̣n khi con trỏ chuô ̣t di chuyể n qua vùng cƣ̉a sổ của chƣơng trình. hbrBackground: Tham số sƣ̉ du ̣ng để thiế t lâ ̣p mầ u nề n của cƣ̉a sổ . lpszMenuName: tên của tài nguyên menu đƣơ ̣c sƣ̉ du ̣ng cho các cƣ̉a sổ của lớp. lpszClassName: Tên để đinh ̣ danh lớp cƣ̉a sổ hIconSm: Icon nhỏ (16x16) hiể n thi ̣trên thanh task bar và góc trên bên trái của cƣ̉a sổ . Bạn không nên lo lắng nếu chƣa hiểu về các thuộc tính này, chúng sẽ đƣợc giải thích ở các phần tiếp theo của tài liệu này . Mô ̣t điề u khác cầ n phải nhớ là không nên cố nhớ nhƣ̃ng thuô ̣c tính này . Tôi rấ t ít khi (không muố n nói là không bao giờ ) nhớ các thuô ̣c tính cũng nhƣ các tham số của các hàm , điề u đó hoàn toàn là mô ̣t cố gắ ng lañ g phí thời gian và công sƣ́c . Nế u nhƣ ba ̣n biế t các hàm ba ̣n cầ n sƣ̉ du ̣ng trong mô ̣t chƣơng trình nào đó , hãy tra trong các tài liệu help. Nế u ba ̣n không có cá c file help haỹ down chúng về , các file kiểu này trên mạng không hề thiế u . Cuố i cùng thì ba ̣n sẽ biế t các tham số của các hàm mà ba ̣n thƣờng xuyên sƣ̉ dụng. Tiế p đế n chúng ta go ̣i tới hàm RegisterClassEx () và kiểm tra xem hàm này có thành công hay không , nế u nhƣ hàm trả về sai chúng ta sẽ hiể n thi ̣mô ̣t thông báo thấ t ba ̣i và dƣ̀ng chƣơng trình. Bƣớc 2: Tạo ra cửa sổ chƣơng trình Khi đã đăng ký lớp cƣ̉a sổ , chúng ta có thể tạo ra các cửa sổ trong chƣơng triǹ h . Các bạn nên tra các tham số của hàm CreateWindowEx () (bạn luôn nên làm vậy khi làm việc với các hàm API mới), nhƣng tôi sẽ giải thić h mô ̣t chút ở đây: HWND hwnd; hwnd = CreateWindowEx( WS_EX_CLIENTEDGE, g_szClassName, "The title of my window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 240, 120, NULL, NULL, hInstance, NULL); Tham số đầ u tiên (WS_EX_CLIENTEDGE) là kiểu cửa sổ mở rộng (extended), trong trƣờng hơ ̣p này tham số này đƣợc sử dụng để tạo thành một đƣờng viền chìm bên trong xung quanh cƣ̉a sổ . Có thể đặt bằng 0 nế u chúng ta muố n khác . Cũng nên thay đổi các giá trị khác để xem chúng làm việc nhƣ thế nào. Tiế p theo chúng ta cầ n có tên lớp (g_szClassName), tham số này báo cho hê ̣ thố ng biế t loại cửa sổ mà chúng ta muốn tạo ra . Vì chúng ta muốn tạo ra một cửa sổ từ lớp mà chúng ta vƣ̀a đăng ký nên chúng ta sƣ̉ du ̣ng tên của lớp cƣ̉a sổ đó . Sau đó chúng ta chỉ rõ tên của cƣ̉a sổ hoă ̣c tiêu đề (xâu ký tƣ̣ ) sẽ xuất hiện trong vai trò là tham số Caption hoặc Title Bar của cƣ̉a sổ của chúng ta. 10
- Bài giảng môn học: Lâ ̣p trin ̀ h Windows Tham số chúng ta sƣ̉ du ̣ng WS_OVERLAPPEDWINDOW trong vai trò tham số Window Style. Có khá ít các tham số kiểu này do đó bạn nên kiểm tra và thay đổi giá trị của chúng để xem kết quả họat động nhƣ thế nào. Chúng ta sẽ bàn thêm về các tham số này sau. Bố n tham số tiế p theo (CW_USEDEFAULT, CW_USEDEFAULT, 320, 240) là tọa độ X và Y của góc trên bên trái của cƣ̉a sổ và các kích thƣớc dài rô ̣ng của nó . Tôi đã thiế t lâ ̣p giá trị của X và Y là CW _USEDEFAULT để windows tƣ̣ cho ̣n vi ̣trí để đă ̣t cƣ̉a sổ chƣơng trình khi cha ̣y. Hãy nhớ l à bên trái của màn hình là một giá trị 0 của X và nó tăng dần khi sang phải. Đin ̉ h của màn hiǹ h tƣơng ƣ́ng với giá tri ̣ 0 của Y tăng dần theo chiều đi xuống . Các đơn vị là các điểm ảnh , là đơn vị nhỏ nhất mà màn hình có thể hiể n thi ̣đƣơ ̣c ta ̣i đô ̣ phân giải hiê ̣n tại. Tiế p theo (NULL, NULL, g_hInst, NULL) chúng ta có một handle quản lý cửa sổ cha của cửa sổ đƣợc sinh ra , mô ̣t handle quản lý menu , mô ̣t handle cho thể nghiê ̣m của ƣ́ng du ̣ng và một con trỏ trỏ tới dƣ̃ liê ̣u cƣ̉a sổ . Trong windows các cƣ̉a sổ trên màn hình đƣơ ̣c sắ p xế p theo mô ̣t cấ u trúc phân cấ p theo kiể u các cƣ̉a sổ cha và con . Khi chúng ta nhiǹ thấ y mô ̣t nút trên mô ̣t cƣ̉a sổ , nút đó là con và nó đƣợc chứ a trong cƣ̉a sổ là cha của nó . Trong ví du ̣ này của chúng ta handle của cửa sổ cha là NULL vì chúng ta không có cửa sổ cha nào cả , đây là cƣ̉a sổ chính hoă ̣c cƣ̉a sổ ở cấ p cao nhấ t của chúng ta . Menu cũng là NULL vì chúng t a chƣa có menu chƣơng trình nào . Handle dành cho thể nghiê ̣m của chƣơng trình đƣơ ̣c gán là giá tri ̣ đƣơ ̣c truyề n cho tham số đầ u tiên của hàm WinMain (). Dữ liệu cửa sổ (thƣờng là chúng ta chẳ ng bao giờ sƣ̉ du ̣ng chúng ) có thể đƣợ c sƣ̉ du ̣ng để gƣ̉i các dƣ̃ liê ̣u khác tới cƣ̉a sổ đang đƣơ ̣c ta ̣o ra và cũng là NULL. Nế u ba ̣n đang băn khoăn về giá tri ̣NULL bí hiể m này thì haỹ yên tâm vì nó đơn giản chỉ là 0 (zero). Thƣ̣c sƣ̣ trong C nó đƣơ ̣c đinh ̣ nghiã là ((void*)0) vì nó đƣợc sử dụng với các con trỏ. Vì thế cho nên bạn có thể sẽ gặp các cảnh báo khi biên dịch chƣơng trình nếu sử dụng NULL cho các giá tri ̣kiể u nguyên , tùy thuộc vào trình biên dịch và cấp độ cảnh báo đƣợc thiế t lâ ̣p với triǹ h biên dich. ̣ Bạn có thể bỏ qua các cảnh báo hoặc đơn giản là sử dụng giá trị 0 để thay thế. Nguyên nhân số 1 mà mọi ngƣời không biết tại sao chƣơng trình của mình lại có lỗi là do ho ̣ không kiể m tra cá c giá tri ̣trả về của lời go ̣i hàm mà ho ̣ thƣ̣c hiê ̣n trong chƣơng triǹ h của mình. CreateWindow() sẽ trả về sai trong một số trƣờng hợp ngay cả khi bạn là một lập trình viên có nhiều kinh nghiệm , chỉ đơn giản bởi vì có rất n hiề u lỗi mà chúng ta rấ t dễ ta ̣o ra chúng. Cho tới khi ba ̣n ho ̣c đƣơ ̣c cánh nhanh chóng xác đinh ̣ các lỗi kiể u nhƣ vâ ̣y , hãy tự cho mình một cơ hội để có thể tìm ra các lỗi trong chƣơng trình , hãy luôn kiểm tra các giá trị tr ả về khi go ̣i tới các hàm. if(hwnd == NULL) { MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK); return 0; } Sau khi chúng ta đã ta ̣o ra cƣ̉a sổ và kiể m tra để đảm bảo là chúng ta có một handle hợp lê ̣, chúng ta sẽ hiển thị cửa sổ lên màn hình của windows (hê ̣ điề u hành ) bằ ng cách sƣ̉ du ̣ng 11
- Bài giảng môn học: Lâ ̣p trin ̀ h Windows tham số cuố i cùng của hàm WinMain () và sau đó cập nhật nó để đảm bảo là tự nó đƣợc vẽ lại mô ̣t cách hơ ̣p lê ̣ trên màn hình. ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd); Tham số nCmdShow là tùy cho ̣n , bạn có thể đơn giản gán nó là SW _SHOWNORMAL mỗi khi chúng ta làm viê ̣c với nó.Tuy nhiên sƣ̉ du ̣ng tham số đƣơ ̣c truyề n vào h àm WinMain() sẽ tạo cơ hội cho các ngƣời dùng sử dụng chƣơng trình của chúng ta có thể chỉ định họ muốn hoă ̣c không muố n của sổ của chúng ta bắ t đầ u với kić h thƣớc cƣ̉a sổ lớn nhấ t hoă ̣c nhỏ nhấ t … Ba ̣n sẽ thấ y các tùy chọn này trong các tham số của các shortcut của tới các cửa sổ . Bƣớc 3: Vòng lặp xử lý thông điệp Đây chính là trái tim của toàn bô ̣ chƣơng trình , hầ u hế t nhƣ̃ng thƣ́ mà chƣơng trình của chúng ta xử lý là nằm ở đây. while(GetMessage(&Msg, NULL, 0, 0) > 0) { TranslateMessage(&Msg); DispatchMessage(&Msg); } return Msg.wParam; Hàm GetMessage () lấ y mô ̣t thông điê ̣p tƣ̀ hàng đơ ̣i thông điê ̣p của ƣ́ng du ̣ng của ba ̣n . Bấ t kỳ thời điể m nào ngƣời dùng di chuyể n con chuô ̣t , gõ bàn phím , click chuô ̣t trên menu của cửa sổ chƣơng trình, hoă ̣c làm bấ t cƣ́ mô ̣t thao tác nào đa ̣i loa ̣i nhƣ vâ ̣y , các thông điệp sẽ đƣơ ̣c sinh ra và thêm chúng vào hàng đơ ̣i thông điê ̣p của chƣơng trình. Bằ ng cách go ̣i tới hàm GetMessage() bạn đang yêu cầu thông điệp tiếp theo loại bỏ khỏi hàng đợi và trả nó về cho bạn xử lý . Nế u nhƣ không có thông điê ̣p nào hàm GetMesage () sẽ chuyển sang blocks . Nế u bạn không quen với thuâ ̣t ngƣ̃, điề u đó có nghiã là nó sẽ đơ ̣i cho tới khi có mô ̣t thông điê ̣p tiế p theo để xƣ̉ lý (lấ y về cho chƣơng triǹ h). TranslateMessage() thƣ̣c hiê ̣n thêm mô ̣t số xƣ̉ lý trên các sƣ̣ kiê ̣n bàn phim ́ chẳ ng ha ̣n nhƣ sinh ra các thông điê ̣p WM _CHAR cùng với các thông điê ̣p WM _KEYDOWN. Cuố i cùng DispatchMessage() gƣ̉i thông điê ̣p tới cƣ̉a sổ mà thông điê ̣p cầ n đƣơ ̣c gƣ̉i tới (xƣ̉ lý theo kiể u hƣớng sƣ̣ kiê ̣n ). Đó có thể là cƣ̉a sổ chính của chƣơng trình hoă ̣c có th ể là một cửa sổ khác, hoă ̣c là mô ̣t điề u khiể n , và trong một số trƣờng hợp là một cửa sổ đƣợc tạo ra ở hậu trƣờng bởi hê ̣ thố ng hoă ̣c mô ̣t chƣơng triǹ h khác . Đây không phải là điề u mà các ba ̣n cầ n phải lo lắ ng vì tấ t cả nhƣ̃ng gì chúng ta bàn tới là lấ y thông điê ̣p và gƣ̉i nó đi , hê ̣ thố ng sẽ xƣ̉ lý để đảm bảo thông điê ̣p đó đƣơ ̣c gƣ̉i đế n đúng nơi sẽ nhâ ̣n nó . Bƣớc 4: Thủ tục cửa sổ. Nế u nhƣ vòng lă ̣p thông điê ̣p là trái tim của chƣơng trình thì thủ tục cửa sổ là bộ não của chƣơng trình. Đây là nơi mà tấ t cả các thông điê ̣p đƣơ ̣c gƣ̉i tới cƣ̉a sổ của chúng ta đƣơ ̣c xƣ̉ lý. LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 12
- Bài giảng môn học: Lâ ̣p trin ̀ h Windows { switch(msg) { case WM_CLOSE: DestroyWindow(hwnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, msg, wParam, lParam); } return 0; } Thủ tục cƣ̉a sổ đƣơ ̣c go ̣i tới để xƣ̉ lý các thông điê ̣p , tham số HWND là để quản lý cƣ̉a sổ của ba ̣n, cũng chính là đối tƣợng của thông điệp . Điề u này là quan tro ̣ng bởi vì ba ̣n có thể có hai hoặc nhiều hơn nữa các cửa sổ cùng lớp và chúng sẽ sƣ̉ du ̣ng cùng mô ̣t thủ tu ̣c cƣ̉a sổ (WndProc()). Sƣ̣ khác nhau ở đây là tham số hwnd sẽ thay đổ i tùy thuô ̣c vào cƣ̉a sổ là cƣ̉a sổ nào. Chẳ ng ha ̣n khi chúng ta lấ y về mô ̣t thông điê ̣p WM _CLOSE chúng ta sẽ hủy cƣ̉a sổ . Và vì chúng ta sử dụng handle nhận đƣợc để quản lý cửa sổ qua tham số thứ nhất nên các cửa sổ khác sẽ không bị ảnh hƣởng, chỉ có cửa sổ nhận thông điệp là sẽ bị hủy. WM_CLOSE đƣơ ̣c gƣ̉i đế n khi ngƣời dùng nhấ n chu ột vào nút đóng cửa sổ hoặc nhấn tổ hơ ̣p phim ́ Alt +F4. Thao tác này sẽ làm cho cƣ̉a sổ bi ̣hủy theo mă ̣c đinh ̣ , nhƣng tôi muố n xƣ̉ lý nó mô ̣t cách dƣ́t khoát , vì điều này có thể liên quan tới một số thao tác khác chẳng hạn nhƣ đóng các file dƣ̃ liê ̣u đang mở , ngắ t các kế t nố i cơ sở dƣ̃ liê ̣u , các kết nối mạng vân vân trƣớc khi thoát khỏi chƣơng triǹ h. Khi chúng ta go ̣i tới hàm DestroyWindow () hê ̣ thố ng sẽ gƣ̉i thông điê ̣p WM_DESTROY tới cƣ̉a sổ sẽ bi ̣ hủy bỏ, trong trƣờng hơ ̣p này là cƣ̉a sổ của chúng ta , và sau đó hủy tấ t cả các cƣ̉a sổ con trƣớc khi loa ̣i bỏ cƣ̉a sổ của chúng ta khỏi hê ̣ thố ng . Vì chỉ có mô ̣t cƣ̉a sổ trong chƣơng triǹ h của chúng ta nên cũng không có nhiề u viê ̣c phải làm và chúng ta muố n thoát khỏi chƣơng trình , vì thế hàm PostQuitMessage() đƣơ ̣c go ̣i tới. Hàm này sẽ gửi thông điê ̣p WM _QUIT tới vòng lă ̣p thông điê ̣p . Chúng ta không bao nhận đƣợc thông điệp này vì nó làm cho hàm GetMessage() trả về FALSE , và nhƣ bạn sẽ thấy trong đoạn mã vòng lă ̣p xƣ̉ lý thông điê ̣p của chúng ta , khi điề u đó xảy ra chúng ta dƣ̀ng viê ̣c xƣ̉ lý các thông điê ̣p và trả về giá trị cuối cùng , tham số wParam của thông điê ̣p WM _QUIT là giá tri ̣đƣơ ̣c truyề n qua hàm PostQuitMessage (). Giá trị trả về chỉ thực sự có ích nếu chƣơng trình của chúng ta đƣơ ̣c thiế t kế để mô ̣t chƣơng trình khác go ̣i và chúng ta muố n trả về mô ̣t giá tri ̣cu ̣ thể . Bƣớc 5: không có bƣớc 5 Đế n đây là hế t , chúng ta không có bƣớc 5 và tôi hy vọng các bạn đã hiểu đƣợc ít nhiều cấ u trúc cơ bản của mô ̣t chƣơng triǹ h trên Windows. 13
CÓ THỂ BẠN MUỐN DOWNLOAD
-
Bài giảng Lập trình Windows Form - Nguyễn Văn Phong
48 p | 683 | 205
-
Bài giảng Lập trình Windows - ĐH Hàng Hải
96 p | 211 | 41
-
Bài giảng Lập trình Window: Chương 7 - Phan Trọng Tiến
64 p | 201 | 37
-
Bài giảng Lập trình Window: Chương 6 - Phan Trọng Tiến
35 p | 167 | 20
-
Bài giảng Lập trình Window: Chương 8 - Phan Trọng Tiến
45 p | 101 | 17
-
Bài giảng Lập trình Window: Chương 2 - Phan Trọng Tiến
36 p | 119 | 14
-
Bài giảng Lập trình Window: Chương 3 - Phan Trọng Tiến
64 p | 117 | 13
-
Bài giảng Lập trình Window: Chương 1 - Phan Trọng Tiến
24 p | 93 | 12
-
Bài giảng Lập trình Window: Chương 5 - Phan Trọng Tiến
42 p | 107 | 11
-
Bài giảng Lập trình Window: Chương 4 - Phan Trọng Tiến
26 p | 95 | 8
-
Bài giảng Lập trình C#: Phần 1 - ĐH Phạm Văn Đồng
61 p | 51 | 8
-
Bài giảng Lập trình trên môi trường Windows: Chương 6 - Phạm Minh Tuấn
42 p | 101 | 7
-
Bài giảng Lập trình Windows - Ngôn ngữ C
123 p | 72 | 7
-
Bài giảng Lập trình Windows: Chương 1 - Một số khái niệm cơ bản
56 p | 126 | 6
-
Bài giảng Lập trình Windows: Phần 2 - Đại học Hàng Hải
49 p | 100 | 5
-
Bài giảng Lập trình Windows Phone (Module 2): Bài 5 - Trần Duy Thanh
13 p | 67 | 5
-
Bài giảng Lập trình Windows - Trường ĐH Công nghiệp Thực Phẩm TP.HCM
144 p | 49 | 3
Chịu trách nhiệm nội dung:
Nguyễn Công Hà - Giám đốc Công ty TNHH TÀI LIỆU TRỰC TUYẾN VI NA
LIÊN HỆ
Địa chỉ: P402, 54A Nơ Trang Long, Phường 14, Q.Bình Thạnh, TP.HCM
Hotline: 093 303 0098
Email: support@tailieu.vn