Bài giảng Lập trình Windows (Phần 1)
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 hoc̣ 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.
Tóm tắt nội dung tài liệu: Bài giảng Lập trình Windows (Phần 1)
BỘ GIAO THÔNG VẬN TẢI TRƢỜNG ĐẠI HỌC HÀNG HẢI BỘ MÔN: KHOA HOC̣ 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̣ triǹh Windows i 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ƣơṇg, Cấu trúc dƣ̃ liêụ 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̣ trình 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êụ 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: TÊN CHƢƠNG MỤC PHÂN PHỐI SỐ TIẾT 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̣ trình trên 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.3. Vai trò của Windows trên thi ̣ trƣờng phần mềm 1.2. Thƣ viêṇ Win32 và Win64 1.2.1. Win32 API 1.2.2. Win64 API 1.3. Giới thiêụ về bô ̣công cu ̣Visual Studio 2005 1 1 1 Chƣơng II. Hê ̣thống file và thƣ mục 4 4 0 2.1. Truy câp̣ và sƣ̉ duṇg hê ̣thống file trên môi trƣờng Windows 2.1.1. Hê ̣thống file và thƣ muc̣ 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 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 2 1 2 1 Bài giảng môn học: Lâp̣ triǹh Windows ii TÊN CHƢƠNG MỤC PHÂN PHỐI SỐ TIẾT 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ƣ muc̣ hiêṇ 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̣ tính của file và thƣ muc̣ 1 1 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 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 3.2.1. Thay đổi khóa 3.2.2. Thêm mới khóa 3.2.3. Liêṭ kê các khóa 3.3. Can thiêp̣ Windows qua Registry 3.3.1. Thay đổi giao diêṇ 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 1 2 1 2 3 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 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ôṭ 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âṭ ký thời gian thƣc̣ hiêṇ của các tiến trình 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ô hình Boss /Worker và các mô hình khác 4.3.3. Bô ̣nhớ dành cho luồng 4.3.4. Độ ƣu tiên và các trạng thái của luồng 4.4. Môṭ số ví du ̣về tiến trình và luồng 4.4.1. Tìm kiếm song song với các tiến trình 4.4.2. Thuâṭ toán sắp xếp trôṇ bằng đa luồng 2 1 1 2 2 2 1 Chƣơng V. Các dịch vụ của Windows 4 6 0 1 5.1. Tổng quan về dic̣h vu ̣trên Windows 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 dic̣h vu ̣qua các Handler 5.3. Ví du: dịch vụ đơn giản trên Windows 1 1 2 2 Bài giảng môn học: Lâp̣ triǹh Windows iii TÊN CHƢƠNG MỤC PHÂN PHỐI SỐ TIẾT TS LT TH/Xemina BT KT 5.4. Quản lý các dịch vụ của Windows 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 dic̣h vu ̣của Windows 2 2 1 Chƣơng VI. Lâp̣ triǹh maṇg với Sockets 4 4 0 0 6.1. Khái niệm sockets trên Windows 6.2. Các hàm sockets phía server 6.3. Các hàm sockets phía client 6.4. Ứng dụng mạng đơn giản 6.4.1. Phía server 6.4.2. Phía client 6.5. Windows Sockets 2.0 0,5 0,5 0,5 2 0,5 1 0,5 0,5 2 Chƣơng VII. Thƣ viêṇ liên kết đôṇg 4 4 0 0 7.1. Khái niệm và ứng dụng của thƣ viện liên kết đôṇg 7.2. Hê ̣thống thƣ viêṇ DLL của Windows 7.3. Các bƣớc tạo một thƣ viện DLL 7.3.1. Tạo thƣ viêṇ DLL 7.3.2. Viết ƣ́ng duṇg goị tới thƣ viêṇ DLL 1 1 2 0,5 1 2,5 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ṭ. Lâp̣ trình Windows. NXB Giáo duc̣. - 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. Bài giảng môn học: Lâp̣ triǹh Windows i 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Ƣ MUC̣ .................................................................... 21 1. Truy câp̣ và sƣ̉ duṇg 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êṭ kê các khóa .................................................................................................... 44 3. Can thiêp̣ Windows qua Registry .................................................................................. 44 3.1 Thay đổi giao diêṇ ................................................................................................ 44 3.2 Thay đổi các thiết lâp̣ đối với các ổ điã ................................................................ 44 Bài giảng môn học: Lâp̣ triǹh Windows ii 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âṭ ký thời gian thƣc̣ hiêṇ của các tiến trình .................................... 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ô hình Boss/Worker và các mô hình 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ôṭ số ví du ̣về tiến trình và luồng ............................................................................... 50 4.1. Tìm kiếm song song với các tiến trình................................................................. 50 4.2. Thuâṭ toán sắp xếp trôṇ 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ề dic̣h 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 dic̣h 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 Bài giảng môn học: Lâp̣ triǹh Windows iii 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ÊṆ 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êṇ liên kết đôṇg .......................................................... 83 7.5. Các vấn đề khác về thƣ viện liên kết động ................................................................. 84 Bài tập: .......................................................... ... n trên thƣc̣ tế khi chúng ta tiến hành thƣc̣ hiêṇ hàm trên se ̃có môṭ Exception đƣơc̣ throw để kiểm soát lỗi nhƣng ở đây chúng ta tạm thời bỏ qua vấn đề này (xem phu ̣luc̣ A cuốn Teach yourself Visual C++ 6.0 in 21 days để biết thêm chi tiết). Cài đặt các chức năng cho lớp document Khi chúng ta xây dƣṇg môṭ ƣ́ng duṇg daṇg form -based trong đó form nằm trên cƣ̉a sổ là không gian chính để ngƣời dùng có thể tƣơng tác với ƣ́ng duṇg có môṭ giả sƣ̉ không đƣơc̣ đề câp̣ rõ ràng là ƣ́ng duṇg của chúng ta se ̃cho phép ngƣời dùng làm viêc̣ với nhiều bản ghi . Điều này có nghiã là chúng ta cần hỗ trợ các tính năng lƣu và duyệt qua các bản ghi này . Viêc̣ lƣu các bản ghi có thể thƣc̣ hiêṇ dê ̃dàng bằng cách sƣ̉ duṇg môṭ mảng nhƣ chúng ta đa ̃tƣ̀ng làm trong bài thực hành số 10. Cách làm này cho phép chúng ta có thể thêm vào môṭ số lƣơṇg bản ghi không hạn chế (không biết có đúng không nƣ̃a). Viêc̣ duyêṭ qua các bản ghi đƣơc̣ thƣc̣ hiêṇ qua bốn thao tác là First (duyêṭ bản ghi đầu tiên), Last (bản ghi cuối cùng), Previous (bản ghi trƣớc) và Next (bản ghi tiếp theo). Chúng ta cần một chức năng thông báo để xác định bản ghi nào đang đƣơc̣ hiển thi.̣ Để lƣu trƣ̃ và hỗ trơ ̣các tính năng này lớp document cần hai biến : môṭ mảng và môṭ chỉ số bản ghi hiêṇ taị nhƣ bảng sau: Name Typ e m_iCurP osition int m_oaPeo ple CO bArray Môṭ viêc̣ khác chúng ta cần làm là include file header của lớp CPerson vào file cài đăṭ của lớp document (vị trí trƣớc các file header của lớp document và view) nhƣ sau: #include "stdafx.h" #include "Serialize.h" #include "Person.h" Bài giảng môn học: Lâp̣ triǹh Windows 30 #include "SerializeDoc.h" #include "SerializeView.h" Thêm môṭ bản ghi mới Trƣớc khi chúng ta có thể duyêṭ qua các bản ghi trong chƣơng trình chúng ta cần xây dƣṇg chƣ́c năng thêm môṭ bản ghi mới cho mảng các đối tƣơṇg . Cách tiếp cận tƣơng tự nhƣ bài thực hành sẽ đƣợc sử dụng , và vì các bản ghi mặc định đều có các trƣờng dữ liệu là rỗng nên chúng ta chỉ cần sƣ̉ duṇg hàm cấu tƣ̉ măc̣ điṇh do Visual C ++ cung cấp là đủ , đồng thời mỗi khi thêm vào môṭ bản ghi mới chúng ta se ̃gán bản ghi hiêṇ taị là bản ghi mới đó (hàm này là private). CPerson* CSerializeDoc::AddNewRecord(void) { // Create a new CPerson object CPerson *pPerson = new CPerson(); try { // Add the new person to the object array m_oaPeople.Add(pPerson); // Mark the document as dirty SetModifiedFlag(); // Set the new position mark m_iCurPosition = (m_oaPeople.GetSize() - 1); } // Did we run into a memory exception? catch (CMemoryException* perr) { // Display a message for the user, giving them the // bad news AfxMessageBox("Out of memory", MB_ICONSTOP | MB_OK); // Did we create a line object? if (pPerson) { // Delete it delete pPerson; pPerson = NULL; } Bài giảng môn học: Lâp̣ triǹh Windows 31 // Delete the exception object perr->Delete(); } return pPerson; } Tƣơng tƣ ̣nhƣ bài thƣc̣ hành số 10 chúng ta cần các hàm lấy tổng số bản ghi , số thƣ́ tƣ ̣ bà đối tƣợng tƣơng ứng với bản ghi hiện tại nhƣ sau (các hàm này là public): int CSerializeDoc::GetTotalRecords(void) { return m_oaPeople.GetCount(); } int CSerializeDoc::GetCurRecordNbr(void) { return m_iCurPosition + 1; } CPerson* CSerializeDoc::GetCurRecord(void) { // Are we editing a valid record number? if (m_iCurPosition >= 0) // Yes, return the current record return (CPerson*)m_oaPeople[m_iCurPosition]; else // No, return NULL return NULL; } Các chức năng tiếp theo cần đƣợc cài đặt là các hàm cho phép thực hiện các thao tác lấy các bản ghi của mảng một cách tƣơng đối (đầu, cuối, trƣớc, sau): CPerson* CSerializeDoc::GetFirstRecord(void) { // Are there any records in the array? if (m_oaPeople.GetSize() > 0) { Bài giảng môn học: Lâp̣ triǹh Windows 32 // Yes, move to position 0 m_iCurPosition = 0; // Return the record in position 0 return (CPerson*)m_oaPeople[0]; }else // No records, return NULL return NULL; } CPerson* CSerializeDoc::GetNextRecord(void) { // After incrementing the position marker, are we // past the end of the array? if (++m_iCurPosition < m_oaPeople.GetSize()) // No, return the record at the new current position return (CPerson*)m_oaPeople[m_iCurPosition]; else // Yes, add a new record return AddNewRecord(); } CPerson* CSerializeDoc::GetPrevRecord(void) { // Are there any records in the array? if (m_oaPeople.GetSize() > 0) { // Once we decrement the current position, // are we below position 0? if (--m_iCurPosition < 0) // If so, set the record to position 0 m_iCurPosition = 0; // Return the record at the new current position return (CPerson*)m_oaPeople[m_iCurPosition]; }else // No records, return NULL Bài giảng môn học: Lâp̣ triǹh Windows 33 return NULL; } CPerson* CSerializeDoc::GetLastRecord(void) { // Are there any records in the array? if (m_oaPeople.GetSize() > 0) { // Move to the last position in the array m_iCurPosition = (m_oaPeople.GetSize() - 1); // Return the record in this position return (CPerson*)m_oaPeople[m_iCurPosition]; }else // No records, return NULL return NULL; } Tiếp đến là hàm Serialize cho mảng các đối tƣơṇg của lớp document (CSerializeDoc): void CSerializeDoc::Serialize(CArchive& ar) { // Pass the serialization on to the object array m_oaPeople.Serialize(ar); } Hàm làm công tác môi trƣờng, dọn dẹp tất cả mọi thứ trƣớc khi bắt đầu một tài liệu mới (hàm này đƣợc gọi tới khi chƣơng trình kết thúc hoăc̣ trƣớc khi môṭ tài liêụ mới đƣơc̣ mở): void CSerializeDoc::DeleteContents() { // TODO: Add your specialized code here and/or call the base class // Get the number of lines in the object array int liCount = m_oaPeople.GetSize(); int liPos; // Are there any objects in the array? if (liCount) { Bài giảng môn học: Lâp̣ triǹh Windows 34 // Loop through the array, deleting each object for (liPos = 0; liPos < liCount; liPos++) delete m_oaPeople[liPos]; // Reset the array m_oaPeople.RemoveAll(); } CDocument::DeleteContents(); } Chúng ta có thể thấy các bƣớc thực hiện hoàn toàn giống với bài thực hành số 10, và cũng cần nhắc lại một chú ý đó là : cần phải chuyển đối tƣơṇg lấy tƣ̀ mảng CObArray thành kiểu CPerson vì đó là môṭ biến kiểu CObject. Tiếp theo cần phải sƣ̉a laị hàm tƣơng ƣ́ng với sƣ ̣kiêṇ OnNewDocument: BOOL CSerializeDoc::OnNewDocument() { if (!CDocument::OnNewDocument()) return FALSE; // TODO: add reinitialization code here // (SDI documents will reuse this document) // If unable to add a new record, return FALSE if (!AddNewRecord()) return FALSE; // Get a pointer to the view POSITION pos = GetFirstViewPosition(); CSerializeView* pView = (CSerializeView*)GetNextView(pos); // Tell the view that it's got a new data set if (pView) pView->NewDataSet(); return TRUE; } Khi môṭ tài liêụ mới bắt đầu chƣơng trình se ̃đƣa ra môṭ form rỗng sẵn sàng để nhâp̣ thông tin mới , và để bản ghi này có thể sẵn sàng nhận thông tin chúng ta thêm vào môṭ bản ghi trong mảng các đối tƣơṇg và khi môṭ bản ghi mới đƣơc̣ thêm vào mảng chúng ta cần thay đổi viêc̣ hiển thi ̣ để chỉ ra rằng bản ghi mới đó tồn taị ngƣơc̣ laị các hiển thi ̣ se ̃tiếp tuc̣ với bả n Bài giảng môn học: Lâp̣ triǹh Windows 35 ghi cuối cùng tƣ̀ tâp̣ bản ghi trƣớc (và ngƣời dùng có thể băn khoăn tại sao ứng dụng của chúng ta không bắt đầu với một tập bản ghi mới). Khi mở môṭ tâp̣ dƣ̃ liêụ sẵn có chúng ta không cần thêm vào bất cƣ́ bản ghi mới nà o nhƣng vâñ cần phải cho đối tƣơṇg view biết rằng nó cần phải làm tƣơi bản ghi đƣơc̣ hiển thi ̣ cho ngƣời dùng . Do đó chúng ta có thể thêm đoaṇ ma ̃tƣơng tƣ ̣cho hàm OnOpenDocument nhƣ sau (bỏ phần đầu có chức năng thêm vào một bản ghi mới) nhƣ sau: BOOL CSerializeDoc::OnOpenDocument(LPCTSTR lpszPathName) { if (!CDocument::OnOpenDocument(lpszPathName)) return FALSE; // TODO: Add your specialized creation code here // Get a pointer to the view POSITION pos = GetFirstViewPosition(); CSerializeView* pView = (CSerializeView*)GetNextView(pos); // Tell the view that it's got a new data set if (pView) pView->NewDataSet(); return TRUE; } Đó là tất cả các công viêc̣ chuẩn bi ,̣ tổ chƣ́c và xƣ̉ lý dƣ̃ li ệu của lớp document , tiếp đến chúng ta sẽ làm việc với lớp view để tƣơng tác với ngƣời dùng. Điều đầu tiên cần chú ý là các include trong các file ma ̃nguồn cần theo đúng thƣ́ tƣ ̣ (giống bài thƣc̣ hành số 10): lớp CPerson t rƣớc, sau đó tới lớp document và cuối cùng là lớp view và các chỉ thi ̣ include này chỉ thƣc̣ hiêṇ trong các file cài đăṭ lớp (khác với C/C++ thông thƣờng) #include "stdafx.h" #include "Serialize.h" #include "Person.h" #include "SerializeDoc.h" #include "SerializeView.h" Vì số lƣợng các thao tác đối với các bản ghi là khá nhiều nên cũng giống nhƣ bài thực hành 10 (sƣ̉ duṇg 1 biến lƣu điểm hiêṇ taị của con trỏ chuôṭ ) trong bài thƣc̣ hành này để cho tiêṇ chúng ta thêm môṭ biến thành viên kiểu CPerson * có tên là m_pCurPerson cho lớp View. Bài giảng môn học: Lâp̣ triǹh Windows 36 Hàm đầu tiên mà chúng ta sẽ thực hiện là hàm hiển thị dữ liệu , nhƣng chƣ́c năng này đƣơc̣ sƣ̉ duṇg trong hầu hết các tƣơng tác nên chúng ta se ̃l àm một hàm riêng để sau đó gọi đến hàm này (giống hàm Draw của lớp CLine trong bài thƣc̣ hành 10 về chƣ́c năng ) (hàm private): void CSerializeView::PopulateView(void) { // Get a pointer to the current document CSerializeDoc* pDoc = GetDocument(); if (pDoc) { // Display the current record position in the set m_sPosition.Format("Record %d of %d", pDoc->GetCurRecordNbr(), pDoc->GetTotalRecords()); } // Do we have a valid record object? if (m_pCurPerson) { // Yes, get all of the record values m_bEmployed = m_pCurPerson->GetEmployed(); m_iAge = m_pCurPerson->GetAge(); m_sName = m_pCurPerson->GetName(); m_iMaritalStatus = m_pCurPerson->GetMaritalStatus(); } // Update the display UpdateData(FALSE); } Tiếp đến là các hàm duyệt qua các bản ghi , đồng thời cũng là các hàm xƣ̉ lý các sƣ ̣kiêṇ tƣơng ƣ́ng với các nút lêṇh: void CSerializeView::OnBnClickedBfirst() { // TODO: Add your control notification handler code here // Get a pointer to the current document CSerializeDoc * pDoc = GetDocument(); if (pDoc) { Bài giảng môn học: Lâp̣ triǹh Windows 37 // Get the first record from the document m_pCurPerson = pDoc->GetFirstRecord(); if (m_pCurPerson) { // Display the current record PopulateView(); } } } void CSerializeView::OnBnClickedBlast() { // TODO: Add your control notification handler code here // Get a pointer to the current document CSerializeDoc * pDoc = GetDocument(); if (pDoc) { // Get the last record from the document m_pCurPerson = pDoc->GetLastRecord(); if (m_pCurPerson) { // Display the current record PopulateView(); } } } void CSerializeView::OnBnClickedBprev() { // TODO: Add your control notification handler code here // Get a pointer to the current document CSerializeDoc * pDoc = GetDocument(); if (pDoc) { Bài giảng môn học: Lâp̣ triǹh Windows 38 // Get the last record from the document m_pCurPerson = pDoc->GetPrevRecord(); if (m_pCurPerson) { // Display the current record PopulateView(); } } } void CSerializeView::OnBnClickedBnext() { // TODO: Add your control notification handler code here // Get a pointer to the current document CSerializeDoc * pDoc = GetDocument(); if (pDoc) { // Get the last record from the document m_pCurPerson = pDoc->GetNextRecord(); if (m_pCurPerson) { // Display the current record PopulateView(); } } } Tiếp đến chúng ta cần môṭ hàm reset laị lớp view mỗi khi môṭ bản ghi mới đƣơc̣ bắt đầu hoăc̣ đƣơc̣ mở để ngƣời không tiếp tuc̣ nhìn thấy tâp̣ bản ghi cũ . Chúng ta có thể gọi tới hàm xƣ̉ lý sƣ ̣kiêṇ của nút First để buôc̣ lớp view đƣa ra bản ghi đầu tiên trong tâp̣ bản ghi . Để làm điều này chúng ta thêm môṭ hàm void (pubic) tên là NewDataSet nhƣ sau: void CSerializeView::NewDataSet(void) { OnBnClickedBfirst(); } Bài giảng môn học: Lâp̣ triǹh Windows 39 Đến đây chúng ta có thể dic̣h và chaỵ chƣơng trình nhƣng các baṇ se ̃thấy chỉ các các nút duyệt qua các bản ghi là có tác dụng còn các điều khiển khác của form là không có tác dụng gì. Điều này là do chúng ta chƣa có các hàm xƣ̉ lý các điều khiển trên form . Cần thêm các hàm xử lý các sự kiện với các điều khiển trên form chƣơng trình nhƣ sau : Hàm xử lý dấu check Employed: void CSerializeView::OnBnClickedCbemployed() { // TODO: Add your control notification handler code here UpdateData(TRUE); // If we have a valid person object, pass the data changes to it if (m_pCurPerson) m_pCurPerson->SetEmployed(m_bEmployed); } hàm xử lý các sự kiện cho các nút Radio: void CSerializeView::OnBnClickedMaritalstatus() { // TODO: Add your control notification handler code here UpdateData(TRUE); // If we have a valid person object, pass the data changes to it if (m_pCurPerson) m_pCurPerson->SetMaritalStat(m_iMaritalStatus); } Đối với các trƣờng tên và tuổi chúng ta cần xử lý sự kiện EN _CHANGE và goị tới các hàm SetName, SetAge tƣơng ƣ́ng của lớp CPerson nhƣ sau: void CSerializeView::OnEnChangeEname() { // TODO: Add your control notification handler code here UpdateData(TRUE); // If we have a valid person object, pass the data changes to it if (m_pCurPerson) m_pCurPerson->SetName(m_sName); } void CSerializeView::OnEnChangeEage() { Bài giảng môn học: Lâp̣ triǹh Windows 40 // TODO: Add your control notification handler code here UpdateData(TRUE); // If we have a valid person object, pass the data changes to it if (m_pCurPerson) m_pCurPerson->SetAge(m_iAge); } Hãy dịch chạy thử và nhập dữ liệu vào để thấy các chức năng của chƣơng trình đã chạy đúng (đây quả là môṭ bài thƣc̣ hành không dê ̃dàng). 3. Quản lý file và thƣ mục nâng cao Bài tập: Bài tập 1: Viết chƣơng trình mô phỏng tìm kiếm file. Bài tập 2: Viết chƣơng trình liệt kê tất cả các thông tin về các file và thƣ mục trong một thƣ mục.
File đính kèm:
- bai_giang_lap_trinh_windows_phan_1.pdf