Giáo trình Lập trình Windows
BỘ GIAO THÔNG VẬN TẢI
TRƢỜNG ĐẠI HỌC HÀNG HẢI
́ ́
BỘ MÔN: KHOA HOC MAY TINH
̣
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 trinh Windows
̀
Tên học phần: Lập trình Windows
Bộ môn phụ trách giảng dạy: Khoa học Máy tính
Khoa phụ trách: CNTT
Loại học phần: 2
Tổng số TC: 3
Mã học phần: 17214
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
Đ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:
0
0
0
Lâp trinh hƣơng đôi tƣơng, Câu truc 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ê
- Cung câp cac kiên thƣc vê truy câp
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
̣
́
̣
́
̣
́
́
̃
̀
̀
lâp
̣
trinh trƣc
̣
quan trên hê
̣
điê
̀u hanh Windows
̀
̀
́
́
̀
̣
va can thiêp
̣
vao cac t
hành phần cꢀa hꢁ điề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
Chƣơng I. Các khái niệm cơ bản
TS
LT TH/Xemina BT
KT
0
3
0
0
1.1. Giới thiꢁu về môi trƣơng lâp
̣
trinh trên
1
̀
̀
Windows
1.1.1. Cơ sơ vê
̀
̣
hê điều hanh Windows
̀
̉
̉
1.1.2. Các phiên bản cꢀa
hê
̣
điê
̀u hanh
̀
Windows
1.1.3. Vai tro cua Windows trên thi
1
1
̣
̉
̀
̀
mê
̀m
1.2. Thƣ viên
̣
Win32 và Win64
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ê
2.1. Truy câp va sƣ dun
trƣơng Windows
́
̣
thông file va thƣ mục
4
2
4
2
0
̀
̣
̣
g hê
̣
thô
́
ng file trên môi
̣ ̣
2.1.1. Hê thống file va thƣ muc cua 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 tac 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 trinh Windows
̀
PHÂN PHỐI SỐ TIẾT
TS LT TH/Xemina BT
TÊN CHƢƠNG MỤC
KT
2.2.2. Copy file
̉
2.2.3. Hiên thi
hiên thơi
2.3. Quản lý file và thƣ mꢂc nâng cao
2.3.1. Con tro file
danh sach cac file trong thƣ muc
̣
1
1
́
́
̣
̀
̉
2.3.2. Truy câp
̣
tơi cac thuôc
̣
tinh cꢀa file và
́
́
́
thƣ muc
̣
́
Chƣơng III. Hê
̣
thông cơ sơ dƣ liêu
̣
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
2
3
̉
3.2.1. Thay đôi khoa
́
3.2.2. Thêm mơi khoa
́
́
3.2.3. Liêt
̣
kê cac khoa
́
́
3.3. Can thiêp
̣
Windows qua Registry
̉
3.3.1. Thay đôi giao diên
̣
̉
̉
́i vơi cac ô đia
́ ́
̃
3.3.2. Thay đôi cac thiê
́
t lâp
̣
đô
́
̉
3.3.3. Thay đôi cac thiêt lâp
́
̣
vơi ngƣơi dung
1
́
́
̀
̀
Chƣơng IV. Quản lꢀ các tiến trình và luꢁng
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
6
2
0
1
4.2.1. Tꢅo tiến trình
4.2.2. Kết thuc va thoat khoi môt tiến trinh
̣
̉
́ ̀ ́
̀
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 ky thơi gian thƣc hiên
́ ̀
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
1
1
2
2
4.3.2. Mô hinh Boss /Worker va cac mô hinh
̀
́
̀
̀
khác
̣
4.3.3. Bô nhơ danh cho luồng
́ ̀
4.3.4. Đꢄ ƣu tiên và các trꢅng thái cꢀa luồng
4.4. Môt sô vi du vê tiên trinh va luông
4.4.1. Tìm kiếm song song với các tiến trình
4.4.2. Thuât toan săp xêp trôn băng đa luông
Chƣơng V. Các dꢂch vụ của Windows
̣
́
̣
̀
́
̀
1
̀
́
̀
̣
́
́
̣
̀
̀
́
4
6
0
1
̉
5.1. Tông quan vê
̀
dic
̣
h 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 soat dic
̣
h 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 trinh Windows
̀
PHÂN PHỐI SỐ TIẾT
TS LT TH/Xemina BT
TÊN CHƢƠNG MỤC
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
2
2
̉
5.4.2. Ví dꢂ : Điê
Windows
Chƣơng VI. Lâp
̀
u khiên cac dic
̣
h vu
̣
cua
1
̉
́
̣
trinh man
̣
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
0,5
0,5 0,5
0,5 0,5
1
6.4. ꢌng dꢂng mꢅng đơn gian
2
2
̉
6.4.1. Phía server
6.4.2. Phía client
6.5. Windows Sockets 2.0
0,5
4
1
1
2
́
Chƣơng VII. Thƣ viên
7.1. Khái niꢁm và ứng dꢂng cꢀa thƣ viꢁn liên
kêt đôn
7.2. Hê
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 dung goi
̣
liên kêt đôn
̣
g
4
0
0
0,5
1
2,5
́
̣
g
̣
thô
́
ng thƣ viên
̣
DLL cua Windows
̉
̣
́
̣
̣ ̣
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 Đat. Lâp trinh Windows. NXB Giao 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.
iii
̣
Bài giảng môn học: Lâp trinh 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 trinh cƣa sô đơn gian.................................................................................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
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 khoa .......................................................................................................43
2.2 Thêm mơi khoa.....................................................................................................43
kê các khꢉa ....................................................................................................44
Windows qua Registry ..................................................................................44
3.1 Thay đôi giao diên ................................................................................................44
3.2 Thay đôi cac thiết lâp đối vơi cac ô đia ................................................................44
i
̣
Bài giảng môn học: Lâp trinh Windows
̀
3.3 Thay đôi cac thiết lâp vơi ngƣơi dung ..................................................................44
Bài tập: ..............................................................................................................................44
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.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 ky thơi gian thƣc hiên cua cac tiên trinh....................................47
́t thꢓc và thoát khꢔi mꢄt 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ô hinh Boss/Worker va cac mô hinh khac ........................................................49
3.4. Đꢄ ƣu tiên và các trꢅng thái cꢀa luồng ................................................................50
4. Môt sô vi du vê tiên trinh va luông ...............................................................................50
4.1. Tìm kiếm song song với các tiến trình.................................................................50
4.2. Thuât toan săp xêp trôn băng đa luông................................................................52
nhơ danh cho luồng........................................................................................49
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
Bài tập: ..............................................................................................................................64
CHƢƠNG 6: LÂP TRINH 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 trinh 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 se bô nhơ giƣa cac 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 trinh 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ừ cac khai niêm
̣
cơ ban 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
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
̣
trinh Windows
̀
̣
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 trinh 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 trinh 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 <windows.h>
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 trinh 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 trinh cƣa sô đơn gian
̉
̉
̀
̉
Ví dꢂ: chƣơng trinh gồm 1 cƣa sô đơn gian trên Windows
̉ ̉
̀
Đôi khi moi
̣
ngƣơi hoi nhau trong khi ho
̣
chat vơi nhau bă
̀
ng phâ
̀
n mê
̀
m IRC la “Lam
̉
̀
́
́
̀
̀
̉
̉
thê
́
nao đê tao
̣
ra môt
̣
cƣa sô ?”. Tôi e ră
̀
ng điê
̀
u nay hoan toan không phai la môt
̣
điê
câ
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 khoang môt vai phut chat băng IRC.
̀
u đơn
̉
̉
̀
̀
̀
̀
̀
̉
̀n biết đê
giản. Không kho khi ban
̣
biê
́
t minh đang lam gi nhƣng co kha it nhƣng điê
̀
u ban
̣
́
̀
́
́
́
̃
̀
̀
̣
̣
̀
̉
̀
́
5
Bài giảng môn học: Lâp
̣ ̣
Tôi luôn muôn lam trƣơc va hoc ky cang sa u vi thế ơ đây tôi se trinh bay đoan ma
̀ ̀
̃ ̃ ̃
̉
̀ ̀
̣
trinh Windows
̀
́
̀
́
̀
̉
̣
chƣơng trinh tao ra môt cƣa sô trƣơc va giai thich sau:
̉ ̉
́ ̀
́
̣
̀
#include <windows.h>
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 trinh 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);
= LoadCursor(NULL, IDC_ARROW);
wc.hCursor
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 trinh 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 co le la môt chƣơng trinh windows đơn gian nhất ma ban co thê viết va 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à
̉
̃
̣ ̣
h đê chay thƣ va hay đam bao la không co lôi gi xay ra.
̀ ̀ ́
̃
̉ ̉ ̉ ̉
̀
biên dic
̉
Bƣơc 1: Đăng ky (Registering) lơp cƣa sô (Window).
̉
́
́
́
̉ ̉ ̉
̣ ̣
Môt lơp cƣa sô (Window Class) chƣa cac thông tin về kiêu cƣa sô , bao gồm thu tuc
̉ ̉ ̉
́ ́ ́
̉
Window cua no (thꢀ tꢂc này kiꢊm soát cƣa sô khi no đƣơc
̣
tao
̣
ra va đap ƣng lai cac sƣ kiên
̣
̣
̣
̉
̉
́
́
̀
́
́
́
̉
ngƣơi dung tac đôn
̣
g 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
̉
̀
̀
́
̉
sô tuy thich ma không
̀ ̀
́
cách này bꢅn cꢉ thꢊ đăng ký mꢄt lớp và sau đꢉ tꢅo ra bao nhiêu cꢆa
cân chi ro tât ca cac thuôc tinh đo thêm môt lân nao nƣa . Hâu hêt cac thuôc
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
nhƣ ban
C++.
̀
́
̣
̣
̀
̀
́
̣
tinh ma ban
̣
thiê
́t
̃
̉
́
́
̀
̃
́
̀
̉
́
́
̉
̉
̣
̣
) nê
́
u
̉
́
̣
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
const char g_szClassName[] = "myWindowClass";
̉
Biê
́
n trên lƣu tên cua lơp cƣa sô cua chung ta , chꢓng ta sẽ sꢆ dꢂng nꢉ đꢊ đăng ký lớp
̉
̉
̉
́
́
̉
cƣa sô cua chung ta vơi hê
̣
thô
́
ng.
̉
̉
́
́
8
̣
Bài giảng môn học: Lâp trinh Windows
̀
WNDCLASSEX wc;
wc.cbSize
wc.style
= sizeof(WNDCLASSEX);
= 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon
= LoadIcon(NULL, IDI_APPLICATION);
= LoadCursor(NULL, IDC_ARROW);
wc.hCursor
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;
}
̣ ̣
Đo la đoan ma chƣơng trinh chung ta sƣ dung trong ham WinMain() đꢊ đăng ky lơp cƣa
̃
́ ̀ ́ ́
̉ ̉
̀
́
̀
̉
sô cua chung 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 ham 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
̣
tinh nay đƣơc
̣
gan bă
̀
ng 0.
̀
́
́
̉ ̉
quan ly cƣa sô cho lơp cƣa sô nay.
̉ ̉ ̉
́ ́ ̀
lpfnWndProc: con tro tro tơi thu tuc
̣
̉
̉
̉
́
cbClsExtra: Lƣơn
̣
g dƣ liêu
̣
thêm đƣơc
̣
câ
́
p phat trong bô
̣
nhơ cho mô
̃
i cƣa sô thuôc
̉
̣
loai
̣
̃
́
́
̉
này. Thông thƣơng cung đƣơc
̣
gan băng 0.
̀
̀
̃
́
hInstance: Quản lý mꢄt thꢊ nghiꢁm (instance) cꢀa ứng dꢂng (tham sô
WinMain()).
́ đầu tiên cua ham
̉
̀
̉
hIcon: Icon lơn (thƣơng la 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 trinh Windows
̀
̉ ̉
̣ ̣
t hiên khi con tro chuôt di chuyên qua vung cƣa sô cua chƣơng
̉ ̉ ̉
̀
hCursor: Con tro se xuâ
́
̉
̃
trình.
̉
̉
̀u nền cua cƣa sô.
̉ ̉
hbrBackground: Tham sô
́
sƣ dun
̣
g đê thiê
́
t lâp
̣
mâ
̉
̣
sƣ dung cho cac cƣa sô cua lơp.
̉ ̉
́ ́
̉
lpszMenuName: tên cua tai nguyên menu đƣơc
̣
̉
̉
̀
̉
̉
̣
h danh lơp cƣa sô
̉
́
lpszClassName: Tên đê đin
̉
̉
̣
trên thanh task bar va goc trên bên trai cua cƣa sô.
̉ ̉
̀ ́ ́
hIconSm: Icon nho (16x16) hiên thi
̉
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 khac cân phai nhơ la không nên cô nhơ nhƣng
̣
thuôc tinh nay. Tôi rât it khi (không muôn noi la không bao giơ ) nhơ cac thuôc tinh cung nhƣ
̃
́
̣
̀
̀
́
̉
̃
́
́
̀
́
̣
́
́
̀
́
̀
̀
́
́
́
́
các tham số cꢀa các hàm , điê
Nêu nhƣ ban biêt cac ham ban
tài liꢁu help. Nêu ban
không hê thiêu. Cuôi cung thi ban
dꢂng.
̀
u đo hoan toan la môt
̣
cô
g trong môt chƣơng trinh nao đo , hãy tra trong các
không co ca c file help hay down chung vê
́
gă
́
ng lang phi thơi gian va công sƣc
.
́
̀
̀
̀
̃
̀
̀
́
́
́
̣
́
̣
câ
̀
n sƣ dun
̣
̣
̉
́
̀
̀
́
̀
́
̣
̀
, các file kiꢊu này trên mꢅng
́
́
̃
́
̀
́
́
̣
se biê
́
t cac tham sô
́
cua cac ham ma ban thƣơng xuyên sƣ
̣
̉
̉
̀
̃
́
́
̀
̀
̀
̀
Tiê
công hay không, nê
chƣơng trinh.
́p đến chung ta goi tơi ham RegisterClassEx () và kiꢊm tra xem hàm này cꢉ thành
̣
́
́
̀
̉
̣ ̣ ̣
u nhƣ ham tra về sai chung ta se hiên thi môt thông bao thất bai va dƣng
̉
̃
̀ ́ ́ ̀ ̀
́
̀
Bƣơc 2: Tꢅo ra cꢆa sổ chƣơng trình
́
̉
Khi đa đăng ky lơp cƣa sô , chꢓng ta cꢉ thꢊ tꢅo ra các cꢆa sổ trong chƣơng trinh. 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 se giai thich môt chut ơ đâ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 chung ta muô
́
n khac . 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 chung ta cần co tên lơp (g_szClassName), tham số nay bao 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 ky nên chung ta sƣ dun
̣
g tên cua lơp cƣa sô đo . Sau đo chung ta chi ro tên cua cƣa
̉
̉
̉
̃
̉
̉
̀
́
́
́
́
́
́
̉
̉
sô hoăc tiêu đề (xâu ky tƣ ) sẽ xuất hiꢁn trong vai trꢈ là tham số Caption hoꢏc Title Bar cꢀa
̣
̣
́
̉
cƣa sô cua chung ta.
̉
̉
́
10
̣
Bài giảng môn học: Lâp trinh Windows
̀
Tham sô chung ta sƣ dun
́
̣
g
WS_OVERLAPPEDWINDOW trong vai tro 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 va Y cua goc trên bên trai cua cƣa sô va cac kich thƣơc dai rôn
̣
g cua no . Tôi đa thiê
́
t lâp
̉
̣ ̣ ̣ ̣
chon vi tri đê đăt cƣa sô chƣơng trinh
́
̣
gia
̉
̉
̉
̉
̃
̀
́
́
̀
́
́
̀
́
́
́
̉
̉
trꢃ cꢀa X và Y là CW _USEDEFAULT đê windows tƣ
khi chay. 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. Đinh cua man hinh tƣơng ƣng vơi gia 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 tai đô phân giai hiên
̉
tꢅi.
Tiê
cꢀa cꢆa sổ đƣợc sinh ra , môt
và mꢄt con tro tro tơi dƣ liêu
́p theo (NULL, NULL, g_hInst, NULL) chꢓng ta cꢉ mꢄt handle quản lý cꢆa sổ cha
̉
̣ ̣ ̣
handle quan ly menu , môt handle cho thê nghiêm cua ƣng dung
̉ ̉
́ ́
̣
̉ ̉
̣
cƣa sô . Trong windows cac cƣa sô trên man hinh đƣơc ́p xếp
̉ ̉
́ ̀
̀
̣
să
y môt
cƣa sô , nꢓt đꢉ là con và nꢉ đƣợc chứ a trong cƣa sô la cha cua no . Trong vi du
̉
̉
̃
́
̉
̉
theo môt
̣
câ
́
u truc phân câ
́
p theo kiêu cac cƣa sô cha va con . Khi chung ta nhin thâ
́
̣
nut
̉
́
́
̀
́
́
̀
̉
̉
trên môt
̣
̣
nay
̀
̉
̉
̉
̀
́
́
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 la
̀
̉
̉
cƣa sô chinh hoăc
̣
cƣa sô ơ câ
́
p cao nhâ
́
t cua chung ta . Menu cung la NULL vi chung t a chƣa
̉
̉
̉
̉
̃
́
̀
́
́
̀
̉
cꢉ menu chƣơng trình nào . Handle danh cho thê nghiêm
̣
cua chƣơng trinh đƣơc
̣
gan la gia tri
̣
̉
̀
́
̀
́
̀
đƣơc
̣
truyê
̀
n cho tham sô
̉ ̉
̣ ̣
chăng bao giơ sƣ dung chung ) cꢉ thꢊ đƣợc sƣ dung đê gƣi cac dƣ liêu khac tơi cƣa sô đang
́ ́ ́
̃
̉ ̉
́ đầu tiên cua ham WinMain (). Dꢋ liꢁu cꢆa sổ (thƣơng la chung ta
̉
̀ ̀ ̀ ́
̉
̣
̉
̉
̀
́
đƣơc
̣
tao
Nê
chỉ là 0 (zero). Thƣc
con tro. 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
̣
ra va cung la NULL.
̀
̃
̀
̉
̣
̀ gia tri NULL bi hiêm nay thi hay yên tâm vi no đơn gian
́ ̀ ́
̃
̉
́ ̀ ̀
́
́
u ban
̣
đang băn khoăn vê
̣ ̣
sƣ trong C no đƣơc đinh nghia la ((void*)0) vì nꢉ đƣợc sꢆ dꢂng với các
̀
̃
̣
̣
̉
̉
̣
NULL cho cac gia 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 trinh biên dic
̣
h. 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à
̉
̣ ̣ ̣ ̣ ̣ ̣
không kiêm tra ca c gia tri tra về cua lơi goi ham ma ho thƣc hiên trong chƣơng trinh
̉ ̉
́ ́ ̀ ̀ ̀
̀
do ho
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 ma chung ta rât dê tao
chꢓng. Cho tơi khi ban hoc đƣơc canh nhanh chong xac đinh cac 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 goi tơi cac ham.
̀
̃
́
̃
̣
ra
̀
́
̃
̉
̣
̣
̣
̣
̣
́
́
́
́
́
̀
̣
́
́
̀
if(hwnd == NULL)
{
MessageBox(NULL, "Window Creation Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
̉ ̉ ̉
̣
Sau khi chung ta đa tao ra cƣa sô va kiêm tra đê đam bao la 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 hanh) bă
̀
ng cach sƣ dun
̣
g
̉
̀
́
11
̣
Bài giảng môn học: Lâp trinh Windows
̀
tham sô
́
cuô
́
i cung cua ham WinMain () và sau đꢉ cập nhật nꢉ đꢊ đảm bảo là tự nꢉ đƣợc vẽ lꢅi
̉
̀
̀
môt cach hơp
̣
̣
lê
̣
trên man hinh.
̀
̀
́
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
Tham sô
́
nCmdShow la tuy chon
̣
, bꢅn cꢉ thꢊ đơn giản gán nꢉ là SW _SHOWNORMAL
vơi no.Tuy nhiên sƣ dung tham sô đƣơc truyên vao 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
̀
̀
mô
̃
i khi chung ta lam viêc
̣
̣
́
̣
̀
̉
́
̀
́
́
̀
̉ ̉
̣
́n cua sô cua chung ta bắt đầu vơi kich thƣơc cƣa sô lơn nhất hoăc nho nhất
̉ ̉ ̉ ̉
́ ́ ́ ́
́
hoăc
… Ban
̣
không muô
se thây cac tuy 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 chinh la trai tim cua toan bô chƣơng trinh , hầu hết nhƣng thƣ ma chƣơng trinh cua
̃
́ ̀
̉
̀ ̀
̉
̀
́
̀
́
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ƣ hang đơi
̣
thông điêp
, gõ bàn phím , click chuôt
thao tac nao đai loai nhƣ vây , các thông điꢁp sẽ
cua chƣơng trình. Băng cach goi tơi ham
̣
cua ƣng dun
̣
g cua ban
̣
trên menu
̣
.
̉
̉
̀
̀
́
̉
̉
Bâ
cꢀa cꢆa sổ chƣơng trình, hoăc
́
t ky thơi điêm nao ngƣơi dung di chuyên con chuôt
̣
̀
̀
̀
̀
̀
̣
lam bâ
̀
́
t cƣ môt
̣
̣
̣
̣
́
́
̀
đƣơc
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 co thông điêp nao ham GetMesage () sẽ chuyꢊn sang blocks . Nê
bꢅn không quen với thuât
̣
sinh ra va thêm chung vao hang đơi
̣
thông điêp
̣
̀
̣
̉
̀
́
̀
̀
́
́
̀
́
̣
́
u
p
́
̀
̀
̣
̣ ̣ ̣
ngƣ, điều đo co nghia la no se đơi cho tơi khi co môt thông điêp tiế
́ ́ ̀ ́ ́ ́
̃ ̃
̃
̉
theo đê xƣ ly (lâ
́
y vê
TranslateMessage() thƣc
nhƣ sinh ra cac thông điêp WM _CHAR cung vơi cac thông điêp
̀ cho chƣơng trinh).
̉
́
̀
̉
̣ ̣
ban phim chăng han
̀
́
̣
hiên
̣
thêm môt
̣
số
xƣ ly trên cac sƣ
̣
kiên
WM _KEYDOWN. Cuô
cân đƣơc gƣi tơi (xƣ ly theo
). Đo co thê la cƣa sô chinh cua chƣơng trinh hoăc co th ꢊ là mꢄt cꢆa sổ
̉
́
́
̣
̣
́i
́
̀
́
́
̉
cꢘng DispatchMessage() gƣi thông điêp
kiêu hƣơng sƣ
khác, hoăc
trƣơng bơi hê
̣
tơi cƣa sô ma thông điêp
̣
̀
̣
̉
̉
̉
̉
́
̀
́
́
̉
̉
̉
̣
kiên
la môt điê
ng hoăc
t ca nhƣng gi chung ta ban tơi la lâ
̣
̣
̉
̉
́
́
́
̀
́
́
̀
̉
̣
̣
̀
u khiên , và trong mꢄt số trƣờng hợp là mꢄt cꢆa sổ đƣợc tꢅo ra ở hậu
môt chƣơng trinh khac. Đây không phai la điêu ma cac ban cân phai
ng se xƣ ly đê
̀
̣
thô
́
̣
̣
̀
̣
̀
̉
̉
̉
̀
́
̀
̀
́
̀
̉
lo lă
́
ng vi tâ
́
́
y thông điêp
̣ ̣
va gƣi no đi , hê thố
̉
̀ ́
̉
̃
̃
̉
́
̀
́
̀
́
̀
̀
đam bao thông điêp
̣
đo đƣơc
̣
gƣi đê
́
n đung nơi se nhân no.
̣
̉
̉
̉
̃
́
́
́
Bƣơc 4: Thꢀ tꢂc cꢆa sổ.
́
Nê
̣ ̣
́u nhƣ vong lăp thông điêp la trai tim cua chƣơng trình thì thꢀ tꢂc cꢆa sổ là bꢄ não
̉
̀ ̀ ́
̉
̣ ̣ ̣
t ca cac thông điêp đƣơc gƣi tơi cƣa sô cua chung ta đƣơc
̉ ̉ ̉ ̉
́ ́ ́
cꢀa chƣơng trình. Đây la nơi ma tâ
́
̀
̀
xƣ ly.
̉
́
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam,
LPARAM lParam)
12
̣
Bài giảng môn học: Lâp trinh Windows
̀
{
switch(msg)
{
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
̉
̉
̉
́ HWND la đê quan ly cƣa
̉ ̉
̀ ́
Thꢀ tꢂc cƣa sô đƣơc
̣
goi
̣
tơi đê xƣ ly cac thông điêp
̣
, tham sô
̉
̣ ̣
u nay la quan trong bơi vi ban co thê
̉
́
̀
̉
̉
́
́
́
̉
sô cua ban
̣
, cũng chính là đối tƣợng cꢀa thông điꢁp . Điê
̀
̉
̀
̀
̉
̣ ̣
g cung môt thu tuc cƣa sô
̉ ̉
̀
cꢉ hai hoꢏc nhiều hơn nꢋa các cꢆa sổ cꢘng lơp va chung se sƣ dun
̣
̉
́
̀
́
̃
̉ ̉ ̉
̣ ̣
(WndProc()). Sƣ khac nhau ơ đây la tham số hwnd se thay đôi tuy thuôc vao cƣa sô la cƣa sô
́ ̀ ̀ ̀ ̀
̃
̉ ̉ ̉
̉
̉
̣ ̣ ̣
nào. Chăng han khi chung ta lấy về môt thông điêp WM _CLOSE chung ta se huy 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
tô hơp phim Alt +F4. Thao tac nay se lam cho cƣa sô bi
xƣ ly no môt
̣
gƣi đến khi ngƣơi dung nhấn chu ꢄt vào nꢓt đꢉng cꢆa sổ hoꢏc nhấn
̉
̀ ̀
̉
̉
̣
huy theo măc
̣
̣
đinh , nhƣng tôi muốn
̃
̀
̉
̉
́
̀
́
̣
cach dƣt khoat , 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ƣ đong cac file dƣ liêu đang mơ , ngắt cac kết nối cơ sơ dƣ liêu , các kết nối mꢅng vân vân
̉ ̉
̃
́
́
́
̃
trƣơc khi thoat khoi chƣơng trinh.
̉
́
́
̀
Khi chung ta goi
̣
tơi ham DestroyWindow
() hê
̣ ̣
thống se gƣi thông điêp
̃
̉
́
́
̀
̉
̉
WM_DESTROY tơi cƣa sô se bi
̣
hꢀy bꢔ, trong trƣơng hơp nay la cƣa sô cua chung ta , và sau
̣
̉
̃
̉
̉
́
̀
̀
̀
́
̉
̉
đo huy tâ
́
t ca cac cƣa sô con trƣơc khi loai
̣
bo cƣa sô cua chung ta khoi hê
̣
thô
u viêc phai lam va chung
n thoat khoi chƣơng trinh, vì thế hàm PostQuitMessage() đƣơc goi tơi. Hàm này sẽ gꢆi
́
ng
. Vì chỉ cꢉ
̉
̉
̉
̉
̉
̉
̉
́
́
́
́
̉
môt
ta muô
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ƣ ly thông điêp cua chung ta , khi điêu đo xay ra chung ta dƣng viêc xƣ ly cac thông điêp
và trả về giá trꢃ cuối cꢘng , tham sô
qua ham PostQuitMessage(). Giá trꢃ trả về chỉ thực sự cꢉ ích nếu chƣơng trình cꢀa chꢓng ta
̣
cƣa sô trong chƣơng trinh cua chung ta nên cung không co nhiê
̀
̣
̉
̉
̃
̉
́
́
̀
̀
́
̀
́
̣
̣
̉
́
́
̀
̣
WM _QUIT tơi vong lăp thông điêp . Chꢓng ta không bao nhận đƣợc thông điꢁp
̣
̣
́
̀
̣
̣
̀
̣
̣
̉
̉
̉
̉
́
́
́
́
̀
́
́
́
̣ ̣ ̣
wParam cua thông điêp WM _QUIT la gia tri đƣơc truyền
̉
̀ ́
̀
̉ ̉
̣ ̣ ̣ ̣ ̣
́t kế đê môt chƣơng trinh khac goi va chung ta muốn tra về môt gia tri cu thê.
̉
́ ̀ ́ ́
̀
đƣơc
̣
thiê
Bƣơc 5: không co bƣơc 5
́
́
́
Đê
́
n đây la 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
chƣơng trinh trên Windows.
̉
̀
cấ
u truc cơ ban cua môt
̣
̉
́
̀
13
Tải về để xem bản đầy đủ
Bạn đang xem 20 trang mẫu của tài liệu "Giáo trình Lập trình Windows", để tải tài liệu gốc về máy hãy click vào nút Download ở trên
File đính kèm:
giao_trinh_lap_trinh_windows.pdf

