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.

pdf 47 trang yennguyen 1960
Bạn đang xem 20 trang mẫu của tài liệu "Bài giảng Lập trình Windows (Phần 1)", để tải tài liệu gốc về máy hãy click vào nút Download ở trê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à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:

  • pdfbai_giang_lap_trinh_windows_phan_1.pdf