mfc tieng viet

133

Click here to load reader

Upload: binhdinh0708

Post on 11-Nov-2014

5.963 views

Category:

Education


21 download

DESCRIPTION

Lap trinh giao dien bang MFC

TRANSCRIPT

Page 1: Mfc Tieng Viet

LEÂ NGOÏC THAÏNH [email protected]

LAÄP TRÌNH WINDOWS VÔÙI MFC Microsoft Visual C++ 6.0

NHAØ XUAÁT BAÛN THOÁNG KEÂ

Page 2: Mfc Tieng Viet

MUÏC LUÏC

CHÖÔNG 1 : MOÄT SOÁ KHAÙI NIEÄM LAÄP TRÌNH TRONG MOÂI TRÖÔØNG WINDOWS 1.1 Chöông trình ( Program ) 1.2 ÖÙng duïng ( Application ) 1.3 Tieán trình ( Process ) 1.4 Tieåu trình (Thread ) 1.5 Thoâng ñieäp ( Message )

1.5.1 Nguoàn goác cuûa message 1.5.2 Caùc loaïi message 1.5.3 Soá hieäu message (Message Indentifier – MessageID) 1.5.4 Ñaëc taû message

1.6 Cöûa soå giao dieän (window) cuûa öùng duïng 1.7 Message queue 1.8 Kieán truùc xöû lyù cuûa öùng duïng trong Windows 1.9 Resource cuûa öùng duïng CHÖÔNG 2 : THÖ VIEÄN MFC CUÛA MICROSOFT & ÖÙNG DUÏNG CÔ BAÛN TRONG WINDOWS 2.1 Thö vieän MFC (Microsoft Foundation Class) 2.2 Tieáp �an MFC 2.3 Taïo öùng duïng windows vôùi MFC nhö theá naøo ? 2.4 Lôùp quaûn lyù tieåu trình CwinThread 2.5 Lôùp quaûn lyù tieåu trình giao dieän chính CwinApp 2.6 Thöïc hieän öùng duïng ñôn giaûn 2.7 Thöïc hieän öùng duïng giao taùc ñôn giaûn 2.8 Taïo môùi Icon Resource cho öùng duïng 2.9 Löu tröõ chöông trình nguoàn 2.10 Lôùp Cstring cuûa MFC CHÖÔNG 3 : CAÙC LÔÙP GIAO DIEÄN ÑOÀ HOÏA CUÛA MFC 3.1 Caùc coâng cuï giao dieän ñoà hoïa 3.2 Device Context 3.3 Toïa ñoä treân giao dieän ñoà hoïa 3.4 Caùc lôùp MFC hoã trôï GDI

3.4.1 Caùc lôùp ñoái töôïng ñieåm, hình chöõ nhaät

Trang 1 1 1 1 1 2 2 2 3 3 3 5 7 8 10 10 10 10 11 12 14 20 25 27 27 29 29 29 29 30 30

3.4.2 Lôùp Cpen 3.4.3 Lôùp CBrush 3.4.4 Lôùp CFont 3.4.5 Lôùp CBitmap 3.4.6 Lôùp CPalette 3.4.7 Lôùp CRgn

3.5 Lôùp CDC 3.6 Lôùp CImageList CHÖÔNG 4 : CÖÛA SOÅ GIAO DIEÄN LÔÙP VAØ LÔÙP CWnd 4.1 Cöûa soå giao dieän 4.2 Lôùp CWnd 4.3 Söû duïng ñoái töôïng CWnd

4.3.1 Söû duïng CWnd laøm giao dieän chính cuûa öùng duïng 4.3.2 ÖÙng duïng chæ chaïy moät baûn (instance) taïi moãi thôøi ñieåm

CHÖÔNG 5 : XÖÛ LYÙ MESSAGES 5.1 Lôùp xöû lyù message CCmdTarget: 5.2 Khai baùo muïc xöû lyù message trong MessageMap 5.3 Caùc lôùp keá thöøa CCmdTarget 5.4 MessageMap cuûa lôùp keá thöøa CWnd trong öùng duïng

5.4.1 Cöûa soå cuûa öùng duïng coù chöùc naêng hoaït ñoäng 5.4.2 WM_PAINT vaø haønh vi OnPaint cuûa CWnd

CHÖÔNG 6 : ÖÙNG DUÏNG COÂNG CUÏ GDI 6.1 DC vaø BITMAP 6.2 ÖÙng duïng vôùi cöûa soå chính hieån thò aûnh 6.3 Sao cheùp aûnh töøø DC ñeán DC, phoùng to & thu nhoû aûnh 6.4 DC trong boä nhôù ( DC aûo) – vuøng veõ ñeäm lyù töôûng 6.5 AÛnh chuyeån ñoäng trong vuøng client 6.6 CImageList – coâng cuï quaûn lyù boä aûnh cuøng côõ 6.7 CRgn – Cöûa soå coù hình daïng tuøy yù CHÖÔNG 7 : MENU – PHÍM TAÉT 7.1 Ñònh nghóa 7.2 Menu resoure

31 31 32 32 33 34 35 38 40 40 40 49 49 50 51 51 52 55 55 55 58 60 60 60 63 64 65 66 67 69 69 69

Page 3: Mfc Tieng Viet

7.3 Söû duïng menu resource 7.4 Muïc xöû lyù command message töø muïc choïn cuûa menu 7.5 Phím taét (hot key ) cho muïc choïn treân menu 7.6 Lôùp quaûn lyù menu – CMenu 7.7 Xöû lyù ñieàu khieån muïc choïn cuûa menu CHÖÔNG 8 : CAÙC LÔÙP ÑOÁI TÖÔÏNG NHAÄP LIEÄU ( WINDOWS CONTROLS ) 8.1 CStatic 8.2 CEdit 8.3 CButton 8.4 ClistBox 8.5 CComboBox 8.6 CSpinButtonCtrl 8.7 CProgressCtrl 8.8 CscrollBar 8.9 CSliderBar CHÖÔNG 9 : HOÄP HOÄI THOAÏI 9.1 Hoäp hoäi thoaïi (Dialog) 9.2 Lôùp CDialog 9.3 Taïo vaø söû duïng dialog trong chöông trình

9.3.1 Taïo dialog resource 9.3.2 Khai baùo lôùp keá thöøa CDialog söû duïng dialog resource 9.3.3 Söû duïng dialog trong chöông trình

9.4 Lieân keát giöõa dialog vaø caùc thaønh phaàn khaùc 9.5 Söû duïng dialog laøm giao dieän chính cuûa öùng duïng

9.5.1 Thöïc hieän öùng duïng vôùi giao dieän chính laø dialog 9.5.2 Duøng MFC wizard taïo öùng duïng vôùi giao dieän dialog

9.6 Khai baùo bieán cho control treân dialog 9.7 Khai thaùc caùc tieän ích hoã trôï CHÖÔNG 10 : KHUNG CÖÛA SOÅ GIAO DIEÄN CHÍNH 10.1 Khung cöûa soå giao dieän (Frame Window) 10.2 Thanh traïng thaùi (statusbar) & lôùp CStatusbar 10.3 Thanh coâng cuï (toolbar) & lôùp CToolBar

71 72 73 75 77 78 78 80 84 85 88 91 93 94 96 97 97 97 99 99 103 104 104 106 106 107 109 112 117 117 117 119

10.3.1 Thieát keá ToolBar resource 10.3.2 Duøng toolbar resource cho CToolBar cuûa FrameWnd

10.4 Lôùp CFrameWnd 10.5 Söû duïng frame window laøm giao dieän chính

10.5.1 Thöïc hieän öùng duïng vôùi giao dieän frame window 10.5.2 String Table vaø CFrameWnd 10.5.3 Duøng MFC wizard taïo öùng duïng giao dieän framewindow

CHÖÔNG 11 : CAÙC KIEÁN TRUÙC DOCUMENT – VIEW 11.1 CDocument 11.2 CView 11.3 CFrameWnd 11.4 CDoctemplate 11.5 Hoã trôï töø phía ñoái töôïng quaûn lyù öùng duïng 11.6 Trình töï taïo laäp caùc ñoái töôïng tham gia boä DVF 11.7 Text Document Appication 11.8 Rich Text Format (rtf) Document Appication 11.9 HTML Document View Appication 11.10 Moät soá lôùp view ñaëc bieät

11.10.1 CListView 11.10.2 CTreeView 11.10.3 CSplitterWnd 11.10.4 Söû duïng splitterwnd trong frame window 11.10.5 Caùc ví duï thöïc haønh

CHÖÔNG 12 : MOÄT SOÁ VAÁN ÑEÀ TRONG WINDOWS 12.1 Taäp tin INI 12.2 System Registry 12.3 Vuøng Status Area treân Taskbar 12.4 ÖÙng duïng ScreenSaver

12.4.1 Ñaëc ñieåm 12.4.2 Tham soá doøng leänh 12.4.3 Ñaëc ñieåm giao taùc vôùi ngöôøi duøng 12.4.4 Thöïc hieän öùng duïng ScreenSaver ñôn giaûn 12.5 ÖÙng duïng söû duïng nhieàu tieåu trình

12.5.1 Tieåu trình xöû lyù noäi

120 121 121 123 123 124 130 134 134 135 136 136 137 138 139 143 146 149 149 150 152 154 155 158 158 160 162 167 168 168 170 171 175 175

Page 4: Mfc Tieng Viet

12.5.2 Tieåu trình giao dieän 12.5.3 Caùc haøm hoã trôï

12.6 Laäp trình Multimedia vôùi MCI 12.7 AÁn ñònh moät soá tính naêng cuûa Windows 12.8 Baãy (hook) message (Windows Hook)

12.8.1 Caùc kieåu hook (Hook Type) 12.8.2 Danh saùch hook (Hook Chain) 12.8.3 Thuû tuïc hook (Hook Procedure) 12.8.4 Caùc dòch vuï lieân quan hook 12.8.5 ÖÙng duïng hook messages cuûa keyboard

12.9 Caøi ñaët cheá ñoä thöïc hieän öùng duïng töï ñoäng CHÖÔNG 13 : MFC VÔÙI INTERNET 13.1 Giao thöùc truyeàn thoâng TCP/IP 13.1.1 Giôùi thieäu 13.1.2 Kieán truùc cuûa giao thöùc TCP/IP treân moâ hình DARPA 13.1.3 Ñòa chæ IP 13.1.4 Subnet 13.1.5 Subnet Mask 13.1.6 Host domain name 13.1.7 IP Routing 13.2 Laäp trình TCP/IP vôùi Winsock 13.2.1 Port 13.2.2 Socket 13.2.3 Moät soá caáu truùc döõ lieäu cuûa Winsock API 13.2.4 Moät soá dòch vuï cuûa Winsock API 13.3 MFC vôùi laäp trình Winsock 13.3.1 Khôûi ñoäng Winsock 13.3.2 Lôùp CAsyncSocket 13.4 Laäp trình Winsock cho giao thöùc UDP 13.5 Laäp trình Winsock cho giao thöùc TCP 13.6 TCP vôùi SMTP (Simple Mail Transfer Protocol) 13.6.1 Qui öôùc giöõa öùng duïng göûi mail vaø nhaän mail

13.6.2 Thieát keá öùng duïng göûi mail 13.7 TCP vôùi Pop3 (Post Office Protocol – Version 3)

13.7.1 Qui öôùc giöõa öùng duïng mail client vaø mail server

177 179 179 181 182 183 183 183 184 185 186 187 187 187 187 189 190 191 192 194 197 197 198 198 199 200 200 200 204 207 215 215 217 219 219

13.7.2 Thieát keá öùng duïng nhaän mail 13.8 TCP vôùi HTTP vaø FTP 13.8.1 Lôùp CInternetSession 13.8.2 Lôùp CInternetFile 13.8.3 Lôùp CFtpConnection 13.8.4 Lôùp CFtpFindFile 13.8.5 Lôùp CHttpConnection 13.8.6 Lôùp CHttpFile 13.8.7 Thöïc hieän öùng duïng FTP client ñôn giaûn 13.8.8 Thöïc hieän öùng duïng HTTP client ñôn giaûn Phuï luïc A: MOÄT SOÁ VAÁN ÑEÀ LAÄP TRÌNH HÖÔÙNG ÑOÁI TÖÔÏNG A.1 Laäp trình höôùng ñoái töôïng (OOP) A.2 Caùc khaùi nieäm

A.2.1 Lôùp (Class) A.2.2 Ñoái töôïng (Object) A.2.3 Thuoäc tính (Attribute) A.2.4 Haønh vi (Method) A.2.5 Chöông trình (Program)

A.3 Ñaëc ñieåm laäp trình höôùng ñoái töôïng A.4 Phaân loaïi thuoäc tính vaø haønh vi A.5 Caùc haønh vi ñaëc bieät A.6 Khai baùo lôùp, ñoái töôïng trong C++

A.6.1 Khai baùo lôùp A.6.2 Khai baùo ñoái töôïng A.6.3 Söû duïng ñoái töôïng trong chöông trình

A.7 Keá thöøa trong C++ A.7.1 Keá thöøa haønh vi taïo laäp A.7.2 Keá thöøa haønh vi huûy boû A.7.3 Thöïc hieän haønh vi lôùp cô sôû

A.8 Khai baùo haønh vi toaùn töû soá hoïc A.9 Con troû this A.10 Haønh vi virtual A.11 Thuoäc tính vaø haønh vi tónh

220 223 223 224 225 227 228 229 231 232 234 234 234 234 234 234 235 235 235 236 236 236 236 238 238 239 239 240 240 241 243 243 244

Page 5: Mfc Tieng Viet

LÔØI MÔÛ ÑAÀU

Ngoân ngöõ laäp trình C++ ñöôïc bieát ñeán nhö laø moät trong nhöõng ngoân ngöõ laäp trình maïnh nhaát nhôø khaû naêng cuûa noù trong vieäc trieån khai phaàn meàm ôû caùc möùc ñoä khaùc nhau. Töø möùc heä thoáng ñeán möùc öùng duïng, töø laäp trình caáu truùc ñeán laäp trình höôùng ñoái töôïng, töø laäp trình döïa treân thuaät giaûi ñeán laäp trình trí tueä nhaân taïo, vaø töø laäp trình cô sôû döõ lieäu ñeán laäp trình cô sôû tri thöùc…, baát cöù ñaâu, khi maø ngöôøi laäp trình muoán theå hieän yù töôûng khoa hoïc vaø ngheä thuaät cuûa mình treân maùy tính thì C++ laø moät ñieàu nghó ñeán tröôùc tieân.

Nhöng duø yù töôûng coù bay boång theá naøo ñi nöõa thì cuõng khoâng theå boû qua vaán ñeà caøi ñaët maø moâi tröôøng cho öùng duïng laø ñieàu phaûi quan taâm. Vôùi xu höôùng söû duïng heä ñieàu haønh Microsoft Windows nhö hieän nay, chuùng ta buoäc phaûi nghó ñeán vieäc caøi ñaët öùng duïng cuûa mình trong moâi tröôøng naøy vaø khai thaùc noù sao cho öùng duïng hoaït ñoäng hieäu quaû nhaát.

Microsoft Visual C++, saûn phaåm cuûa Microsoft, vôùi khaû naêng bieân dòch öu vieät vaø loái khai thaùc heä thoáng roäng môû nhôø taäp hôïp lôùp thö vieän MFC cho C++ coù ñaày ñuû caùc tieän ích giuùp chuùng ta veùt ñöôïc moïi ngoõ ngaùch cuûa Windows haàu phuïc vuï cho öùng duïng cuûa mình.

Töø nhöõng nhaän ñònh noùi treân, cuoán saùch naøy ñöôïc thöïc hieän ñeå cuøng caùc baïn baét ñaàu laøm quen laäp trình trong Windows aùp duïng kyõ thuaät laäp trình höôùng ñoái töôïng vôùi C++, nhaèm khai thaùc hieäu quaû thö vieän MFC vaø töøng böôùc du nhaäp vaøo theá giôùi tuyeät vôøi naøy thoâng qua caùc öùng duïng ñöôïc saép xeáp theo caùc caáp ñoä tieán trieån phuø hôïp.

Trong laàn xuaát baûn ñaàu tieân, cuoán saùch naøy chaéc khoâng traùnh khoûi thieáu soùt. Chuùng toâi raát mong tieáp thu yù kieán ñoùng goùp vaø trao ñoåi cuøng baïn ñoïc. Cuoái cuøng, chuùng toâi xin chaân thaønh caûm ôn baïn beø, ñoàng nghieäp ñaõ cung caáp nhöõng nhaän xeùt vaø kieán thöùc quí baùu ñeå thöïc hieän cuoán saùch naøy. Xin caûm ôn caùc baïn hoïc vieân-sinh vieân, nhöõng ngöôøi ñaõ cuøng laøm vieäc vôùi chuùng toâi qua noäi dung naøy vaø ñaõ coù nhöõng yù kieán khaùch quan giuùp chænh söûa cuoán saùch kòp thôøi.

Thaønh phoá Hoà Chí Minh, ngaøy 19.11.2002 Taùc giaû

TAØI LIEÄU THAM KHAÛO

[1] Richard Simon, Windows 95 - Win32 Programming API-BIBLE, Waite Group Press 1996.

[2] Jeff Prosise, Programming Windows 95 with MFC, Microsoft Press. [3] M. Tracy, Professional Visual C++ ISAPI Programming, Wrox Press. [4] Dr. GUI, Microsoft Developer Network - MSDN,

Microsoft Corporation Software. [5] Dino Esposito,Visual C++ Windows Shell Programming, Wrox Press.

PHAÀN MEÀM CAÀN CAØI ÑAËT: - Microsoft Visual C++ 6.0 hoaëc Microsoft Visual C++ .NET. - MSDN ( Microsoft Developer Network ), baûn thaùng 10/2003.

MAÕ NGUOÀN: Source Code cuûa caùc ví duï minh hoïa trong cuoán saùch naøy vaø cuûa moät soá chöông trình troø chôi maø chuùng toâi mong muoán chia xeû cuøng baïn ñoïc ñöôïc löu trong ñóa meàm ñính keøm, vaø coù theå download töø ñòa chæ:

http://thanh.andisw.com/?id=16&id2=85

WEB SITE: Source Code ñaëc saéc cuûa nhieàu taùc giaû treân theá giôùi coù theå download: - http://msdn.microsoft.com - http://www.codeguru.com - http://www.codeproject.com - http://www.softechsoftware.it - http://www.flipcode.com - http://nps.vnet.ee

LIEÂN HEÄ: - Taùc giaû: Leâ Ngoïc Thaïnh - Cô quan: Khoa Tin Hoïc Quaûn Lyù, Tröôøng ÑHKT TP.HCM

Ñòa chæ: 279 Nguyeãn Tri Phöông Q10, TP.HCM. - Ñòa chæ e-mail: [email protected]

[email protected]

Page 6: Mfc Tieng Viet

Moät soá khaùi nieäm laäp trình trong moâi tröôøng Windows 1

CHƯƠNG 1:

Một số khái niệm Lập trình Trong môi trường Windows

1.1 CHƯƠNG TRÌNH (PROGRAM):

Chương trình máy tính là tập hợp các chỉ thị điều khiển hoạt động của máy, được bố trí theo một trình tự logic nhằm phối hợp thực hiện một công việc xác định. Các chỉ thị được thể hiện dưới dạng mã nguồn (source code) hay mã máy (machine code). Chương trình mã máy có thể thực hiện được trên máy có bộ lệnh tương thích, với chương trình mã nguồn thì phải sử dụng một ứng dụng chuyên dụng để chuyển sang mã máy trước khi thực hiện.

Việc chuyển các chỉ thị dạng mã nguồn sang chỉ thị mã máy để thực hiện được tiến hành bằng một trong hai cơ chế sau: Thông dịch: Mỗi chỉ thị mã nguồn được chuyển sang chỉ thị mã máy

tương ứng và được thực hiện ngay, sau đó tiếp tục với chỉ thị kế tiếp. Biên dịch: Tất cả các chỉ thị mã nguồn được chuyển sang các chỉ thị

mã máy tướng ứng. Tập hợp các chỉ thị mã máy này gọi là chương trình mã máy. Chương trình mã máy được lưu lại trong tập tin chương trình và về sau ta có thể thực hiện chúng một cách độc lập trên máy.

1.2 ỨNG DỤNG (APPLICATION): Khi một chương trình được cài đặt trên máy tính để sử dụng, ta gọi đó

là ứng dụng, ví dụ như ứng dụng NotePad, ứng dụng Microsoft Word,.... Trong môi trường windows, mỗi ứng dụng có thể được thi hành nhiều

lần thành nhiều bản khác nhau. Mỗi bản đang thực hiện của một ứng dụng gọi là thể hiện (instance) của ứng dụng đó.

1.3 TIẾN TRÌNH (PROCESS): Tiến trình là khái niệm chỉ một instance đang hoạt động của ứng

dụng. Khi ta double-click trên biểu tượng NotePad để chạy ứng dụng này, ta có một tiến trình của ứng dụng NotePad.

1.4 TIỂU TRÌNH (THREAD): Tiểu trình là một nhánh xử lý độc lập trong tiến trình. Khi một ứng

dụng được thực hiện ta có thêm một tiến trình. Do bản chất chương trình làm nên ứng dụng đó bao gồm chương trình chính (main hay WinMain) và các chương trình con mà tiến trình ứng với nó có thể tách thành các nhánh xử lý: một nhánh xử lý chính (primary thread), các nhánh xử lý phụ (other threads). Các nhánh xử lý này gọi là các tiểu trình. Có hai loại tiểu trình:

2 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

Tiểu trình giao diện (user-interface thread): Có nhiệm vụ xử lý các yêu cầu của người dùng trong quá trình giao tác với họ.

Tiểu trình xử lý nội (worker thread): Có nhiệm vụ thực hiện các xử lý tính toán bên trong, không trực tiếp nhận yêu cầu của người dùng.

Thực ra, có thể xem tiểu trình giao diện như là một tiểu trình xử lý nội nhưng có tính năng giao tác với người sử dụng.

1.5 THÔNG ÐIỆP (MESSAGE): Thông điệp (message) là giá trị phản ánh một nội dung giao tiếp hay

yêu cầu xử lý giữa hệ thống (windows) và ứng dụng, giữa các ứng dụng với nhau hoặc giữa các thành phần trong cùng một ứng dụng. 1.5.1 Nguồn gốc message:

Cả windows và ứng dụng đều có thể phát sinh message. Windows phát sinh message khi cần thông tin cho ứng dụng các

hoạt động nhập-xuất (hoạt động gõ phím, di chuyển hay click chuột, . của người dùng), các thay đổi của hệ thống (font chữ, chế độ phân giải màn hình, màu sắc,...) hoặc những biến đổi khác liên quan đến ứng dụng.

Ứng dụng phát sinh message khi xử lý điều khiển các thành phần bên trong ứng dụng phối hợp thực hiện chức năng giao tiếp với người dùng, hoặc khi ứng dụng thực hiện giao tiếp với windows hay với các ứng dụng khác đang thực hiện trong cùng hệ thống.

1.5.2 Các loại message: Message được định nghĩa bởi hệ thống: Là các message do hệ điều

hành windows tạo ra nhằm phục vụ hoạt động điều khiển toàn bộ hệ thống, xử lý thông tin vào-ra hoặc các thông tin khác cho ứng dụng. Khi có nhu cầu, ứng dụng có thể sử dụng những message này để phát động một chức năng điều khiển nào đó của windows.

Message được định nghĩa bởi người dùng: Là các message do người viết ứng dụng định nghĩa nhằm tạo kênh liên lạc đặc thù giữa các thành phần trong ứng dụng, giữa ứng dụng với windows hoặc với các ứng dụng khác đang thực hiện trong cùng hệ thống.

Page 7: Mfc Tieng Viet

Moät soá khaùi nieäm laäp trình trong moâi tröôøng Windows 3

1.5.3 Số hiệu message (Message Indentifier - MessageID): Có rất nhiều message khác nhau được sử dụng trong môi trường

windows. Ứng với mỗi message xác định, windows sử dụng một giá trị nguyên không âm để đặc tả, giá trị này gọi là số hiệu message.

Các message do windows định nghĩa có số hiệu được khai báo sẵn và duy nhất với các hằng số xác định và tên gọi gợi nhớ của chúng có dạng WM_xxx. Các messges do người dùng định nghĩa cũng phải đăng ký số hiệu. Số hiệu đăng ký không được trùng lặp và có giá trị nhỏ nhất bằng WM_USER (một hằng số do windows định nghĩa).

Số hiệu message là cơ sở để phân biệt các message lẫn nhau.

1.5.4 Ðặc tả message: Ðể đối tượng nhận message có thêm thông tin về hoàn cảnh phát

sinh và ý nghĩa cụ thể của message, windows cho phép message được nhận thông qua một cấu trúc chứa số hiệu message và các thông số kèm theo. Cấu trúc này được khai báo thành kiểu MSG với nội dung như sau:

typedef struct tagMSG { HWND hwnd; // Giá trị có kích thước 4 bytes (long) UINT message; // Số hiệu của message WPARAM wParam; // Giá trị không âm có kích thước 2 bytes LPARAM lParam; // Giá trị không âm có kích thước 4 bytes DWORD time; // Thời điểm sinh ra messsge POINT pt; // Tọa độ cursor khi message được gửi. } MSG;

Trường hwnd (window handle) của cấu trúc chứa thẻ (handle) quản lý cửa sổ giao diện liên quan đến message. wParam và lParam là hai tham số gửi kèm theo message làm nhiệm vụ chứa thông tin bổ sung. Hai tham số này được dùng khi message có nhiều ý nghĩa thực tế khác nhau.

Windows sử dụng giá trị có kích thước 4 bytes để quản lý các đối tượng của nó. Giá trị này gọi là thẻ quản lý đối tượng (object handle). Ứng với mỗi loại đối tượng cụ thể, windows sử dụng một kiểu handle riêng. HWND là kiểu handle dùng quản lý đối tượng cửa sổ giao diện trong windows.

1.6 CỬA SỔ GIAO DIỆN (WINDOW) CỦA ỨNG DỤNG: Cửa sổ giao diện là thành phần quan trọng trong việc tạo ra môi

trường giao diện đồ họa của các ứng dụng trong windows. Cùng với sự phát triển của hệ điều hành windows, hình ảnh cửa sổ giao diện cũng thay đổi theo với chiều hướng sinh động hơn về hình thức và phong phú hơn về chức năng. Ðiều đó không chỉ góp phần tăng tính thẩm mỹ mà

4 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

còn tạo sự gần gũi hơn giữa giao diện của ứng dụng trong windows với người dùng.

Dạng thông thường của một cửa sổ giao diện trong windows:

System Menu Box: Chứa biểu tượng của ứng dụng, là nút mở hộp

menu hệ thống với các mục di chuyển, thay đổi kích thước hoặc đóng cửa sổ.

Caption bar: Thanh tiêu đề của ứng dụng. Menu bar: Hệ thống menu với các mục lựa chọn xử lý. Minimize / Maximize Box : Nút điều khiển thu nhỏ / phóng to cửa sổ. Restore Box : Nút khôi phục kích thước trước đó của cửa số. Border: Ðường viền bao quanh cửa sổ. Client area: Vùng làm việc của cửa sổ, dùng để hiển thị thông tin. Scroll bar: Thanh cuộn nội dung vùng làm việc của cửa sổ. Window Procedure: Ngoài giao diện đồ họa, cửa sổ của windows có

khả năng tiếp nhận và xử lý message. Khả năng này được thực hiện thông qua hàm xử lý message mà ta đã gắn cho cửa sổ. Hàm xử lý này có khai báo như sau: LRESULT CALLBACK WindowProc ( HWND hwnd, // Tham số chứa Handle của cửa sổ liên quan UINT uMsg, // Tham số chứa số hiệu message WPARAM wParam, // Tham số bổ sung thứ nhất kiểu WORD LPARAM lParam // Tham số bổ sung thứ hai kiểu LONG ) ; Hàm trả về một giá trị có kích thước là 32 bits. Khi một yêu cầu xử lý được chuyển đến cửa sổ dưới dạng message, hàm WindowProc gắn với cửa sổ sẽ căn cứ trên số hiệu message (uMsg) để chọn xử lý phù hợp. Theo nguyên tắc, nếu message được xử lý hoàn tất thì hàm trả về giá trị 0, ngược lại (message không thuộc

Page 8: Mfc Tieng Viet

Moät soá khaùi nieäm laäp trình trong moâi tröôøng Windows 5

khả năng xử lý của cửa sổ) hàm phải chuyển message cho windows xử lý thông qua lời gọi hàm xử lý message mặc nhiên của windows. Hàm xử lý này có tên gọi là DefWindowProc với khai báo như sau:

LRESULT DefWindowProc( // Default Window Procedure HWND hWnd, // Với các tham số có ý nghĩa như trên UINT Msg, WPARAM wParam, LPARAM lParam ) ; Khi đó, kết quả trả về của DefWindowProc được dùng làm kết quả của hàm WindowProc. Qui tắc nói trên cần phải được đảm bảo, nếu không, ứng dụng có thể làm rối loạn hoạt động của hệ điều hành windows.

1.7 MESSAGE QUEUE: Message queue là danh sách thứ tự các message do windows tạo ra

và được dùng để chứa các message đang chờ được xử lý. Message queue hoạt động theo nguyên tắc FIFO (First-In, First-Out: vào trước, ra trước). Có hai loại message queue trong windows: Message queue của hệ thống (system queue): Ðược windows dùng

riêng cho việc lưu trữ các messge đặc tả thông tin nhập-xuất liên quan đến thiết bị phần cứng trong quá trình hệ thống giao tác với người dùng.

Message queue của ứng dụng (application queue): Ðược windows tạo ra và cấp cho các thể hiện của ứng dụng. Windows tự động điều phối các message từ system queue sang application queue một cách phù hợp, nhờ đó mỗi ứng dụng có thể tiếp nhận và thực hiện các yêu cầu xử lý của người dùng thông qua hệ thống. Cơ chế này ngăn các ứng dụng trong windows quyền truy cập trực tiếp các thiết bị phần cứng của máy tính.

Việc truy cập message queue của ứng dụng được thực hiện với sự hỗ trợ của các hàm liên quan do windows cung cấp như sau: Chờ và lấy một message từ message queue của ứng dụng:

BOOL GetMessage ( LPMSG lpMsg, // Con trỏ đến biến MSG nhận thông tin HWND hWnd, // Handle của cửa sổ liên quan UINT wMsgFilterMin, // Số hiệu message nhỏ nhất nhận được UINT wMsgFilterMax // Số hiệu message lớn nhất nhận được ); Hàm tự động chờ đến khi phát hiện có message cần xử lý trong message queue. Khi đó, message vào trước nhất sẽ được lấy ra khỏi hàng chờ và thông tin của nó được điền vào biến kiểu MSG chỉ bởi

6 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

con trỏ tham số plMSG. Khi đã lấy được một message, hàm kết thúc và trả về một giá trị nguyên. Nếu message nhận được là message kết thúc ứng dụng (số hiệu WM_QUIT) thì hàm trả về giá trị 0. Ngược lại, hàm trả về giá trị khác 0.

Kiểm tra và lấy một message trong message queue của ứng dụng: BOOL PeekMessage( LPMSG lpMsg; // . Như GetMessage HWND hWnd; UINT wMsgFilterMin; UINT wMsgFilterMax; UINT wRemoveMsg; // Có thực hiện xóa message không ? // PM_NOREMOVE: không xóa ); Hàm trả về giá trị 0 nếu message queue rỗng. Ngược lại, hàm trả về một giá trị khác không và thông tin về message được điền vào biến kiểu MSG được chỉ bởi tham số kiểu con trỏ lpMSG.

Diễn dịch message của bàn phím sang mã phím ASCII: BOOL TranslateMessage( CONST MSG *lpMsg; // con trỏ đến biến chứa message ); Tham số lpMsg là con trỏ chỉ đến biến kiểu MSG chứa nội dung đặc tả message được lấy từ message queue và cần diễn dịch.

Hàm trả về giá trị khác 0 nếu message nhận được tương ứng với một thao tác trên bàn phím (nhấn phím: WM_KEYDOWN, WM_SYSKEYDOWN; thôi nhấn phím: WM_KEYUP, WM_SYSKEYUP) hoặc một message có ý nghĩa tương đương mà việc diễn dịch sang mã phím ASCII là thành công. Khi đó hàm tự động tạo message WM_CHAR cho phím diễn dịch được. Trong các trường hợp khác, hàm trả về giá trị 0.

Page 9: Mfc Tieng Viet

Moät soá khaùi nieäm laäp trình trong moâi tröôøng Windows 7

Ðiều phối message đến cửa sổ giao diện chính: Cửa sổ giao diện chính của ứng dụng có thể tiếp nhận và xử lý message thông qua hàm WindowProc của nó (1.6). Như vậy, ta có thể điều phối message lấy từ message queue của ứng dụng đến cho cửa sổ chính xử lý. Việc điều phối được thực hiện thông qua hàm sau: LRESULT DispatchMessage( CONST MSG *lpmsg; // Con trỏ đến biến chứa message ); Tham số lpMSG chỉ đến biến kiểu MSG chứa thông tin đặc tả message được điều phối. Hàm điều phối sẽ chờ đến khi hàm xử lý message WindowProc của cửa sổ chính xử lý xong messge, và lấy giá trị kết thúc của hàm này làm giá trị trả về của chính nó.

Quá trình tiếp nhận và điều phối xử lý message từ message queue của ứng dụng được tiến hành liên tục cho đến khi nhận được message kết thúc ứng dụng (WM_QUIT). Quá trình này có tên gọi là vòng lặp nhận và điều phối message (MessageLoop). Ðoạn chương trình nhận và điều phối message trong ứng dụng được cài đặt như sau: MSG msg; // biến chứa nội dung đặc tả message nhận được while( GetMessage( &msg, NULL, 0, 0 ) != 0 ) { // Nếu message nhận được không phải là WM_QUIT TranslateMessage(&msg); // Diễn dịch nếu là phím DispatchMessage(&msg); // Ðiều phối cho cửa sổ chính. }

1.8 KIẾN TRÚC XỬ LÝ CỦA ỨNG DỤNG TRONG WINDOWS: Khi ứng dụng được thực hiện, windows tạo thêm một tiến trình cho thể

hiện mới của ứng dụng, đồng thời xây dựng một message queue dùng riêng cho thể hiện này. Tiểu trình chính của tiến trình được tạo ra có nhiệm vụ thực hiện MessageLoop trên message queue dành cho ứng dụng, đồng thời khởi tạo các giao diện và tiểu trình hỗ trợ (nếu cần).

Các cách xử lý của tiểu trình chính khi nắm quyền điều khiển ứng dụng: Không thực hiện xử lý nào cả: Ứng dụng kết thúc. Thực hiện MessageLoop nhưng không tạo cửa sổ giao diện chính: Ứng dụng chờ nhận message nhưng người dùng không giao tác được.

Khởi tạo một cửa sổ với hàm xử lý message WindowProc và chọn cửa sổ này làm cửa sổ giao diện chính: Hàm WindowProc của cửa sổ sẽ tiếp nhận và xử lý message được điều phối từ MessageLoop của tiểu trình chính. Người dùng có thể giao tác và kết thúc ứng dụng được.

Như mục thứ ba, đồng thời tạo ra các tiểu trình phục vụ: Ứng dụng có khả năng tiếp nhận và thực hiện đồng thời nhiều yêu cầu xử lý.

8 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

Kiến trúc xử lý chung của ứng dụng trong môi trường windows

1.9 RESOURCE CỦA ỨNG DỤNG:

Ðối với một chương trình trong windows, ngoài phần mã lệnh của các hàm xử lý, resource là một thành phần không kém phần quan trọng chứa các nội dung hỗ trợ cho việc trang trí hoặc phục vụ cho một mục đích đặc biệt của ứng dụng. Các nội dung phổ biến trong resource như sau: Cursor: Ảnh nhỏ đặc tả vị trí làm việc của thiết bị liên quan như

mouse, pen, trackball. Khi người dùng tác động lên những thiết bị này thì windows sử dụng cursor để phản ánh hiện tượng đó.

Bitmap: Tập ảnh điểm (pixels) của một ảnh. Các ảnh điểm này bố trí theo các dòng và phối hợp làm nên hình ảnh của đối tượng.

Dialog: Thông tin mô tả khung giao diện với các đối tượng nhập liệu bên trong, là cơ sở để tạo ra các hộp hội thoại trong ứng dụng.

Icon : Ảnh nhỏ được dùng để đặc tả chức năng của một đối tượng, ứng dụng hay một nội dung dữ liệu.

HTML (Hypertext Markup Language): Ngôn ngữ dùng tạo ra những tài liệu dạng văn bản với những ký pháp và kỹ thuật định dạng mà trình duyệt tương ứng có thể thể hiện một cách xúc tích.

Page 10: Mfc Tieng Viet

Moät soá khaùi nieäm laäp trình trong moâi tröôøng Windows 9

Menu : Một danh sách các lựa chọn xử lý mà người dùng có thể chọn nhằm thực hiện một xử lý xác định

String Table: Bảng chứa các chuỗi được đánh dấu phân biệt bởi các số hiệu và được sử dụng như các thông báo trong chương trình. Việc sử dụng String Table giúp ứng dụng dễ dàng thay đổi ngôn ngữ giao diện của nó mà không cần phải có sự chỉnh sửa trên phần mã lệnh.

ToolbarBitmap: Tập các ảnh con xác định các nút được cài đặt trên thanh công cụ của cửa sổ hay hộp hội thoại trong ứng dụng. Mỗi nút này là một mục chọn (có thể thay thế mục chọn của menu) giúp tạo ra các message lệnh (WM_COMMAND) với số hiệu phân biệt để có thể ấn định xử lý cần thiết.

Version: Phần khai báo các thông tin liên quan đến ứng dụng, tác giả. Font: Chứa thông tin về bộ font chữ được lưu trong tập tin fnt. Custom Resource: Bao gồm các nội dung không thuộc các loại nội

dung resource chuẩn nói trên. Người dùng có thể tùy ý cài vào resource của ứng dụng, đồng thời phải tự cài đặt xử lý thích hợp cho các resource này trong chương trình.

Page 11: Mfc Tieng Viet

10 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

CHƯƠNG 2:

Thư viện MFC của microsoft & ứng dụng cơ bản trong windows

2.1 THƯ VIỆN MFC (MICROSOFT FOUNDATION CLASS):

Thư viện MFC của Microsoft bao gồm các lớp cơ bản, cài đặt bằng ngôn ngữ C++, hỗ trợ việc lập trình trong môi trường windows. Từ các lớp này, MFC xác lập nền tảng hình thành ứng dụng của windows, bao gồm việc định nghĩa bộ khung ứng dụng, các công cụ chuẩn và phổ biến để bổ sung vào bộ khung nói trên nhằm tạo ra ứng dụng hoàn chỉnh. Với MFC, công việc của người lập trình chỉ còn là việc lựa chọn các thành phần cần thiết, điều chỉnh và phối hợp chúng hợp lý để có được ứng dụng kết quả mong muốn.

Lập trình windows với MFC và MicroSoft Visual C++ 6.0 (VC) đạt được hiệu quả cao bởi không chỉ khai thác được phiên bản mới nhất của MFC mà còn nhận được nhiều tiện nghi lập trình mà VC cung cấp. Ðây là con đường ngắn và đơn giản, đặc biệt với người tự học, để viết ứng dụng windows.

2.2 TIẾP CẬN MFC: MFC là thư viện khổng lồ với khoảng 200 lớp đối tượng mà việc hiểu

rõ và vận dụng chúng trong một khoảng thời gian ngắn là không thể được. Mục tiêu của chúng ta là hiểu và vận dụng những thành phần phổ biến nhất của thư viện để xây dựng ứng dụng thông thường. Khi đã có khả năng nhất định về sử dụng MFC thì với tài liệu MSDN, sẽ chẳng khó khăn gì trong việc mở rộng khai thác thư viện để ứng dụng trở nên mạnh mẽ và tinh tế hơn.

Trong những phần trình bày sau, chúng ta sẽ lần lượt tiếp nhận hệ thống nội dung hơi nặng tính lý thuyết để đảm bảo cấu trúc kiến thức, và phần thực hành phối hợp sẽ giúp chúng ta kiểm nghiệm và hiểu rõ vấn đề.

2.3 TẠO ỨNG DỤNG WINDOWS VỚI MFC NHƯ THẾ NÀO ?: Theo mô hình kiến trúc ứng dụng windows ở mục (1.8), việc giải quyết

vấn đề trên chính là việc thực hiện trả lời các câu hỏi sau đây: Làm thế nào tạo đối tượng tiểu trình chính của ứng dụng ? Làm thế nào tạo đối tượng giao diện của ứng dụng ? Quản lý tương tác giữa đối tượng ứng dụng và đối tượng giao diện ?

Bằng việc xem xét các lớp MFC liên quan sẽ giúp lần lượt lý giải các câu hỏi được đặt ra. Tiếp theo, chúng ta tìm hiểu xem những lớp nào của MFC giúp khai báo đối tượng tiểu trình trong ứng dụng.

Thö vieän MFC cuûa Microsoft & öùng duïng cô baûn trong windows 11

2.4 LỚP QUẢN LÝ TIỂU TRÌNH CWinThread: CWinThread là một lớp của MFC, lớp đối tượng quản lý tiểu trình được

tạo ra trong tiến trình của một ứng dụng đang được thực hiện. Tiểu trình được quản lý có thể là là tiểu trình giao diện hoặc tiểu trình xử lý nội. Các dịch vụ cơ bản phục vụ cho quản lý tiểu trình do CWinThread cung cấp thông qua các thuộc tính và hành vi của nó.

DWORD m_nThreadID : Thuộc tính lưu số hiệu của tiểu trình. CWnd* m_pMainWnd : Lưu con trỏ đối tượng cửa sổ giao diện

chính của tiểu trình. Khi cửa sổ giao diện chính chấm dứt hoạt động, tiểu trình liên quan sẽ kết thúc. Nếu tiểu trình thuộc loại tiểu trình xử lý nội thì giá trị này kế thừa từ tiểu trình giao diện cấp cao hơn.

CWinThread( ); Hành vi tạo lập (constructor) đối tượng tiểu trình. virtual BOOL InitInstance( ); Khởi tạo thông số cho đối tượng tiểu

trình và đảm nhận các xử lý bổ sung khác của ứng dụng. Ðối với tiểu trình giao diện, hành vi này được dùng để khởi tạo đối tượng cửa sổ giao diện và gán địa chỉ của đối tượng cửa sổ cho m_pMainWnd.

virtual int ExitInstance( ); Hành vi kết thúc của đối tượng tiểu trình. Thông qua hành vi này, đối tượng quản lý tiểu trình thực hiện hoàn trả các tài nguyên của hệ thống mà nó đã đăng ký sử dụng.

virtual int Run( ); Hành vi dành riêng cho tiểu trình giao diện, nó thực hiện vòng lặp nhận message, chuyển message cho hành vi PreTranslateMessage của lớp. Nếu hành vi này trả về giá trị 0 thì message sẽ tiếp tục được chuyển đến các hàm diễn dịch phím TranslateMessage và hàm điều phối message DispatchMessage.

virtual BOOL PreTranslateMessage(MSG *pMsg); Hành vi cho phép can thiệp trước trên các message nhận được từ message queue của ứng dụng. Thông qua đó, tiểu trình giao diện có thể thực hiện các tiền xử lý message đặc trưng nhằm đáp ứng yêu cầu đặt ra cho ứng dụng.

Khi CWinThread được dùng để quản lý đối tượng tiểu trình chính thì hàm WinMain (cài sẵn bên trong lớp bởi thư viện MFC) tự động thực hiện các hành vi InitInstance(), Run() và ExitInstance() theo thứ tự.

Page 12: Mfc Tieng Viet

12 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

2.5 LỚP QUẢN LÝ TIỂU TRÌNH GIAO DIỆN CHÍNH CWinApp: CWinApp, kế thừa từ CWinThread, là lớp đối tượng chuyên dùng quản

lý tiểu trình giao diện chính của ứng dụng. Ứng dụng windows chỉ được phép sử dụng một đối tượng thuộc lớp này. Ngoài các thuộc tính, hành vi kế thừa public từ CWinThread, CWinApp có các thuộc tính và hành vi bổ sung sau:

const char* m_pszAppName: Lưu chuỗi tên của ứng dụng. LPTSTR m_lpCmdLine: Lưu nội dung chuỗi tham số dòng lệnh.

Tham số dòng lệnh là toàn bộ phần nội dung mà người dùng gõ vào ngay sau chuỗi đường dẫn và tên chương trình ứng dụng khi họ thực hiện ứng dụng. Ðối với ứng dụng có nhiều chế độ hoạt động khác nhau thì việc sử dụng tham số dòng lệnh là một cơ chế xác lập các giao ước giữa ứng dụng và người dùng để chọn chế độ sử dụng ứng dụng thích hợp.

int m_nCmdShow: Lưu giá trị thông số đã được dùng để kích hoạt cửa sổ giao diện chính của ứng dụng.

CWinApp( ); Tạo lập đối tượng tiểu trình chính. HCURSOR LoadCursor( int nID ); Nạp cursor từ resource của ứng

dụng vào bộ nhớ (nếu cursor chưa được nạp). nID là số hiệu của cursor. Hàm trả về giá trị handle quản lý cursor. Giá trị này có kiểu HCURSOR (handle of cursor) mà windows dùng để quản lý cursor.

HICON LoadIcon ( int nID ); Nạp icon từ resource của ứng dụng vào bộ nhớ. nID là số hiệu của icon. Hàm trả về giá trị handle quản lý icon. Giá trị này có kiểu HICON (handle of icon).

Hành vi hiển thị hộp thông báo và chờ nhận ý kiến người dùng: virtual int DoMessageBox ( LPCTSTR lpszPrompt, // Nội dung thông báo UINT nType, // Dạng hộp thông báo UINT hlpIndex = 0 // Số hiệu mục giúp đỡ (WinHelp) ); Hành vi này được kích hoạt với tham số tương ứng mỗi khi trong chương trình sử dụng hàm AfxMessageBox để hiển thị hộp thông báo. int AfxMessageBox ( LPCTSTR lpszPrompt, UINT nType, UINT hlpIndex = 0 );

nType: Ấn định dạng hộp thông báo. Giá trị này là sự kết hợp giữa thông số qui định biểu tượng hiển thị và các nút chọn bố trí trong hộp.

• Các thông số qui định các nút chọn bố trí trong hộp thông báo: Giá trị thông số Nút chọn bố trí trong hộp

Thö vieän MFC cuûa Microsoft & öùng duïng cô baûn trong windows 13

MB_OK OK MB_OKCANCEL OK - Cancel MB_YESNO Yes - No MB_YESNOCANCEL Yes - No - Cancel MB_ABORTRETRYIGNORE Abort - Retry - Ignore MB_RETRYCANCEL Retry - Cancel

• Các thông số qui định biểu tượng dùng trong nút chọn:

Giá trị thông số Biểu tượng MB_ICONHAND, MB_ICONSTOP, MB_ICONERROR MB_ICONQUESTION

MB_ICONEXCLAMATION, MB_ICONWARNING

MB_ICONASTERISK, MB_ICONINFORMATION

• Số hiệu các nút chọn được sử dụng trong hộp thông báo:

Số hiệu Nút chọn Số hiệu Nút chọn IDABORT Abort IDOK OK IDCANCEL Cancel IDRETRY Retry IDIGNORE Ignore IDYES Yes IDNO No

• Hành vi DoMessageBox chờ người sử dụng trả lời bằng cách chọn một nút chọn xác định trong hộp thông báo. Hành vi kết thúc với giá trị trả về là số hiệu của nút được chọn. Kế thừa hành vi này để chặn và thực hiện xử lý đặc trưng (sử dụng dạng hộp thông báo riêng) cho tất cả các lời gọi AfxMessageBox trong ứng dụng.

• Hàm AfxMessageBox sử dụng DoMessageBox để hiển thị hộp thông báo và lấy giá trị của hành vi này làm kết quả trả về của nó.

Ví dụ: AfxMessageBox( "Chao Ban", MB_ICONSTOP | MB_OK, 0 ); Hàm trên thực hiện hiển thị hộp thông báo với nội dung là

"Chao Ban" , biểu tượng đi kèm, và nút chọn OK kết thúc.

Page 13: Mfc Tieng Viet

14 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

2.6 THỰC HIỆN ỨNG DỤNG ÐƠN GIẢN: Trong phần này, chúng ta thực hiện ứng dụng với đối tượng thuộc lớp

CWinApp quản lý tiểu trình chính. Ðặt tên cho dự án của ứng dụng là VD0.

Các bước thực hiện dự án VD0 như sau:

Khởi động windows với hệ điều hành Win95 hoặc bản mới hơn. Tạo mới một thư mục để chứa các dự án. Ví dụ C:\VC6. Thực hiện ứng dụng Microsoft Visual C++ 6.0 (VC). Chọn mục File / New từ hệ thống menu của VC. Trong hộp hội thoại New, chọn trang Projects :

- Win32 Application : Loại ứng dụng thực hiện. - Location : Ðường dẫn thư mục của dự án. - Project Name : Tên dự án. Sau đó chọn OK.

Tiếp theo, trong hộp hội thoại Step 1 of 1. - An empty project : Tạo dự án rỗng. - Finish : Hoàn tất việc khởi tạo dự án.

Thö vieän MFC cuûa Microsoft & öùng duïng cô baûn trong windows 15

VC hiển thị hộp hội thoại New Project Information để thông báo các thông tin liên quan đến dự án vừa tạo. Chọn OK.

Một dự án đã được tạo ra trên đĩa. Với thông tin nhập như trên, dự án mới tạo ra có tên là VD0, toàn bộ phần chương trình nguồn của dự án được lưu trong thư mục VD0 thuộc thư mục C:\VC6.

Tiếp tục thực hiện các bước sau để hoàn tất dự án theo yêu cầu.

Ðăng ký sử dụng lớp CWinApp của thư viện MFC: Lớp CWinApp được khai báo trong afxwin.h của MFC. Bổ sung tập tin stdafx.h vào dự án và dùng tập tin này đăng ký các thư viện cần thiết của MFC. Việc bổ sung tập tin stdafx.h vào dự án được tiến hành như sau: • Chọn mục File / New từ hệ thống menu của VC. • Trong hộp hội thoại New, chọn trang Files:

- C/C++ Header File : Loại nội dung tập tin (.h). - Add To Project : Bổ sung tập tin vào dự án VD0. - File Name : Tên tập tin (StdAfx.h) Chọn OK, tiếp tục thực hiện các công việc sau.

• Soạn thảo tập tin stdafx.h, nhập các định hướng biên dịch và các chỉ thị sử dụng thư viện MFC cần cho dự án:

Page 14: Mfc Tieng Viet

16 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

#if !defined( _DU_AN_0_ ) #define _DU_AN_0_

// _DU_AN_0_ giúp trình dịch không thực hiện lặp chỉ thị #include

#include <afxwin.h> // thư viện chuẩn của MFC #endif Sau khi nhập xong nội dung tập tin stdafx.h, chọn mục File / Save (hoặc click biểu tuợng trên thanh công cụ) để lưu tập tin.

Tạo tập tin Resource Script của dự án: Tập tin này chứa khai báo của các resource được sử dụng trong ứng dụng. Khi biên dịch, các resource này sẽ được nhúng vào tập tin chương trình (.EXE). Các bước tạo tập tin Resource Script trong dự án như sau: • Chọn mục File / New. Trong hộp hội thoại New, chọn trang

Files.

- Resource Script : Loại nội dung tập tin (.rc). - Add To Project : Bổ sung tập tin vào dự án. - File Name : Tên tập tin, trùng với tên của dự án. Sau đó chọn OK.

• Ðăng ký các hỗ trợ của MFC cho thao tác trên resource: Việc đăng ký này là cơ sở tạo quan hệ giữa các nội dung của

Thö vieän MFC cuûa Microsoft & öùng duïng cô baûn trong windows 17

resource và đối tượng lập trình tương ứng của MFC trong dự án. Thực hiện như sau: - Right-click trên mục tên resource (VD0 Resource):

- Chọn mục Properties:

Chọn các mục như trên, gõ phím Enter để kết thúc.

• Soạn thảo resource: Dự án VD0 chưa cần sử dụng resource, tập tin resource script sẽ tạm thời bỏ trống. Chọn mục File / Save, và đóng màn hình soạn thảo resource để kết thúc bước này.

Chọn phiên bản biên dịch: Có hai phiên bản biên dịch chương trình. • Debug version : Biên dịch chương trình với thông tin

debug. • Release version : Phiên bản đem giao, không chứa thông

tin debug. Chọn mục Build / Set Active Configurations:

Chọn phiên bản biên dịch ( chẳng hạn Win32 Debug ). Chọn OK.

Page 15: Mfc Tieng Viet

18 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

Ấn định biên dịch với thư viện MFC: Chọn mục Project / Setting.

Trong hộp hội thoại Project Settings, - Setting For: : Chọn phiên bản ấn định (ví dụ: Win32 Debug ), - General : Các ấn định chung cho dự án.

Microsoft Foundation Classes: Cách liên kết thư viện MFC vào ứng dụng. Có thể tùy chọn một trong hai cách sau: Use MFC in Shared DLL: Chương trình sử dụng thư viện

MFC theo cơ chế liên kết động. Tập tin chương trình có kích thước nhỏ nhưng khi thực hiện cần có các tập tin thư viện (DLL) của MFC trong thư mục hệ thống của windows.

Use MFC in Static Library: Thư viện MFC được nhúng vào chương trình trong lúc biên dịch. Tập tin chương trình có kích thước lớn hơn nhưng ứng dụng có thể hoạt động độc lập.

Sau khi ấn định xong, chọn OK. Khai báo đối tượng thuộc lớp CWinApp: Dùng bất kỳ tập tin CPP

nào của dự án để thực hiện công việc này. Vì dự án VD0 đang thực hiện ở đây chưa có tập tin CPP, chúng ta tạo mới tập tin CPP cho dự án. Giả sử tập tin CPP này có tên là MAIN.CPP. Cách thực hiện như sau: • Chọn mục File / New. Trong hộp hội thoại New, chọn trang

Files:

Thö vieän MFC cuûa Microsoft & öùng duïng cô baûn trong windows 19

- C++ Source File : Loại nội dung tập tin (.cpp). - Add To Project : Bổ sung tập tin vào dự án. - File Name : Tên tập tin (MAIN). Sau đó chọn OK.

• Trong màn hình soạn thảo của main.cpp, nhập nội dung tập tin: #include "stdafx.h" // Tập tin chứa đăng ký thư viện của MFC CWinApp theApp; // Ðối tượng quản lý tiểu trình chính Sau khi nhập xong, chọn mục File / Save để lưu tập tin.

Biên dịch chương trình: Chọn mục Build / Build <project name>.exe hoặc chọn mục trên thanh công cụ. Ta đã thực hiện xong một ứng dụng đơn giản trong môi trường windows. Tập tin chương trình được lưu trong thư mục DEBUG (phiên bản biên dịch debug) hoặc RELEASE (phiên bản biên dịch release).

Chạy chương trình: Có thể chạy chương trình trực tiếp trong VC bằng cách nhấn phím F5 hoặc click chọn trên thanh công cụ.

Nhận xét: Ứng dụng VD0 không thực hiện một giao tác hay công việc gì cả bởi nó chỉ là một ứng dụng khung - được xây dựng hoàn toàn từ lớp CWinApp của MFC mà không có một xử lý bổ sung nào.

2.7 THỰC HIỆN ỨNG DỤNG GIAO TÁC ÐƠN GIẢN:

Page 16: Mfc Tieng Viet

20 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

Trong phần này ta thiết kế một ứng dụng mà khi thực hiện sẽ hiển thị hộp thông báo "Do You want to Stop" với biểu tượng và các nút chọn YES- NO. Ứng dụng kết thúc khi người dùng chọn mục YES.

Nhận xét: Ứng dụng chỉ hoàn thành công việc xác định khi đối tượng quản lý tiểu trình chính của ứng dụng tiến hành xử lý thích hợp. Ðối tượng này thuộc lớp kế thừa từ lớp CWinApp với xử lý bổ sung nhằm thực hiện công việc mong muốn. Hành vi InitInstance của CWinApp là hành vi thích hợp cho việc kế thừa và thực hiện các bổ sung này.

Giả sử dự án của ứng dụng có tên là VD01. Các bước thực hiện như sau:

Tạo dự án VD01 theo các bước như dự án VD0 nhưng dừng lại ở bước "Khai báo đối tượng thuộc lớp CWinApp" (không thực hiện bước này). Tiếp tục thực hiện các bước sau đây.

Tạo mới lớp CEmpApp kế thừa từ CWinApp: Mở màn hình Workspace của dự án (nếu chưa mở) bằng cách chọn mục menu View/Workspace hoặc click chọn biểu tượng trên thanh công cụ. • Chọn trang ClassView:

• Right-click trên mục VD01 Classes, chọn New Class. • Khai báo lớp CEmpApp thông qua hộp hội thoại New Class.

Thö vieän MFC cuûa Microsoft & öùng duïng cô baûn trong windows 21

Class Type = Generic Class: Chọn loại lớp thông thường vì

MFC không hỗ trợ lớp CWinApp trong ClassWizard của nó. Name = CEmpApp : Tên của lớp mới. Change: Ấn định tên tập tin chứa khai báo (.h) và cài đặt

(.cpp) của lớp CEmpApp ( nên trùng với tên của dự án : VD01 ):

Sau đó chọn OK.

Derived From = CWinApp : Chọn CWinApp làm lớp cơ sở. As = public : Kế thừa public. Chọn OK để kết thúc.

• Lớp CEmpApp đã được bổ sung vào dự án VD01 cùng với hai tập tin là VD01.H và VD01.CPP: VD01.H : Chứa nội dung khai báo (header) của lớp. VD01.CPP : Chứa nội dung cài đặt (implement) của lớp.

Có thể mở và chỉnh sửa nội dung các tập tin của lớp bằng cách thao tác trực tiếp trên cấu trúc ClassView của màn hình Workspace.

Page 17: Mfc Tieng Viet

22 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

• Ðiều chỉnh lớp CEmpApp để nhận được hỗ trợ của ClassWizard:

Mở tập tin VD01.H chứa khai báo của lớp, bổ sung các nội dung:

class CEmpApp : public CWinApp { public: CEmpApp(); virtual ~CEmpApp();

//{{AFX_VIRTUAL(CEmpApp) //}}AFX_VIRTUAL // Hỗ trợ kế thừa hành vi ảo

//{{AFX_MSG(CEmpApp) //}}AFX_MSG // Hỗ trợ ấn định xử lý message DECLARE_MESSAGE_MAP() // Ðăng ký MessageMap }

Lưu ý: //{{ và //}} là ký pháp sử dụng của ClassWizard.

Mở tập tin VD01.CPP chứa cài đặt của lớp, bổ sung nội dung:

#include "stdafx.h" #include "Emp.h"

BEGIN_MESSAGE_MAP(CEmpApp, CWinApp) //{{AFX_MSG_MAP(CEmpApp) // Bảng message map, //}}AFX_MSG_MAP // sẽ đề cập đến ở các END_MESSAGE_MAP() // phần sau

Phần bổ sung

Bổ sung

Thö vieän MFC cuûa Microsoft & öùng duïng cô baûn trong windows 23

Khởi tạo thông tin ClassWizard: Thao tác này là cơ sở để khai thác tiện ích của ClassWizard trong việc định nghĩa lớp, khai báo thông tin kế thừa, ấn định xử lý message, định nghĩa biến,. • Chọn menu View / Classwizard:

• Chọn Yes:

Chọn Add All, sau đó chọn OK. • Trong hộp hội thoại MFC Class Wizard, Chọn OK để kết thúc.

Thông tin ClassWizard được lưu trong tập tin có cùng tên với tên của dự án và phần mở rộng là .CLW.

Kế thừa hành vi InitInstance của lớp CWinApp cho lớp CEmpApp. Dùng hành vi này cài đặt xử lý bổ sung như yêu cầu của ứng dụng:

Page 18: Mfc Tieng Viet

24 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

• Trong màn hình Workspace của dự án, chọn ClassView, right-click trên tiêu đề của lớp CEmpApp:

• Chọn mục Add Virtual Function.

• Chọn hành vi InitInstance, sau đó chọn mục Add and Edit. • Trong phần soạn thảo nội dung của hành vi InitInstance thuộc

lớp CEmpApp, ta cài đặt đoạn chương trình xử lý sau:

BOOL CEmpApp::InitInstance() {

Thö vieän MFC cuûa Microsoft & öùng duïng cô baûn trong windows 25

UINT stop; // Biến kiểm tra đồng ý dừng? do { stop = AfxMessageBox( "Do You want to stop", MB_YESNO | MB_ICONQUESTION, 0 ); } while (stop == IDNO ); // Tiếp tục lặp nếu chọn NO return TRUE; // Xử lý tiến hành bình thường }

Dùng lớp CEmpApp khai báo đối tượng quản lý tiểu trình chính của ứng dụng: Mở tập tin VD01.CPP của lớp CEmpApp, bổ sung nội dung:

#include "stdafx.h" #include "Emp.h" CEmpApp theApp; // Ðối tượng kiểu CEmpApp, dùng quản lý // tiểu trình chính của ứng dụng. // Không chỉnh sửa các nội dung khác!

Biên dịch và chạy chương trình.

2.8 TẠO MỚI ICON RESOURCE CHO ỨNG DỤNG: Ðối với ứng dụng trong windows, icon không chỉ là hình ảnh trang trí

đơn thuần mà còn là yếu tố gợi nhớ về ứng dụng tốt nhất. Windows sử dụng icon của ứng dụng để đại diện cho ứng dụng ở tất cả những nơi nào mà người dùng có thể nhìn thấy và khai thác ứng dụng.

Việc bổ sung icon resource vào dự án của ứng dụng được thực hiện thông qua các bước sau:

Mở dự án trong VC. Mở màn hình Workspace của dự án, chọn trang ResourceView.

right-click trên tiêu đề resource của dự án.

Page 19: Mfc Tieng Viet

26 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

Chọn mục Insert...

Chọn mục Icon, sau đó chọn New: Ta nhận được màn hình thiết kế icon. Vẽ icon có nội dung tùy ý.

Ấn định các thông số

thuộc tính của icon (số hiệu icon, tên thư mục và tên tập tin chứa icon) trong dự án: Chọn ResourceView trong Workspace của dự án, rigth-click trên icon mới thêm. Chọn mục Properties.

Thö vieän MFC cuûa Microsoft & öùng duïng cô baûn trong windows 27

Thực hiện ấn định thông số của icon thông qua hộp hội thoại sau:

- ID : Số hiệu icon. IDR_MAINFRAME là số hiệu qui ước dùng cho icon chính của ứng dụng.

- File name : Tên tập tin chứa icon. RES là thư mục con sẽ được tạo trong thư mục dự án để chứa các tập tin resource.

Sau khi ấn định xong, gõ phím Enter để kết thúc. Ðóng màn hình thiết kế icon resource. Biên dịch dự án. Dùng Windows Explorer xem tập tin VD01.exe

trong thư mục debug của dự án. Lúc này, ứng dụng VD01 đã có icon riêng.

2.9 LƯU TRỮ CHƯƠNG TRÌNH NGUỒN: Sau khi hoàn tất dự án, một việc rất thường xuyên là lưu giữ lại

chương trình nguồn của dự án. Công việc này đòi hỏi phải loại bỏ khỏi thư mục dự án các tập tin không cần thiết. Ðó là các tập tin sau:

Thư mục dự án : Các tập tin .NCB, .PLG, .OPT, .APS. Thư mục Debug : Tất cả các tập tin, trừ tập tin .exe cần giữa lại. Thư mục Release : Tất cả các tập tin, trừ tập tin .exe cần giữa

lại.

2.10 LỚP CString CỦA MFC: CString là lớp đối tượng của MFC cho phép quản lý một nội dung

chuỗi trong bộ nhớ với những đặc tính ưu việt sau: - Nội dung chuỗi lưu trữ có độ dài lớn với cơ chế sử dụng bộ nhớ tối

ưu. - Xây dựng dựa trên kiểu TCHAR nên thích nghi với bộ mã

UNICODE. - Các hành vi xử lý sẵn sàng cho các tác vụ chuỗi thông thường. Một số hành vi được sử dụng phổ biến của CString như sau: CString( ); Hành vi tạo lập đối tượng chuỗi. int GetLength( ) const; Trả về số đo chiều dài chuỗi.

Page 20: Mfc Tieng Viet

28 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

void Empty( ); Xóa rỗng nội dung đối tượng chuỗi. BOOL IsEmpty( ) const; Trả về TRUE nếu nội dung chuỗi là rỗng. TCHAR operator []( int nIndex ) const; Trả về ký tự ở vị trí nIndex. void SetAt( int nIndex, TCHAR ch ); Ðặt ký tự ch vào vị trí nIndex. operator LPCTSTR ( ) const; Chuyển về kiểu chuỗi của C. CString::operator = ; Phép toán gán chuỗi cho đối tượng. CString::operator + ; Phép toán cộng chuỗi. CString::operator += ; Phép toán nối chuỗi mới vào đối tượng. CString Comparison Operators ; Trong đó Operators là phép toán

quan hệ thông thường như: == , < , <= , > , >= , !=. CString Mid( int nFirst [, int nCount] ) const; Trích chuỗi con giữa. CString Left( int nCount ) const; Trích chuỗi con bên trái. CString Right( int nCount ) const; Trích chuỗi con bên phải.

nCount là chiều dài (số ký tự) của chuỗi con được trích ra. void MakeUpper( ) / void MakeLower( ); Viết hoa / thường nội

dung. void Format( LPCTSTR lpszFormat, ... ); Tạo nội dung cho chuỗi. void TrimLeft( ) / void TrimRight( ); Hủy khoảng trắng trái / phải. BOOL LoadString( UINT nID ); Gán nội dung cho chuỗi bởi một

hằng chuỗi trong string table resource. nID là số hiệu của hằng chuỗi.

THỰC HÀNH: 1. Viết ứng dụng cho phép hiển thị đường dẫn đến tập tin chương trình và chuỗi tham số dòng lệnh thực thi nó. 2. Viết ứng dụng có cài đặt DoMessageBox sao cho hàm AfxMessageBox sử dụng trong ứng dụng hiển thị hộp thông báo với icon riêng của ứng dụng. HD: Sử dụng hàm: int MessageBoxIndirect( LPMSGBOXPARAMS pMsg );

typedef struct { UINT cbSize; // Kích thước, = sizeof( MSGBOXPARAMS ) HWND hwndOwner; // Handle của cửa sổ cha, có thể = NULL HINSTANCE hInstance; // Handle ứng dụng = AfxGetInstanceHandle() LPCTSTR lpszText; // Nội dung chuỗi thông báo LPCTSTR lpszCaption; // Nội dung chuỗi tiêu đề DWORD dwStyle; // Dạng hộp, chứa thông số MB_USERICON LPCTSTR lpszIcon; // Chuỗi tên icon được hiển trị trong hộp DWORD_PTR dwContextHelpId; // Số hiệu giúp đỡ MSGBOXCALLBACK lpfnMsgBoxCallback; // Hàm xử lý DWORD dwLanguageId; // Số hiệu ngôn ngữ sử dụng } MSGBOXPARAMS, *PMSGBOXPARAMS;

Page 21: Mfc Tieng Viet

Caùc lôùp giao dieän ñoà hoïa cuûa MFC 29

CHƯƠNG 3:

Các lớp GIAO DIỆN đồ họa của MFC 3.1 CÁC CÔNG CỤ GIAO DIỆN ÐỒ HỌA:

Ðể hỗ trợ ứng dụng trong việc trang trí giao diện đồ họa (Graphic Device Interface - GDI) như màn hình, máy in., windows cung cấp một hệ thống các công cụ đồ họa cơ bản như sau:

Pen : Công cụ vẽ điểm hoặc đường thẳng. Brush : Công cụ tô màu. Font : Công cụ qui định kiểu ký tự cho nội dung văn bản. Bitmap : Công cụ quản lý vùng ảnh điểm. Palette : Công cụ quản lý bộ màu hiển thị. Region : Công cụ quản lý vùng hiển thị có dạng bất kỳ.

Thông qua các công cụ nói trên, ứng dụng trong windows có thể thực hiện các tác vụ đồ họa cơ bản một cách dễ dàng mà không phải bận tâm đến cấu trúc vật lý của thiết bị hiển thị. Các công cụ này gọi là công cụ GDI.

3.2 DEVICE CONTEXT: Việc khai thác khả năng của các công cụ GDI được thực hiện thông

qua một cấu trúc chứa thông tin quản lý thiết bị hiển thị: Device Context (DC). Tại mỗi thời điểm, mỗi DC được phép gắn với một thiết bị hiển thị đồ họa và sử dụng một bộ các công cụ GDI duy nhất. Muốn sử dụng một công cụ GDI mới thì DC phải chấm dứt sử dụng công cụ tương ứng mà nó đang dùng.

Mỗi khi một DC được tạo mới, hệ thống tự động chuẩn bị một bộ công cụ GDI (trừ bitmap) mặc nhiên cho nó. Ứng dụng có thể tùy nghi thay đổi các công cụ này cho phù hợp với nhu cầu của ứng dụng.

3.3. TỌA ÐỘ TRÊN GIAO DIỆN ÐỒ HỌA: Việc định vị trên giao diện đồ họa được thực hiện dựa trên hệ trục tọa

độ có gốc (0,0) là góc trái-trên (top-left corner) của giao diện đồ họa, chiều dương của trục hoành (trục x) hướng từ trái sang phải, chiều dương của trục tung (trục y) hướng từ trên xuống dưới. Trên mặt phẳng giao diện đồ họa đó:

Ðiểm: Biểu diễn bằng cặp tọa độ (x,y). Hình chữ nhật: Biểu diễn bằng cặp đỉnh góc trái trên và góc phải

dưới. Thông tin về điểm, vùng hình chữ nhật và kích thước của các đối

tượng trong mặt phẳng giao diện đồ họa được đặc tả thông qua các cấu trúc sau:

30 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

Cấu trúc quản lý 1 điểm: typedef struct _POINT { int x, y // Tọa độ ( hoành độ, tung độ ) của điểm } POINT ;

Cấu trúc quản lý 1 vùng hình chữ nhật: typedef struct _RECT { int top, left; // Tọa độ góc trái trên hình chữ nhật. int right, bottom; // Tọa độ góc phải dưới hình chữ nhật. } RECT ;

Cấu trúc quản lý chiều rộng và chiều cao vùng hình chữ nhật: typedef struct _SIZE { int cx, cy; // Chiều rộng, chiều cao vùng hình chữ nhật. } SIZE ;

3.4 CÁC LỚP MFC HỖ TRỢ GDI: MCF cung cấp một hệ thống phong phú các lớp với đầy đủ chức năng

nhằm hỗ trợ người dùng tối đa trong lập trình GDI. Với việc vận dụng kỹ thuật OOP trên các lớp GDI của MFC, người dùng dễ dàng tạo ra ứng dụng mong muốn mà không phải viết quá nhiều mã lệnh trong chương trình.

3.4.1 Các lớp đối tượng điểm, hình chữ nhật: CPoint : Lớp đối tượng điểm, tương ứng với cấu trúc POINT. CRect : Lớp đối tượng vùng hình chữ nhật trên giao diện đồ họa,

tương ứng với cấu trúc RECT. CRect có các hành vi đặc trưng sau: • CRect( ); Tạo lập đối tượng vùng hình chữ nhật rỗng. • CRect (int left, int top, int right, int bottom); Tạo lập đối tượng

vùng hình chữ nhật có thông số xác định. • int Width( ) const; Trả về độ rộng vùng hình chữ nhật. • int Heigth( ) const; Trả về độ cao vùng hình chữ nhật. • void NormalizeRect( ); Hợp lý hóa các thành phần tọa độ của

rect mà không làm thay đổi vị trí và kích thước của nó. VD: Giả sử khởi tạo một rect không hợp lệ như sau: CRect rect( 100, 0, 0, 50 ); // rect.left = 100 > rect.right = 0 rect. NormalizeRect(); rect trở nên hợp lệ với: rect ( 0, 0, 100, 50 );

CSize : Lớp đối tượng kích thước, tương ứng với cấu trúc SIZE.

3.4.2 Lớp CPen: CPen là lớp đối tượng quản lý pen, một công cụ GDI quan trọng của

DC. Thông qua đối tượng này, DC có thể thay đổi màu sắc, nét vẽ của

Page 22: Mfc Tieng Viet

Caùc lôùp giao dieän ñoà hoïa cuûa MFC 31

điểm hay đường thẳng mà DC sẽ trực hiện. CPen có các hành vi đặc trưng sau:

CPen( ); Tạo lập đối tượng pen rỗng. Chúng ta phải khởi tạo tham số cho đối tượng này trước khi sử dụng.

CPen ( // Tạo lập đối tượng pen với tham số int nPenStyle, // Kiểu nét vẽ int nWidth, // Ðộ rộng nét vẽ (=1: mặc nhiên) COLORREF crColor // Màu sắc của nét vẽ ); nPenStyle có thể nhận một trong các giá trị sau:

PS_SOLID : PS_DASH : PS_DOT : PS_DASHDOT :

crColor có thể nhận giá trị từ macro phối màu RGB( ) như sau: RGB (int màu_đỏ , int màu_xanh_lá_cây , int màu_xanh_dương ) Mỗi màu được đặc trưng bằng một giá trị trong đoạn 0255 phản ánh độ sáng của nó. Bộ phối màu theo qui tắc phối màu tự nhiên.

BOOL CreatePen( int nPenStyle, int nWidth, COLORREF crColor ); Khởi tạo thông số cho đối tượng pen. Ý nghĩa tham số như trên.

operator HPEN() const; Toán tử chuyển kiểu, trả về handle của pen (HPEN) quản lý bởi đối tượng.

3.4.3 Lớp CBrush: CBrush là lớp đối tượng quản lý brush, công cụ GDI của DC. Thông

qua đối tượng này, DC có thể thay đổi màu sắc, dạng của nét tô trong một vùng hình chữ nhật mà DC sẽ trực hiện. CBrush có các hành vi đặc trưng sau:

CBrush( ); Tạo lập đối tượng brush rỗng. CBrush( COLORREF crColor ); Tạo lập đối tượng brush có màu tô

tương ứng với màu qui định bởi tham số crColor. CBrush( int nIndex, COLORREF crColor ); Tạo lập đối tượng brush

có màu tô crColor, và nét tô nIndex. Giá trị nét tô có thể là: HS_VERTICAL (đường kẻ sọc đứng), HS_HORIZAONTAL (đường kẻ sọc ngang).

BOOL CreateSolidBrush( COLORREF crColor ); Tạo đặc tính tô đặc với màu crColor cho đối tượng brush chưa có thông số.

operator HBRUSH() const; Toán tử chuyển kiểu, trả về handle của brush (HBRUSH) quản lý bởi đối tượng.

3.4.4 Lớp CFont: CFont là lớp đối tượng quản lý font, công cụ GDI của DC. Thông qua

đối tượng này, DC thực hiện ấn định font, kiểu dáng, kích thước của bộ ký

32 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

tự được sử dụng cho việc hiển thị các nội dung văn bản. Các hành vi đặc trưng:

CFont( ); Tạo lập đối tượng font rỗng. CFont(const LOGFONT* lpLogFont ); Tạo lập đối tượng font với

thông số đầy đủ. Giá trị thông số được ấn định bởi tham số kiểu cấu trúc LOGFONT chứa thông tin. LOGFONT được khai báo như sau: typedef struct tagLOGFONT { LONG lfHeight; // chiều cao của ký tự LONG lfWidth; // chiều rộng trung bình các ký tự LONG lfEscapement; // góc (1/10) giữa hướng in và trục X LONG lfOrientation; // góc (1/10) giữa ký tự và trục X (No 9x) LONG lfWeight; // mức độ đậm của font chữ (0 - 1000) BYTE lfItalic; // = TRUE : Chữ nghiêng BYTE lfUnderline; // = TRUE : Chữ gạch dưới BYTE lfStrikeOut; // = TRUE : Chữ gạch ngang thân BYTE lfCharSet; // bộ ký tự (=DEFAULT_CHARSET ) BYTE lfOutPrecision; // = OUT_DEFAULT_PRECIS BYTE lfClipPrecision; // = CLIP_DEFAULT_PRECIS BYTE lfQuality; // = DEFAULT_QUALITY BYTE lfPitchAndFamily; // =DEFAULT_PITCH|FF_DONTCARE TCHAR lfFaceName[LF_FACESIZE]; // Chuỗi tên của font } LOGFONT ;

Win9x chỉ dùng lfEscapement. int GetLogFont( LOGFONT * pLogFont ); Lấy thông tin của font

quản lý bởi đối tượng font chữ. Kết quả được điền vào biến kiểu LOGFONT chỉ bởi tham số kiểu con trỏ LOGFONT* : pLogFont.

operator HFONT( ); Toán tử chuyển kiểu, trả về handle của font được quản lý bởi đối tượng.

BOOL CreateFontIndirect( LOGFONT *lpLogFont ); Khởi tạo thông số cho đối tượng font từ thông tin lưu trong cấu trúc chỉ bởi lpLogFont.

3.4.5 Lớp CBitmap: CBitmap là lớp đối tượng quản lý bitmap, một công cụ GDI quan trọng

giúp quản lý vùng ảnh điểm (pixels) của DC. Thông qua đối tượng này, DC có thể dễ dàng tạo nội dung trang trí trên giao diện đồ họa từ nội dung ảnh có sẵn được lưu trong tập tin, đồng thời thực hiện các tác vụ xử lý ảnh cơ bản trên nội dung đó. CBitmap cung cấp các hành vi đặc trưng sau:

CBitmap( ); Tạo lập đối tượng bitmap rỗng.

Page 23: Mfc Tieng Viet

Caùc lôùp giao dieän ñoà hoïa cuûa MFC 33

BOOL LoadBitmap( UINT nIDResource ); Tạo nội dung cho đối tượng bitmap với thông tin được lấy từ một ảnh trong resource. nIDResource : số hiệu của ảnh bitmap trong resource của chương trình.

BOOL CreateCompatibleBitmap ( CDC* pDC, // Con trỏ đối tượng DC tương ứng int nWidth, // Chiều rộng, int nHeight // chiều cao tính bằng pixel của bitmap được tạo. ); Tạo nội dung cho đối tượng bitmap với thông tin về màu sắc, độ phân giải tương ứng với DC chỉ bởi con trỏ tham số pDC.

int GetBitmap( BITMAP* pBitMap ); Lấy thông tin về bitmap được quản lý bởi đối tượng. Kết quả nhận được sẽ được điền vào biến có kiểu BITMAP chỉ bởi tham số kiểu con trỏ BITMAP* : pBitmap. Cấu trúc BITMAP bao gồm các trường có ý nghĩa như sau:

typedef struct tagBITMAP { /* bm */ int bmType ; // Kiểu bitmap, int bmWidth ; // Chiều rộng bitmap tính bằng pixel int bmHeight ; // Chiều cao bitmap tính bằng pixel int bmWidthBytes ; // Kích thước 1 dòng pixel trong bitmap BYTE bmPlanes ; // Số màu. BYTE bmBitsPixel ; // Số bit màu của 1 pixel LPVOID bmBits ; // Ðịa chỉ vùng nhớ chứa pixel của bitmap } BITMAP;

operator HBITMAP() const; Toán tử chuyển kiểu, trả về handle của bitmap được quản lý bởi đối tượng.

3.4.6 Lớp CPalette: CPalette là lớp đối tượng quản lý palette, một công cụ GDI của DC.

Thông qua đối tượng này, DC có thể tạo ra các hiệu ứng màu trên giao diện đồ họa bằng cách thay đổi các bộ màu một cách phù hợp.

CPalette( ); Tạo lập đối tượng palette rỗng. CreatePalette( LPLOGPALETTE lpLogPalette ); Khởi tạo thông số

cho đối tượng palette rỗng. Con trỏ tham số lpLogPalette chỉ đến biến kiểu cấu trúc LOGPALETTE chứa thông tin bộ màu dùng khởi tạo. typedef struct tagLOGPALETTE { WORD palVersion; // Số hiệu palette hệ thống WORD palNumEntries; // Số màu sử dụng PALETTEENTRY palPalEntry[1]; // Chứa các giá trị màu, // có số phần tử mảng bằng palNumEntries } LOGPALETTE ;

34 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

Mỗi phần tử của palPalEntry có kiểu PALETTEENTRY phản ánh giá trị màu dùng hiển thị màu chỉ mục (color index) tương ứng với vị trí thứ tự của nó. Cấu trúc PALETTEENTRY có nội dung như sau:

typedef struct tagPALETTEENTRY { BYTE peRed ; // Giá trị thành phần màu đỏ BYTE peGreen ; // Giá trị thành phần màu xanh lá cây BYTE peBlue ; // Giá trị thành phần màu xanh dương BYTE peFlags ; // Vai trò màu trong hệ thống. } PALETTEENTRY;

operator HPALETTE( ) const; Toán tử chuyển kiểu, trả về handle của palette quản lý bởi đối tượng.

3.4.7 Lớp CRgn: CRgn là lớp đối tượng quản lý region, một công cụ GDI quan trọng

giúp DC ấn định vùng ảnh xử lý có hình dạng tùy ý trên giao diện đồ họa của nó.

CRgn( ); Tạo lập đối tượng vùng ảnh rỗng. BOOL CreateRectRgn( int x1, int y1, int x2, int y2 ); Khởi tạo thông

số cho đối tượng vùng ảnh bằng 1 hình chữ nhật với tọa độ góc trái trên và góc phải dưới lần lượt là (x1, y1) và (x2, y2).

BOOL CreateEllipticRgn( int x1, int y1, int x2, int y2 ); Khởi tạo thông số cho đối tượng vùng ảnh bởi hình ellipse nội tiếp hình chữ nhật có góc trái trên (x1, y1) và góc phải dưới (x2, y2).

BOOL CreatePolygonRgn ( LPPOINT lpPoints, // Mảng chứa tọa độ các điểm ziczac int nCount, // Số phần tử POINT trong mảng trên int nMode // = WINDING ); Khởi tạo thông số cho đối tượng vùng ảnh bởi một đường ziczac khép kín qua các điểm có tọa độ xác định và được lưu trong một mảng. int CombineRgn ( CRgn* pRgn1, // Con trỏ đối tượng quản lý vùng ảnh thứ nhất CRgn* pRgn2, // Con trỏ đối tượng quản lý vùng ảnh thứ hai int nCombineMode // Cách kết hợp hai vùng ảnh ); Tạo thông số cho đối tượng vùng ảnh trên cơ sở kết hợp hai vùng ảnh đã có. Tham số nCombineMode có thể là:

RGN_AND : Vùng ảnh kết quả là vùng giao nhau giữa hai vùng ảnh. RGN_OR : Vùng ảnh kết quả là vùng hợp giữa hai vùng ảnh. RGN_DIFF : Vùng ảnh kết quả là vùng bù giữa hai vùng ảnh.

Page 24: Mfc Tieng Viet

Caùc lôùp giao dieän ñoà hoïa cuûa MFC 35

operator HRGN() const; Toán tử chuyển kiểu, trả về handle của vùng ảnh quản lý bởi đối tượng.

3.5 LỚP CDC: CDC là lớp đối tượng quản lý DC. Thông qua đối tượng DC, khả năng

của các công cụ đồ họa được khai thác cho việc trang trí giao diện đồ họa quản lý bởi DC. CDC có các hành vi đặc trưng như sau:

CDC( ); Tạo lập đối tượng DC rỗng. virtual BOOL CreateCompatibleDC( CDC* pDC ); Khởi tạo thông

số cho đối tượng DC một cách tương thích với một DC có sẵn được chỉ bởi con trỏ tham số pDC.

virtual BOOL DeleteDC( ); Hủy bỏ đối tượng DC. CPen* SelectObject( CPen* pPen ); Chọn công cụ vẽ mới cho DC.

pPen : con trỏ đến đối tượng pen sẽ được dùng cho DC. Hàm trả về con trỏ chỉ đến đối tượng pen mà DC đang sử dụng.

Có thể sử dụng hành vi này cho các công cụ trang trí khác của DC. Kết quả trả về là con trỏ đến đối tượng đang dùng tương ứng.

CPent* GetCurrentPen( ); Trả về giá trị con trỏ của đối tượng pen đang được sử dụng bởi DC.

Một cách tương tự cho các công cụ trang trí khác. virtual COLORREF SetBkColor( COLORREF crColor ); Ðặt màu

nền cho DC. crColor là giá trị màu đặt. COLORREF GetBkColor( ); Trả về giá trị màu nền của DC. virtual COLORREF SetTextColor( COLORREF crColor ); Ấn định

màu được sử dụng để hiển thị các nội dung văn bản trên DC. COLORREF GetTextColor( ); Trả về giá trị màu hiện dùng để hiển

thị các nội dung văn bản trên DC. int SetBkMode ( int nBkMode ); Ấn định chế độ hiển thị nền ký tự

biểu diễn nội dung văn bản. nbkMode chứa thông số ấn định: TRANSPARENT : Nền chữ hiển thị trong suốt. OPAQUE : Chữ hiển thị có màu nền.

int GetBkMode( ); Lấy chế độ hiển thị chữ của DC. virtual BOOL TextOut (

int x, y , // Tọa độ bắt đầu hiển thị LPCTSTR lpszString, // Nội dung chuỗi hiển thị. int nCount // Chiều dài chuỗi. ); Hiển thị nội dung chuỗi văn bản lên giao diện đồ họa của DC.

virtual int DrawText ( LPCTSTR lpszString, // Nội dung chuỗi hiển thị int nCount, // Chiều dài chuỗi LPRECT lpRect, // Con trỏ đến biến kiểu RECT

36 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

UINT nFormat // Chứa thông tin canh chỉnh chuỗi hiển thị. ); In nội dung chuỗi lên giao diện đồ họa của DC với các canh chỉnh. lpRect : Chỉ đến biến kiểu RECT chứa thông tin giới hạn vùng hiển thị. nFormat : Cho phép kết hợp một cách hợp lý các canh chỉnh trong vùng hình chữ nhật giới hạn. Các thông số canh chỉnh có thể là:

DT_CENTER : Chỉnh giữa theo chiều ngang DT_VCENTER : Chỉnh giữa theo chiều dọc DT_RIGHT : Chỉnh phải.

CPoint MoveTo( int x, int y ); Ấn định điểm vẽ hiện hành. BOOL LineTo( int x, int y ); Vẽ đường thẳng từ điểm vẽ hiện hành đến điểm có tọa độ (x, y).

void FillRect ( LPCRECT lpRect, // Con trỏ chỉ đến biến kiểu RECT. CBrush* pBrush // Con trỏ đến đối tượng brush dùng tô màu. ); Tô màu vùng hình chữ nhật được xác định bởi các giá trị chứa trong biến kiểu RECT do tham số lpRect chỉ đến.

void Draw3dRect ( // Vẽ hình chữ nhật 3 chiều LPCRECT lpRect, // Con trỏ đến biến RECT COLORREF clrTopLeft, // Màu vẽ cạnh trái và cạnh trên. COLORREF clrBottomRight // Màu vẽ cạnh phải và cạnh dưới );

BOOL DrawEdge ( LPRECT lpRect, // Con trỏ đến biến kiểu RECT. UINT nEdge, // Cách vẽ trên các gờ (trong, ngoài) cạnh. UINT nFlags // Các cạnh được vẽ. ); Vẽ khung chữ nhật với hiệu ứng 3 chiều. nEdge có thể kết hợp các giá trị sau:

BDR_RAISEDINNER : Vẽ nổi gờ trong BDR_SUNKENINNER : Vẽ chìm gờ trong BDR_RAISEDOUTER : Vẽ nổi gờ ngoài BDR_SUNKENOUTER : Vẽ chìm gờ ngoài

nFlags có thể kết hợp các giá trị sau: BF_RECT : Vẽ tất cả các cạnh BF_TOPLEFT : Vẽ cạnh trái và cạnh trên BF_BOTTOMRIGHT : Vẽ cạnh phải và cạnh dưới

BOOL DrawState ( CPoint pt, // Ðiểm đặt góc trái trên của ảnh trên DC CSize size, // Kích thước vùng hiển thị ảnh CBitmap* pBitmap, // Con trỏ đối tượng bitmap được vẽ

Page 25: Mfc Tieng Viet

Caùc lôùp giao dieän ñoà hoïa cuûa MFC 37

UINT nFlags, // = DST_BITMAP (vẽ bitmap) CBrush* pBrush // Con trỏ đối tượng Brush, sử dụng khi vẽ // Bitmap ẩn: nFlags |= DSS_DISABLED ); Vẽ bitmap hoặc icon lên DC.

BOOL BitBlt ( int x, int y, // Tọa độ góc trái trên và int nWidth, int nHeight, // kích thước vùng nhận ảnh. CDC* pSrcDC, // Con trỏ đối tượng quản lý DC nguồn. int xSrc, int ySrc, // Góc trái trên phần ảnh nguồn được chép. DWORD dwRop // Cách chụp pixel từ ảnh nguồn. ); Chụp nội dung phần ảnh bắt đầu từ vị trí (xSrc,ySrc) trong DC nguồn sang vùng nhận ảnh bắt đầu từ vị trí (x, y), với kích thước (nWidth, nHeight) trong DC quản lý bởi đối tượng. Giá trị pixel được chuyển vào vùng nhận ảnh tùy thuộc vào giá trị tham số dwRop. Một số giá trị dùng cho tham số này có thể như sau: • SRCCOPY : Giá trị pixel lấy trực tiếp từ pixel của ảnh nguồn. • SRCPAINT : Là kết quả OR của pixel ảnh nguồn và ảnh nhận. • SRCAND : Là kết quả AND của pixel ảnh nguồn và ảnh

nhận. BOOL MaskBlt (

int x, int y, // Tọa độ góc trái trên và int nWidth, int nHeight, // Kích thước vùng nhận ảnh CDC* pSrcDC, // Con trỏ đối tượng quản lý DC nguồn int xSrc, int ySrc, // Góc trái trên phần ảnh được chép CBitmap& maskBitmap, // Con trỏ đối tượng bitmap mặt nạ int xMask, int yMask, // Góc trái trên vùng ảnh làm mặt nạ DWORD dwRop // Cách chụp pixel từ ảnh nguồn. ); Tương tự BitBlt nhưng sử dụng mặt nạ lọc pixel. Ðối tượng maskBitmap sử dụng ảnh trắng đen (monochrome bmp) mà mỗi pixel "đen" sẽ ngăn việc chuyển pixel ở vị trí tương ứng từ DC nguồn sang DC quản lý bởi đối tượng, các vị trí khác được chuyển bình thường.

BOOL StretchBlt ( int x, int y, // Tọa độ góc trái trên và int nWidth, int nHeight, // Kích thước vùng nhận ảnh. CDC* pSrcDC, // Con trỏ đối tượng DC nguồn. int xSrc, int ySrc, // Tọa độ góc trái trên và int nSrcWidth, int nSrcHeight, // Kích thước phần ảnh được chép.

38 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

DWORD dwRop // Cách chụp pixel từ ảnh nguồn. ); Tương tự BitBlt nhưng ảnh đích và ảnh nguồn có thể có kích thước khác nhau nên tạo hiệu ứng co dãn ảnh chép được so với ảnh nguồn.

BOOL DrawIcon ( int x, int y, // Tọa độ góc trái trên nơi đặt icon trên DC HICON hIcon // Handle của icon ); Vẽ icon hIcon lên vị trí (x, y) của DC quản lý bởi đối tượng.

3.6 LỚP CImagelist: CImageList là lớp đối tượng imagelist. Mỗi imagelist cho phép quản lý

danh sách ảnh có cùng kích thước và hỗ trợ nhiều tiện ích trên chúng. CImageList( ); Tạo lập đối tượng imagelist rỗng. BOOL Create (

UINT nBitmapID, // Số hiệu của resource bitmap chứa các ảnh int cx, // Ðộ rộng mỗi ảnh trong bitmap nói trên int nGrow, // Số ảnh trong bitmap COLORREF crMask // Màu mặt nạ (không hiển thị) ); Khởi tạo nội dung cho đối tượng từ một bitmap trong resource.

int GetImageCount( ); Số ảnh của imagelist quản lý bởi đối tượng. int Add (

CBitmap* pbmImage, // Con trỏ đối tượng bitmap của ảnh mới. CBitmap* pbmMask | // Ðối tượng bitmap mặt nạ hoặc [ COLORREF crMask ] // màu mặt nạ của ảnh mới. ); Thêm một ảnh (bitmap) vào imagelist.

BOOL BeginDrag( int nImage, CPoint ptHotSpot ); Chuẩn bị chuyển ảnh thứ nImage trong imagelist với vị trí bắt đầu ptHotSpot.

static BOOL DragEnter( CWnd* pWndLock, CPoint point ); Cấm cửa sổ pWndLock, nơi mà imagelist đang thực hiện chuyển ảnh.

static BOOL DragMove(CPoint pt); Chuyển ảnh nImage đến vị trí pt.

static BOOL DragLeave( CWnd* pWndLock ); Chấm dứt tình trạng bị cấm của cửa sổ pWndLock.

static void EndDrag( ); Chấm dứt tác vụ chuyển ảnh. static BOOL DragShowNolock( BOOL bShow ); Hiển thị hoặc che ảnh trong quá trình chuyển hình.

BOOL Draw ( CDC* pdc, // Ðối tượng DC dùng vẽ hình int nImage, // Số thứ tự hình được vẽ trong imagelist POINT pt, // Tọa độ góc trái trên nơi vẽ hình

Page 26: Mfc Tieng Viet

Caùc lôùp giao dieän ñoà hoïa cuûa MFC 39

UINT nStyle // Kiểu vẽ = ILD_NORMAL ); Vẽ hình nImage của imagelist quản lý bởi đối tượng lên DC.

BOOL DrawIndirect ( CDC* pDC, int nImage,POINT pt, // Tương tự Draw SIZE sz, // Kích thước vùng nhận ảnh POINT ptOrigin, // Góc trái trên phần ảnh được vẽ UINT fStyle, // Kiểu ảnh ( = ILD_NORMAL ) DWORD dwRop , // Cách chép pixel ( = SRCCOPY ) COLORREF rgbBack , // Màu vùng bị lọc = CLR_DEFAULT

COLORREF rgbFore // Màu phối hợp cho fStyle có thông số // ILD_BLEND25 hoặc ILD_BLEND50 ( = CLR_DEFAULT) ); Vẽ hình nImage.

Ðối tượng GDI được khởi tạo trong chương trình bởi hành vi Createxxx cần được hủy bỏ khi chấm dứt sử dụng để tránh lãng phí bộ nhớ hệ thống: - Các đối tượng công cụ GDI, sử dụng hành vi: DeleteObject( ); - Các đối tượng quản lý thiết bị đồ họa, sử dụng hành vi: DeleteDC(

);

Page 27: Mfc Tieng Viet

40 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

CHƯƠNG 4:

Cửa sổ giao diện và lớp CWnd 4.1 CỬA SỔ GIAO DIỆN:

Cửa sổ giao diện là thành phần quan trọng của ứng dụng. Nó không chỉ đóng vai trò trung gian trong trao đổi thông tin giữa ứng dụng với người dùng bởi giao diện đồ họa dễ nhìn mà còn là công cụ xử lý message hiệu quả và không thể thiếu cho cơ chế điều phối message của ứng dụng windows.

Bên cạnh đó, cửa sổ giao diện còn làm chức năng nhận diện ứng dụng, là thẻ thông hành cho ứng dụng trong hành trình tồn tại, hoạt động độc lập cũng như phối hợp trao đổi dữ liệu với các ứng dụng khác trong windows.

4.2 LỚP CWnd: CWnd là lớp đối tượng quản lý cửa sổ của windows. Thông qua các

thuộc tính và hành vi của lớp CWnd, MFC cung cấp các dịch vụ cần thiết cho phép tạo lập và khai thác các tính năng của cửa sổ windows một cách dễ dàng.

HWND m_hWnd : Thuộc tính lưu handle của cửa sổ. CWnd( ); Hành vi tạo lập đối tượng cửa sổ. virtual BOOL Create (

LPCTSTR lpszClassName, // Tên đăng ký của lớp cửa sổ LPCTSTR lpszWindowName, // Tên cửa sổ. DWORD dwStyle, // Các thông số về dạng cửa sổ const RECT& rect, // Qui định vị trí, kích thước cửa sổ CWnd* pParentWnd, // Con trỏ đối tượng cửa sổ cha UINT nID, // Số hiệu cửa sổ CCreateContext* pContex = NULL ); Khởi tạo thông số cho cửa sổ quản lý bởi đối tượng. Tham số dwStyle qui định đặc điểm và kiểu dáng cửa sổ. Giá trị dùng cho tham số này có thể kết hợp một số trong các giá trị sau: WS_POPUP : Cửa sổ được tạo là cửa sổ chính. WS_CHILD : Cửa sổ được tạo là cửa sổ con. WS_TABSTOP : Cửa sổ con, chuyển được bằng phím tab. WS_OVERLAPPED : Cửa sổ chính. WS_SYSMENU : Cửa sổ có hộp menu hệ thống. WS_BORDER : Cửa sổ có viền. WS_CAPTION : Cửa sổ có tiêu đề (caption) WS_DISABLED : Cửa sổ bị cấm. WS_DLGFRAME : Cửa sổ có viền đậm kiểu hộp thoại,

Cöûa soå giao dieän vaø lôùp CWnd 41

WS_HSCROLL : Cửa sổ có thanh trượt ngang ở biên. WS_VSCROLL : Cửa sổ có thanh trượt dọc ở biên. WS_MAXIMIZEBOX : Có hộp phóng to trên caption của cửa sổ. WS_MINIMIZEBOX : Có hộp thu nhỏ trên caption của cửa sổ. WS_THICKFRAME : Viền cho phép thay đổi kích thước cửa sổ. WS_VISIBLE : Cửa sổ nhìn thấy được (hiển thị). Ví dụ: WS_POPUP | WS_CAPTION : Cửa sổ chính có tiêu đề.

lpszClassName là một tên đã đăng ký cho lớp cửa sổ. Ngoài các tên mà windows đã đăng ký như STATIC, BUTTON, EDIT, ... (chương 8), ta có thể đăng ký tên lớp cửa sổ riêng của mình một cách tùy ý. Việc đăng ký tên lớp cửa sổ có thể thực hiện bằng một trong hai cách sau: • Ðăng ký trực tiếp:

LPCTSTR AFXAPI AfxRegisterWndClass ( UINT nClassStyle, // Thông số dạng của cửa sổ HCURSOR hCursor = 0, // Cursor hiển thị trong cửa sổ HBRUSH hbrBackground = 0, // Brush dùng tô nền cửa sổ HICON hIcon = 0 // Icon trên tiêu đề của cửa sổ ); Trả về chuỗi tên lớp cửa sổ được đăng ký. Các lần đăng ký tên lớp cửa sổ có tham số giống nhau sẽ nhận được một tên duy nhất. Tham số nClassStyle có thể kết hợp từ các giá trị sau: CS_HREDRAW : Cửa sổ được vẽ lại khi chiều rộng thay đổi. CS_VREDRAW : Cửa sổ được vẽ lại khi chiều cao thay đổi. CS_NOCLOSE : Cấm hộp đóng [] trên tiêu đề của cửa sổ.

Ví dụ: Ðăng ký lớp cửa sổ có nền màu xanh dương. CString myClassName; CBRUSH myBrush; myBrush.CreateSolidBrush( RGB ( 0, 0, 255 ) ); myClassName = AfxRegisterWndClass ( CS_VREDRAW | CS_HREDRAW, NULL, myBrush, NULL );

• Ðăng ký qua cấu trúc chứa các thông số:

BOOL AFXAPI AfxRegisterClass( WNDCLASS* lpWndClass ); Hàm trả về giá trị TRUE nếu tác vụ đăng ký thành công. Thực hiện đăng ký theo cách này tránh được sự dùng chung tên lớp cửa sổ ở hai ứng dụng khác nhau khi hai ứng dụng này tình cờ đăng ký các tên lớp cửa sổ giống nhau về thông số.

Page 28: Mfc Tieng Viet

42 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

lpWndClass là con trỏ chỉ đến biến có kiểu cấu trúc WNDCLASS.

typedef struct _WNDCLASS { UINT style; // Dạng của lớp đăng ký WNDPROC lpfnWndProc; // Con trỏ hàm WindowProc của // cửa sổ. Có thể lấy hàm do MFC // khai báo sẵn: AfxWndProc int cbClsExtra; // Dành riêng của hệ thống int cbWndExtra; // Dành riêng của hệ thống HINSTANCE hInstance; // Instance handle của ứng dụng HICON hIcon; // Handle của icon HCURSOR hCursor; // Handle của cursor HBRUSH hbrBackground; // Handle của brush vẽ nền LPCTSTR lpszMenuName; // Chuỗi tên menu trong resource LPCTSTR lpszClassName; // Tên lớp cửa sổ đăng ký } WNDCLASS;

BOOL CreateEx ( DWORD dwExStyle, // Các thông số dạng mở rộng LPCTSTR lpszClassName, // Tên lớp LPCTSTR lpszWindowName, // Tên cửa sổ DWORD dwStyle, // Dạng cửa sổ int x, int y, // Tọa độ góc trái trên của cửa sổ int nWidth, int nHeight, // Chiều rộng và cao của cửa sổ HWND hwndParent, // Handle của cửa sổ cha HMENU nIDorHMenu, // Handle của menu gắn với cửa sổ LPVOID lpParam = NULL ); Khởi tạo cửa sổ với việc sử dụng các thông số mở rộng về dạng. Tham số dwExStyle qui định dạng mở rộng của cửa sổ có thể kết hợp từ các giá trị sau:

WS_EX_TOPMOST : Cửa sổ không bị che khuất. WS_EX_TOOLWINDOW : Cửa sổ không hiển thị trên taskbar. WS_EX_TRANSPARENT : Cửa sổ có nền trong suốt. WS_EX_CLIENTEDGE : Cửa sổ có gờ quanh vùng client.

virtual BOOL PreCreateWindow( CREATESTRUCT& cs ); Hành vi được thực hiện trước khi windows khởi tạo thông số cho cửa sổ. Tham biến cs kiểu CREATESTRUCT chứa thông số khởi tạo.

typedef struct tagCREATESTRUCT {

Cöûa soå giao dieän vaø lôùp CWnd 43

LPVOID lpCreateParams; // Con trỏ vùng chứa thông số cửa sổ HANDLE hInstance; // Handle của ứng dụng HMENU hMenu; // Handle của menu gắn với cửa sổ HWND hwndParent; // Handle của cửa sổ cha int cy; int cx; // Chiều rộng và cao của cửa sổ int y; int x; // Tọa độ góc trái trên của cửa sổ LONG style; // Thông số ấn định dạng cửa sổ LPCSTR lpszName; // Tên cửa sổ được tạo LPCSTR lpszClass; // Tên lớp cửa sổ dùng cho cửa sổ DWORD dwExStyle; // Thông số ấn định dạng mở rộng } CREATESTRUCT;

Trong các lớp kế thừa CWnd, hành vi này được dùng để can thiệp cài đặt các ấn định riêng trên cấu trúc thông số cs của cửa sổ.

BOOL EnableWindow( BOOL bEnable = TRUE ); Cho phép hoặc cấm hoạt động của cửa sổ.

BOOL ShowWindow( int nCmdShow ); Ấn định trạng thái hiển thị của cửa sổ trên màn hình. Giá trị cho tham số nCmdShow có thể là:

SW_HIDE : Dấu cửa sổ SW_MINIMIZE : Thu nhỏ cửa sổ SW_RESTORE : Ðưa cửa sổ về trạng thái trước đó SW_SHOW : Hiển thị cửa sổ SW_SHOWNA : Hiển thị nhưng không kích hoạt cửa sổ SW_SHOWMAXIMIZED : Hiển thị và phóng to cửa sổ SW_SHOWMINIMIZED : Hiển thị và thu nhỏ cửa sổ

BOOL SetWindowPos ( const CWnd* pWndInsertAfter, // Con trỏ cửa sổ làm mốc int x, int y, // Tọa độ góc trái trên của cửa sổ int cx, int cy, // Kích thước cửa sổ UINT nFlags // Thông số trạng thái ); Ấn định vị trí cửa sổ trên màn hình. Giá trị pWndInsertAfter qui định vị trí đặt cửa sổ theo chiều thứ 3 (z-order). Giá trị này có thể như sau:

wndBottom : Cửa sổ được đặt dưới mọi cửa sổ. wndTop : Cửa sổ được đặt trên các cửa sổ thông thường. wndTopMost : Cửa sổ được đặt trên mọi cửa sổ.

Tham số nFlags qui định trạng thái mới của cửa sổ: SWP_SHOWWINDOW : Hiển thị cửa sổ.

Page 29: Mfc Tieng Viet

44 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

SWP_DRAWFRAME : Vẽ lại frame của cửa sổ. SWP_NOREDRAW : Không cập nhật lại thông tin cửa sổ.

void MoveWindow ( int x, int y, // Tọa độ mới cho góc trái trên int nWidth, int nHeight, // Chiều rộng và chiều cao của cửa sổ BOOL bRepaint = TRUE // Yêu cầu windows vẽ lại cửa sổ ); Thay đổi vị trí và kích thước của cửa sổ.

void GetWindowRect( LPRECT lpRect ); Lấy thông tin tọa độ, kích thước của cửa sổ, lpRect chỉ đến biến kiểu RECT chứa kết quả.

void GetClientRect( LPRECT lpRect ); Lấy thông tin tọa độ, kích thước vùng client của cửa sổ, lpRect chỉ đến biến RECT chứa kết quả.

int GetWindowRgn(HRGN hRgn); Xác định vùng hiển thị của cửa sổ.

int SetWindowRgn ( HRGN hRgn, // Handle của region quản lý vùng ấn định BOOL bRedraw // Vẽ lại cửa sổ (TRUE) hay không (FALSE) ); Ấn định vùng hiển thị của cửa sổ theo dạng của region.

void GetWindowText( CString rString ); Lấy nội dung chuỗi tiêu đề của cửa sổ và lưu vào biến đối tượng chuỗi rString.

int GetWindowTextLength( ); Trả về chiều dài của chuỗi tiêu đề. void ClientToScreen( LPPOINT lpPoint / LPRECT lpRect );

Chuyển tọa độ điểm hay vùng hình chữ nhật trong client của cửa sổ sang hệ trục tọa độ của màn hình.

void ScreenToClient( LPPOINT lpPoint / LPRECT lpRect ); Chuyển tọa độ điểm hay vùng hình chữ nhật trên màn hình sang hệ trục tọa độ của vùng client trong cửa sổ.

HICON GetIcon( BOOL bBigIcon ); Trả về handle của icon mà cửa sổ đang sử dụng. Giá trị tham số bBigIcon có ý nghĩa như sau:

TRUE : Handle của icon hiển thị trên taskbar (big Icon) FALSE : Handle của icon hiển thị trên caption (small Icon)

HICON SetIcon ( HICON hIcon, // handle của icon BOOL bBigIcon // TRUE (đặt bigIcon) , FALSE (đặt smallIcon) ); Ðặt icon mới cho cửa sổ.

static CWnd* PASCAL GetFocus( ); Trả về con trỏ chỉ đến đối tượng CWnd đang được phép nhận thông tin nhập từ bàn phím.

CWnd* SetFocus( ); Kích hoạt cửa sổ. Hàm trả về con trỏ của đối tượng CWnd đã được kích hoạt trước đó.

CFont* GetFont( ); Trả về đối tượng font chữ của cửa sổ. void SetFont (

CFont* pFont, // Con trỏ đến đối tượng font chữ Cöûa soå giao dieän vaø lôùp CWnd 45

BOOL bRedraw = TRUE // Vẽ lại cửa sổ sau tác vụ đặt font ? ); Ấn định font chữ cho cửa sổ.

CMenu* GetMenu( ); Trả về con trỏ đối tượng menu gắn với cửa sổ.

BOOL SetMenu( CMenu* pMenu ); Gắn menu cho cửa sổ. CWnd* GetParent( ); Trả về con trỏ đến đối tượng cửa sổ cha. int GetScrollPos( int nBar ); Trả về vị trí hiện hành của nút cuộn

trên thanh cuộn. nBar chứa số hiệu thanh cuộn quan tâm. nBar có thể là:

SB_HORZ : Thanh cuộn ngang. SB_VERT : Thanh cuộn dọc.

int SetScrollPos ( int nBar, // Thanh cuộn được chọn int nPos, // Vị trí đặt BOOL bRedraw = TRUE // Vẽ lại thanh cuộn sau tác vụ đặt ); Ðặt vị trí nút cuộn cho thanh cuộn tương ứng.

UINT SetTimer ( UINT nIDEvent, // Số hiệu của timer, phân biệt duy nhất UINT nElapse, // Chu kỳ timer (tính bằng mili-second) NULL // Sử dụng hành vi OnTimer xử lý timer ); Ðặt biến cố định thời (timer) cho cửa sổ quản lý bởi đối tượng. Mỗi khi hết một chu kỳ của timer, hệ thống gửi WM_TIMER kèm theo số hiệu của timer đó đến cho cửa sổ.

BOOL KillTimer( int nIDEvent ); Hủy bỏ timer có số hiệu nIDEvent. afx_msg void OnTimer( UINT nIDEvent ); Hành vi xử lý WM_TIMER

của cửa sổ. Tham số nIDEvent chứa số hiệu của timer liên quan. void Invalidate( BOOL bErase = TRUE ); Kích hoạt cơ chế vẽ lại

vùng client của cửa sổ. Nếu bErase = FALSE, windows không thực hiện xóa thông tin trong vùng cần vẽ lại.

void InvalidateRect( LPCRECT lpRect, BOOL bErase = TRUE ); Kích hoạt cơ chế vẽ lại một vùng trong client của cửa sổ. Thông tin về vị trí và kích thước của vùng cần vẽ lại được lưu trong biến kiểu RECT chỉ bởi lpRect. Tham số bErase có ý nghĩa như Invalidate.

int MessageBox ( LPCTSTR lpszText, // Nội dung thông báo LPCTSTR lpszCaption = NULL // Tiêu đề hộp thông báo UINT nType = MB_OK // Dạng hộp thông báo ); Hiển thị hộp thông báo và trả về số hiệu của nút được chọn.

LRESULT SendMessage ( UINT message, // Số hiệu message WPARAM wParam = 0, // Tham số kiểu WORD LPARAM lParam = 0 // và kiểu LONG kèm theo message

Page 30: Mfc Tieng Viet

46 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

); Gửi message và tham số kèm theo đến hàm WindowProc của cửa sổ quản lý bởi đối tượng, và chờ đến khi hàm WindowProc xử lý xong.

BOOL PostMessage( UINT message, WPARAM wParam = 0, LPARAM lParam=0 ); Ðặt message và các tham số kèm theo vào message queue của ứng dụng. Hành vi kết thúc mà không chờ message đó được xử lý.

afx_msg void OnSize( UINT nType, int cx, int cy ); Hành vi xử lý WM_SIZE, message do windows gửi đến cửa sổ khi một tác vụ thay đổi kích thước cửa sổ hoàn tất. cx, cy chứa kích thước mới của cửa sổ.

afx_msg int OnCreate( LPCREATESTRUCT lpCreateStruct ); Hành vi xử lý WM_CREATE, message do windows gửi đến cửa sổ khi tác vụ khởi tạo thông số cho cửa sổ được thực hiện xong.

afx_msg void OnClose( ); Hành vi xử lý WM_CLOSE, message do windows gửi đến cửa sổ khi tác vụ đóng cửa sổ đang xảy ra.

afx_msg void OnDestroy( ); Hành vi xử lý WM_DESTROY, message do windows gửi đến cửa sổ khi tác vụ hủy bỏ cửa sổ đang xảy ra.

afx_msg void OnKeyDown ( UINT nChar, // Mã phím UINT nRepCnt, // Số lần gõ phím UINT nFlags // Trạng thái các phím kèm theo ); Hành vi xử lý WM_KEYDOWN, message do windows gửi đến cửa sổ khi cửa sổ đang được kích hoạt, đồng thời có phím vừa được ấn xuống mà không có sự sử dụng phím Alt kèm theo.

afx_msg void OnKeyUp ( // Các tham số tương tự như trên UINT nChar, UINT nRepCnt , UINT nFlags ); Hành vi xử lý WM_KEYUP. Một cách tương tự WM_KEYDOWN.

afx_msg void OnChar ( UINT nChar , // Mã ASCII UINT nRepCnt , // Số lần gõ UINT nFlags // Trạng thái các phím kèm theo ); Hành vi xử lý WM_CHAR, message do windows gửi đến cửa sổ khi một phím ký tự được gõ.

afx_msg void OnLButtonDblClk ( UINT nFlags, // Chứa giá trị phím được nhấn kèm CPoint point // Vị trí double-click chuột ); Hành vi xử lý WM_LBUTTONDBLCLK, message do windows gửi đến cửa sổ khi người dùng double-click vào nút chuột trái. Tham số nFlag có thể là kết hợp của các giá trị sau:

MK_CONTROL : Phím CTRL được nhấn kèm theo

Cöûa soå giao dieän vaø lôùp CWnd 47

MK_SHIFT : Phím SHIFT được nhấn kèm theo afx_msg void OnLButtonDown( UINT nFlags, CPoint point ); Hành

vi xử lý WM_LBUTTONDOWN, message do windows gửi đến cửa sổ khi người dùng ấn nút chuột trái. Các thông tin như trên.

afx_msg void OnLButtonUp( UINT nFlags, CPoint point ); Hành vi xử lý WM_LBUTTONUP, message do windows gửi đến cửa sổ khi người dùng nhả nút chuột trái. Các thông tin như trên.

Một cách tương tự cho các hành vi xử lý message của nút chuột phải.

afx_msg void OnMouseMove( UINT nFlags, CPoint point ); Hành vi xử lý WM_MOUSEMOVE, message do windows gửi đến cửa sổ khi người dùng di chuyển chuột trong cửa sổ. Các thông tin như trên.

int GetDlgCtrlID( ); Trả về số hiệu của đối tượng cửa sổ con. afx_msg void OnPaint( ); Hành vi xử lý WM_PAINT, message do

windows gửi đến cửa sổ khi hệ thống hoặc ứng dụng có nhu cầu trang trí lại một phần hay toàn bộ giao diện của cửa sổ.

Công việc thông thường của OnPaint là vẽ lại các nội dung cần duy trì trên bề mặt giao diện của cửa sổ. Ðể thực hiện việc này, OnPaint sử dụng một đối tượng CDC và dùng nó cho các thao tác đồ họa cần thiết nhằm hoàn thành yêu cầu nói trên. Bố cục xử lý thông thường của hành vi OnPaint như sau:

PAINTSTRUCT ps ; // Biến chứa thông tin trang trí CDC* pDC = BeginPaint(&ps); // Lấy DC của giao diện cửa sổ . // Xử lý trang trí giao diện đồ họa EndPaint(&ps); // Chấm dứt.

afx_msg void OnHScroll ( UINT nSBCode, // Số hiệu ghi nhận đặc điểm tác động UINT nPos, // Vị trí nút cuộn / nút trượt trên mục CScrollBar* pScrollBar // Con trỏ đối tượng quản lý mục ); Hành vi xử lý WM_HSCROLL, message do windows gửi đến cửa sổ khi có một mục là thanh cuộn hay thanh trượt đặt ngang (horizontal scrollbar hoặc horizontal sliderCtrl) trong cửa sổ bị tác động. nSBCode ghi nhận đặc điểm tác động lên nút cuộn / trượt như sau:

SB_LEFT : Giảm nút về vị trí thấp nhất SB_ENDSCROLL : Chấm dứt tác vụ chuyển nút SB_LINELEFT : Giảm nút một vị trí SB_LINERIGHT : Tăng nút một vị trí SB_PAGELEFT : Giảm nút một đoạn

Page 31: Mfc Tieng Viet

48 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

SB_PAGERIGHT : Tăng nút một đoạn SB_RIGHT : Tăng nút đến vị trí cao nhất SB_THUMBPOSITION : Chuyển nút bằng chuột SB_THUMBTRACK : Ðang chuyển nút bằng chuột .

nPos được sử dụng trong các tác vụ định vị nút tuyệt đối ( ). Dùng hành vi GetDlgCtrlID của đối tượng chỉ bởi pScrollBar để xác định số hiệu của mục phát sinh message WM_HSCROLL. Ðây là cơ sở giúp phân biệt mục này với các mục khác trong cùng cửa sổ giao diện nhằm lựa chọn xử lý thích hợp cho WM_HSCROLL.

afx_msg void OnVScroll ( UINT nSBCode, // Số hiệu ghi nhận đặc điểm tác động UINT nPos, // Vị trí nút cuộn / nút trượt trên mục CScrollBar* pScrollBar // Con trỏ đối tượng quản lý mục ); Hành vi xử lý WM_VSCROLL, message do windows gửi đến cửa sổ khi có một mục là thanh cuộn hay thanh trượt đặt thẳng đứng (vertical scrollbar hoặc vertical sliderCtrl) trong cửa sổ bị tác động.

Xử lý của hành vi này được cài đặt tương tự hành vi OnHScroll. afx_msg BOOL OnSetCursor (

CWnd* pWnd, // Con trỏ đến đối tượng cửa sổ chứa cursor UINT nHitTest, // Thông tin về vị trí cursor UINT message // Chứa các số hiệu message có liên quan đến // trạng thái hiện thời của các nút con chuột ); Hành vi xử lý WM_SETCURSOR, message do windows gửi đến cửa sổ khi windows cần ấn định lại hình dạng cursor cho phù hợp với vị trí hiện thời của nó trên cửa sổ. nHitTest chứa thông tin vị trí hiện thời của cursor:

HTBORDER : Cursor hiện nằm trên biên cửa sổ HTCLIENT : Cursor hiện nằm trong vùng client HTCAPTION : Cursor hiện nằm trên tiêu đề của cửa sổ

virtual LRESULT WindowProc( UINT message, WPARAM wParam, LPARAM lParam ); Hành vi xử lý các message gửi đến cửa sổ. Mặc nhiên, hành vi này dựa vào bảng MessageMap để chuyển message đến hành vi xử lý message tương ứng của đối tượng quản lý cửa sổ.

4.3 SỬ DỤNG ÐỐI TƯỢNG CWnd: 4.3.1 Sử dụng CWnd làm giao diện chính của ứng dụng:

Tạo dự án VD02 như dự án VD01. Thực hiện các bổ sung sau: Tạo icon có số hiệu là IDC_MAINFRAME. Tham khảo (2.8). Tạo cursor có số hiệu là IDC_MAINFRAME: • Tạo mới cursor: Thực hiện tương tự như tạo mới icon, (2.8).

Cöûa soå giao dieän vaø lôùp CWnd 49

• Ðặt điểm chỉ (hotpot) của cursor: Trong màn hình thiết kế cursor:

- Click chọn biểu tượng trên thanh công cụ. - Click tại vị trí hotpot của cursor trên màn hình thiết kế.

Dùng đối tượng CWnd làm cửa sổ giao diện chính của ứng dụng: Ðược thực hiện bởi hành vi InitInstance (xem 2.4) của đối tượng CEmpApp quản lý tiểu trình chính. Kế thừa hành vi này từ CWinApp cho lớp CEmpApp (xem 2.7). Nội dung cài đặt của hành vi như sau:

CWnd* main = new CWnd(); // Con trỏ đối tượng CWnd. HICON myIcon; // Khai báo biến quản lý HCURSOR myCursor; // handle của cursor và icon CBrush myBrush; // Nạp cursor và icon từ resource vào bộ nhớ. myIcon = LoadIcon ( IDR_MAINFRAME ); myCursor = LoadCursor ( IDR_MAINFRAME ); // Tạo brush tô nền cửa sổ với màu RGB(190, 190, 0) myBrush. CreateSolidBrush (RGB(190, 190, 0) );

// Khởi tạo thông số cho đối tượng cửa sổ main main->CreateEx( WS_EX_TOPMOST, AfxRegisterWndClass( CS_HREDRAW|CS_VREDRAW, myCursor, myBrush, myIcon), "Emp.Example 2", WS_SYSMENU | WS_VISIBLE | WS_MINIMIZEBOX, 100, 100, 300, 200, NULL, NULL ); // Dùng main làm cửa sổ giao diện chính m_pMainWnd = main; main->ShowWindow ( SW_SHOW ); // Kích hoạt cửa sổ main

Khi đối tượng cửa sổ main ngừng hoạt động thì ứng dụng cũng kết thúc.

Xem VD02: Cửa sổ main với ExStyle là WS_EX_TOPMOST có thể nổi trên mọi cửa sổ khác ngay cả khi nó không phải là cửa sổ kích hoạt. Với ExStyle là WS_EX_TOOLWINDOW, cửa sổ sẽ không hiển thị trên taskbar.

4.3.2 Ứng dụng chỉ chạy một bản (instance) tại mỗi thời điểm: Ðể ứng dụng chỉ được thực hiện với 1 bản duy nhất, ta cài đặt cơ chế

đánh dấu và kiểm tra. Trong chương trình của ứng dụng, ta qui ước đăng

Page 32: Mfc Tieng Viet

50 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

ký và sử dụng một tên duy nhất cho cửa sổ chính. Khi chương trình được thực hiện, nó kiểm tra xem tên đó đã được đăng ký chưa thông qua hàm sau:

HANDLE CreateMutex( NULL, FALSE, LPCTSTR Tên );

Hàm trả về giá trị ERROR_ALREADY_EXISTS nếu Tên đã được đăng ký. Trong trường hợp này ta có thể khẳng định một instance của ứng dụng đã được thực hiện, chương trình kết thúc để chỉ cho phép một instance duy nhất.

Hãy cài đặt cơ chế này cho ứng dụng VD02 (Tham khảo VD03).

THỰC HÀNH: 1. Viết ứng dụng windows chỉ cho phép thực hiện tối đa hai bản (instance). 2. Cài đặt hành vi PreCreateWindow cho lớp kế thừa CWnd của ứng dụng để cửa sổ giao diện luôn có kích thước 100100 và tiêu đề là "Hello !" bất chấp giá trị kích thước và tiêu đề dùng cho khởi tạo thông số của đối tượng cửa sổ.

Page 33: Mfc Tieng Viet

Xöû lyù Message 51

CHÖÔNG 5:

Xử lý message 5.1 LÔÙP XÖÛ LYÙ MESSAGE CCmdTarget:

Windows laø moâi tröôøng maø phaàn lôùn giao taùc giöõa caùc boä phaän döïa treân cô cheá göûi-nhaän message. Vieäc taïo ra ñoái töôïng coù khaû naêng xöû lyù vaø ñieàu phoái messages laø raát caàn thieát khoâng chæ ñoái vôùi heä thoáng maø vôùi caû öùng duïng. Treân quan ñieåm ñoù, MFC cung caáp lôùp ñoái töôïng CCmdTarget phuïc vuï xöû lyù vaø ñieàu phoái messages trong phaïm vi öùng duïng, giöõa öùng duïng vôùi heä thoáng vaø vôùi caùc öùng duïng khaùc. Caùc haønh vi ñaëc tröng cuûa lôùp nhö sau:

void BeginWaitCursor( ); Hieån thò cursor chôø xöû lyù (ñoàng hoà caùt). void EndWaitCursor( ); Chaám döùt hieån thò cursor chôø xöû lyù. Ñònh höôùng xöû lyù message: Cô cheá ñònh höôùng xöû lyù message do MFC

cung caáp cho pheùp boå sung muïc xöû lyù message cho caùc lôùp ñoái töôïng keá thöøa lôùp CCmdTarget. Caùc macro giuùp caøi ñaët cô cheá naøy nhö sau: • DECLARE_MESSAGE_MAP( ): AÁn ñònh ñaëc tính xöû lyù message

cho lôùp ñoái töôïng xöû lyù message thoâng qua caùc caøi ñaët boå sung sau: - Thuoäc tính private kieåu caáu truùc maûng chöùa caùc phaàn töû coù kieåu

AFX_MSGMAP_ENTRY. Moãi phaàn töû cuûa maûng ñöôïc duøng löu tröõ moät muïc xöû lyù message maø lôùp keá thöøa khai baùo boå sung.

- Thuoäc tính protected kieåu caáu truùc AFX_MSGMAP vôùi teân laø MessageMap chæ ñeán baûng caùc muïc xöû lyù message noùi treân.

- Haønh vi protected: virtual AFX_MSGMAP GetMessageMap( ); traû veà ñòa chæ cuûa baûng MessageMap chöùa caùc muïc xöû lyù.

DECLARE_MESSAGE_MAP ñöôïc ñaët cuoái phaàn khai baùo lôùp: class MyClass : public CCmdTarget { // Taäp tin .H cuûa lôùp … // Caùc noäi dung khai baùo cuûa lôùp DECLARE_MESSAGE_MAP() };

• BEGIN_MESSAGE_MAP( Teân_lôùp_keá thöøa, Teân_lôùp_cô_sôû ): Baét ñaàu noäi dung khai baùo caùc muïc xöû lyù cuûa baûng MessageMap.

• END_MESSAGE_MAP( ): Keát thuùc khai baùo baûng MessageMap. Toaøn boä noäi dung khai baùo cuûa baûng MessageMap ñöôïc ñaët trong taäp tin caøi ñaët (.CPP) cuûa lôùp, neân ñaët ñaàu taäp tin ñeå tieän theo doõi.

virtual BOOL OnCmdMsg (

52 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

UINT nID, // Soá hieäu command message int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo ); Ñieàu phoái command message. Neáu baûn thaân ñoái töôïng laø cöûa soå giao dieän chính thì caùc WM_COMMAND ñöôïc öu tieân gôûi ñeán cho ñoái töôïng. Thoâng qua haønh vi naøy, ñoái töôïng coù theå ñieàu phoái command message cho caùc ñoái töôïng khaùc (öùng duïng, caùc control, view…). Löu yù laø ñoái töôïng ñöôïc ñieàu phoái coù theå khoâng coù chöùc naêng xöû lyù command message göûi ñeán, do ñoù caàn kieåm tra keát quaû cuûa haønh vi OnCmdMsg treân ñoái töôïng ñöôïc ñieàu phoái. Boá cuïc xöû lyù ñieàu phoái nhö sau: if (Ñoái_töôïng->OnCmdMsg(...) != 0) { return; // Ñoái töôïng ñöôïc ñieàu phoái ñaõ xöû lyù message } … // Chuû theå phaûi xöû lyù message

5.2 KHAI BAÙO MUÏC XÖÛ LYÙ MESSAGE TRONG MESSAGE MAP: Muïc xöû lyù message trong baûng MessageMap cho pheùp aán ñònh moät xöû lyù

duy nhaát cho moät message. Caùc loaïi message khaùc nhau coù kieåu muïc xöû lyù message khaùc nhau. Caùc kieåu muïc xöû lyù message phoå bieán nhö sau:

Caùc message cuûa heä thoáng, ñöôïc bieåu dieãn bôûi caùc haèng soá baét ñaàu baèng WM_ *, muïc xöû lyù message töông öùng coù daïng ON_WM_* (). Ví duï: WM_PAINT ON_WM_PAINT() WM_SIZE ON_WM_SIZE()

Caùc message cuûa ngöôøi duøng: Soá hieäu message ñöôïc choïn tuøy yù trong ñoaïn WM_USER ÷ WM_USER+0×7FFF. Muïc xöû lyù message cho caùc message cuûa ngöôøi duøng coù daïng nhö sau:

ON_MESSAGE( userMessageID , UserFuncName )

Trong ñoù: - userMessageID : Soá hieäu message do ngöôøi duøng choïn tröôùc - UserFuncName : Haøm xöû lyù message, coù khai baùo nhö sau:

afx_msg LRESULT UserFuncName ( WPARAM wParam, // Tham soá kieåu WORD vaø LPARAM lParam // Tham soá kieåu LONG keøm theo message );

Page 34: Mfc Tieng Viet

Xöû lyù Message 53

Caùc message coù ñaêng kyù cuûa ngöôøi duøng: Ngoaøi caùc message töï ñònh nghóa vaø söû duïng theo qui öôùc trong moät öùng duïng, windows cho pheùp öùng duïng ñaêng kyù message ñeå message ñoù coù theå söû duïng treân nhieàu öùng duïng khaùc nhau. Vieäc ñaêng kyù ñöôïc thöïc hieän thoâng qua haøm sau:

UINT RegisterWindowMessage (LPCSTR Chuoãi_teân_message );

Haøm traû veà soá hieäu ñaêng kyù ñöôïc cuûa message. Giaù trò naøy naèm trong ñoaïn 0×C000÷0×FFFF. Caùc öùng duïng ñang chaïy treân moät heä thoáng coù theå chia xeû message duøng rieâng vôùi ñieàu kieän chuùng phaûi thöïc hieän thao taùc ñaêng kyù cuøng moät chuoãi teân message ñeå laáy soá hieäu message. Muïc xöû lyù message cho caùc message coù ñaêng kyù cuûa ngöôøi coù daïng:

ON_REGISTERED_MESSAGE(UserRegMessageID, UserFuncName)

Sau ñaây laø moät ví duï:

// Ñaêng kyù message vôùi teân laø “MY_MESS” const UINT myMess = RegisterWindowMessage(“MY_MESS”); // Khai baùo muïc xöû lyù cho message ñöôïc ñaêng kyù BEGIN_MESSAGE_MAP ( CMyWnd, CMyBasedWndClass ) //{{AFX_MSG_MAP ( CMyWnd ) ON_REGISTERED_MESSAGE ( myMess, myFunc ) // ... //}}AFX_MSG_MAP END_MESSAGE_MAP ( )

Message WM_COMMAND: Khi WM_COMMAND ñöôïc göûi ñeán ñoái töôïng xöû lyù message thì tham soá wParam keøm theo chöùa soá hieäu (CommandID) cuûa ñoái töôïng phaùt sinh message. Muïc xöû lyù message WM_COMMAND aán ñònh xöû lyù töông öùng, vaø coù daïng nhö sau:

ON_COMMAND ( CommandID, FunctionName )

Coù theå caøi ñaët xöû lyù ñieàu khieån ñoái vôùi ñoái töôïng laøm phaùt sinh WM_COMMAND thoâng qua muïc xöû lyù ñieàu khieån message nhö sau:

ON_UPDATE_COMMAND_UI( CommandID, PreFunctionName )

PreFunctionName laø haønh vi thöïc hieän xöû lyù ñieàu khieån treân ñoái töôïng phaùt sinh WM_COMMAND, tham soá nhaän ñöôïc laø giaù trò con troû ñeán ñoái töôïng CCmdUI*. Haønh vi Enable ( BOOL isEnabled ) cuûa ñoái töôïng naøy ñöôïc duøng ñeå caám hoaëc cho pheùp hoaït ñoäng ñoái vôùi ñoái töôïng phaùt sinh WM_COMMAND. Xöû lyù cuûa haønh vi naøy coù theå laø:

54 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

void [ClassName::]PreFunctionName (CCmdUI* pCmdUI ) { pCmdUI->Enabled (FALSE ); // Caám ñoái töôïng hoaït ñoäng }

Caùc message do ñoái töôïng con (controls) göûi ñeán cöûa soå cha: Tham soá wParam chöùa soá hieäu control, giaù trò WORD cao cuûa tham soá lParam chöùa thoâng tin veà traïng thaùi control ôû thôøi ñieåm göûi message ñeán cöûa soå cha (ví duï BN_CLICKED laø moät traïng thaùi cuûa button control,…). Muïc xöû lyù message cho message göûi töø control coù daïng nhö sau:

ON_CONTROL (Traïng_thaùi_control, Soá_hieäu_Control, Haøm_xöû_lyù )

Ví duï: Ta coù ví duï minh hoïa ñònh höôùng xöû lyù message nhö sau:

* Khai baùo lôùp (teâp tin .H):

class CMyClass: public CBasedWnd { public: CMyClass(); void myProc(void); void mySerach(); void myWork(); void PremyWork(); void OnExit(void); DECLARE_MESSAGE_MAP() }

* Phaàn caøi ñaët cuûa lôùp (teâp tin .CPP):

#define MY_MESSAGE WM_USER + 1 static UINT NEAR MY_MESS = RegisterWindowMessage(“MY_MESS”); BEGIN_MESSAGE_MAP(CMyClass, CDerivedWnd) //{{AFX_MSG_MAP(CMyClass) ON_WM_PAINT() // WindowsMessage ON_MESSAGE (MY_MESSAGE, myProc) // UserMessage ON_REGISTERED_MESSAGE(MY_MESS,OnSearch) // UserRegMessage ON_COMMAND(ID_DO, myWork) // CommandMessage // Command Preprocess ON_UPDATE_COMMAND_UI(ID_DO, PremyWork) //Control IDC_EXIT ON_CONTROL(BN_CLICKED, IDC_EXIT, OnExit) //}}AFX_MSG_MAP END_MESSAGE_MAP()

Caùc muïc xöû lyù message do Classwizard quaûn lyù ñaët giöõa //{{ vaø //}}

Page 35: Mfc Tieng Viet

Xöû lyù Message 55

5.3 CAÙC LÔÙP KEÁ THÖØA CCmdTarget: Caùc lôùp ñoái töôïng cuûa MFC keá thöøa töø CCmdTarget coù chöùc naêng xöû lyù

message laø CWnd, CWinApp, CDocument. ÖÙng duïng coù theå döïa treân nhöõng lôùp naøy ñeå xaây döïng caùc lôùp keá thöøa ñaûm nhaän chöùc naêng xöû lyù message phuø hôïp vôùi yeâu caàu cuûa öùng duïng.

5.4 MESSAGE MAP CUÛA LÔÙP KEÁ THÖØA CWnd TRONG ÖÙNG DUÏNG: 5.4.1 Cöûa soå cuûa öùng duïng coù chöùc naêng hoaït ñoäng:

Trong phaàn naøy, ta thöïc hieän öùng duïng vôùi cöûa soå giao dieän chính coù tieâu ñeà chöùa noäi dung chöõ chaïy theo kieåu baûng chöõ ñieän töû.

Lôùp CWnd cuûa MFC khoâng cung caáp tieän ích naøy. Chuùng ta caàn xaây döïng lôùp cöûa soå môùi vôùi nhöõng khaû naêng phuø hôïp; coù caùc chöùc naêng nhö CWnd ñeå laøm giao dieän, ñoàng thôøi coù khaû naêng töï thay ñoåi noäi dung tieâu ñeà (caption) theo thôøi gian (timer). Lôùp cöûa soå naøy keá thöøa töø lôùp CWnd, töï caøi ñaët timer (SetTimer) khi baét ñaàu (OnCreate) hoaït ñoäng, xöû lyù thay ñoåi noäi dung tieâu ñeà ôû moãi chu kyø Timer (OnTimer) vaø huûy boû Timer (KillTimer) khi chaám döùt hoaït ñoäng (OnDestroy). Sau ñaây laø caùc böôùc thöïc hieän döï aùn:

Taïo döï aùn VD04 töông töï döï aùn VD03. Boå sung lôùp CEmpWnd (teân lôùp cöûa soå môùi) keá thöøa töø CWnd: Thöïc

hieän nhö boå sung lôùp CEmpApp trong muïc (2.7). Löu yù trong hoäp hoäi thoaïi New Class : choïn Class Type = MFC Class ; BaseClass = CWnd.

Caøi ñaët caùc haønh vi xöû lyù message caàn thieát cho lôùp CEmpWnd treân cô sôû keá thöøa töø lôùp CWnd cuûa MFC: • Haønh vi OnCreate thöïc hieän caùc aán ñònh caàn thieát cho CEmpWnd

tröôùc khi ñi vaøo hoaït ñoäng. Boå sung vaø caøi ñaët haønh vi nhö sau: - Trong maøn hình Workspace cuûa döï aùn, choïn trang ClassView. - Right-click treân tieâu ñeà cuûa lôùp CEmpWnd:

- Choïn muïc Add Windows Message Handler... :

56 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

- Choïn WM_CREATE. Sau ñoù choïn Add and Edit. - Haønh vi OnCreate vôùi tham soá thích hôïp ñöôïc boå sung vaøo lôùp

CEmpWnd, ñoàng thôøi muïc xöû lyù ON_WM_CREATE() ñöôïc ñaët vaøo baûng MessageMap. Caøi ñaët noäi dung cuûa OnCreate nhö sau:

int CEmpWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CWnd::OnCreate(lpCreateStruct) == -1) return -1; // Ñaët timer soá hieäu 100, chu kyø 250 ms SetTimer(100, 250, NULL);

return 0; }

• Haønh vi OnTimer xöû lyù WM_TIMER, cho pheùp xöû lyù yeâu caàu ôû moãi chu kyø cuûa timer. Vieäc boå sung haønh vi naøy ñöôïc thöïc hieän töông töï OnCreate. Noäi dung caøi ñaët cuûa haønh vi nhö sau: void CEmpWnd::OnTimer( UINT nIDEvent ) {

Page 36: Mfc Tieng Viet

Xöû lyù Message 57

if (nIDEvent == 100) { // Timer do chuùng ta caøi ñaët char s[200], ch; GetWindowText(s, 200); // Laáy tieâu ñeà cöûa soå ch = s[0]; for (UINT i=0; i<strlen(s)-1; i++) s[i] = s[i+1]; // Dòch noäi dung chuoãi s[i] = ch; SetWindowText(s); // Ñaët tieâu ñeà cöûa soå } CWnd::OnTimer(nIDEvent); // Thöïc hieän haønh vi lôùp cô sôû }

• Haønh vi OnDestroy xöû lyù WM_DESTROY: void CEmpWnd::OnDestroy() { KillTimer (100 ); // Soá hieäu timer (TimerID) CWnd::OnDestroy(); // Goïi haønh vi lôùp cô sôû. }

Duøng lôùp CEmpWnd cho ñoái töôïng cöûa soå chính cuûa öùng duïng: Môû haønh vi InitInstance cuûa CEmpApp, thöïc hieän caùc chænh söûa sau: • Thöïc hieän chæ thò sau ôû ñaàu taäp tin chöông trình:

#include "EmpWnd.h" // Taäp tin khai baùo cuûa lôùp CEmpWnd • Duøng CEmpWnd laøm kieåu cho bieán con troû ñoái töôïng main.

Bieân dòch döï aùn vaø chaïy thöû öùng duïng.

Löu yù: Döï aùn VD04 söû duïng 100 laøm soá hieäu timer. Vieäc söû duïng giaù trò haèng nhö theá khoâng gôïi nhôù vaø keùm linh hoaït trong söû duïng. Ta neân khai baùo moät teân rieâng cho haèng ñeå traùnh caùc haïn cheá treân. Caùch thöïc hieän nhö sau:

Choïn trang ResourceView trong maøn hình Workspace. Right-click treân project resources:

Choïn Resource Symbols...:

58 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

Ta nhaän ñöôïc hoäp hoäi thoaïi Resource Symbols chöùa danh saùch caùc giaù trò ñaõ khai baùo. Coù theå thöïc hieän theâm, xoùa caùc giaù trò khai baùo naøy.

Choïn muïc New:

Nhaäp teân cuûa giaù trò khai baùo trong hoäp Name, nhaäp giaù trò khai baùo

trong hoäp Value. Sau ñoù choïn OK Ñoùng hoäp hoäi thoaïi Resource Symbol ñeå keát thuùc.

Thoâng tin khai baùo löu trong taäp tin resource.h cuûa döï aùn. Khi ñoù, trong chöông trình, thay vì vieát giaù trò haèng cuï theå cho soá hieäu cuûa Timer (chaúng haïn 100), ta söû duïng teân khai baùo cuûa noù (theo ví duï laø ID_TIMER).

5.4.2 WM_PAINT vaø haønh vi OnPaint cuûa CWnd: Ñeå duy trì thoâng tin hieån thò treân beà maët cöûa soå, heä thoáng thöôøng xuyeân

gôûi WM_PAINT ñeán cho cöûa soå moãi khi coù hieän töôïng xaâm phaïm ñeán noäi dung hieån thò cuûa noù. ÖÙng duïng cuõng coù theå kích hoaït heä thoáng phaùt sinh message naøy thoâng qua moät trong caùc haønh vi sau:

Page 37: Mfc Tieng Viet

Xöû lyù Message 59

void Invalidate(BOOL bErase = TRUE ); Yeâu caàu caäp nhaät toaøn boä vuøng client cuûa cöûa soå. Neáu tham soá bErase = FALSE thì heä thoáng seõ khoâng töï ñoäng xoùa hoä phaàn noäi dung cuõ trong cöûa soå.

void InvalidateRect ( LPCRECT lpRect, // Con troû ñeán bieán kieåu RECT chöùa // thoâng tin vuøng ñöôïc caäp nhaät BOOL bErase = TRUE // Coù yù nghóa nhö Invalidate () ); Yeâu caàu caäp nhaät moät vuøng giôùi haïn trong client cuûa cöûa soå.

Haønh vi OnPaint cuûa CWnd duøng xöû lyù WM_PAINT. Vieäc söû duïng haønh vi naøy trong caùc lôùp keá thöøa CWnd nhaèm thöïc hieän caùc trang trí rieâng theo boá cuïc ôû muïc OnPaint trong (4.2). Toaøn boä thao taùc xöû lyù naøy ñöôïc MFC thöïc hieän thoâng qua lôùp CPaintDC nhö sau: CPaintDC dc(this); // Device context ñeå veõ leân ... // Thöïc hieän caùc taùc vuï veõ treân dc

THÖÏC HAØNH: 1. Töông töï VD04. Khi ngöôøi duøng keát thuùc öùng duïng, chöông trình hieån thò hoäp thoâng baùo "Are you sure to exit this program ?" vôùi hai muïc YES-NO. Neáu ngöôøi duøng choïn YES thì keát thuùc: HD: Caøi ñaët haønh vi OnClose xöû lyù message WM_CLOSE cho CEmpWnd. Duøng haønh vi MessageBox cuûa CWnd ñeå hieån thò caâu thoâng baùo. Neáu ngöôøi duøng ñoàng yù thì thöïc hieän haønh vi OnClose cuûa CWnd ñeå keát thuùc, ngöôïc laïi khoâng thöïc hieän xöû lyù gì caû (xem VD05) 2. Töông töï VD04 vôùi phaàn demo laø aûnh vieân bi chaïy trong client cuûa cöûa soå. HD: Duøng timer ñeå lieân tuïc phaùt WM_PAINT baèng haønh vi Invalidate theo moãi chu kyø. Haønh vi OnPaint thöïc hieän veõ vaøo vuøng client cuûa cöûa soå chính moät doøng chöõ coù noäi dung chaïy kieåu baûng chöõ ñieän töû. (xem VD06). 3. Thöïc hieän öùng duïng cho pheùp hieån thò moät vaät theå coù hình daïng baát kyø trong vuøng client. Caùc phím ← , ↑ , → , ↓ cho pheùp dòch chuyeån vaät theå naøy. HD: Nhö baøi taäp 2 nhöng khoâng söû duïng timer. Duøng haønh vi OnKeyDown xöû lyù message WM_KEYDOWN. Haønh vi naøy kieåm tra giaù trò phím nhaän ñöôïc nChar vôùi caùc giaù trò haèng phím VK_LEFT (phím ←), VK_UP (phím ↑), VK_RIGHT (phím →), VK_DOWN (phím ↓) ñeå thay ñoåi toïa ñoä vaät theå cho phuø hôïp. Sau cuøng phaùt sinh message WM_PAINT ñeå veõ laïi vaät theå.

Page 38: Mfc Tieng Viet

60 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

CHÖÔNG 6:

ÖÙÙng duïng coâng cuï GDI 6.1 DC VAØ BITMAP:

Vaán ñeà trang trí thieát bò ñoà hoïa ñöôïc tieán haønh thoâng qua ñoái töôïng DC quaûn lyù thieát bò, treân cô sôû khai thaùc chöùc naêng caùc coâng cuï GDI lieân quan. Keát quaû trang trí treân DC ñöôïc quaûn lyù bôûi ñoái töôïng Bitmap maø DC ñang söû duïng. Bitmap laø coâng cuï laøm neàn khoâng theå thieáu cho caùc DC.

Vieäc khôûi taïo noäi dung cho ñoái töôïng bitmap trong öùng duïng coù theå ñöôïc thöïc hieän baèng caùch laáy aûnh bitmap töø resource (LoadBitmap) hay taïo môùi noäi dung cho bitmap döïa treân moät DC xaùc ñònh (CreateCompatibleBitmap).

Thoâng thöôøng, öùng duïng ñoà hoïa phaûi chuaån bò saün caùc aûnh caàn thieát trong resource cuûa öùng duïng. ÔÛ phaàn xöû lyù, caùc resource naøy ñöôïc taûi vaøo boä nhôù laøm noäi dung cho caùc ñoái töôïng bitmap. Töø caùc ñoái töôïng bitmap naøy, aûnh seõ ñöôïc veõ leân caùc thieát bò hieån thò ñoà hoïa thoâng qua ñoái töôïng DC töông öùng.

6.2 ÖÙNG DUÏNG VÔÙI CÖÛA SOÅ CHÍNH HIEÅN THÒ AÛNH: Trong phaàn naøy ta thöïc hieän öùng duïng coù chöùc naêng hieån thò moät aûnh xaùc

ñònh trong vuøng client cuûa cöûa soå chính. Caùc böôùc tieán haønh döï aùn nhö sau: Taïo döï aùn VD07 töông töï döï aùn VD06. Taïo moät aûnh bitmap trong resource vôùi soá hieäu laø IDB_MYPICT: Noäi

dung aûnh naøy coù theå ñöôïc taïo môùi hoaøn toaøn hoaëc laáy töø noäi dung cuûa moät taäp tin bitmap (.bmp) ñaõ coù. Choïn moät trong hai caùch sau: • Caùch 1 – aûnh bitmap ñöôïc taïo môùi: Töông töï taïo môùi icon (2.8). • Caùch 2 – aûnh bitmap ñöôïc laáy töø noäi dung taäp tin bitmap (.bmp):

- Choïn trang ResourceView trong maøn hình Workspace. - Right-click treân Project Resource:

- Choïn Insert:

ÖÙng duïng coâng cuï GDI 61

- Choïn Bitmap, Import. Sau ñoù choïn taäp tin chöùa aûnh bitmap thoâng

qua hoäp hoäi thoaïi File-Folder. - AÁn ñònh caùc thoâng soá cuûa bitmap (soá hieäu laø IDB_MYPICT).

Boå sung ñoái töôïng thuoäc tính m_myPict kieåu CBitmap cho CEmpWnd: - Choïn trang ClassView trong maøn hình Workspace cuûa döï aùn. - Right-click treân tieâu ñeà cuûa lôùp CEmpWnd:

- Choïn Add Member Variable… :

- Nhaäp caùc thoâng tin veà kieåu, teân vaø loaïi cuûa thuoäc tính. Choïn OK.

Duøng haønh vi OnCreate cuûa CEmpWnd ñeå laáy aûnh bitmap töø resource laøm noäi dung cuûa m_myPict. Xöû lyù ñöôïc caøi ñaët nhö sau:

Page 39: Mfc Tieng Viet

62 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

int CEmpWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CWnd::OnCreate(lpCreateStruct) == -1) return -1;

// Khôûi ñoäng bitmap töø bitmap resource IDB_MYPICT

mypict.LoadBitmap( IDB_MYPICT );

return 0; }

Duøng haønh vi OnPaint cuûa CEmpWnd, veõ aûnh bitmap trong m_myPict thoâng qua haønh vi DrawState cuûa ñoái töôïng CPaintDC dc. void CEmpWnd::OnPaint() { CPaintDC dc(this); RECT rect; GetClientRect( &rect ); // Kích thöôùc vuøng client // draw on client dc.DrawState ( CPoint(0,0), /* Goùc traùi treân cuûa aûnh */ CSize (rect.right-rect.left, rect.bottom-rect.top), &m_myPict, DST_BITMAP); }

Haønh vi OnDestroy cuûa CEmpWnd giaûi phoùng ñoái töôïng m_myPict.

void CEmpWnd::OnDestroy() { CWnd::OnDestroy(); m_myPict.DeleteObject(); }

Löu yù: Ñeå xöû lyù trang trí ñoà hoïa trong vuøng client cuûa cöûa soå giao dieän khoâng gaây ra hieän töôïng "chôùp", ta coù theå söû duïng moät soá giaûi phaùp sau: - Khoâng söû duïng ñoái töôïng brush cho cöûa soå lieân quan: Duøng giaù trò NULL

cho tham soá naøy trong haønh vi khôûi taïo thoâng soá cuûa ñoái töôïng cöûa soå. - Duøng tham soá FALSE cho yeâu caàu caäp nhaät vuøng client cuûa cöûa soå (5.4.2) - Duøng moät DC trong boä nhôù laøm coâng cuï trang trí trung gian. Thöïc hieän caùc

noäi dung trang trí caàn thieát leân DC naøy. Sau khi hoaøn taát caùc taùc vuï trang trí caàn thieát thì chuyeån noäi dung DC coâng cuï leân DC cuûa maøn hình.

6.3 SAO CHEÙP AÛNH TÖØ DC VAØO DC, PHOÙNG TO & THU NHOÛ AÛNH:

ÖÙng duïng coâng cuï GDI 63

Ñoái töôïng DC cho pheùp sao cheùp laïi noäi dung trang trí ñoà hoïa treân thieát bò hieån thò ñoà hoïa ñöôïc quaûn lyù bôûi moät ñoái töôïng DC khaùc leân thieát bò hieån thò ñoà hoïa ñöôïc quaûn lyù bôûi chính noù thoâng qua moät soá haønh vi sau:

- BitBlt : Sao cheùp vaø giöõ nguyeân tyû leä trong noäi dung aûnh. - StretchBlt : Sao cheùp vaø thay ñoåi tyû leä trong noäi dung aûnh.

Trong phaàn naøy ta xaây döïng öùng duïng coù caùc ñaëc ñieåm sau: - Cöûa soå chính cuûa öùng duïng coù theå thay ñoåi kích thöôùc. - Noäi dung aûnh hieån thò trong vuøng client cuûa cöûa soå töï ñoäng thay ñoåi

kích thöôùc moät caùch phuø hôïp khi kích thöôùc cöûa soå thay ñoåi. Vieäc thöïc hieän caàn löu yù caùc böôùc sau:

- Cöûa soå chính cuûa öùng duïng coù thuoäc tính WS_THICKFRAME. - Duøng moät DC aûo ñeå loàng aûnh bitmap thoâng qua ñoái töôïng CBitmap. Veõ

aûnh bitmap töø DC naøy leân DC hieån thò. Caùc böôùc thöïc hieän nhö sau:

Taïo döï aùn VD08 töông töï döï aùn VD07. Haønh vi OnPaint cuûa CEmpWnd söû duïng DC trong boä nhôù ñeå loàng aûnh

bitmap, töø ñoù veõ leân vuøng client cuûa cöûa soå. Xöû lyù caøi ñaët nhö sau: void CEmpWnd::OnPaint() { CPaintDC dc(this); RECT rt; CDC memDC; CBitmap *oldBmp; BITMAP bmpInfo; GetClientRect(&rect); // Kích thöôùc vuøng client mypict.GetBitmap(&bmpInfo); // Laáy thoâng tin cuûa aûnh bitmap memDC.CreateCompatibleDC(&dc); // Loàng bitmap m_myPict vaøo memDC vaø löu laïi bitmap cuõ cuûa noù. oldBmp = memDC.SelectObject(&m_myPict); // Cheùp aûnh töø memDC leân DC quaûn lyù vuøng client cuûa cöûa soå: dc dc.StretchBlt( 0, 0, rt.right-rt.left, rt.bottom-rt.top, &memDC, 0, 0, bmpInfo.bmWidth, bmpInfo.bmHeight, SRCCOPY); // Phuïc hoài aûnh bitmap cuõ cuûa memDC memDC.SelectObject(oldBmp); memDC.DeleteDC(); } // Xem VD08

6.4 DC TRONG BOÄ NHÔÙ (DC AÛO) - VUØNG VEÕ ÑEÄM LYÙ TÖÔÛNG:

Page 40: Mfc Tieng Viet

64 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

Neáu vieäc trang trí goàm nhieàu thao taùc phöùc taïp thì neân thöïc hieän chuùng treân DC aûo, sau ñoù chuyeån keát quaû ra DC hieån thò. Chæ moät laàn duy nhaát cho moãi noäi dung trang trí, nhö theá seõ caûi thieän ñaùng keå chaát löôïng ñoà hoïa.

ÖÙng vôùi moãi DC aûo taïo ra trong boä nhôù, ngoaøi ñoái töôïng CDC quaûn lyù, ta caàn söï phoái hôïp cuûa ñoái töôïng bitmap laøm neàn thay theá ñoái töôïng bitmap töôïng tröng khoâng söû duïng ñöôïc maø heä thoáng gaùn cho DC khi taïo laäp. Boá cuïc xöû lyù cuûa haønh vi OnPaint coù söû duïng ñoái töôïng DC aûo nhö sau:

CClientDC dc(this); // Ñoái töôïng DC hieån thò RECT rect; CDC memDrawDC; // Ñoái töôïng DC aûo ñeå veõ trung gian CBitmap memDrawBmp; CBitmap *memDrawOldBmp; GetClientRect ( &rt ); int CX = rect.right–rect.left ; int CY = rect.bottom–rect.top; memDrawBmp.CreateCompatibleBitmap( &dc, CX, CY ); memDrawDC.CreateCompatibleDC( &dc ); memDrawOldBmp = memDrawDC.SelectObject( &memDrawBmp );

... // Trang trí memDrawDC

// Chuyeån noäi dung DC aûo sang dc: dc.StretchBlt ( 0, 0, CX,CY, &memDrawDC, CX,CY, SRCCOPY ); // Huûy boû caùc ñoái töôïng GDI: memDrawDC.SelectObject(&memDrawOldBmp); memDrawBmp.DeleteObject(); memDrawDC.DeleteDC();

Phaàn tieáp theo ta thöïc hieän öùng duïng töông töï VD08, ñoàng thôøi taïo doøng chöõ chaïy theo kieåu baûng chöõ ñieän töû trong vuøng client cuûa cöûa soå chính. Taïo döï aùn VD09 töông töï döï aùn VD08. Xöû lyù Trang trí memDrawDC trong OnPaint cuûa CEmpWnd nhö sau:

BITMAP bmpInfo; m_myPict.GetBitmap( &bmpInfo ); memDrawDC.StretchBlt( 0, 0, CX, CY, &memDC, 0, 0, bmpInfo.bmWidth, bmpInfo.bmHeight, SRCCOPY ); memDrawDC.SetTextColor( RGB(255,0,0) ); // text color memDrawDC.SetBkMode( TRANSPARENT ); // transparent memDrawDC.TextOut( 30, 100, Chuoãi, I );

Xem VD09.

ÖÙng duïng coâng cuï GDI 65

Vôùi caùc ñoái töôïng GDI ñöôïc söû duïng thöôøng xuyeân thì vieäc laëp ñi laëp laïi caùc thao taùc taïo vaø huûy boû chuùng trong caùc haønh vi trang trí cuûa CEmpWnd seõ laøm laõng phí taøi nguyeân cuûa heä thoáng. Neân chuyeån taát caû caùc thao taùc ñoù veà hai haønh vi OnCreate vaø OnDestroy cuûa CEmpWnd moät caùch phuø hôïp.

Baïn haõy thöû aùp duïng ñieàu löu yù naøy cho VD09.

6.5 AÛNH CHUYEÅN ÑOÄNG TRONG VUØNG CLIENT: Ñöôïc thöïc hieän moät caùch ñôn giaûn baèng kyõ thuaät hoaït hình. Ta chuaån bò

moät soá aûnh cô baûn cuûa chuoãi hoaït ñoäng ñoù, sau ñoù thöïc hieän hieån thò vaø traùo aûnh theo trình töï vôùi khoaûng thôøi gian chôø hôïp lyù. Caùc aûnh trong noäi dung hoaït hình ñöôïc quaûn lyù bôûi coâng cuï GDI thích hôïp:

CBitmap: Moãi bitmap quaûn lyù ñöôïc moät aûnh. Ta duøng nhieàu bitmap. AÛnh veõ baèng haønh vi DrawState cuûa ñoái töôïng DC quaûn lyù thieát bò hieån thò. Kích thöôùc aûnh hieån thò khoâng thay ñoåi.

CDC: Loàng taát caû caùc aûnh vaøo moät DC. Töø DC naøy ta coù theå cheùp baát kyø phaàn aûnh caàn veõ naøo sang DC hieån thò. Coù theå thay ñoåi kích thöôùc aûnh tuøy yù: StretchBlt.

CImageList: Lôùp ñoái töôïng quaûn lyù taäp hôïp nhieàu aûnh coù cuøng kích thöôùc. Khaû naêng thao taùc treân danh saùch aûnh cuûa CImageList laø raát toát.

Trong phaàn naøy ta xaây döïng öùng duïng vôùi hình aûnh chuù böôùm bay trong vuøng client cuûa cöûa soå. Taäp tin butterfly.bmp trong thö muïc BMP chöùa caùc aûnh chuyeån ñoäng cuûa böôùm. Ta duøng caùch thöù 2, loàng caùc aûnh vaøo DC vaø veõ leân DC hieån thò. Caùc böôùc thöïc hieän döï aùn nhö sau: Taïo döï aùn VD10 töông töï döï aùn VD09. Boå sung bitmap resource vôùi soá hieäu IDB_ANIMATION maø noäi dung

ñöôïc laáy töø taäp tin chöùa caùc aûnh hoaït hình. Ghi nhôù soá aûnh trong bitmap ñoù. Chaúng haïn, choïn taäp tin butterfly.bmp trong thö muïc BMP. Taäp tin naøy coù 4 aûnh, kích thöôùc 32x28.

Boå sung caùc ñoái töôïng thuoäc tính protected cho lôùp CEmpWnd: - m_butterDC : Ñoái töôïng CDC, quaûn lyù DC loàng aûnh. - m_butterBmp : Ñoái töôïng CBitmap, quaûn lyù caùc aûnh hoaït hình. - m_butterOldBmp : Ñoái töôïng CBitmap*, quaûn lyù con troû chæ ñeán

ñoái töôïng bitmap cuõ cuûa m_butterDC. - m_pictNo : Kieåu int, quaûn lyù soá thöù töï cuûa hình ñang ñöôïc

hieån thò trong caùc aûnh hoaït hình noùi treân. Haønh vi OnCreate cuûa CEmpWnd thöïc hieän caùc chuaån bò:

int CEmpWnd::OnCreate( LPCREATESTRUCT lpCreateStruct )

Page 41: Mfc Tieng Viet

66 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

{ if (CWnd::OnCreate(lpCreateStruct) == -1) return -1;

// TODO: Add your specialized creation code here SetTimer( IDD_TIMER, 250, NULL ); m_myPict.LoadBitmap( IDB_MYPICT );

// Animation objects by EX10 m_butterBmp.LoadBitmap( IDB_ANIMATION ); m_butterDC.CreateCompatibleDC( NULL ); m_butterOldBmp = butterDC.SelectObject( &m_butterBmp ); m_pictNo = 0; return 0; }

Haønh vi OnPaint veõ hình vaø töï taêng vò trí choïn hình cho laàn veõ sau ñoù:

memDrawDC.StretchBlt( 20, 50, 32, 28, &m_butterDC, m_pictNo*32 , 0 , 32 , 28 , SRCCOPY ); m_pictNo++; // Choïn aûnh keá tieáp if (m_pictNo >= 4) m_pictNo = 0;

Haønh vi OnDestroy huûy boû caùc thuoäc tính GDI:

m_butterDC.SelectObject(m_butterOldBmp); m_butterBmp.DeleteObject(); m_butterDC.DeleteDC();

Nhaän xeùt: Phaàn neàn cuûa aûnh hoaït hình che khuaát aûnh neàn. Ñeå khaéc phuïc ta söû duïng moät aûnh bitmap laøm maët naï cho aûnh hoaït hình ñeå aán ñònh phaàn noäi dung ñöôïc veõ treân aûnh hoaït hình.

Haønh vi MaskBlt cuûa CDC cho pheùp duøng monochrome bitmap laøm löôùi loïc aûnh ñieåm phaàn noåi cuûa aûnh khi cheùp aûnh töø DC nguoàn leân DC ñích (95/98/Me unsupported). Baïn haõy thöû thöïc hieän vôùi VD10 nhö baøi taäp.

6.6 CImageList - COÂNG CUÏ QUAÛN LYÙ BOÄ AÛNH CUØNG CÔÕ: Xaây döïng döï aùn VD11 treân cô sôû caûi tieán VD10; boä aûnh hoaït hình seõ ñöôïc

quaûn lyù bôûi ñoái töôïng CImageList:

Taïo döï aùn VD11 töông töï döï aùn VD10. Boå sung ñoái töôïng thuoäc tính m_butterImg kieåu CImageList laøm nhieäm

vuï quaûn lyù caùc aûnh. Xoùa caùc thuoäc tính m_butterBmp, m_butterDC vaø m_butterOldBmp vì khoâng coøn caàn thieát.

ÖÙng duïng coâng cuï GDI 67

Haønh vi OnCreate cuûa CEmpWnd thöïc hieän caùc chuaån bò nhö sau:

int CEmpWnd::OnCreate( LPCREATESTRUCT lpCreateStruct ) { if (CWnd::OnCreate(lpCreateStruct) == -1) return -1;

// TODO: Add your specialized creation code here SetTimer(IDD_TIMER, 250, NULL); m_mypict.LoadBitmap(IDB_MYPICT);

// animation object by EX10 m_butterImg.Create(IDB_ANIMATION,32,4,RGB(255,255,255)); m_pictNo = 0; return 0; }

Haønh vi OnPaint söû duïng haønh vi Draw cuûa m_butterImg veõ aûnh:

m_butterImg.Draw( &memDrawDC, m_pictNo, CPoint(30, 170), ILD_NORMAL); m_pictNo++; if (m_pictNo >= 4) m_pictNo = 0;

Haønh vi OnDestroy huûy boû ñoái töôïng CImageList:

m_butterImg.DeleteImageList();

6.7 CRgn – CÖÛA SOÅ COÙ HÌNH DAÏNG TUØY YÙ: Khuoân daïng cuûa region coù theå duøng laøm khuoân daïng cuûa cöûa soå thoâng qua

haønh vi SetWindowRgn cuûa ñoái töôïng cöûa soå. Phaàn sau ñaây minh hoïa cho vaán ñeà treân vaø ñöôïc caøi ñaët trong haønh vi OnCreate cuûa cöûa soå (VD12).

CRgn newShape; newShape.CreateEllipticRgn( 0, 0, 200, 100 ); SetWindowRgn( newShape, TRUE );

THÖÏC HAØNH: 1. Vieát öùng duïng vôùi cöûa soå giao dieän chính coù hình tam giaùc. 2. Vieát öùng duïng vôùi cöûa soå giao dieän chính coù hình ngoâi sao naêm caùnh. 3. Vieát öùng duïng hieån thò noäi dung cuûa nhieàu aûnh theo thöù töï luaân phieân. Söï chuyeån tieáp giöõa hai aûnh baát kyø ñöôïc thöïc hieän baèng kyõ thuaät pha troän aûnh. 4. Vieát öùng duïng hieån thò aûnh cuoän (scroll) töø traùi sang phaûi.

Page 42: Mfc Tieng Viet

68 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

5. Vieát öùng duïng hieån thò aûnh zoom töø beù ñeán lôùn vaø ngöôïc laïi. 6. Vieát öùng duïng hieån thò moät doøng chöõ baát kyø theo hình aûnh cuoän (scroll). 7. Vieát öùng duïng vôùi hình aûnh chuù böôùm bay thô thaån trong vuøng client. 8. Vieát öùng duïng ScreenSaver vaø söû duïng noù cho maùy tính cuûa baïn. 9. Vieát öùng duïng vôùi maøn hình chính chöùa caùc doøng chöõ troâi töø ñaùy leân ñænh maøn hình, lieân tuïc ñeán khi keát thuùc öùng duïng. HD: Taïo DC aûo vaø vieát caùc doøng chöõ leân DC naøy. Sau ñoù cheùp phaàn noäi dung thích hôïp cuûa DC aûo sang DC thöïc.

- Chieàu roäng DC aûo baèng chieàu roäng DC thöïc. Chieàu cao DC aûo baèng chieàu cao DC thöïc + 2 laàn chieàu cao moät doøng chöõ treân DC.

- Vieát caùc doøng chöõ hôïp leä (toïa ñoä hieån thò naèm trong giôùi haïn DC aûo) leân DC aûo. Sau moãi laàn hieån thò, tònh tieán vò trí veõ leân phía treân moät ñoaïn tuøy yù, neáu vò trí tònh tieán laøm taát caû caùc doøng chöõ rôi ra ngoaøi DC aûo thì aán ñònh laïi vò trí aáy ôû cuoái DC aûo.

10. Chænh söûa baøi taäp 9 nhö sau: - Hieån thò caùc doøng chöõ vôùi ñoä saùng giaûm daàn töø doøng döôùi leân doøng treân

ñeå taïo hieäu öùng 3 chieàu. - Taùc vuï cheùp söû duïng haøm StretchBlt treân töøng doøng pixel ñeå aûnh xaï

aûnh chöõ nhaät töø DC aûo thaønh aûnh tam giaùc caân treân DC thöïc. Keát quaû nhaän ñöôïc laø hình aûnh troâi caùc doøng chöõ theo chieàu thöù 3.

11. Vieát öùng duïng vôùi maøn hình chính hieån thò "thieân thaïch vuõ truï". HD: Moãi ‘thieân thaïch’ ñöôïc quaûn lyù baèng toïa ñoä 3 giaù trò (x, y, z).

- Toïa ñoä z tieán daàn veà phía ngöôøi duøng sau moãi laàn hieån thò. - Toïa ñoä x, y töông öùng thay ñoåi theo z:

x = Hoaønh ñoä taâm vuøng Client + x * 100 / z; y = Tung ñoä taâm vuøng Client + y * 100 / z;

- Ñoä saùng phuï thuoäc vaøo z. - Duøng haønh vi Circle cuûa DC ñeå veõ caùc ‘thieân thaïch’.

12. Keát hôïp hai baøi taäp 10 vaø 11 ñeå coù moät öùng duïng vôùi maøn hình chính nhö maøn hình StarWar. 13. Duøng lôùp ñoái tuôïng CTime cuûa MFC ñeå laáy giôø hieän haønh cuûa heä thoáng. Thöïc hieän öùng duïng hieån thò moät chieác ñoàng hoà analog (ñoàng hoà kim) chaïy theo thôøi gian.

Page 43: Mfc Tieng Viet

Menu & Phím taét 69

CHÖÔNG 7:

MENU & PHÍM TAÉT 7.1 ÑÒNH NGHÓA:

Menu laø heä thoáng caùc muïc choïn töông öùng vôùi caùc xöû lyù xaùc ñònh. Thoâng qua menu, ngöôøi duøng coù theå deã daøng aán ñònh thöïc hieän xöû lyù mong muoán.

Xem moät öùng duïng vôùi heä thoáng menu nhö sau:

- Game vaø Exit laø caùc muïc choïn cuûa menu bar. - Muïc choïn Game gaén vôùi moät menu popup coù ba muïc choïn: Start,

Option, About vaø daáu ngaên caùch muïc (separator).

7.2 MENU RESOURCE: Ñeå tieän vieäc söû duïng vaø chænh söûa menu trong chöông trình, VC cho pheùp

soaïn thaûo vaø löu caáu truùc menu vaøo resource cuûa öùng duïng moät caùch ñoäc laäp, phaàn chöông trình seõ duøng caùc leänh caàn thieát ñeå naïp vaø söû duïng menu. Caùch taïo menu trong resource:

Taïo môùi menu resource: Thöïc hieän töông töï vieäc taïo môùi icon (2.8). Löu yù: Choïn Resource Type laø Menu.

Ñaët soá hieäu cho menu (ví duï IDR_MAINFRAME vôùi menu chính). Thieát keá menu thoâng qua maøn hình thieát keá maø ta vöøa nhaän ñöôïc töø

böôùc treân. Caùc thao taùc cô baûn nhö sau: • Caøi ñaët muïc popup: Double-click (hoaëc goõ phím

Enter) treân vò trí döï ñònh caøi ñaët muïc popup: Ta nhaän ñöôïc hoäp hoäi thoaïi Menu Item Properties:

70 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

- Caption: Noäi dung thoâng baùo. & duøng ñaët tröôùc kyù töï phím taét. - Ñaùnh daáu choïn muïc Pop-up. Cuoái cuøng, goõ Enter keát thuùc.

• Caøi ñaët muïc leänh: Thöïc hieän töông töï nhö treân nhöng phaàn aán ñònh trong hoäp Menu Item Properties nhö sau:

- Prompt: Noäi dung giaûi thích (ñöôïc hieån thò treân StatusBar) vaø noäi

dung giaûi thích vaén taét (Tiptext treân thanh coâng cuï). Giöõa hai noäi dung naøy ñöôïc ngaên caùch baèng kyù töï \n.

- ID: Soá hieäu cuûa muïc choïn (menu-ID). Neân ñaët teân gôïi nhôù. • Caøi ñaët daáu ngaên caùch: Thöïc hieän töông töï nhö treân. Ñaùnh daáu choïn

Separator trong hoäp Menu Item Properties. • Cheøn muïc vaøo giöõa caùc muïc choïn ñaõ coù: Ñöa veät saùng ñeán vò trí

cheøn, sau ñoù nhaán phím Insert. • Xoùa muïc caøi ñaët: Ñöa veät saùng ñeán vò trí xoùa, goõ phím Delete.

Taïo môùi döï aùn VD13 nhö VD12, sau ñoù thieát keá menu resource vôùi soá hieäu IDR_MAINFRAME. Soá hieäu caùc muïc choïn laàn löôït laø:

- Start = ID_GAME_START - Option = ID_GAME_OPTION - About = ID_GAME_ABOUT - Exit = ID_EXIT

Page 44: Mfc Tieng Viet

Menu & Phím taét 71

7.3 SÖÛ DUÏNG MENU RESOURCE: Menu resource laø cô sôû khôûi taïo heä thoáng menu duøng trong öùng duïng. Heä

thoáng menu coù theå ñöôïc gaén vaøo cöûa soå giao dieän ñeå tieän söû duïng. Quaù trình naøy ñöôïc thöïc hieän thoâng qua caùc böôùc sau:

Naïp menu resource vaøo boä nhôù: HMENU LoadMenu ( HINSTANCE hInstance, // Handle cuûa öùng duïng LPCTSTR lpMenuName // Chuoãi teân resource cuûa menu ); Haøm traû veà handle cuûa menu trong boä nhôù. - Giaù trò handle cuûa öùng duïng nhaän ñöôïc töø haøm sau: HINSTANCE AfxGetInstanceHandle( ); - Moãi ñoái töôïng trong resource ñöôïc nhaän dieän baèng moät soá hieäu hoaëc

chuoãi teân. Haøm sau ñaây giuùp chuyeån soá hieäu cuûa ñoái töôïng resource sang chuoãi teân töông öùng:

LPTSTR MAKEINTRESOURCE( UINT resourceID ); Gaén menu vôùi cöûa soå giao dieän: Duøng handle cuûa menu laøm tham soá

cho haønh vi khôûi taïo thoâng soá CreateEx cuûa ñoái töôïng cöûa soå. Haønh vi InitInstance cuûa ñoái töôïng quaûn lyù öùng duïng ñaûm nhaän vieäc naøy:

BOOL CEmpApp::InitInstance() { CEmpWnd *main = new CEmpWnd; HICON myIcon = LoadIcon(IDR_MAINFRAME); HCURSOR myCursor = LoadCursor(IDC_MAINFRAME); CBrush myBrush; CString myClassName = "Emp.WndClassName"; myBrush.CreateSolidBrush(RGB(190, 190, 0)); m_pMainWnd = main; main->CreateEx( WS_EX_TOPMOST, AfxRegisterWndClass( CS_VREDRAW | CS_HREDRAW, myCursor, myBrush, myIcon ), _T("Emp.Example 13"), WS_SYSMENU | WS_VISIBLE | WS_MINIMIZEBOX | WS_THICKFRAME, 100, 100, 300, 200, NULL, LoadMenu( AfxGetInstanceHandle(), MAKEINTRESOURCE( IDR_MAINFRAME )) ); main->ShowWindow(SW_SHOW); return TRUE; } // Xem VD13 (heä thoáng menu chöa coù xöû lyù)

72 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

7.4 MUÏC XÖÛ LYÙ COMMAND MESSAGE TÖØ MUÏC CHOÏN CUÛA MENU: Ñeå muïc choïn cuûa menu coù yù nghóa söû duïng ta phaûi caøi xöû lyù cho chuùng. Khi ngöôøi duøng choïn moät muïc treân menu, heä thoáng laäp töùc göûi

WM_COMMAND ñeán öùng duïng vôùi tham soá wParam chöùa soá hieäu (ID) cuûa muïc menu ñöôïc choïn. Baát cöù ñoái töôïng naøo trong öùng duïng coù chöùc naêng xöû lyù mesage ñeàu coù theå ñaûm nhaän vieäc xöû lyù caùc message naøy.

Tieáp theo, ta xaây döïng öùng duïng vôùi heä thoáng menu nhö VD13. Muïc choïn About hieån thò hoäp thoâng baùo giôùi thieäu taùc giaû vaø saûn phaåm.

Taïo döï aùn VD14 nhö VD13. Duøng lôùp CEmpWnd caøi ñaët

muïc xöû lyù message: - Trong maøn hình Workspace,

choïn ClassView. Right-click treân tieâu ñeà lôùp CEmpWnd:

- Choïn Add Windows Message Handler...

- Choïn soá hieäu ID_GAME_ABOUT, click choïn COMMAND. Sau ñoù choïn muïc Add and Edit.

Page 45: Mfc Tieng Viet

Menu & Phím taét 73

- Ñaët teân haønh vi xöû lyù message WM_COMMAND. Choïn OK. - Noäi dung caøi ñaët cuûa haønh vi naøy nhö sau:

void CEmpWnd::OnGameAbout() { MessageBox( "The program was written by Mr.EMP\n" "This product is a not-licensed one.", "About", MB_OK | MB_ICONINFORMATION ); }

Xem baûng MessageMap cuûa lôùp CEmpWnd, muïc ID_GAME_ABOUT ?

7.5 PHÍM TAÉT (HOT KEY) CHO MUÏC CHOÏN TREÂN MENU: Phím taét laø toå hôïp phím cho pheùp thöïc hieän nhanh moät muïc choïn xaùc ñònh

treân heä thoáng menu. Caùc phím taét ñöôïc ñònh nghóa trong phaàn resource cuûa öùng duïng. Chöông trình seõ duøng leänh ñeå naïp baûng phím taét khi caàn.

Trong phaàn naøy, ta vieát öùng duïng töông töï VD14 vôùi caùc phím taét Ctrl+S, Ctrl+P, Ctrl+A vaø Ctrl+E cho caùc muïc menu: Start, Option, About vaø Exit. Taïo döï aùn VD15 töông töï VD14. Taïo môùi baûng phím taét trong resource (Accelerator resource): Thöïc

hieän töông töï vieäc taïo môùi icon (2.8). Resource Type = Accelerator. Ñaët soá hieäu cho Accelerator ( giaû söû laø IDR_MAINFRAME ). Thieát keá baûng phím taét. Caùc thao taùc cô baûn nhö sau: • Boå sung ñònh nghóa phím taét: Double-click treân doøng roãng:

74 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

- ID : Soá hieäu muïc menu söû duïng phím taét. - Key : Phím taét. - Modifier : Caùc phím heä thoáng phoái hôïp. - Type : ASCII Phím kyù töï ; VirtKey Phím baát kyø. Sau khi aán ñònh xong goõ phím Enter.

• Chænh söûa ñònh nghóa phím taét: Double-click treân doøng phím taét, ñieàu chænh caùc thoâng tin caàn thieát. Goõ phím Enter ñeå keát thuùc.

• Xoùa ñònh nghóa phím taét: Choïn doøng ñònh nghóa phím, goõ phím Del. Löu noäi dung baûng phím taét vaø ñoùng maøn hình soaïn thaûo phím taét.

Söû duïng phím taét trong chöông trình: Thöïc hieän tuaàn töï hai böôùc sau: • Naïp baûng phím taét vaøo boä nhôù:

HACCEL LoadAccelerators ( HINSTANCE hInstance, // Handle cuûa öùng duïng LPCTSTR lpTableName // Chuoãi teân resource ); Haøm traû veà handle cuûa baûng phím taét trong boä nhôù.

• Dòch phím taét treân message nhaän ñöôïc töø haøng chôø cuûa öùng duïng: int TranslateAccelerator ( HWND hWnd, // Handle cöûa soå giao dieän duøng phím taét HACCEL hAccTable, // Handle cuûa baûng phím taét LPMSG lpMsg // Con troû bieán chöùa message ñieàu phoái ); Haøm naøy phaûi ñöôïc thöïc hieän treân taát caû caùc message maø öùng duïng nhaän ñöôïc. Do ñoù, noù ñöôïc loàng vaøo voøng laëp MessageLoop cuûa öùng duïng. Lôùp CWinThread (xem 2.4) cho pheùp caøi ñaët ñaëc tính naøy thoâng qua haønh vi sau cuûa lôùp: BOOL CWinThread::PreTranslateMessage( MSG *pMsg ); Trong caùc lôùp keá thöøa CWinThread, caøi ñaët naøy coù boá cuïc nhö sau:

BOOL CEmpApp::PreTranslateMessage (MSG *pMsg) { // CEmpApp laø lôùp keá thöøa CWinApp (töø CWinThread) // Thöïc hieän haøm dòch treân message nhaän ñöôïc. TranslateAccelerator( m_pMainWnd->m_hWnd, m_hAccel, pMsg ); // m_hAccel : Handle cuûa baûng phím taét. return CWinApp::PreTranslateMessage( pMsg ); }

• AÙp duïng cho döï aùn VD15: Boå sung moät soá thuoäc tính vaø haønh vi cho lôùp CEmpApp:

Page 46: Mfc Tieng Viet

Menu & Phím taét 75

- Thuoäc tính m_hAccel kieåu HACCEL löu handle baûng phím taét. - Haønh vi InitInstance: Boå sung leänh naïp baûng phím taét vaø giöõ giaù

trò handle cuûa noù vaøo bieán m_hAccel ñeå söû duïng sau naøy:

m_hAccel = LoadAccelerators( AfxGetInstanceHandle(), MAKEINTRESOURCE( IDR_MAINFRAME ) );

- Haønh vi keá thöøa PreTranslateMessage coù caøi ñaët nhö treân.

7.6 LÔÙP QUAÛN LYÙ MENU - CMenu: Ñeå tieän thao taùc treân menu, MFC cung caáp lôùp ñoái töôïng CMenu cho pheùp

quaûn lyù menu thoâng qua caùc thuoäc tính vaø haønh vi ñaëc tröng sau: CMenu( ); Haønh vi taïo laäp ñoái töôïng menu. BOOL LoadMenu( UINT nIDResource ); Khôûi taïo thoâng soá cho ñoái

töôïng menu töø menu resource. BOOL DestroyMenu( ); Huûy boû ñoái töôïng menu. BOOL DeleteMenu( UINT nPosition, UINT nFlags ); Xoùa moät muïc

choïn trong menu. Boä giaù trò (nPosition, nFlags) xaùc ñònh muïc choïn. nFlags = MF_BYCOMMAND : nPosition laø soá hieäu cuûa muïc choïn

(menu-ID). = MF_BYPOSITION : nPosition laø vò trí thöù töï cuûa muïc

choïn (ñeám töø 0). BOOL AppendMenu (

UINT nFlags, // Ñaëc ñieåm muïc choïn UINT nIDNewItem = 0, // Soá hieäu muïc choïn LPCTSTR lpszNewItem=NULL // Chuoãi thoâng baùo cuûa muïc ); Theâm muïc choïn vaøo cuoái heä thoáng menu. nFlags = MF_SEPARATOR : Caùc tham soá khaùc khoâng coù yù nghóa. = MF_STRING : Caùc thoâng soá ñöôïc hieåu nhö treân. = MF_POPUP : nIDNewItem laø handle cuûa menu popup.

BOOL InsertMenu ( UINT nPosition, // Vò trí ñöôïc cheøn. UINT nFlags, // Caùc thoâng tin khaùc UINT nIDNewItem = 0, // töông töï AppendMenu(). LPCTSTR lpszNewItem = NULL ); Cheøn theâm muïc choïn vaøo tröôùc muïc ñöôïc chæ bôûi nPosition.

UINT CheckMenuItem ( UINT nIDCheckItem, // Soá hieäu | vò trí muïc choïn

76 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

UINT nCheck // Caùch thöùc ñaùnh daáu muïc choïn ); Ñaùnh daáu hoaëc huûy boû ñaùnh daáu muïc choïn treân menu. nCheck laø giaù trò keát hôïp cuûa hai noäi dung: - Caùch ñaùnh daáu muïc: = MF_CHECKED : Ñaùnh daáu

= MF_UNCHECKED : Boû ñaùnh daáu - Caùch chæ ñònh muïc: = MF_BYPOSITION : Theo vò trí

= MF_BYCOMMAND : Theo soá hieäu muïc nIDCheckItem töông öùng chöùa soá hieäu hoaëc vò trí cuûa muïc choïn.

UINT EnableMenuItem ( UINT nIDEnableItem, // Soá hieäu | vò trí muïc choïn (nhö treân) UINT nEnable // Caùch thöùc aán ñònh muïc choïn. ); Caám hoaëc cho pheùp muïc choïn hoaït ñoäng. nIDEnableItem laø giaù trò keát hôïp cuûa hai noäi dung: - Caùch ñònh vò muïc choïn: Nhö treân. - Traïng thaùi muïc: = MF_ENABLED : Cho pheùp muïc hoaït ñoäng.

= MF_DISABLED : Caám muïc hoaït ñoäng. = MF_GRAYED : Che môø muïc choïn.

int GetMenuString ( UINT nIDItem, // Soá hieäu muïc choïn CString& rString, // Tham bieán nhaän keát quaû UINT nFlags // Caùch ñònh vò muïc choïn ); Laáy noäi dung thoâng baùo cuûa moät muïc choïn.

BOOL ModifyMenu ( UINT nPosition, // Soá hieäu | vò trí cuûa muïc choïn UINT nFlags, // Caùch ñònh vò muïc choïn UINT nIDNewItem = 0, // Soá hieäu | vi trí môùi cuûa muïc choïn LPCTSTR lpszNewItem = NULL // Thoâng baùo môùi cuûa muïc choïn ); Thay ñoåi caùc thoâng soá lieân quan ñeán muïc choïn.

Löu yù: Haønh vi GetMenu cuûa CWnd traû veà con troû ñeán ñoái töôïng menu gaén vôùi cöûa soå. Giaù trò traû veà = NULL neáu cöûa soå khoâng gaén vôùi menu naøo.

Giaû söû coù yeâu caàu vieát öùng duïng VD16 töông töï VD15; trong ñoù muïc choïn Start töï ñoäng chuyeån thaønh Stop vaø ngöôïc laïi moãi khi ngöôøi duøng choïn muïc naøy. Coâng vieäc treân ñöôïc thöïc hieän thoâng qua muïc xöû lyù command message ID_GAME_START. Baïn haõy thöû thöïc hieän öùng duïng naøy (xem VD16).

7.7 XÖÛ LYÙ ÑIEÀU KHIEÅN MUÏC CHOÏN CUÛA MENU:

Page 47: Mfc Tieng Viet

Menu & Phím taét 77

Trong phaàn naøy, ta xaây döïng öùng duïng nhö VD16. Khi choïn muïc Start (Star Stop), öùng duïng khoâng cho pheùp ngöôøi duøng choïn muïc Option.

Caùch thöù nhaát: Caøi ñaët xöû lyù cho muïc choïn Start ( Stop ) ñeå thöïc hieän caám hoaëc cho pheùp muïc choïn Option moät caùch phuø hôïp.

Caùch thöù hai: Duøng traïng thaùi hieän haønh cuûa muïc choïn Start ñeå quyeát ñònh cho pheùp hay caám hoaït ñoäng cuûa muïc Option. Caùch laøm naøy döïa treân cô cheá xöû lyù ñieàu khieån ñoái töôïng phaùt sinh command message laø muïc Option. Thoâng tin traïng thaùi cuûa muïc Start ñöôïc löu trong thuoäc tính m_isStop. Thoâng qua giaù trò naøy, haønh vi xöû lyù ñieàu khieån choïn giaù trò tham soá thích hôïp duøng cho haønh vi Enable cuûa ñoái töôïng CCmdUI chæ bôûi con troû laøm tham soá; TRUE (cho pheùp) , FALSE (caám). Caùc böôùc thöïc hieän döï aùn theo caùch thöù hai nhö sau:

Taïo döï aùn VD17 töông töï VD16. Chænh söûa lôùp CEmpWnd nhö sau: Boå sung thuoäc tính protected m_isStop kieåu BOOL cho lôùp CEmpWnd.

Khoâng duøng bieán cuïc boä isStop nhö VD16, thay theá bieán naøy baèng m_isStop, chænh söûa caùc leänh lieân quan. Thoâng qua haønh vi OnCreate, gaùn giaù trò khôûi ñaàu cho m_isStop laø FALSE.

Khai baùo xöû lyù ñieàu khieån cho muïc Option: Thöïc hieän töông töï muïc (7.4). Löu yù choïn soá hieäu muïc choïn ID_GAME_OPTION, sau ñoù choïn UPDATE_COMMAND_UI. Cuoái cuøng choïn Add and Edit.

Ñaët teân cho haønh vi xöû lyù ñieàu khieån. Caøi ñaët cuûa haønh vi naøy nhö sau:

void CEmpWnd::OnUpdateGameOption (CCmdUI* pCmdUI) { pCmdUI->Enable( !m_isStop ); // pCmdUI con troû tham soá. }

THÖÏC HAØNH: 1. Töø VD15, boå sung haønh vi PreTranslateMessage vaø caøi ñaët xöû lyù söû duïng baûng phím taét cho lôùp CEmpWnd. 2. Caøi ñaët haønh vi xöû lyù muïc choïn thoaùt (Exit) cho lôùp CEmpWnd.

HD: Ñeå chaám döùt öùng duïng, ta duøng haønh vi PostMessage maø CEmpWnd keá thöøa töø CWnd ñeå göûi WM_QUIT ñeán cöûa soå cuûa noù nhö sau:

PostMessage( WM_QUIT, 0, 0 ); 3. Thöïc hieän yeâu caàu muïc (7.7) baèng caùch thöù nhaát.

Page 48: Mfc Tieng Viet

78 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

CHÖÔNG 8:

Caùc lôùp ñoái Töôïng nhaäp lieäu

Lôùp ñoái töôïng nhaäp lieäu, keá thöøa töø lôùp CWnd, cho pheùp quaûn lyù caùc muïc nhaäp lieäu (controls) treân cöûa soå giao dieän. Cöûa soå chöùa caùc control goïi laø cöûa soå cha. Hình aûnh sau laø moät cöûa soå cha vôùi moät soá loaïi control phoå bieán:

8.1 CStatic: CStatic laø lôùp ñoái töôïng quaûn lyù muïc thoâng baùo hoaëc aûnh treân cöûa soå giao

dieän. Caùc thuoäc tính vaø haønh vi ñaëc tröng cuûa lôùp naøy nhö sau: CStatic( ); Taïo laäp ñoái töôïng roãng. BOOL Create (

LPCTSTR lpszText, // Noäi dung thoâng baùo cuûa muïc DWORD dwStyle, // Thoâng soá daïng muïc thoâng baùo const RECT& rect, // Toïa ñoä, kích thöôùc cuûa muïc CWnd* pParentWnd, // Con troû ñoái töôïng cöûa soå cha

Caùc lôùp ñoái töôïng nhaäp lieäu 79

UINT nID = 0xFFFF // Soá hieäu muïc thoâng baùo, duy nhaát. ); Khôûi taïo thoâng soá cho ñoái töôïng muïc thoâng baùo. dwStyle: Phaûi chöùa caùc thoâng soá qui ñònh ñoái vôùi control: WS_CHILD | WS_VISIBLE [ | WS_DISABLED ] vaø caùc thoâng soá boå sung cho ñaëc tröng cuûa muïc nhö sau: SS_BITMAP : Coù chöùc naêng hieån thò aûnh bitmap. SS_ICON : Coù chöùc naêng hieån thò aûnh icon hoaëc cursor. SS_xxx : Moät soá thoâng soá khaùc, xem MSDN.

Maøu neàn ñoái töôïng CStatic do MFC ñaêng kyù, muoán thay ñoåi phaûi xaây döïng lôùp keá thöøa CStatic, caøi ñaët haønh vi PreCreateWindow.

HBITMAP SetBitmap ( HBITMAP hBitmap // Handle cuûa aûnh bitmap ); Duøng aûnh bitmap laøm noäi dung cuûa muïc thoâng baùo.

HBITMAP GetBitmap ( ); Traû veà handle cuûa aûnh bitmap ñang duøng. HICON SetIcon (

HICON hIcon // Handle cuûa icon ); Duøng icon laøm noäi dung cuûa muïc thoâng baùo.

HICON GetIcon( ); Traû veà handle cuûa icon ñang duøng. HCURSOR SetCursor (

HCURSOR hCursor // Handle cuûa cursor ); Choïn cursor cho muïc thoâng baùo. Windows laáy cursor naøy laøm hình daïng con chuoät khi noù di chuyeån vaøo vuøng giôùi haïn cuûa muïc.

HCURSOR GetCursor( ); Traû veà handle cuûa cursor ñang duøng. Coù theå duøng haønh vi CreateEx (lôùp CStatic keá thöøa töø CWnd) khôûi taïo thoâng soá muïc thoâng baùo vôùi daïng môû roäng (WS_EX_xxx). Trong tröôøng hôïp naøy, giaù trò cho tham soá lpszClassName laø _T("STATIC").

Phaàn naøy, ta thöïc hieän öùng duïng VD18 töông töï VD15; caøi ñaët hai muïc thoâng baùo treân cöûa soå giao dieän chính: muïc thöù nhaát coù noäi dung "My Icon is", muïc thöù hai hieån thò icon cuûa öùng duïng.

Duøng hai ñoái töôïng thuoäc lôùp CStatic ñeå taïo vaø quaûn lyù hai muïc thoâng baùo. Ñoái töôïng CEmpWnd laáy chuùng laøm thuoäc tính ñeå tieän quaûn lyù.

Döï aùn ñöôïc thöïc hieän qua caùc böôùc sau: Taïo döï aùn VD18 töông töï VD15. Chænh söûa lôùp CEmpWnd nhö sau: Boå sung hai ñoái töôïng thuoäc tính protected: m_staticIcon vaø

m_staticText coù kieåu CStatic. Haønh vi OnCreate thöïc hieän khôûi taïo thoâng soá cho hai ñoái töôïng naøy:

Page 49: Mfc Tieng Viet

80 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

int CEmpWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CWnd::OnCreate(lpCreateStruct) == -1) return -1; m_staticText.Create( _T("This is my Icon:"), WS_CHILD|WS_VISIBLE, CRect(10, 15, 120, 35), this ); m_staticIcon.Create( _T(""), WS_CHILD | WS_VISIBLE | SS_ICON, CRect( 125,7,157,39 ), this ); m_staticIcon.SetIcon ( AfxGetApp()->LoadIcon(IDR_MAINFRAME) ); return 0; }

Bieân dòch vaø chaïy thöû öùng duïng.

8.2 CEdit: CEdit laø lôùp ñoái töôïng quaûn lyù hoäp nhaäp treân cöûa soå giao dieän. Ngoaøi vieäc

hoã trôï xöû lyù caùc hoaït ñoäng nhaäp lieäu, CEdit coù khaû naêng thoâng tin cho cöûa soå cha cuûa hoäp nhaäp veà tình hình nhaäp lieäu ñang dieãn ra trong hoäp.

CEdit( ); Taïo laäp ñoái töôïng roãng. BOOL Create (

DWORD dwStyle, // Thoâng soá daïng hoäp nhaäp const RECT& rect, // Toïa ñoä vaø kích thöôùc hoäp nhaäp CWnd* pParentWnd, // Con troû ñoái töôïng cöûa soå cha UINT nID // Soá hieäu hoäp nhaäp, phaûi duy nhaát ); Khôûi taïo thoâng soá cho ñoái töôïng hoäp nhaäp lieäu. dwStyle: Goàm thoâng soá qui ñònh ñoái vôùi control vaø caùc daïng boå sung:

ES_MULTILINE : Hoäp nhaäp cho pheùp nhieàu doøng. ES_PASSWORD : Hoäp nhaäp duøng nhaäp password. ES_READONLY : Hoäp nhaäp chæ xem noäi dung. ES_xxx : Xem thoâng tin trong MSDN.

void GetRect ( LPRECT lpRect // Con troû ñeán bieán RECT chöùa keát quaû ); Laáy thoâng tin veà toïa ñoä, kích thöôùc hoäp nhaäp.

BOOL GetModify( ); Traû veà TRUE neáu noäi dung hoäp nhaäp thay ñoåi. void SetModify( BOOL bModified = TRUE ); Xaùc laäp hoaëc xoùa côø

hieäu ghi nhaän söï thay ñoåi noäi dung trong hoäp nhaäp.

Caùc lôùp ñoái töôïng nhaäp lieäu 81

void SetMargins ( UINT nLeft, // Leà traùi vaø UINT nRight // leà phaûi tính baèng pixel ); AÁn ñònh bieân traùi vaø bieân phaûi cuûa hoäp nhaäp.

DWORD GetMargins( ); Traû veà giaù trò chöùa thoâng tin bieân traùi (WORD thaáp) vaø bieân phaûi (WORD cao) cuûa hoäp nhaäp.

void GetSel ( int& nStartChar, // Bieán chöùa vò trí kyù töï ñaàu tieân vaø int& nEndChar // kyù töï cuoái cuøng cuûa ñoaïn vaên baûn. ); Laáy thoâng tin veà ñoaïn vaên baûn ñang ñöôïc ñaùnh daáu trong hoäp nhaäp.

void SetSel ( int nStartChar, // Vò trí kyù töï ñaàu tieân int nEndChar, // Vò trí kyù töï cuoái cuøng cuûa ñoaïn vaên baûn BOOL bNoScroll = FALSE ); Ñaùnh daáu moät ñoaïn vaên baûn trong hoäp nhaäp.

BOOL SetReadOnly( BOOL bReadOnly = TRUE ); Xaùc laäp traïng thaùi chæ xem ñoái vôùi döõ lieäu cuûa hoäp nhaäp.

void Copy( ); Cheùp noäi dung ñoaïn vaên baûn ñang ñöôïc ñaùnh daáu trong hoäp nhaäp vaøo vuøng nhôù heä thoáng (clipboard).

void Paste( ); Cheøn noäi dung vaên baûn trong clipboard vaøo hoäp nhaäp baét ñaàu töø vò trí ñang choïn (hoaëc vò trí daáu carret).

void Clear( ); Xoùa noäi dung ñoaïn vaên baûn ñang ñöôïc ñaùnh daáu. void Cut( ); Thöïc hieän caùc thao taùc Copy vaø Clear. void SetPasswordChar (

TCHAR ch // Kyù töï ñöôïc choïn ); Ñaët kyù töï ‘che’ cho noäi dung cuûa password trong hoäp nhaäp.

int GetLineCount( ); Traû veà soá doøng vaên baûn trong hoäp nhaäp. int GetLine (

int nIndex, // Chæ soá doøng vaên baûn trong hoäp nhaäp LPTSTR lpszBuffer, // Vuøng ñeäm chöùa keát quaû int nMaxLength // Chieàu daøi vuøng ñeäm ); Laáy noäi dung moät doøng vaên baûn trong hoäp nhaäp.

int GetFirstVisibleLine( ); Traû veà chæ soá doøng vaên baûn ñöôïc nhìn thaáy ñaàu tieân trong hoäp. Caùc doøng ôû tröôùc doøng naøy trong noäi dung vaên baûn laø bò che khuaát.

Page 50: Mfc Tieng Viet

82 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

int LineFromChar ( int nIndex = -1 // Chæ soá kyù töï. –1 laø kyù töï cuoái cuøng. ); Traû veà chæ soá doøng vaên baûn chöùa kyù töï (Hoäp nhaäp coù nhieàu doøng).

int LineIndex ( int nLine = -1 // Chæ soá doøng vaên baûn, -1 laø doøng cuoái cuøng ); Traû veà chæ soá cuûa kyù töï ñaàu tieân trong doøng vaên baûn laøm tham soá.

int LineLength ( int nLine = -1 // Chæ soá doøng. –1 laø doøng ñang chöùa carret. ); Traû veà soá kyù töï trong noäi dung cuûa doøng vaên baûn.

CPoint PosFromChar ( UINT nChar // Chæ soá kyù töï trong hoäp nhaäp ); Traû veà toïa ñoä ñieåm ôû goùc traùi treân cuûa kyù töï.

int CharFromPos ( CPoint pt // Toïa ñoä cuûa ñieåm ); Traû veà chæ soá cuûa kyù töï gaàn ñieåm ñang xeùt nhaát.

void LineScroll ( int nLines, // Soá doøng cuoän doïc, < 0 laø cuoän xuoáng. int nChars = 0 // Soá kyù töï cuoän ngang, < 0 laø cuoän traùi. ); Cuoän noäi dung vaên baûn ñang hieån thò trong hoäp nhaäp.

Hoäp nhaäp vaø cöûa soå cha: Ñoái töôïng hoäp nhaäp coù theå göûi message ñeán cöûa soå cha ñeå thoâng baùo tình hình nhaäp lieäu trong hoäp. Cöûa soå cha ñònh höôùng xöû lyù caùc message thoâng qua muïc xöû lyù message coù daïng nhö sau: ON_Notification ( ID, memberFxn ) Trong ñoù: - ID : Soá hieäu muïc ñoái töôïng edit - memberFxn : Teân haønh vi xöû lyù message, khai baùo nhö sau: afx_msg void memberFxn( void ); ON_Notification coù theå laø moät trong caùc muïc xöû lyù cuï theå sau:

Muïc xöû lyù message YÙ nghóa cuûa message ñöôïc xöû lyù ON_EN_CHANGE Noäi dung edit ñang thay ñoåi. ON_EN_HSCROLL Ngöôøi duøng click choïn thanh tröôït ngang. ON_EN_VSCROLL Ngöôøi duøng click choïn thanh tröôït doïc. ON_EN_KILLFOCUS Edit chaám döùt hoaït ñoäng. ON_EN_MAXTEXT Noäi dung vöôït quaù chieàu daøi cho pheùp. ON_EN_SETFOCUS Edit baét ñaàu hoaït ñoäng. ON_EN_UPDATE Döõ lieäu nhaäp ñang ñöôïc caäp nhaät cho edit.

Caùc lôùp ñoái töôïng nhaäp lieäu 83

Thöïc haønh 1: Vieát öùng duïng vôùi muïc thoâng baùo "Enter your name:" vaø hoäp nhaäp döõ lieäu beân caïnh treân maøn hình giao dieän chính. Taïo döï aùn VD19 töông töï VD18. Chænh söûa CEmpWnd nhö sau: Boå sung hai thuoäc tính protected: m_staticName kieåu CStatic vaø

m_editName kieåu CEdit. Trong haønh vi OnCreate, thöïc hieän khôûi taïo hai ñoái töôïng naøy:

int CEmpWnd::OnCreate (LPCREATESTRUCT lpCreateStruct) { if (CWnd::OnCreate(lpCreateStruct) == -1) return -1; m_staticName.Create( _T("Enter your name:" ), WS_CHILD | WS_VISIBLE, CRect(10, 75, 130, 95), this ); m_editName.Create( WS_CHILD | WS_VISIBLE | WS_BORDER, CRect(135, 75, 280, 95), this, -1 ); return 0; }

Thöïc haønh 2: Chænh söûa öùng duïng ñeå khi ngöôøi duøng söûa teân trong hoäp nhaäp thì noäi dung naøy laäp töùc chuyeån leân laøm tieâu ñeà cuûa cöûa soå chính. HD: Cöûa soå cha coù haønh vi xöû lyù message thoâng baùo söï thay ñoåi döõ lieäu trong hoäp nhaäp thoâng qua muïc xöû lyù message ON_EN_CHANGE. Taïo döï aùn VD20 töông töï VD19, Chænh söûa lôùp CEmpWnd nhö sau: Boå sung haønh vi xöû lyù: afx_msg void OnYourNameChange()

void CEmpWnd::OnYourNameChange () { CString yourname; m_editName.GetWindowText(yourname); SetWindowText(yourname); }

Taïo môùi soá hieäu resource: IDC_YOURNAME, duøng giaù trò naøy laøm soá hieäu cho ñoái töôïng m_editName. Trong haønh vi OnCreate:

int CEmpWnd::OnCreate ( LPCREATESTRUCT lpCreateStruct ) { if (CWnd::OnCreate(lpCreateStruct) == -1) return -1; m_staticName.Create ( _T("Enter your name:"), WS_CHILD | WS_VISIBLE, CRect( 10, 75, 130, 95 ), this );

Page 51: Mfc Tieng Viet

84 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

m_editName.Create( WS_CHILD | WS_VISIBLE | WS_BORDER, CRect( 135, 75, 280, 95 ), this, IDC_YOURNAME ); return 0; }

Trong baûng MessageMap, boå sung muïc xöû lyù message:

BEGIN_MESSAGE_MAP(CEmpWnd, CWnd) //{{AFX_MSG_MAP(CEmpWnd) ON_WM_CREATE() ON_WM_DESTROY() ON_WM_PAINT() //}}AFX_MSG_MAP ON_EN_CHANGE( IDC_YOURNAME, OnYourNameChange ) END_MESSAGE_MAP()

8.3 CButton: CButton laø lôùp ñoái töôïng quaûn lyù nuùt choïn treân cöûa soå giao dieän. Trong

windows, caùc nuùt choïn coù theå hoaït ñoäng ñoäc laäp hay theo nhoùm. CButton( ); Taïo laäp ñoái töôïng nuùt choïn roãng. BOOL Create (

LPCTSTR lpszCaption, // Noäi dung thoâng baùo DWORD dwStyle, // Thoâng soá daïng nuùt (BS_PUSHBUTTON) const RECT& rect, // Toïa ñoä, kích thöôùc nuùt choïn CWnd* pParentWnd, // Con troû cöûa soå cha UINT nID // Soá hieäu nuùt choïn ); Khôûi taïo thoâng soá cho ñoái töôïng nuùt choïn.

HBITMAP GetBitmap( ) const ; Handle cuûa aûnh bitmap ñang duøng. HBITMAP SetBitmap(HBITMAP hBitmap); Gaén aûnh bitmap vaøo nuùt. HICON GetIcon( ) const; Handle cuûa icon ñang duøng. HICON SetIcon( HICON hIcon ); Gaén icon vaøo nuùt. virtual void DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct );

Haønh vi keá thöøa ñeå thöïc hieän trang trí rieâng treân nuùt choïn.

Nuùt choïn vaø cöûa soå cha: Nuùt choïn coù theå göûi message ñeán cöûa soå cha. Muïc ON_Notification maø cöûa soå cha duøng xöû lyù message töø nuùt choïn laø:

Muïc xöû lyù message YÙ nghóa cuûa message ñöôïc xöû lyù ON_BN_CLICKED Ngöôøi duøng click treân nuùt. ON_BN_DOUBLECLICKED Ngöôøi duøng double-click treân nuùt

Muïc boå sung

Caùc lôùp ñoái töôïng nhaäp lieäu 85

Thöïc haønh 1: Vieát öùng duïng nhö VD19. Boå sung nuùt choïn "Nhap xong", maø khi choïn, seõ duøng hoäp thoâng baùo ñeå hieån thò noäi dung vöøa nhaäp. Taïo döï aùn VD21 nhö VD19. Chænh söûa cho CEmpWnd nhö sau: Boå sung haønh vi xöû lyù: afx_msg void OnClickNhapxong()

void CEmpWnd::OnClickNhapxong () { CString yourname; m_editName.GetWindowText( yourname ); MessageBox ( yourname, "Hello !", MB_OK | MB_ICONEXCLAMATION ); }

Khai baùo ID resource: IDC_NHAPXONG, boå sung ñoái töôïng thuoäc tính protected m_buttonNhapxong kieåu CButton. Trong OnCreate:

int CEmpWnd::OnCreate( LPCREATESTRUCT lpCreateStruct ) { if (CWnd::OnCreate(lpCreateStruct) == -1) return -1; m_staticName.Create( _T("Enter your name:"), WS_CHILD | WS_VISIBLE, CRect(10, 75, 130, 95), this ); m_editName.Create( WS_CHILD | WS_VISIBLE | WS_BORDER, CRect( 135, 75, 280, 95 ), this, -1 ); m_buttonNhapxong.Create ( _T("Nhap xong"), WS_CHILD | WS_VISIBLE, CRect(10, 115, 90, 140), this, IDC_NHAPXONG ); return 0; }

Trong baûng MessageMap cuûa CEmpWnd, boå sung muïc xöû lyù message:

ON_BN_CLICKED ( IDC_NHAPXONG , OnClickNhapxong )

8.4 CListBox: CListbox laø lôùp ñoái töôïng quaûn lyù hoäp nhaäp chöùa danh saùch caùc muïc choïn

treân cöûa soå giao dieän. Tuøy theo loaïi listbox maø khi söû duïng, ngöôøi duøng ñöôïc pheùp ñaùnh daáu choïn moät hoaëc nhieàu muïc ñoàng thôøi trong listbox.

CListBox( ); Taïo laäp ñoái töôïng roãng.

Page 52: Mfc Tieng Viet

86 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

BOOL Create ( DWORD dwStyle, // Thoâng soá aán ñònh daïng listbox const RECT& rect, // Toïa ñoä, kích thöôùc cuûa listbox CWnd* pParentWnd, // Con troû ñoái töôïng cöûa soå cha UINT nID // Soá hieäu cuûa listbox ); Khôûi taïo thoâng soá cho ñoái töôïng ListBox. dwStyle: Goàm thoâng soá qui ñònh ñoái vôùi control vaø caùc daïng boå sung:

LBS_MULTIPLESEL : Cho pheùp choïn nhieàu muïc ñoàng thôøi LBS_NOTIFY : Thoâng tin cho cöûa soå cha LBS_SORT : Caùc muïc ñöôïc xeáp thöù töï LBS_MULTICOLUMN : Coù nhieàu coät chöùa caùc muïc LBS_STANDARD : = LBS_NOTIFY | LBS_SORT

int GetCount( ); Traû veà soá muïc choïn trong Listbox. int GetCurSel( ); Traû veà chæ soá cuûa muïc ñöôïc choïn (single). int SetCurSel (

int nSelect // Chæ soá muïc ñöôïc choïn ); AÁn ñònh muïc choïn trong listbox.

int GetSelCount( ); Traû veà soá muïc ñöôïc choïn trong moät listbox. Chæ duøng cho listbox cho pheùp choïn nhieàu muïc.

int GetSelItems ( int nMaxItems, // Soá muïc ñöôïc choïn vaø LPINT rgIndex // maûng chöùa caùc chæ soá cuûa chuùng ); Laáy chæ soá cuûa caùc muïc ñöôïc choïn trong listbox.

int AddString ( LPCTSTR lpszItem // Thoâng baùo cuûa muïc ); Theâm moät muïc vaøo listbox. Neáu listbox khoâng coù ñaëc tính xeáp thöù töï thì muïc môùi theâm ñöôïc ñaët vaøo cuoái danh saùch caùc muïc.

int DeleteString ( UINT nIndex // Chæ soá cuûa muïc bò xoùa ); Xoùa moät muïc trong listbox.

int InsertString ( int nIndex, // Vò trí cheøn, -1 laø vò trí cuoái listbox LPCTSTR lpszItem // Thoâng baùo cuûa muïc ); Cheøn moät muïc vaøo listbox taïi vò trí xaùc ñònh.

void ResetContent( ); Xoùa taát caû caùc muïc hieän coù trong listbox, laøm roãng noäi dung listbox quaûn lyù bôûi ñoái töôïng.

Caùc lôùp ñoái töôïng nhaäp lieäu 87

virtual void DrawItem ( LPDRAWITEMSTRUCT lpDrawItemStruct ); Haønh vi keá thöøa nhaèm thöïc hieän trang trí caùc muïc theo caùch rieâng.

virtual void MeasureItem ( LPMEASUREITEMSTRUCT lpMeasureItemStruct ); Laáy thoâng tin laøm cô sôû cho vieäc töï trang trí caùc muïc trong listbox.

virtual void DeleteItem ( LPDELETEITEMSTRUCT lpDeleteItemStruct ); Haønh vi keá thöøa ñeå tuøy nghi xöû lyù khi moät muïc bò xoùa khoûi listbox.

virtual int VKeyToItem ( UINT nKey, // Maõ phím (virtual key) ñöôïc goõ UINT nIndex // Chæ soá muïc hieän haønh trong listbox ); Haønh vi keá thöøa cho pheùp tuøy nghi xöû lyù treân phím.

virtual int CharToItem ( UINT nKey, // Maõ phím (character) ñöôïc goõ UINT nIndex // Chæ soá muïc hieän haønh trong listbox ); Haønh vi keá thöøa cho pheùp tuøy nghi xöû lyù phím kyù töï.

ListbBox vaø cöûa soå cha: ListBox vôùi thoâng soá daïng LBS_NOTIFY coù theå göûi message ñeán cöûa soå cha ñeå thoâng baùo tình traïng hoaït ñoäng cuûa noù. Muïc ON_Notification maø cöûa soå cha duøng xöû lyù message töø listbox laø:

Muïc xöû lyù message YÙ nghóa cuûa message ñöôïc xöû lyù ON_LBN_DBLCLK Ngöôøi duøng double-click treân listbox. ON_LBN_KILLFOCUS Keát thuùc hoaït ñoäng nhaäp. ON_LBN_SELCANCEL Huûy boû thao taùc choïn. ON_LBN_SELCHANGE Thay ñoåi muïc choïn trong listbox. ON_LBN_SETFOCUS Baét ñaàu nhaäp lieäu treân listbox. ON_WM_CHARTOITEM Duøng cho ownerDraw listbox. ON_WM_VKEYTOITEM Xöû lyù WM_KEYDOWN

Thöïc haønh: Vieát öùng duïng töông töï VD21, theâm listbox coù ba muïc choïn: "Ong A", "Ba B" vaø "Co C". Khi ngöôøi duøng click choïn moät muïc trong listbox thì noäi dung cuûa muïc aáy ñöôïc ñieàn vaøo hoäp nhaäp Name. HD: Duøng ON_LBN_SELCHANGE ñònh höôùng xöû lyù message lieân quan.

Taïo öùng duïng VD22 nhö VD21. Chænh söûa lôùp CEmpWnd nhö sau: Boå sung haønh vi protected: afx_msg void OnSelectDanhsach()

void CEmpWnd::OnSelectDanhsach()

Page 53: Mfc Tieng Viet

88 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

{ CString info; int iSel = m_listboxDanhsach.GetCurSel(); if (iSel == LB_ERR) // Khoâng coù löïa choïn iSel = 0; // Xem nhö choïn muïc ñaàu tieân m_listboxDanhsach.GetText( iSel, info ); m_editName.SetWindowText( info ); }

Khai baùo ID resource: IDC_DANHSACH, thuoäc tính protected m_listboxDanhsach kieåu CLisBox quaûn lyù listbox.

Haønh vi OnCreate thöïc hieän caùc khôûi taïo caàn thieát cho listbox.

int CEmpWnd::OnCreate( LPCREATESTRUCT lpCreateStruct ) { if (CWnd::OnCreate(lpCreateStruct) == -1) return -1;

... // Thöïc hieän töông töï döï aùn VD21, // Vaø boå sung caùc noäi dung sau:

m_listboxDanhsach.Create ( WS_CHILD | WS_VISIBLE | WS_BORDER | LBS_NOTIFY | WS_VSCROLL, CRect( 195, 7, 280, 65 ), this, IDC_DANHSACH ); m_listboxDanhsach.AddString( "Ong A" ); m_listboxDanhsach.AddString( "Ba B" ); m_listboxDanhsach.AddString( "Co C" ); return 0; }

Trong MessageMap cuûa CEmpWnd, boå sung muïc xöû lyù message:

ON_LBN_SELCHANGE( IDC_DANHSACH, OnSelectDanhsach )

8.5 CComboBox: CComboBox laø lôùp ñoái töôïng quaûn lyù hoäp nhaäp vaø phaàn hoã trôï nhaäp vôùi

danh saùch caùc muïc thoâng tin cho tröôùc. Caùch keát hôïp giöõa hoäp nhaäp vaø danh saùch hoã trôï taïo thaønh caùc daïng khaùc nhau cuûa comboBox:

- Drop-list : Giaù trò nhaäp chæ ñöôïc choïn töø danh saùch. - Simple : Nhö Drop-list maø danh saùch hieån thò thöôøng tröïc. - Drop-down : Nhö Drop-list vaø coù theå nhaäp noäi dung môùi. CComboBox( ); Taïo laäp ñoái töôïng roãng.

Caùc lôùp ñoái töôïng nhaäp lieäu 89

BOOL Create ( DWORD dwStyle, // Chöùa thoâng soá veà daïng cuûa comboBox const RECT& rect, // Toïa ñoä, kích thöôùc comboBox CWnd* pParentWnd, // Con troû ñoái töôïng cöûa soå cha UINT nID // Soá hieäu comboBox ); Khôûi taïo thoâng soá cho ñoái töôïng comboBox. dwStyle: Goàm thoâng soá qui ñònh ñoái vôùi control vaø caùc daïng boå sung:

CBS_DROPDOWNLIST : Drop-list comboBox. CBS_SIMPLE : Simple comboBox. CBS_DROPDOWN : Drop-Down comboBox. CBS_SORT : Danh saùch caùc muïc xeáp thöù töï.

int GetCount( ); Traû veà soá muïc choïn trong comboBox. int GetCurSel( ); Traû veà chæ soá muïc ñöôïc choïn trong comboBox. int SetCurSel( int nSelect ); AÁn ñònh muïc choïn trong comboBox. void GetLBText (

int nIndex, // Chæ soá muïc trong comboBox CString& rString // Bieán chöùa keát quaû ); Laáy noäi dung thoâng baùo cuûa moät muïc trong comboBox.

void ShowDropDown ( BOOL bShowIt = TRUE // TRUE = hieån thò ; FALSE = daáu ); Hieån thò hoaëc danh saùch chöùa caùc muïc hoã trôï trong comboBox.

int AddString(LPCTSTR lpszString ); Nhö listbox. int DeleteString( UINT nIndex ); Nhö listbox. int InsertString( int nIndex , LPCTSTR lpszString ); Nhö listbox. void ResetContent( ); Nhö listbox. virtual void DrawItem (

LPDRAWITEMSTRUCT lpDrawItemStruct ); Nhö listbox.

virtual void MeasureItem ( LPMEASUREITEMSTRUCT lpMeasureItemStruct ); Nhö listbox.

virtual void DeleteItem ( LPDELETEITEMSTRUCT lpDeleteItemStruct ); Nhö listbox.

Page 54: Mfc Tieng Viet

90 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

ComboBox vaø cöûa soå cha: Ñoái töôïng comboBox coù theå göûi message ñeán cöûa soå cha ñeå thoâng baùo tình hình hoaït ñoäng cuûa noù. Muïc xöû lyù message ON_Notification maø cöûa soå cha duøng xöû lyù message töø comboBox laø:

Muïc xöû lyù message YÙ nghóa cuûa message ñöôïc xöû lyù ON_CBN_CLOSEUP Danh saùch vöøa ñöôïc ñoùng laïi ON_CBN_DBLCLK Double-click treân muïc choïn ON_CBN_DROPDOWN Danh saùch vöøa ñöôïc môû ra ON_CBN_EDITCHANGE Noäi dung hoäp nhaäp ñang thay ñoåi ON_CBN_EDITUPDATE Saép caäp nhaät noäi dung hoäp nhaäp ON_CBN_SELENDCANCEL Boû qua vieäc thay ñoåi muïc choïn. ON_CBN_SELENDOK Moät muïc trong danh saùch ñöôïc choïn ON_CBN_KILLFOCUS Keát thuùc nhaäp lieäu trong comboBox ON_CBN_SELCHANGE Thay ñoåi muïc choïn trong danh saùch ON_CBN_SETFOCUS Baét ñaàu nhaäp lieäu trong comboBox

Thöïc haønh: Vieát öùng duïng töông töï VD22, Boå sung combobox kieåu dropdown coù ba muïc choïn: "Vo van A", "Nguyen thi B" vaø "Tran thi C". Khi choïn treân combobox, noäi dung choïn ñöôïc ñieàn vaøo hoäp nhaäp Name. HD: Duøng ON_CBN_SELCHANGE ñònh höôùng xöû lyù message lieân quan.

Taïo döï aùn VD23 töông töï VD22. Chænh söûa lôùp CEmpWnd nhö sau: Boå sung haønh vi protected: afx_msg void OnSelectCombobox ()

void CEmpWnd::OnSelectCombobox() { CString info; int iSel = m_Combobox.GetCurSel( ); if (iSel == LB_ERR) // no selection iSel = 0; m_Combobox.GetLBText( iSel, info ); m_editName.SetWindowText( info ); }

Khai baùo ID resource: IDC_COMBOBOX. Khai baùo ñoái töôïng thuoäc tính protected m_Combobox kieåu CComboBox quaûn lyù comboBox.

Haønh vi OnCreate thöïc hieän caùc khôûi taïo caàn thieát cho comboBox:

int CEmpWnd::OnCreate (LPCREATESTRUCT lpCreateStruct) { if (CWnd::OnCreate(lpCreateStruct) == -1) return -1;

Caùc lôùp ñoái töôïng nhaäp lieäu 91

... // Nhö VD22, boå sung caùc noäi dung sau: m_Combobox.Create ( WS_CHILD | WS_VISIBLE | WS_BORDER | CBS_DROPDOWNLIST, CRect( 135, 100, 280, 225 ), this, IDC_COMBOBOX ); m_Combobox.AddString( "Vo van A" ); m_Combobox.AddString( "Nguyen thi B" ); m_Combobox.AddString( "Tran thi C" ); return 0; }

Trong MessageMap cuûa CEmpWnd, khai baùo muïc xöû lyù message:

ON_CBN_SELCHANGE( IDC_COMBOBOX,OnSelectCombobox )

8.6 CSpinButtonCtrl: CSpinButtonCTrl laø lôùp ñoái töôïng quaûn lyù nuùt taêng-giaûm treân cöûa soå giao

dieän. Nuùt taêng-giaûm ñöôïc duøng hoã trôï cho caùc hoäp nhaäp soá nguyeân. CSpinButtonCtrl( ); Taïo laäp ñoái töôïng roãng. BOOL Create (

DWORD dwStyle, // Chöùa thoâng soá daïng nuùt taêng giaûm const RECT& rect, // Toïa ñoä, kích thöôùc. Khoâng baét buoäc. CWnd* pParentWnd, // Con troû ñoái töôïng cöûa soå cha UINT nID // Soá hieäu nuùt taêng giaûm ); Khôûi taïo thoâng soá cho ñoái töôïng nuùt taêng giaûm. dwStyle: Goàm thoâng soá qui ñònh ñoái vôùi control vaø caùc daïng boå sung:

UDS_HORZ : Hai nuùt taêng-giaûm naèm ngang UDS_SETBUDDYINT : Duøng cho hoäp nhaäp soá nguyeân. UDS_ALIGNRIGHT : Naèm beân phaûi hoäp nhaäp. UDS_ALIGNLEFT : Naèm beân traùi hoäp nhaäp. UDS_ARROWKEYS : Duøng caùc phím ↑, ↓ ñeå taêng-giaûm.

CWnd* SetBuddy ( CWnd* pWndBuddy // Con troû ñoái töôïng ñöôïc hoã trôï. ); AÁn ñònh ñoái töôïng hoäp nhaäp maø nuùt taêng-giaûm naøy seõ hoã trôï. Haønh vi traû veà con troû ñoái töôïng hoäp nhaäp ñöôïc hoã trôï tröôùc ñoù.

CWnd* GetBuddy( ); Traû veà con troû ñoái töôïng hoäp nhaäp ñöôïc hoã trôï.

Page 55: Mfc Tieng Viet

92 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

void SetRange ( int nLower, // Giaù trò caän döôùi int nUpper // Giaù trò caän treân. ); AÁn ñònh giôùi haïn bieán thieân cuûa nuùt taêng-giaûm.

void GetRange ( int &lower, // Tham bieán chöùa giaù trò caän döôùi int& upper // Tham bieán chöùa giaù trò caän treân ); Laáy thoâng tin veà giôùi haïn cuûa nuùt taêng-giaûm.

int SetPos( int nPos ); Ñaët giaù trò cho nuùt taêng-giaûm. int GetPos( ); Traû veàgiaù trò hieän taïi cuûa nuùt taêng-giaûm.

Thöïc haønh: Vieát öùng duïng töông töï VD21; muïc thoâng baùo "Enter your age:" vaø hoäp nhaäp tuoåi. Hoäp nhaäp ñöôïc hoã trôï cuûa nuùt spin coù giôùi haïn 15-250. Nuùt choïn "Nhap xong" cho pheùp hieån thò teân vaø tuoåi vöøa nhaäp.

Taïo döï aùn VD24 töông töï VD21. Chænh söûa lôùp CEmpWnd nhö sau: Khai baùo thuoäc tính m_editAge kieåu CEdit quaûn lyù hoäp nhaäp. Haønh vi OnCreate thöïc hieän khôûi taïo thoâng soá cho caùc muïc. Rieâng muïc

thoâng baùo vaø nuùt spin, do khoâng coù yeâu caàu truy xuaát neân caùc ñoái töôïng quaûn lyù chuùng seõ ñöôïc khai baùo static trong OnCreate:

int CEmpWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CWnd::OnCreate(lpCreateStruct) == -1) return -1; ... // Töông töï VD21, vaø caùc noäi dung boå sung sau: m_editAge.Create ( WS_CHILD | WS_VISIBLE | WS_BORDER | ES_NUMBER, CRect( 135, 45, 190, 65 ), this, -1 );

static CStatic m_staticAge; static CSpinButtonCtrl m_spinAge; m_staticAge.Create ( _T( "Enter your age:" ), WS_CHILD | WS_VISIBLE, CRect( 10, 45, 130, 65 ), this ); m_spinAge.Create ( WS_CHILD | WS_VISIBLE | UDS_ARROWKEYS | UDS_SETBUDDYINT | UDS_ALIGNRIGHT, CRect(0,0,1,1), this, -1 ); m_spinAge.SetBase( 1 ); m_spinAge.SetRange( 15, 250 ); m_spinAge.SetBuddy ( &m_editAge ); return 0; }

Caùc lôùp ñoái töôïng nhaäp lieäu 93

Haønh vi OnClickNhapxong thöïc hieän hieån thò thoâng tin nhaäp:

void CEmpWnd::OnClickNhapxong( ) { CString yourname, yourage, mess; m_editName.GetWindowText( yourname ); m_editAge.GetWindowText( yourage ); mess.Format ( "%s\n is %s years old", yourname, yourage ); MessageBox( mess,"Hello!", MB_OK | MB_ICONEXCLAMATION ); }

8.7 CProgressCtrl: CProgressCtrl laø lôùp ñoái töôïng quaûn lyù thanh tieán ñoä xöû lyù treân giao dieän. CProgressCtrl( ); Taïo laäp ñoái töôïng roãng. BOOL Create (

DWORD dwStyle, // Thoâng soá daïng thanh tieán ñoä xöû lyù const RECT& rect, // Toaï ñoä, kích thöôùc cuûa thanh CWnd* pParentWnd, // Con troû ñoái töôïng cöûa soå cha UINT nID // Soá hieäu cuûa thanh tieán ñoä ); Haønh vi khôûi taïo thoâng soá cho thanh tieán ñoä treân giao dieän. dwStyle: Goàm thoâng soá qui ñònh ñoái vôùi control vaø caùc daïng boå sung:

PBS_VERTICAL : Thanh tieán ñoä naèm thaúng ñöùng. PBS_SMOOTH : Chæ muïc tieán ñoä laø daõi maøu (xanh) lieân tuïc.

void SetRange ( short nLower, // Giaù trò nhoû nhaát short nUpper // Giaù trò lôùn nhaát ); AÁn ñònh giôùi haïn tieán ñoä xöû lyù chæ bôûi thanh tieán ñoä.

void GetRange( int& nLower, // Bieán chöùa giaù trò nhoû nhaát int& nUpper // Bieán chöùa giaù trò lôùn nhaát ); Laáy thoâng tin veà giôùi haïn tieán ñoä xöû lyù chæ bôûi thanh tieán ñoä.

int SetPos( int nPos ); AÁn ñònh vò trí hieän taïi cuûa thanh tieán ñoä. int GetPos( ); Traû veà vò trí hieän taïi cuûa thanh tieán ñoä xöû lyù. int OffsetPos( int nPos ); AÁn ñònh möùc taêng (giaûm) treân moät ñôn vò cuûa

chæ muïc tieán ñoä trong thanh tieán ñoä baèng nPos, ñoàng thôøi caäp nhaät traïng thaùi hieån thò cuûa thanh tieán ñoä theo giaù trò aán ñònh môùi.

int StepIt( ); Thay ñoåi chæ muïc tieán ñoä moät ñôn vò.

Page 56: Mfc Tieng Viet

94 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

8.8 CScrollBar: CScrollBar laø lôùp ñoái töôïng quaûn lyù thanh cuoän treân cöûa soå giao dieän. CScrollBar( ); Taïo laäp ñoái töôïng roãng. BOOL Create (

DWORD dwStyle, // Thoâng soá daïng cuûa thanh cuoän const RECT& rect, // Toïa ñoä, kích thöôùc cuûa thanh cuoän CWnd* pParentWnd, // Con troû ñoái töôïng cöûa soå cha UINT nID // Soá hieäu thanh cuoän ); Khôûi taïo thoâng soá cho ñoái töôïng thanh cuoän treân giao dieän. dwStyle: Goàm thoâng soá qui ñònh ñoái vôùi control vaø caùc daïng boå sung:

SBS_HORZ : Thanh cuoän ñaët ngang (horizontal) SBS_VERT : Thanh cuoän ñaët ñöùng (vertical)

int GetScrollPos( ); Traû veà vò trí hieän thôøi cuûa moät thanh cuoän. int SetScrollPos (

int nPos, // Vò trí ñaët nuùt cuoän BOOL bRedraw = TRUE // Caäp nhaät laïi hình aûnh thanh cuoän ); Ñaët vò trí nuùt cuoän treân thanh cuoän.

void SetScrollRange ( int nMinPos, // Giaù trò nhoû nhaát int nMaxPos, // Giaù trò lôùn nhaát BOOL bRedraw = TRUE // Caäp nhaät laïi thanh cuoän ); AÁn ñònh giôùi haïn vò trí ñaàu vaø cuoái cuûa nuùt cuoän treân thanh cuoän.

void GetScrollRange ( LPINT lpMinPos, // Chöùa vò trí ñaàu LPINT lpMaxPos // Chöùa vò trí cuoái ); Laáy giaù trò giôùi haïn vò trí ñaàu vaø cuoái cuûa nuùt cuoän treân thanh cuoän.

void ShowScrollBar ( BOOL bShow = TRUE ); Baät / Taét thanh cuoän.

ScrollBar vaø cöûa soå cha: Ñoái töôïng scrollbar göûi WM_HSCROLL (ñoái vôùi loaïi scrollbar ngang) hoaëc WM_VSCROLL (ñoái vôùi loaïi scrollbar ñöùng) ñeán cöûa soå cha ñeå thoâng baùo traïng thaùi hieän thôøi cuûa noù. Caùc haønh vi OnVScroll hoaëc OnHScroll cuûa ñoái töôïng CWnd quaûn lyù cöûa soå cha seõ xöû lyù caùc message töông öùng noùi treân.

Thöïc hieän öùng duïng nhö VD15. Boå sung thanh cuoän, vaø muïc thoâng baùo ñeå hieån thò vò trí nuùt cuoän khi ngöôøi duøng taùc ñoäng leân thanh cuoän.

Taïo döï aùn VD24A nhö döï aùn VD15. Chænh söûa lôùp CEmpWnd nhö sau:

Caùc lôùp ñoái töôïng nhaäp lieäu 95

Khai baùo caùc thuoäc tính protected: m_staticScroll kieåu CStatic quaûn lyù muïc thoâng baùo, m_Scroll kieåu CScrollBar quaûn lyù thanh cuoän.

Haønh vi OnCreate thöïc hieän khôûi taïo thoâng soá cho caùc muïc: int CEmpWnd::OnCreate( LPCREATESTRUCT lpCreateStruct ) { if (CWnd::OnCreate(lpCreateStruct) == -1) return -1;

m_staticScroll.Create( _T(""), WS_CHILD | WS_VISIBLE, CRect( 10, 15, 120, 35 ), this ); m_Scroll.Create( WS_CHILD | WS_VISIBLE | SBS_HORZ, CRect( 10,45,127,65 ), this, IDC_SCROLLBAR ); m_Scroll.SetScrollRange( 0,100 ); return 0; }

Haønh vi OnHScroll xöû lyù WM_HSCROLL: void CEmpWnd::OnHScroll( UINT nSBCode, UINT nPos, CScrollBar* pScrollBar ) { char s[10]; int pos = nPos; switch (nSBCode) { case SB_LINELEFT: pos = pScrollBar->GetScrollPos() - 1; if (pos < 0) pos = 0; pScrollBar->SetScrollPos( pos ); sprintf( s, "%d", pos ); m_staticScroll.SetWindowText(s); break; case SB_LINERIGHT: pos = pScrollBar->GetScrollPos() + 1; if (pos > 90) pos = 100; pScrollBar->SetScrollPos(pos); sprintf(s, "%d", pos); m_staticScroll.SetWindowText(s); break; case SB_THUMBPOSITION: pScrollBar->SetScrollPos(pos); sprintf(s, "%d", pos); m_staticScroll.SetWindowText(s); break; default: CWnd::OnHScroll(nSBCode, nPos, pScrollBar); } }

Bieân dòch vaø chaïy thöû öùng duïng.

Page 57: Mfc Tieng Viet

96 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

8.9 CSliderCtrl: CSliderCtrl laø lôùp ñoái töôïng quaûn lyù thanh tröôït treân cöûa soå giao dieän. CSliderCtrl ( ); Taïo laäp ñoái töôïng roãng. BOOL Create (

DWORD dwStyle, // Thoâng soá daïng cuûa thanh tröôït. const RECT& rect, // Toïa ñoä, kích thöôùc cuûa thanh CWnd* pParentWnd, // Con troû ñoái töôïng cöûa soå cha UINT nID // Soá hieäu thanh tröôït ); Khôûi taïo thoâng soá cho ñoái töôïng thanh tröôït treân giao dieän. dwStyle: Goàm thoâng soá qui ñònh ñoái vôùi control vaø caùc daïng boå sung:

TBS_HORZ : Thanh tröôït ngang TBS_VERT : Thanh tröôït ñöùng TBS_NOTICKS : Thanh tröôït khoâng coù thöôùc laøm moác. TBS_LEFT, TBS_RIGHT : Thöôùc ñaët traùi/phaûi thanh tröôït ñöùng TBS_TOP, TBS_BOTTOM : Thöôùc ñaët treân/döôùi thanh tröôït ngang TBS_BOTH : Thöôùc ñaët ôû caû hai phía thanh tröôït.

int GetPos( ); Traû veà vò trí hieän thôøi cuûa nuùt tröôït treân thanh tröôït. int SetPos( int nPos ); Ñaët vò trí nuùt tröôït treân thanh tröôït.

void SetRange ( int nMinPos, // Giaù trò nhoû nhaát int nMaxPos, // Giaù trò lôùn nhaát BOOL bRedraw = TRUE // Caäp nhaät laïi thanh cuoän ); AÁn ñònh giôùi haïn nhoû nhaát vaø lôùn nhaát cuûa thanh tröôït.

void GetRange ( LPINT lpMinPos, // Laáy giaù trò nhoû nhaát LPINT lpMaxPos // Laáy giaù trò lôùn nhaát ); Laáy giaù trò giôùi haïn nhoû nhaát vaø lôùn nhaát cuûa thanh tröôït.

SliderCtrl vaø cöûa soå cha: Töông töï ScrollBar.

THÖÏC HAØNH: 1. Vieát öùng duïng nhö VD18. Taïo 5 icon resource coù noäi dung phoái hôïp hoaït hình trong resource cuûa öùng duïng. Caøi ñaët timer cho CEmpWnd ñeå thöïc hieän ñoåi icon cho ñoái töôïng m_staticIcon tuaàn töï theo thôøi gian vôùi 5 icon noùi treân. 2. Vieát öùng duïng vôùi thanh ProgressBar chaïy theo thôøi gian. Khi progressbar ñaày thì keát thuùc öùng duïng. 3. Thöïc hieän döï aùn töông töï VD24A cho thanh tröôït.

Page 58: Mfc Tieng Viet

Hoäp hoäi thoaïi 97

CHÖÔNG 9:

Hoäp hoäi thoaïi 9.1 HOÄP HOÄI THOAÏI (DIALOG):

Dialog laø cöûa soå giao dieän vôùi caùc ñaëc ñieåm trang trí ñöôïc moâ taû thoâng qua moät caáu truùc ñoäc laäp. Caáu truùc naøy ñöôïc löu tröõ trong resource cuûa öùng duïng, goïi laø dialog resource. Coù hai kieåu hoaït ñoäng cuûa dialog:

Dialog khoùa (modal dialog): Taùc vuï thöïc hieän dialog phaûi chôø ñeán khi dialog chaám döùt hoaït ñoäng.

Dialog khoâng khoùa (modeless dialog): Taùc vuï thöïc hieän dialog coù theå tieáp tuïc caùc xöû lyù tieáp theo ngay sau leänh thöïc hieän dialog.

9.2 LÔÙP CDialog: CDialog laø lôùp ñoái töôïng keá thöøa töø lôùp CWnd, ñöôïc söû duïng ñeå quaûn lyù

dialog. Ngoaøi caùc thuoäc tính vaø haønh vi keá thöøa public töø lôùp CWnd, lôùp CDialog coù caùc haønh vi boå sung sau ñaây:

CDialog ( UINT nIDTemplate, // Soá hieäu cuûa dialog resource CWnd* pParentWnd = NULL // Con troû ñoái töôïng cöûa soå cha ); Taïo laäp ñoái töôïng dialog hoaït ñoäng kieåu khoùa.

CDialog( ); Taïo laäp ñoái töôïng dialog hoaït ñoäng kieåu khoâng khoùa. virtual BOOL OnInitDialog( ); Haønh vi maø ñoái töôïng dialog söû duïng ñeå

xöû lyù WM_INITDIALOG, message do windows göûi ñeán dialog tröôùc khi kích hoaït dialog. Keá thöøa haønh vi naøy nhaèm thöïc hieän khôûi taïo thoâng soá cho dialog vaø caùc controls cuûa noù.

afx_msg HBRUSH OnCtlColor ( CDC* pDC, // Con troû ñoái töôïng DC cuûa control CWnd* pWnd, // Con troû ñoái töôïng cöûa soå quaûn lyù control UINT nCtlColor // Thoâng tin veà loaïi control ñöôïc trang trí ); Haønh vi xöû lyù WM_CTLCOLOR, message do windows göûi ñeán dialog khi coù nhu caàu trang trí moät control treân dialog. nCtlColor coù theå laø moät trong caùc giaù trò sau:

CTLCOLOR_BTN : Ñoái töôïng trang trí laø button CTLCOLOR_DLG : Dialog CTLCOLOR_EDIT : Hoäp nhaäp lieäu

98 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

CTLCOLOR_LISTBOX : Listbox CTLCOLOR_SCROLLBAR : Thanh tröôït CTLCOLOR_STATIC : Muïc thoâng baùo

virtual int DoModal( ); Kích hoaït dialog kieåu khoùa. Haønh vi chæ keát thuùc khi dialog keát thuùc hoaït ñoäng vaø giaù trò traû veà cuûa noù laø tham soá cuûa haønh vi EndDialog ñöôïc duøng ñeå keát thuùc dialog.

void EndDialog ( int nResult // Giaù trò tham soá cuûa haønh vi. ); Haønh vi ñöôïc duøng ñeå keát thuùc hoaït ñoäng cuûa dialog kieåu khoùa.

virtual void OnOK( ); Haønh vi keá thöøa ñeå caøi ñaët xöû lyù choïn button coù soá hieäu IDOK. Trong CDialog, phaàn caøi ñaët cuûa OnOK chæ laø leänh goïi haønh vi EndDialog vôùi tham soá IDOK.

virtual void OnCancel( ); Haønh vi keá ñeå caøi ñaët xöû lyù choïn button coù soá hieäu IDCANCEL (phím taét laø ESC). Trong CDialog, caøi ñaët cuûa OnCancel chæ laø leänh goïi haønh vi EndDialog vôùi tham soá IDCANCEL.

BOOL Create ( UINT nIDTemplate, // Soá hieäu dialog resource CWnd* pParentWnd = NULL // Con troû ñoái töôïng cöûa soå cha. ); Haønh vi kích hoaït dialog kieåu khoâng khoùa.

virtual BOOL DestroyWindow( ); Haønh vi ñöôïc duøng ñeå keát thuùc hoaït ñoäng cuûa dialog kieåu khoâng khoùa.

CWnd* GetDlgItem ( int nID // Soá hieäu cuûa control treân dialog ); Traû veà con troû ñoái töôïng thuoäc lôùp CWnd quaûn lyù control.

int GetDlgItemText ( int nID, // Soá hieäu cuûa control treân dialog CString& rString // Tham bieán kieåu chuoãi chöùa keát quaû ); Laáy noäi dung chuoãi thoâng baùo cuûa control.

UINT GetDlgItemInt ( int nID // Soá hieäu cuûa control treân dialog ); Traû veà giaù trò soá cuûa noäi dung nhaäp trong control.

void SetDlgItemText ( int nID, // Soá hieäu cuûa control treân dialog LPCTSTR lpszString // Giaù trò kieåu chuoãi ); Ñaët noäi dung kieåu chuoãi cho control.

Page 59: Mfc Tieng Viet

Hoäp hoäi thoaïi 99

void SetDlgItemInt ( int nID, UINT nValue // Soá hieäu control vaø giaù trò gaùn ); Gaùn giaù trò soá nValue cho control.

UINT IsDlgButtonChecked ( int nIDButton // Soá hieäu cuûa button control ); Traû veà giaù trò TRUE neáu control ñöôïc ñaùnh daáu choïn.

int GetCheckedRadioButton ( int nIDFirstButton, // Soá hieäu nuùt RadioButton ñaàu tieân vaø int nIDLastButton // cuoái cuøng trong nhoùm caùc nuùt RadioButtons ); Traû veà soá hieäu nuùt radioButton ñöôïc ñaùnh daáu choïn.

void CheckRadioButton ( int nIDFirstButton, // Soá hieäu nuùt RadioButton ñaàu tieân vaø int nIDLastButton, // cuoái cuøng trong nhoùm caùc nuùt RadioButtons int nIDCheckButton // Soá hieäu nuùt RadioButton ñöôïc ñaùnh daáu. ); Ñaùnh daáu choïn moät nuùt trong nhoùm caùc nuùt RadioButtons.

9.3 TAÏO VAØ SÖÛ DUÏNG DIALOG TRONG CHÖÔNG TRÌNH: Moãi ñoái töôïng dialog hình thaønh trong chöông trình laø keát quaû keát hôïp giöõa

lôùp ñoái töôïng keá thöøa töø CDialog vaø dialog resource. Nhö vaäy, ñeå söû duïng dialog trong chöông trình, ta phaûi thöïc hieän hai böôùc sau:

Thieát keá dialog resource. Khai baùo lôùp keá thöøa töø

CDialog söû duïng dialog resource noùi treân.

Trong chöông trình, moãi khi coù nhu caàu söû duïng dialog, ta chæ vieäc khai baùo bieán ñoái töôïng thuoäc lôùp noùi treân vaø söû duïng noù moät caùch thích hôïp.

Trong phaàn naøy, ta thöïc hieän öùng duïng töông töï VD21. Khi ngöôøi duøng choïn muïc Option treân menu thì hieån thò dialog nhö hình veõ treân. Tröôùc tieân, taïo döï aùn môùi VD25 töông töï döï aùn VD21. Sau ñoù thöïc hieän caùc coâng vieäc sau:

9.3.1 Taïo Dialog resource: Taïo môùi dialog resource: Thöïc hieän töông töï vieäc taïo môùi icon (2.8).

Löu yù: Choïn Resource Type laø Dialog. Ñaët soá hieäu cho dialog resource ( ví duï IDD_OPTION ).

100 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

Thieát keá dialog thoâng qua maøn hình thieát keá maø ta vöøa nhaän ñöôïc töø böôùc treân. Caùc thao taùc cô baûn nhö sau: • Baät / Taét thanh coâng cuï hoã trôï thieát keá dialog:

- Choïn muïc menu Tools / Customize...

- Ñaùnh daáu hoaëc boû ñaùnh daáu muïc Controls. Choïn Close.

(Thanh coâng cuï vôùi caùc loaïi control söû duïng ñöôïc treân dialog)

• AÁn ñònh caùc ñaëc tính cuûa dialog resource: Right-clict treân khung dialog resource (vuøng khoâng caøi controls), choïn muïc Properties:

- Choïn General ñeå aán ñònh caùc thoâng soá chung.

Page 60: Mfc Tieng Viet

Hoäp hoäi thoaïi 101

ID : Soá hieäu cuûa dialog resource. Caption : Noäi dung tieâu ñeà cuûa dialog. Menu : Soá hieäu cuûa menu resource gaén vaøo dialog. Font : AÁn ñònh font duøng cho noäi dung chöõ treân dialog.

- Choïn Styles ñeå aán ñònh thoâng soá daïng cöûa soå cuûa dialog: Style : Ñaëc tính cuûa dialog. Chaúng haïn choïn Popup cho

pheùp dialog taïo ra coù thoâng soá daïng WS_POPUP. Border : Kieåu ñöôøng vieàn cuûa dialog. Title Bar : Dialog coù tieâu ñeà. System Menu : Dialog coù hoäp System Menu.

- Choïn More Styles ñeå aán ñònh caùc thoâng soá daïng môû roäng: Visible : Dialog hieån thò. Ñoái vôùi dialog resource duøng cho

modeless dialog thì muïc naøy phaûi luoân ñöôïc choïn. - Choïn Extended Style ñeå aán ñònh caùc thoâng soá daïng môû roäng:

ToolWindow : Töông öùng WS_EX_TOOLWINDOW. Static edge : Vuøng client ñöôïc chìm xuoáng (3D).

Goõ phím Enter ñeå keát thuùc. • Caøi ñoái töôïng muïc thoâng baùo leân dialog:

- Click choïn bieåu töôïng treân thanh coâng cuï. - Drag chuoät treân vuøng daønh cho muïc thoâng baùo treân dialog. - Right-click treân ñoái töôïng muïc thoâng baùo vöøa caøi ñaët, choïn muïc

Properties. Thöïc hieän caùc aán ñònh caàn thieát: ID : Soá hieäu muïc thoâng baùo, maëc nhieân IDC_STATIC. Ñeå

dialog nhaän dieän ñöôïc muïc khi xöû lyù message thì giaù trò naøy phaûi ñöôïc khai baùo töôøng minh vaø duy nhaát.

Caption : chuoãi thoâng baùo Style : Visible : Neáu ñaùnh daáu thì muïc ñöôïc hieån thò. Align Text : Canh chænh noäi dung thoâng baùo trong muïc. Center Vertically : Canh chænh giöõa noäi dung thoâng baùo theo

chieàu doïc trong muïc. Border : Coù khung bao quanh muïc thoâng baùo. Sunken : Khung chìm. Notify : Muïc thoâng baùo coù khaû naêng thoâng tin cho cöûa soå cha.

Extened style : Transparent : Neàn muïc trong suoát.

102 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

Static edge : Khung chìm. • Caøi ñoái töôïng hoäp nhaäp leân dialog:

- Click choïn bieåu töôïng treân thanh coâng cuï. - Thöïc hieän caøi ñaët vaø aán ñònh thoâng soá nhö vôùi muïc thoâng baùo:

Multi Line : Hoäp nhaäp cho pheùp nhaäp nhieàu doøng. AutoHScroll/AutoVScroll : Töï ñoäng tröôït noäi dung khi thoâng

tin nhaäp vöôït quaù kích thöôùc hoäp nhaäp. HorizontalScroll | VerticalScroll : Hieån thò thanh tröôït ngang,

doïc cuûa hoäp nhaäp. Want return : Söû duïng phím enter ñeå xuoáng doøng trong hoäp

nhaäp nhieàu doøng. Password : Duøng nhaäp password.

• Caøi ñoái töôïng comboBox leân dialog: - Click choïn bieåu töôïng treân thanh coâng cuï. - Thöïc hieän caøi ñaët vaø aán ñònh thoâng soá nhö vôùi muïc thoâng baùo:

Data : Chöùa caùc muïc choïn. Caùc muïc naøy ñöôïc nhaäp treân caùc doøng khaùc nhau. Löu yù duøng phím Ctrl+Enter ñeå xuoáng doøng.

Type : Kieåu comboBox. Sort : Caùc muïc trong comboBox ñöôïc saép xeáp theo noäi dung.

• Caøi ñoái töôïng comboBox leân dialog: - Click choïn bieåu töôïng treân thanh coâng cuï. - Thöïc hieän caøi ñaët vaø aán ñònh thoâng soá nhö vôùi muïc thoâng baùo:

Selection : Kieåu listbox. Multi-column : Listbox coù nhieàu coät. Want Key Input : Lisbox cho pheùp xöû lyù phím.

• Caøi ñoái töôïng button leân dialog: - Click choïn bieåu töôïng treân thanh coâng cuï. - Thöïc hieän caøi ñaët vaø aán ñònh thoâng soá nhö vôùi muïc thoâng baùo:

Default Button: Button öùng vôùi phím taét laø Enter. Multi-lines: Noäi dung thoâng baùo cuûa button coù nhieàu doøng. Notify : Button coù khaû naêng thoâng tin cho cöûa soå cha.

• Ñaùnh daáu choïn caùc ñoái töôïng treân dialog: Thöïc hieän thao taùc click. Phoái hôïp phím Shift hoaëc Ctrl ñeå ñaùnh daáu nhieàu ñoái töôïng.

• Chænh vò trí cuûa moät ñoái töôïng: Thöïc hieän thao taùc drag ñoái töôïng. • Chænh kích thöôùc cuûa moät ñoái töôïng:

- Click choïn ñoái töôïng.

Page 61: Mfc Tieng Viet

Hoäp hoäi thoaïi 103

- Thöïc hieän thao taùc Drag treân bieân cuûa ñoái töôïng ñeå ñaït kích thöôùc mong muoán.

• Canh chænh vò trí, kích thöôùc moät nhoùm ñoái töôïng: - Ñaùnh daáu nhoùm ñoái töôïng - Choïn coâng cuï phuø hôïp treân thanh coâng cuï:

Canh thaúng theo bieân: Canh thaúng giöõa dialog: Caùc ñeàu nhau: Baèng côõ ñoái töôïng choïn cuoái cuøng trong nhoùm:

9.3.2 Khai baùo lôùp keá thöøa CDialog söû duïng dialog resource: Thoâng qua lôùp naøy, ta thöïc hieän caøi ñaët caùc xöû lyù phuø hôïp treân dialog vaø

caùc ñoái töôïng nhaäp lieäu ñöôïc moâ taû trong dialog resource ôû treân. Trong maøn hình thieát keá dialog, choïn View / ClassWizard (Ctrl+W).

Choïn OK ñeå taïo lôùp môùi öùng vôùi dialog resource.

- Name = COptionDlg : Nhaäp teân lôùp môùi

104 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

- File name = OptDlg : Teân taäp tin, - Base class = CDialog : Lôùp cô sôû - Dialog ID = IDD_OPTION : Soá hieäu dialog resource. Sau cuøng choïn OK.

Ñoùng maøn hình thieát keá dialog. Trong maøn hình Workspace, choïn ClassView, ta coù lôùp COptionDlg trong danh saùch caùc lôùp cuûa döï aùn.

Treân lôùp COptionDlg, ta coù theå thöïc hieän boå sung thuoäc tính, caøi ñaët caùc haønh vi thoâng thöôøng cuõng nhö caùc haønh vi xöû lyù message. Caùc thao taùc hoaøn toaøn töông töï nhö ñaõ thöïc hieän vôùi caùc lôùp CEmpApp vaø CEmpWnd.

9.3.3 Söû duïng dialog trong chöông trình: Khai baùo ñoái töôïng thuoäc lôùp dialog môùi taïo. Duøng chæ thò #include taäp

tin (.H) chöùa khai baùo lôùp ôû ñaàu chöông trình:

#include "Optdlg.h" // EmpWnd.cpp : implement file ... COptionDlg dlg (this); // Ñoái töôïng COptionDlg

Goïi haønh vi DoModal hoaëc Create cuûa ñoái töôïng dialog moät caùch phuø hôïp tuøy theo yeâu caàu duøng dialog khoùa hay khoâng khoùa.

dlg.DoModal(); // Dialog hoaït ñoäng ôû cheá ñoä khoùa

Thöïc haønh: Boå sung döï aùn VD25: Caøi ñaët haønh vi xöû lyù muïc choïn Option treân menu cho CEmpWnd vôùi noäi dung thöïc hieän dialog COptionDlg. Boå sung haønh vi xöû lyù muïc choïn Option cho lôùp CEmpWnd. Trong phaàn caøi ñaët haønh vi naøy, ta khai baùo ñoái töôïng COptionDlg vaø

goïi haønh vi DoModal cuûa noù:

void CEmpWnd::OnGameOption () { COptionDlg dlg(this); dlg.DoModal(); }

9.4 LIEÂN KEÁT GIÖÕA DIALOG VAØ CAÙC THAØNH PHAÀN KHAÙC: Dialog laø coâng cuï giao dieän raát tieän lôïi vôùi ngöôøi duøng. Taïo moái lieân keát

giöõa dialog vaø caùc thaønh phaàn khaùc cuûa öùng duïng ñeå trao ñoåi thoâng tin töø ngöôøi duøng laø vaán ñeà thöôøng gaëp. Vaán ñeà naøy coù theå giaûi quyeát nhö sau:

Ñoái töôïng nhaän thoâng tin seõ chuyeån con troû (handle) quaûn lyù mình cho ñoái töôïng cung caáp thoâng tin.

Page 62: Mfc Tieng Viet

Hoäp hoäi thoaïi 105

Ñoái töôïng cung caáp thoâng tin seõ duøng handle cuûa ñoái töôïng nhaän tin ñeå xaùc ñònh caùc oâ chöùa tin cuûa ñoái töôïng naøy, sau ñoù ñieàn caùc thoâng tin cuûa mình vaøo caùc oâ chöùa tin cuûa ñoái töôïng nhaän tin.

Thöïc haønh: Taïo öùng duïng VD26 nhö VD25. Thöïc hieän caùc boå sung: Khi option dialog hoaït ñoäng, ngöôøi duøng goõ thoâng tin vaøo hoäp nhaäp. Neáu ngöôøi duøng choïn OK thì thoâng tin nhaäp chuyeån vaøo hoäp nhaäp YourName treân cöûa soá chính, ngöôïc laïi muïc choïn Cancel seõ khoâng xöû lyù gì caû. HD: Muïc nhaäp YourName ñöôïc quaûn lyù bôûi thuoäc tính m_editName cuûa ñoái töôïng CEmpWnd, ñaây laø oâ chöùa tin cuûa ñoái töôïng nhaän tin CEmpWnd. Ñoái töôïng COptionDlg laø ñoái töôïng cung caáp tin. Xöû lyù ñieàn thoâng tin chæ xaûy ra khi ngöôøi duøng choïn OK. Xöû lyù naøy ñöôïc caøi ñaët trong haønh vi maø ñoái töôïng COptionDlg duøng ñeå traû lôøi thao taùc click treân nuùt OK. Caùc böôùc thöïc hieän döï aùn VD26: Taïo döï aùn VD26 töông töï döï aùn VD25. Haønh vi thöïc hieän OptionDlg trong CEmpWnd söû duïng duøng con troû chæ

ñeán noù laøm tham soá cho haønh vi taïo laäp cuûa ñoái töôïng COptionDlg: void CEmpWnd::OnGameOption () { COptionDlg dlg( this ); dlg.DoModal(); }

Boå sung thuoäc tính protected m_parent kieåu con troû CEmpWnd* cho lôùp COptionDlg. Thuoäc tính naøy ñöôïc duøng ñeå chöùa con troû ñeán cöûa soå cha cuûa COptionDlg (CEmpWnd). Boå sung #include "EmpWnd.h" vaøo ñaàu taäp tin khai baùo (.h) cuûa lôùp COptionDlg.

Haønh vi taïo laäp cuûa COptionDlg löu giöõ giaù trò con troû cöûa soå cha ñöôïc truyeàn cho noù vaøo thuoäc tính m_parent. COptionDlg::COptionDlg ( CWnd* pParent ) : CDialog( COptionDlg::IDD, pParent ) { m_parent = (CEmpWnd*) pParent;

//{{AFX_DATA_INIT(COptionDlg) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT }

106 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

Haønh vi xöû lyù choïn nuùt OK cuûa lôùp COptionDlg: Thöïc hieän vieäc laáy thoâng tin töø hoäp nhaäp cuûa noù ñeå gaùn cho ñoái töôïng hoäp nhaäp m_editName treân cöûa soå cha CEmpWnd.

void COptionDlg::OnOK() { CString name; // Laáy thoâng tin nhaäp trong hoäp nhaäp cuûa dialog GetDlgItemText( IDC_NAME, name ); // vaø chuyeån thoâng tin naøy sang hoäp nhaäp treân cöûa soá chính m_parent->m_editName.SetWindowText( name ); // Duøng haønh vi lôùp cô sôû ñeå keát thuùc dialog. CDialog::OnOK(); }

Haønh vi OnOK cuûa lôùp COptionDlg bò loãi do truy xuaát thuoäc tính kieåu protected m_editName cuûa lôùp CEmpWnd. Ñeå khaéc phuïc loãi naøy, ta khai baùo lôùp COptionDlg laø moät lôùp baïn (friend) cuûa lôùp CEmpWnd.

class CEmpWnd : public CWnd { friend class COptionDlg; // COptionDlg is a friend public: CEmpWnd(); ... // other declarations } ;

9.5 SÖÛ DUÏNG DIALOG LAØM GIAO DIEÄN CHÍNH CUÛA ÖÙNG DUÏNG: Keá thöøa töø CWnd, lôùp CDialog vaø caùc lôùp keá thöøa töø noù coù theå duøng khai

baùo caùc ñoái töôïng cöûa soå giao dieän chính cuûa öùng duïng.

9.5.1 Thöïc hieän öùng duïng vôùi giao dieän chính laø dialog: Taïo döï aùn VD27 töông töï VD03 (döï aùn chæ coù lôùp keá thöøa CWinApp). Taïo dialog resource coù noäi dung tuøy yù laøm giao dieän chính. Taïo lôùp quaûn lyù dialog resource. Giaû söû lôùp coù teân laø CMainDlg coù maõ

nguoàn trong caùc taäp tin MainDlg.H vaø MainDlg.CPP. Ñaêng kyù söû duïng lôùp CMainDlg cho phaàn caøi ñaët cuûa lôùp quaûn lyù öùng

duïng: Boå sung vaøo ñaàu taäp tin caøi ñaët cuûa lôùp (VD27.cpp):

#include "maindlg.h" // at the begin of program

Haønh vi InitInstance cuûa lôùp CEmpApp taïo dialog giao dieän.

Page 63: Mfc Tieng Viet

Hoäp hoäi thoaïi 107

BOOL CEmpApp::InitInstance () { CMainDlg main; // Khai baùo ñoái töôïng dialog m_pMainWnd = &main; // Duøng dialog laøm cöûa soå chính main.DoModal(); // Thöïc hieän dialog return TRUE; }

* Caøi bieåu töôïng öùng duïng treân tieâu ñeà cuûa dialog: Khai baùo style laø Popup hoaëc Overlap cho dialog resource. Haønh vi OnInitDialog cuûa dialog seõ thöïc hieän caøi ñaët icon

BOOL CMainDlg::OnInitDialog() { CDialog::OnInitDialog(); SetIcon(AfxGetApp()->LoadIcon(IDR_MAINFRAME), TRUE); return TRUE; }

9.5.2 Duøng MFC wizard taïo öùng duïng vôùi giao dieän chính laø dialog: Ñeå ngöôøi duøng coù ngay moät döï aùn côõ VD27 maø khoâng phaûi maát coâng thöïc

hieän caùc vieäc nhö treân, MFC wizard cung caáp chöùc naêng hoã trôï taïo nhanh döï aùn vôùi dialog laøm cöûa soå chính. Caùch söû duïng chöùc naêng hoã trôï naøy nhö sau:

Choïn menu File / New.

108 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

Ñieàn caùc thoâng tin trong hoäp hoäi thoaïi New, Sau ñoù choïn OK.

Choïn muïc Dialog Based, sau ñoù choïn Next.

Page 64: Mfc Tieng Viet

Hoäp hoäi thoaïi 109

AÁn ñònh caùc muïc choïn nhö treân. Sau ñoù choïn Next.

Choïn cô cheá lieân keát vôùi thö vieän MFC. Sau ñoù choïn next. Cuoái cuøng, aán ñònh teân taäp tin chöùa khai baùo caùc lôùp. Choïn Finish. Bieân dòch vaø chaïy thöû öùng duïng.

9.6 KHAI BAÙO BIEÁN CHO CONTROL TREÂN DIALOG: Khai baùo bieán cho control treân dialog laø thöïc hieän ñònh nghóa bieán ñoái

töôïng coù kieåu phuø hôïp vaø thieát laäp moái quan heä giöõa bieán ñoái töôïng vaø control lieân quan. Thoâng qua bieán ñoái töôïng, ta deã daøng tieán haønh caùc xöû lyù caàn thieát ñeå taùc ñoäng hoaëc laáy giaù trò cuûa control. Coù hai loaïi bieán:

- Bieán giaù trò (value variable): Bieán ñöôïc söû duïng ñeå löu tröõ giaù trò cuûa control.

- Bieán ñieàu khieån (control variable): Bieán ñoái töôïng, coù kieåu phuø hôïp vaø caùc haønh vi xöû lyù caàn thieát, ñöôïc söû duïng ñeå taùc ñoäng leân control.

Ñoàng boä noäi dung nhaäp trong control vaø noäi dung bieán giaù trò: Khi ngöôøi duøng thao taùc nhaäp lieäu treân control, noäi dung nhaäp chöa

thöïc söï trôû thaønh giaù trò cuûa bieán. Ngöôïc laïi, vieäc gaùn trò cho bieán cuõng khoâng laøm thay ñoåi ngay noäi dung hieån thò trong control.

110 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

Ñeå thöïc hieän ñoàng boä hai noäi dung khi moät trong hai hieän töôïng noùi treân xaûy ra, ta söû duïng haønh vi sau maø lôùp CDialog keá thöøa töø CWnd:

BOOL UpdateData( BOOL bSaveAndValidate = TRUE );

Tham soá bSaveAndValidate coù yù nghóa nhö sau: TRUE : Chuyeån giaù trò trong control vaøo bieán giaù trò. FALSE : Chuyeån giaù trò trong bieán giaù trò vaøo control.

Söû duïng bieán ñieàu khieån: Bieán ñieàu khieån laø ñoái töôïng thuoäc moät lôùp ñoái töôïng nhaäp lieäu (xem

chöông 8) coù kieåu phuø hôïp vôùi control. Thoâng qua caùc haønh vi cuûa bieán ñoái töôïng naøy, ta coù theå thöïc hieän caùc taùc ñoäng cho pheùp leân control.

Thöïc hieän öùng duïng vôùi giao dieän chính laø dialog, moät muïc nhaäp vaø hai nuùt View vaø Set ñeå hieån thò vaø ñaët noäi dung trong hoäp nhaäp. AÙp duïng muïc (9.5.2), taïo döï aùn VD27A vôùi giao dieän chính laø dialog. Môû resource cuûa dialog giao dieän chính, caøi ñaët caùc control sau:

- Hoäp nhaäp lieäu : Edit Soá hieäu IDC_NHAP - Nuùt leänh hieån thò noäi dung hoäp nhaäp : Button IDC_XEM - Nuùt leänh ñaët noäi dung hoäp nhaäp : Button IDC_DAT

Khai baùo bieán m_szNhap kieåu CString, duøng löu giaù trò hoäp nhaäp lieäu. Caùch thöïc hieän nhö sau: • Môû resource cuûa dialog chính, choïn muïc View/ClassWizard.

Page 65: Mfc Tieng Viet

Hoäp hoäi thoaïi 111

• Choïn trang Member Variables, choïn muïc coù soá hieäu IDC_NHAP. Sau ñoù choïn muïc Add Variable….

- Meber variable name = m_szNhap : Teân bieán - Category = Value : Loaïi bieán - Variable type = CString : Kieåu cuûa bieán. Choïn OK.

Khai baùo bieán m_editNhap kieåu CEdit. Bieán naøy ñöôïc söû duïng ñeå taùc ñoäng giaù trò hoäp nhaäp lieäu. Thöïc hieän nhö khai baùo bieán m_szNhap:

Haønh vi OnXem öùng vôùi nuùt choïn IDC_XEM hieån thò noäi dung nhaäp:

void CEmpDlg::OnXem() { UpdateData(TRUE); // Caäp nhaät giaù trò control vaøo bieán MessageBox( m_szNhap, "Ban da nhap", MB_OK ); }

Haønh vi OnDat öùng vôùi nuùt choïn IDC_XEM ñaët giaù trò cho hoäp nhaäp:

112 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

void CEmpDlg::OnDat() { m_editNhap.SetWindowText( "Mr.Emp, Hello !" ); }

Bieân dòch vaø chaïy thöû öùng duïng.

Haønh vi OnDat coù theå caøi ñaët nhö sau:

void CEmpDlg::OnDat() { m_szNhap = "Mr.Emp, Hello !"; UpdateData(FALSE); // Caäp nhaät giaù trò bieán cho control }

9.7 KHAI THAÙC CAÙC TIEÄN ÍCH HOÃ TRÔÏ: ÖÙng duïng phaùt trieån trong VC coù theå deã daøng khai thaùc caùc tieän ích hoã trôï

bôûi VC (VC Components) hoaëc bôûi caùc öùng duïng khaùc ñöôïc caøi ñaët trong heä thoáng (ActiveX Controls). Vieäc boå sung vaø khai thaùc caùc tieän ích naøy trong öùng duïng ñöôïc thöïc hieän thoâng qua caùc böôùc sau:

Môû döï aùn cuûa öùng duïng trong VC. Ñaêng kyù söû duïng tieän ích:

Choïn muïc: Project / Add to Project / Components and Controls…

• Choïn nhoùm tieän ích: Double-click muïc nhoùm tieän ích caàn duøng.

Page 66: Mfc Tieng Viet

Hoäp hoäi thoaïi 113

(Danh saùch caùc tieän ích cuûa MS Visual C++)

• Choïn tieän ích: Choïn muïc thích hôïp trong danh saùch tieän ích chi tieát. Choïn Insert.

Choïn OK ñeå khaúng ñònh thao taùc. • Khai baùo thoâng tin lôùp ñoái töôïng quaûn lyù tieän ích boå sung (neáu coù). • Khai baùo thoâng tin lôùp ñoái töôïng trong öùng duïng söû duïng tieän ích.

Keát thuùc quaù trình boå sung moät tieän ích vaøo öùng duïng.

114 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

Thöïc hieän öùng duïng TipApp vôùi giao dieän chính laø dialog. Moãi khi thöïc hieän, öùng duïng hieån thò hoäp thoâng baùo "Tip of the Day".

Duøng MFC Wizard taïo döï aùn TipApp vôùi giao dieän chính laø dialog. Ñaêng kyù söû duïng tieän ích: • Nhoùm tieän ích = Visual C++ Components. • Tieän ích = Tip of the day • Khai baùo thoâng tin lôùp ñoái töôïng quaûn lyù tieän ích:

Choïn OK, Choïn Close ñeå ñoùng hoäp hoäi thoaïi tieän ích. • Vôùi tieän ích "Tip of the Day", lôùp ñoái töôïng quaûn lyù tieåu trình chính

cuûa öùng duïng laø lôùp söû duïng. Hai haønh vi boå sung töï ñoäng cho lôùp: - void CTipAppApp::ShowTipAtStartup(void); - void CTipAppApp::ShowTipOfTheDay(void); Haønh vi ShowTipAtStartup ñöôïc thöïc hieän bôûi haønh vi InitInstance.

Haõy thöû quan saùt caùc lôùp cuûa döï aùn TipApp ñeå töï nhaän xeùt. Bieân dòch vaø chaïy thöû öùng duïng.

Thöïc hieän öùng duïng XemLich vôùi giao dieän chính laø dialog. Boå sung vaøo öùng duïng coâng cuï xem vaø choïn lòch Calendar 8 (ActiveX Control). Caøi ñaët control naøy leân dialog giao dieän. Duøng MFC Wizard taïo döï aùn XemLich vôùi dialog giao dieän chính. Ñaêng kyù söû duïng tieän ích: • Nhoùm tieän ích = Registered ActiveX Controls. • Tieän ích = Calendar Control 8.0

Page 67: Mfc Tieng Viet

Hoäp hoäi thoaïi 115

• Khai baùo thoâng tin lôùp ñoái töôïng quaûn lyù tieän ích:

Choïn OK, Choïn Close ñeå ñoùng hoäp hoäi thoaïi tieän ích. • Lôùp ñoái töôïng CXemLichDlg quaûn lyù dialog giao dieän chính cuûa döï

aùn laøm nhieäm vuï söû duïng control boå sung naøy: - Môû resource dialog giao dieän, caøi ñaët control sau:

- Hoäp xem vaø choïn ngaøy CCalendar IDC_DATE - Taïo bieán ñieàu khieån m_Lich kieåu CCalendar cho control. - Haønh vi OnInitDialog cuûa lôùp ñaët giaù trò cho control:

BOOL CXemLichDlg::OnInitDialog() { CDialog::OnInitDialog(); SetIcon(m_hIcon, TRUE); SetIcon(m_hIcon, FALSE);

m_Lich.SetDay( 19 ); m_Lich.SetMonth( 11 ); m_Lich.SetYear( 2002 );

return TRUE; }

Coù theå söû duïng caùc haønh vi: GetDay, GetMonth, GetYear cuûa ñoái töôïng m_List ñeå laáy thoâng tin veà ngaøy ñöôïc choïn.

Bieân dòch vaø chaïy thöû öùng duïng. 116 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

THÖÏC HAØNH: 1. Nhö VD26, khi option dialog ñöôïc thöïc hieän, hoäp nhaäp cuûa noù chöùa saün thoâng tin laø noäi dung ñaõ ñöôïc nhaäp treân maøn hình chính CEmpWnd. HD: Haønh vi OnInitDialog cuûa COptionDlg thöïc hieän laáy thoâng tin töø thuoäc tính m_editName cuûa ñoái töôïng CEmpWnd vaø gaùn cho hoäp nhaäp cuûa noù. 2. Vieát öùng duïng vôùi option dialog cho pheùp nhaäp 4 thoâng soá toïa ñoä (left-top, right-bottom). Khi choïn OK, caùc thoâng soá naøy ñöôïc aùp ñaët cho cöûa soå chính. 3. Vieát öùng duïng vôùi n chuù böôùm bay trong vuøng client cuûa cöûa soå chính vaø option dialog cho pheùp aán ñònh soá löôïng (n), vaän toác cuûa böôùm. 4. Vieát öùng duïng thöïc hieän chöùc naêng cuûa moät caùi maùy tính boû tuùi. Giao dieän laø moät dialog, caùc nuùt baám soá vaø pheùp tính ñöôïc caøi ñaët baèng caùc control. 5. Vieát öùng duïng kính luùp vôùi giao dieän chính laø dialog. Khi di chuyeån dialog treân maøn hình desktop, thoâng tin cuûa desktop beân döôùi dialog ñöôïc phoùng to (vôùi tæ leä aán ñònh ñöôïc) vaø hieån thò trong vuøng client cuûa dialog. 6. Thöïc hieän öùng duïng vôùi giao dieän chính laø dialog coù hình ngoâi sao. 7. Thöïc hieän öùng duïng vôùi giao dieän chính laø dialog maø khuoân daïng cuûa noù ñöôïc hình thaønh töø moät aûnh bitmap baát kyø. 8. Thöïc hieän öùng duïng vôùi giao dieän chính laø dialog. Dialog naøy cho pheùp thay ñoåi vò trí baèng caùch drag chuoät ôû baát kyø vò trí naøo treân beà maët cuûa noù. 9. Thöïc hieän dialog vôùi maøu neàn tuøy choïn, moät muïc thoâng baùo coù noäi dung "Mailto: [email protected]". Hình aûnh chuoät ñoåi thaønh khi di chuyeån chuoät leân vò trí muïc. Click choïn muïc cho pheùp göûi mail.

HD: - Xöû lyù WM_CTLCOLOR ñeå ñaët maøu neàn cuûa dialog vaø maøu chöõ muïc. - Muïc caøi ñaët vôùi soá hieäu xaùc ñònh, thoâng soá daïng chöùa WM_NOTIFY. - Xöû lyù BN_CLICKED treân muïc, vaø göûi mail thoâng qua haøm sau:

HINSTANCE ShellExecute ( HWND hWnd, // Handle cöûa soå cha. LPCTSTR lpOperation, // Chuoãi noäi dung taùc vuï LPCTSTR lpFile, // Ñöôøng daãn taäp tin chöông trình LPCTSTR lpParameters, // Chuoãi tham soá doøng leänh LPCTSTR lpDirectory, // Ñöôøng daãn thö muïc laøm vieäc int nShowCmd // Thoâng soá hieån thò cöûa soå ); Leänh thöïc hieän moät chöông trình öùng duïng trong windows.

VÍ DUÏÏ: Ñeå göûi mail, ta söû duïng haøm treân nhö sau. ShellExecute( NULL, "open", "Mailto:[email protected]","","", SW_SHOW );

Page 68: Mfc Tieng Viet

Khung cöûa soå giao dieän chính 117

CHÖÔNG 10:

KHUNG CÖÛA SOÅ GIAO DIEÄN CHÍNH

10.1 KHUNG CÖÛA SOÅ GIAO DIEÄN (FRAME WINDOW): Frame window laø loaïi cöûa soå chuyeân duøng laøm maøn hình chính cuûa öùng

duïng. Frame window coù caùc ñaëc ñieåm nhö sau:

Cho pheùp loàng vaøo frame window thanh traïng thaùi (statusbar), thanh coâng cuï (toolbar), menu vaø caùc phím taét treân menu.

Cho pheùp loàng moät ñoái töôïng view (thuoäc lôùp keá thöøa töø CWnd) vaøo vuøng client cuûa frame window ñeå hoaït ñoäng phoái hôïp trong vieäc hieån thò noäi dung trao ñoåi cuûa öùng duïng. Haønh vi OnSetFocus cuûa frame window thöïc hieän haønh vi OnSetFocus cuûa view ñeå taïo söï ñoàng boä giöõa frame vaø view khi kích hoaït. Thoâng qua haønh vi OnCmdMsg, frame window coù theå ñieàu phoái command message cho view.

Phoái hôïp, ñoàng boä vieäc thöïc hieän xöû lyù vaø thay ñoåi traïng thaùi cuûa caùc ñoái töôïng tröïc thuoäc: menu, toolbar, statusbar, view.

Cho pheùp cô cheá thöïc hieän WinHelp vaø töï ñoäng keát thuùc WinHelp khi frame window chaám döùt hoaït ñoäng.

10.2 THANH TRAÏNG THAÙI (STATUSBAR) & LÔÙP CStatusBar: StatusBar laø khung bao goàm caùc hoäp (pane) chöùa thoâng baùo. Thoâng qua

statusbar, öùng duïng coù theå thoâng tin cho ngöôøi duøng veà caùc hoaït ñoäng cuûa öùng duïng vaø caùc thoâng soá lieân quan. Statusbar thöôøng ñöôïc ñaët ôû caïnh döôùi cuûa frame window. Moãi pane treân statusbar coù theå ñöôïc aán ñònh moät kieåu daïng theå hieän vaø noäi dung thoâng tin rieâng.

Vieäc quaûn lyù statusbar trong öùng duïng ñöôïc MFC hoã trôï thoâng qua lôùp ñoái töôïng CStatusBar. Caùc haønh vi ñaëc tröng cuûa lôùp naøy nhö sau:

118Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

CStatusBar( ); Taïo laäp ñoái töôïng roãng. BOOL Create (

CWnd* pParentWnd, /* Con troû ñoái töôïng cöûa soå cha */ /* Thoâng soá daïng cuûa statusbar vaø giaù trò maëc nhieân */ DWORD dwStyle WS_CHILD | WS_VISIBLE | CBRS_BOTTOM, /* Soá hieäu statusbar, giaù trò maëc nhieân cho statusbar chính */ UINT nID = AFX_IDW_STATUS_BAR ); Khôûi taïo thoâng soá cho ñoái töôïng statusbar.

BOOL SetIndicators ( const UINT* lpIDArray, // Maûng chöùa soá hieäu panes int nIDCount // Soá pane treân statusbar ); Qui ñònh soá pane vaø soá hieäu cuûa chuùng. Caùc soá hieäu pane ñaëc bieät nhö sau:

ID_SEPARATOR : Duøng cho pane thoâng tin traïng thaùi, ID_INDICATOR_CAPS : Pane traïng thaùi phím capslock. ID_INDICATOR_NUM : Pane traïng thaùi phím numslock ID_INDICATOR_SCRL : Pane traïng thaùi phím scrolllock

void SetWindowText ( LPCTSTR lpszString // Noäi dung thoâng baùo caäp nhaät ); Caäp nhaät thoâng baùo cho pane coù soá hieäu laø 0.

BOOL SetPaneText ( int nIndex, // Soá hieäu pane LPCTSTR lpszNewText, // Noäi dung thoâng baùo caäp nhaät BOOL bUpdate=TRUE // Veõ laïi thoâng tin caäp nhaät ); Caäp nhaät noäi dung thoâng baùo trong pane moät pane.

void SetPaneInfo ( int nIndex, // Soá thöù töï pane trong statusbar UINT nID, // Soá hieäu gaùn cho pane UINT nStyle, // Thoâng soá daïng cuûa pane int cxWidth // Ñoä roäng pane (tính baèng pixel) ); AÁn ñònh caùc thoâng soá lieân quan hoaït ñoäng hieån thò cuûa pane. Giaù trò nStyle coù theå laø:

SBPS_NOBORDERS : Khoâng vieàn. SBPS_POPOUT : Vieàn noåi. SBPS_DISABLED : Caám. SBPS_STRETCH : Töï chænh kích thöôùc (cho 1 pane duy nhaát ).

Page 69: Mfc Tieng Viet

Khung cöûa soå giao dieän chính 119

SBPS_NORMAL : Khoâng coù kieåu daùng ñaëc bieät, void SetPaneStyle (

int nIndex, // Soá thöù töï pane trong statusbar UINT nStyle // Thoâng soá daïng cuûa pane ); AÁn ñònh thoâng soá daïng cuûa pane.

10.3 THANH COÂNG CUÏ (TOOLBAR) & LÔÙP CToolBar: Toolbar laø khung chöùa caùc muïc choïn coù hình aûnh gôïi nhôù vaø ñöôïc keát vaøo

caïnh cuûa frame window. Moãi muïc choïn cuûa toolbar coù moät soá hieäu rieâng hoaëc gaén vôùi moät muïc choïn xaùc ñònh trong heä thoáng menu. CToolBar laø lôùp do MFC cung caáp nhaèm hoã trôï vieäc quaûn lyù toolbar trong öùng duïng.

CToolBar( ); Taïo laäp ñoái töôïng roãng. BOOL Create (

CWnd* pParentWnd, /* Con troû ñoái töôïng cöûa soå cha */ /* Thoâng soá daïng cuûa toolbar vôùi giaù trò maëc nhieân */ DWORD dwStyle = WS_CHILD | WS_VISIBLE | CBRS_TOP, /* Soá hieäu cuûa toolbar, giaù trò maëc nhieân cho toolbar chính */ UINT nID = AFX_IDW_TOOLBAR ); Khôûi taïo thoâng soá cho ñoái töôïng toolbar. dwStyle coù theå nhaän caùc thoâng soá sau:

CBRS_GRIPPER : Toolbar di chuyeån ñöôïc CBRS_FLOAT_MULTI : Cho pheùp nhieàu toolbar trong 1 frame CBRS_TOOLTIPS : Coù tiptext cho moãi muïc choïn CBRS_FLYBY : Ñoàng boä tooltip vaø message info CBRS_SIZE_DYNAMIC : Kích thöôùc thay ñoåi ñöôïc CBRS_SIZE_FIXED : Kích thöôùc coá ñònh

BOOL CreateEx ( CWnd* pParentWnd, DWORD dwCtrlStyle = TBSTYLE_FLAT, // Daïng phaúng DWORD dwStyle = WS_CHILD | WS_VISIBLE | CBRS_TOP CRect rcBorders = CRect ( 0, 0, 0, 0 ), UINT nID = AFX_IDW_TOOLBAR ); Khôûi taïo ñoái töôïng toolbar vôùi thoâng soá daïng môû roäng. dwCtrlStyle coù theå laø TBSTYLE_TRANSPARENT (trong suoát).

BOOL LoadToolBar ( UINT nIDResource // Soá hieäu cuûa toolbar resource ); Taïo daïng cho toolbar töø toolbar resource.

120Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

void SetHeight( int cyHeight ); AÁn ñònh chieàu cao cuûa toolbar. void EnableDocking (

DWORD dwStyle // Caùch keát toolbar vaøo frame window // xem EnableDocking() cuûa CFrameWnd ); AÁn ñònh kieåu keát cho pheùp cuûa toolbar vôùi cöûa soå cha cuûa noù.

CToolBarCtrl& GetToolBarCtrl( ); Traû veà ñoái töôïng quaûn lyù caùc nuùt choïn treân toolbar. Vôùi ñoái töôïng naøy ta coù theå thöïc hieän caùc chænh söûa phuø hôïp treân töøng nuùt choïn.

Thöïc hieän toolbar trong öùng duïng: Ta tieán haønh caùc böôùc sau ñaây. 10.3.1 Thieát keá toolbar resource:

Toolbar resource chöùa thoâng tin veà hình aûnh, soá hieäu, noäi dung thoâng baùo vaø caùc höôùng daãn cho töøng muïc choïn treân thanh toolbar.

Môû döï aùn caàn boå sung toolbar resource trong VC. Taïo môùi toolbar resource: Thöïc hieän töông töï taïo môùi icon (2.8).

Löu yù: Choïn Resource Type = ToolBar. Ñaët soá hieäu cho toolbar (ví duï IDR_MAINFRAME cho toolbar chính). Thieát keá toolbar thoâng qua maøn hình thieát keá maø ta vöøa nhaän ñöôïc töø

böôùc treân. Caùc thao taùc cô baûn nhö sau: • Khai baùo thoâng soá cho nuùt choïn:

- Double-click treân nuùt:

- AÁn ñònh caùc thoâng soá cho nuùt:

ID : Soá hieäu cuûa nuùt choïn, coù theå laø soá hieäu cuûa muïc menu. Width, Height : Chieàu roäng vaø chieàu cao cuûa nuùt. Prompt : Töông töï nhö Prompt cuûa muïc choïn treân menu.

• Theâm moät nuùt môùi: Double-click treân . Sau ñoù thöïc hieän khai baùo thoâng soá cho nuùt nhö treân.

• Chuyeån vò trí cuûa nuùt: Drag nuùt ñeán vò trí thích hôïp.

Page 70: Mfc Tieng Viet

Khung cöûa soå giao dieän chính 121

• Taùch nhoùm nuùt: Drag nuùt ra xa vò trí nuùt keá caän. • Xoùa nuùt: Drag nuùt ra khoûi thanh toolbar. • Trang trí nuùt: Thöïc hieän nhö trang trí icon.

Khi thieát keá xong, choïn muïc Save vaø ñoùng maøn hình thieát keá toolbar.

10.3.2 Duøng toolbar resource cho ñoái töôïng CToolBar cuûa FrameWnd: Khai baùo ñoái töôïng thuoäc tính kieåu CToolBar trong lôùp CFrameWnd

cuûa öùng duïng: CToolBar m_toolbar; // Ñaët trong khai baùo lôùp CFrameWnd

Haønh vi OnCreate cuûa FrameWnd khôûi taïo thoâng soá cho ñoái töôïng toolbar . Sau ñoù keát ñoái töôïng toolbar vaøo frame window.

int CEmpFrame::OnCreate( LPCREATESTRUCT lpCreateStruct ) { if (CFrameWnd::OnCreate(lpCreateStruct) == -1) return -1;

// Create the main toolbar for frame window m_toolbar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY); // Initiate toolbar’s appearance by toolbar resource m_toolbar.LoadToolBar(IDR_MAINFRAME); m_toolbar.EnableDocking(CBRS_ALIGN_ANY); // attach the toolbar to frame window this->EnableDocking(CBRS_ALIGN_ANY); this->DockControlBar(&m_toolbar, AFX_IDW_DOCKBAR_TOP); return 0; }

10.4 LÔÙP CFrameWnd: CFrameWnd laø lôùp ñoái töôïng keá thöøa töø CWnd cho pheùp quaûn lyù frame

window trong öùng duïng. Ngoaøi caùc thuoäc tính vaø haønh vi keá thöøa public töø CWnd, CFrameWnd coù caùc thuoäc tính vaø haønh vi ñaëc tröng giuùp vieäc aán ñònh vaø ñieàu khieån frame window ñöôïc deã daøng vaø hieäu quaû.

CFrameWnd( ); Haønh vi taïo laäp. BOOL Create (

LPCTSTR lpszClassName, // Teân lôùp ñaõ ñaêng kyù cuûa frame LPCTSTR lpszWindowName, // Teân, tieâu ñeà cuûa frame window /* thoâng soá daïng cuûa frame */

122Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

DWORD dwStyle = WS_OVERLAPPEDWINDOW, /* Toïa ñoä, kích thöôùc cuûa frame rectDefault: Giaù trò maëc nhieân */ const RECT& rect = rectDefault, // Con troû ñoái töôïng cöûa soå cha CWnd* pParentWnd = NULL, // Chuoãi teân menu resource LPCTSTR lpszMenuName = NULL, DWORD dwExStyle // Thoâng soá daïng frame môû roäng

); Khôûi taïo thoâng soá cho frame window. afx_msg int OnCreate( LPCREATESTRUCT lpCreateStruct ); Haønh vi

keá thöøa cho pheùp khôûi taïo thoâng soá caùc ñoái töôïng tröïc thuoäc. virtual BOOL LoadFrame (

UINT nIDResource, // Soá hieäu caùc resource lieân quan: icon, // cursor, baûng phím taét, menu (baét buoäc). DWORD dwDefaultStyle // Thoâng soá daïng frame window = WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, CWnd* pParentWnd // Con troû ñoái töôïng cöûa soå cha ); Khôûi taïo thoâng soá cho frame window.

BOOL LoadAccelTable ( LPCTSTR Baûng_phím_taét // Teân baûng phím taét trong resource ); Naïp baûng phím taét, chæ duøng khi frame ñöôïc khôûi taïo bôûi Create.

virtual void ActivateFrame ( int nCmdShow = -1 // Thoâng soá veà traïng thaùi kích hoaït ); Haønh vi keá thöøa ñeå aán ñònh thoâng soá traïng thaùi frame khi kích hoaït.

void EnableDocking ( DWORD dwDockStyle // Thoâng soá aán ñònh ); Qui ñònh caùch keát thanh coâng cuï vaøo frame window. dwDockStyle coù theå nhaän moät trong caùc giaù trò sau:

CBRS_ALIGN_TOP : Keát ôû caïnh treân vuøng client. CBRS_ALIGN_BOTTOM : Keát ôû caïnh döôùi CBRS_ALIGN_LEFT : Keát ôû caïnh traùi CBRS_ALIGN_RIGHT : Keát ôû caïnh phaûi CBRS_ALIGN_ANY : Keát ôû moïi vò trí noùi treân.

Page 71: Mfc Tieng Viet

Khung cöûa soå giao dieän chính 123

void DockControlBar ( CControlBar * pBar, // Con troû ñoái töôïng toolbar UINT nDockBarID // Thoâng soá aán ñònh ); Keát ñoái töôïng toolbar vaøo frame window, söû duïng khi tröôùc ñoù ñònh caùch keát toolbar cho frame window laø CBRS_ALIGN_ANY. Thoâng soá aán ñònh phaûi phuø hôïp vôùi ñaëc tính cuûa pBar, coù theå laø caùc giaù trò sau:

AFX_IDW_DOCKBAR_TOP : Keát ôû caïnh treân AFX_IDW_DOCKBAR_BOTTOM : Keát ôû caïnh döôùi AFX_IDW_DOCKBAR_LEFT : Keát ôû caïnh traùi AFX_IDW_DOCKBAR_RIGHT : Keát ôû caïnh phaûi

virtual BOOL OnCreateClient ( LPCREATESTRUCT lpcs, // Con troû ñeán caáu truùc chöùa CCreateContext* pContext // Caùc thoâng soá lieân keát. ); Haønh vi ñöôïc thöïc hieän khi caùc view ñaõ ñöôïc taïo xong. Keá thöøa haønh vi naøy ñeå aán ñònh caùc thoâng soá rieâng cuûa öùng duïng.

virtual CWnd* GetMessageBar( ); Traû veà con troû troû ñeán ñoái töôïng statusbar tröïc thuoäc.

10.5 SÖÛ DUÏNG FRAME WINDOW LAØM GIAO DIEÄN CHÍNH: Keá thöøa töø CWnd, CFrameWnd vaø caùc lôùp keá thöøa töø noù coù theå duøng khai

baùo caùc ñoái töôïng cöûa soå giao dieän chính cuûa öùng duïng. 10.5.1 Thöïc hieän öùng duïng vôùi giao dieän chính laø CFrameWnd:

Thöïc haønh 1: Thöïc hieän öùng duïng vôùi cöûa soå chính laø frame window. Taïo döï aùn VD28 chæ chöùa lôùp CEmpApp keá thöøa töø CWinApp. Trong haønh vi InitInstance cuûa CEmpApp, khai baùo bieán con troû ñoái

töôïng CFrameWnd* vaø duøng noù laøm cöûa soå giao dieän chính: BOOL CEmpApp::InitInstance( ) { CFrameWnd *main = new CFrameWnd; m_pMainWnd = main; // frame window as the main window main->Create ( AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW, LoadCursor(IDC_MAINFRAME), NULL, LoadIcon(IDR_MAINFRAME) ), "Emp.Example 28" ); main->ShowWindow(SW_SHOW); // Show the frame window return TRUE; }

124Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

Thöïc haønh 2: Thöïc hieän öùng duïng töông töï VD28, caøi heä thoáng menu töông töï ví duï chöông 7 cho ñoái töôïng frame window. Taïo môùi döï aùn VD29 töông töï döï aùn VD28. Taïo môùi menu resource vôùi soá hieäu IDR_MAINFRAME, thieát keá menu

naøy nhö moâ taû ôû chöông 7. Taïo môùi baûng phím taét vôùi soá hieäu IDR_MAINFRAME. Khai baùo noäi

dung baûng phím taét nhö muïc (7.5). Haønh vi InitInstance cuûa CEmpApp thöïc hieän khai baùo con troû ñoái

töôïng CFrameWnd*. Duøng haønh vi LoadFrame cuûa ñoái töôïng naøy ñeå khôûi ñoäng thoâng soá cho noù töø caùc resource lieân quan: BOOL CEmpApp::InitInstance() { CFrameWnd *main = new CFrameWnd; m_pMainWnd = main; main->LoadFrame(IDR_MAINFRAME); main->ShowWindow(SW_SHOW); // Show the frame window return TRUE; }

10.5.2 String Table vaø CFrameWnd: StringTable, moät thaønh phaàn trong resource cuûa öùng duïng, duøng chöùa caùc

giaù trò haèng chuoãi. Moãi haèng chuoãi coù moät soá hieäu phaân bieät. Vieäc taïo môùi haèng chuoãi trong resource cöûa öùng duïng ñöôïc thöïc hieän nhö sau:

Taïo môùi resource (nhö 2.8). Löu yù choïn resource type laø String Table.

Double-click hoaëc goõ Enter treân doøng troáng cuûa StringTable:

Page 72: Mfc Tieng Viet

Khung cöûa soå giao dieän chính 125

- ID = Soá hieäu haèng chuoãi. - Caption = Noäi dung haèng chuoãi. Goõ phím Enter ñeå keát thuùc.

Cuoái cuøng, löu vaø ñoùng maøn hình khai baùo StringTable.

Φ Söû duïng haèng chuoãi trong StringTable: Coù theå söû duïng haèng chuoãi trong StringTable laøm giaù trò cho bieán chuoãi trong chöông trình. Ñoái vôùi bieán chuoãi ñöôïc quaûn lyù bôûi ñoái töôïng chuoãi CString, xöû lyù naøy ñöôïc thöïc hieän thoâng qua haønh vi sau:

BOOL CString::LoadString ( UINT nID // Soá hieäu haèng chuoãi trong resource ); Sau ñaây laø moät ví duï khôûi taïo giaù trò chuoãi myString töø string resource: CString myString; myString.LoadString (ID_GAME_OPTION );

Φ Duøng haèng chuoãi trong Stringtable laøm tieâu ñeà frame window: Haèng chuoãi coù soá hieäu truøng vôùi giaù trò soá hieäu laøm tham soá nIDResource cho haønh vi khôûi taïo thoâng soá LoadFrame cuûa ñoái töôïng frame window seõ ñöôïc söû duïng laøm tieâu ñeà cuûa frame window naøy. Môû döï aùn VD29. Taïo môùi haèng chuoãi “Emp.Example 29” trong StringTable vôùi soá hieäu

laø IDR_MAINFRAME. Thöïc hieän chaïy thöû öùng duïng vaø quan saùt tieâu ñeà cöûa frame window.

Thöïc haønh 3: Thöïc hieän öùng duïng nhö VD29; thanh statusbar vôùi ba muïc (pane): muïc thöù nhaát chöùa noäi dung "Mr.Emp", muïc thöù hai chöùa noäi dung "Hello world!", muïc thöù ba hieån thò thoâng tin hoaït ñoäng cuûa öùng duïng. HD: CFrameWnd khoâng coù saün statusbar. Duøng CEmpFrame keá thöøa CFrameWnd vaø boå sung ñoái töôïng thuoäc tính naøy. Haønh vi OnCreate cuûa CEmpFrame thöïc hieän khôûi taïo thoâng soá cho ñoái töôïng statusbar. Duøng CEmpFrame khai baùo ñoái töôïng cöûa soá chính cuûa öùng duïng. Taïo döï aùn VD30 nhö VD29. Boå sung lôùp CEmpFrame keá thöøa CFrameWnd. Xem (5.4.1). Boå sung ñoái töôïng thuoäc tính protected m_status thuoäc lôùp CStatusBar

cho lôùp CEmpFrame: CStatusBar m_status;

Boå sung haønh vi OnCreate (xöû lyù WM_CREATE) cho CEmpFrame vaø thöïc hieän caøi ñaët nhö sau:

126Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

int CEmpFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CFrameWnd::OnCreate( lpCreateStruct ) == -1) return -1; // The IDs of all statusbar’panes UINT ID_array[3] = { 1, 1, ID_SEPARATOR };

m_status.Create( this ); // Thanh statusbar chính m_status.SetIndicators( ID_array, 3 ); m_status.SetPaneText( 0, "Mr.Emp" ); m_status.SetPaneText( 1, "Hello world!" );

// Set the size of each pane on statusbar m_status.SetPaneInfo( 0, 1000, 0, 40 ); m_status.SetPaneInfo( 1, 1001, 0, 70 ); m_status.SetPaneInfo( 2, ID_SEPARATOR, 0, 300 ); return 0; }

Thöïc haønh 4: Vieát öùng duïng nhö VD30 vôùi thanh coâng cuï coù 4 nuùt choïn töông öùng 4 muïc choïn trong heä thoáng menu. Taïo döï aùn VD31 nhö VD30. Taïo môùi toolbar resource coù soá hieäu IDR_MAINFRAME vôùi caùc nuùt

choïn töông öùng caùc muïc menu. Boå sung ñoái töôïng thuoäc tính m_toolbar thuoäc lôùp CToolBar cho lôùp

CEmpFrame. Haønh vi OnCreate cuûa CEmpFrame thöïc hieän khôûi taïo thoâng soá cho caùc ñoái töôïng m_status vaø m_toolbar, sau ñoù keát ñoái töôïng m_toolbar vaøo frame window int CEmpFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { ... // Caùc caøi ñaët nhö VD30 m_toolbar.CreateEx ( this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY ); m_toolbar.LoadToolBar ( IDR_MAINFRAME ); m_toolbar.EnableDocking ( CBRS_ALIGN_ANY ); this->EnableDocking ( CBRS_ALIGN_ANY ); this->DockControlBar( &m_toolbar, AFX_IDW_DOCKBAR_TOP ); return 0; }

Page 73: Mfc Tieng Viet

Khung cöûa soå giao dieän chính 127

Haønh vi InitInstance cuûa CEmpApp söû duïng lôùp CEmpFrame khai baùo ñoái töôïng cöûa soå chính cuûa öùng duïng: BOOL CEmpApp::InitInstance() { CEmpFrame *main = new CEmpFrame; m_pMainWnd = main;

main->LoadFrame(IDR_MAINFRAME);

main->ShowWindow(SW_SHOW); return TRUE; }

Thöïc haønh 5: Thöïc hieän öùng duïng töông töï VD31. Trong frame window, caøi ñaët cöûa soå view chöùa doøng chöõ chaïy kieåu baûng chöõ ñieän töû. Taïo döï aùn VD32 töông töï VD31. Boå sung lôùp CEmpView keá thöøa töø CWnd. CEmpView ñaûm nhaän vieäc

hieån thò noäi dung chöõ chaïy. Caùc caøi ñaët caàn thieát nhö sau: - Haønh vi OnCreate thöïc hieän caøi ñaët timer:

int CEmpView::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CWnd::OnCreate( lpCreateStruct) == -1 ) return -1; SetTimer( ID_TIMER, 300, NULL ); // Interval = 300ms return 0; }

- Haønh vi OnDestroy huûy boû timer: void CEmpView::OnDestroy() {

KillTimer( ID_TIMER );

CWnd::OnDestroy(); }

- Haønh vi OnTimer kích hoaït OnPaint: void CEmpView::OnTimer(UINT nIDEvent) { if (nIDEvent == ID_TIMER) { Invalidate(); // Generates a WM_PAINT } CWnd::OnTimer(nIDEvent); }

128Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

- Haønh vi OnPaint thöïc hieän veõ chöõ chaïy:

void CEmpView::OnPaint() { static char mess[] = "Chao cac ban ! "; char ch; UINT i; CPaintDC dc(this); // device context for painting

ch = mess[0]; for (i=0; i < strlen(mess)-1; i++) mess[i] = mess[i+1]; mess[i] = ch;

dc.TextOut(10, 10, mess, 15); }

Duøng lôùp CEmpView khai baùo ñoái töôïng view trong CEmpFrame: - Boå sung thuoäc tính protected m_view thuoäc lôùp CEmpView vaøo lôùp

CEmpFrame. - Haønh vi OnCreate cuûa CEmpFrame thöïc hieän khôûi taïo thoâng soá phuø

hôïp cho ñoái töôïng m_view; duøng soá hieäu cho m_view laø AFX_IDW_PANE_FIRST (view maëc nhieân cuûa frame)

int CEmpFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { ... // Nhö caøi ñaët cuûa VD31 m_view.Create ( NULL, NULL, AFX_WS_DEFAULT_VIEW, CRect(0,0,0,0), this, AFX_IDW_PANE_FIRST); return 0; }

- Haønh vi PreCreateWindow thöïc hieän huûy thoâng soá aán ñònh daïng "chìm xuoáng" cho vuøng client (chöùa view – to get a nice look):

BOOL CEmpFrame::PreCreateWindow(CREATESTRUCT& cs) { if (!CFrameWnd::PreCreateWindow(cs)) return FALSE; cs.dwExStyle &= ~WS_EX_CLIENTEDGE; return TRUE; }

Duøng CEmpFrame laøm cöûa soå chính cuûa öùng duïng (nhö VD31).

Page 74: Mfc Tieng Viet

Khung cöûa soå giao dieän chính 129

Thöïc haønh 6: Thöïc hieän öùng duïng nhö VD32. Khi choïn muïc Start cuûa menu thì maøn hình view thöïc hieän chöõ chaïy, ñoàng thôøi noäi dung muïc chuyeån thaønh Stop. Neáu ngöôøi duøng choïn laïi muïc naøy (Stop), hoaït ñoäng chaïy chöõ döøng laïi vaø noäi dung muïc choïn chuyeån thaønh Start. Taïo döï aùn VD33 töông töï VD32. Boå sung thuoäc tính m_isRun kieåu BOOL cho lôùp CEmpView. m_isRun

seõ laøm côø hieäu cho chöõ chaïy. Moät soá chænh söûa sau cuûa CEmpView: - Khôûi ñaàu aán ñònh khoâng chaïy chöõ:

int CEmpView::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CWnd::OnCreate(lpCreateStruct) == -1) return -1; isRun = FALSE; // no animation SetTimer( ID_TIMER, 300, NULL ); return 0; }

- Haønh vi OnTimer() döïa treân m_isRun ñeå haønh ñoäng:

void CEmpView::OnTimer(UINT nIDEvent) { if (nIDEvent == ID_TIMER) { if ( isRun ) Invalidate(); // animation allowed ? } CWnd::OnTimer(nIDEvent); }

- Boå sung haønh vi traû lôøi WM_COMMAND phaùt sinh bôûi muïc choïn ID_GAME_START (Start/Stop) treân menu. Ñoàng thôøi ñieàu chænh noäi dung muïc thoâng baùo cuûa menu cho phuø hôïp: void CEmpView::OnGameStart() { isRun = !isRun; CMenu *theMenu = GetParent()->GetMenu(); theMenu->ModifyMenu(ID_GAME_START, MF_BYCOMMAND, ID_GAME_START, (isRun)? "&Stop" : "&Start" ); }

Boå sung haønh vi OnCmdMsg cho CEmpFrame ñeå chuyeån caùc message WM_COMMAND cho m_view: m_view trong lôùp CEmpFrame chæ laø cöûa soå con, khoâng tröïc tieáp nhaän WM_COMMAND töø menu cöûa soå cha.

130Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

BOOL CEmpFrame::OnCmdMsg ( UINT nID, int nCode, void *pExtra, AFX_CMDHANDLERINFO *pHandlerInfo ) { // Dispatch command messages to m_view

if (m_view.OnCmdMsg(nID, nCode, pExtra, pHandlerInfo)) return TRUE; // message was processed by m_view

return CFrameWnd::OnCmdMsg ( nID, nCode, pExtra, pHandlerInfo ); }

10.5.3 Duøng MFC wizard taïo öùng duïng vôùi giao dieän chính framewindow: Ñeå ngöôøi duøng coù ngay moät döï aùn côõ VD32 maø khoâng phaûi maát coâng thöïc

hieän caùc coâng vieäc nhö treân, MFC wizard cung caáp chöùc naêng hoã trôï taïo nhanh döï aùn vôùi cöûa soå chính laø moät frame window. Caùch söû duïng chöùc naêng hoã trôï naøy nhö sau:

Choïn menu File / New.

Ñieàn caùc thoâng tin trong hoäp hoäi thoaïi New, Sau ñoù choïn OK.

Page 75: Mfc Tieng Viet

Khung cöûa soå giao dieän chính 131

AÁn ñònh nhö treân. Choïn Next.

AÁn ñònh nhö treân. Choïn Next.

132Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

Choïn Next.

Choïn StatusBar vaø ToolBar. Sau ñoù choïn Next

Page 76: Mfc Tieng Viet

Khung cöûa soå giao dieän chính 133

Choïn cô cheá lieân keát vôùi thö vieän MFC. Sau ñoù choïn Next. Cuoái cuøng, aán ñònh teân taäp tin chöùa khai baùo caùc lôùp. Choïn Finish.

THÖÏC HAØNH: 1. Töông töï VD33. Khi ngöôøi duøng choïn muïc Option thì hieån thò dialog vôùi hai muïc nhaäp: noäi dung chuoãi chaïy vaø toác ñoä chaïy chöõ. Neáu ngöôøi duøng click choïn OK thì thoâng tin nhaäp trong dialog seõ ñöôïc aùp duïng cho doøng chöõ chaïy trong view. 2. Töông töï VD33. Thay hoäp hieån thò caâu thoâng baùo "Mr.Emp" baèng moät chieác ñoàng hoà coù daïng hh:mm:ss chaïy theo thôøi gian löu trong maùy. HD: Caøi timer cho CEmpFrame. Söû duïng CTime cuûa MFC (xem VD34). 3. Caøi ñaët muïc progressbar treân thanh statusbar cuûa öùng duïng. 4. Vieát öùng duïng vôùi dialog giao dieän chính coù thanh traïng thaùi. 5. Vieát öùng duïng vôùi dialog giao dieän chính coù thanh coâng cuï vaø thanh traïng thaùi. 6. Quan saùt troø chôi line. Phaân tích vaø thöïc hieän öùng duïng naøy trong VC.

Page 77: Mfc Tieng Viet

134 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

CHÖÔNG 11:

Caùc KIEÁN TRUÙC Document & View

MFC hoã trôï maïnh meõ caùc döï aùn söû duïng döõ lieäu, bao goàm döõ lieäu daïng vaên baûn (text), daïng vaên baûn keøm hình aûnh vaø ñònh daïng (löu döôùi daïng vaên baûn – rich text format vaø löu döôùi daïng maõ nhò phaân – compound file), daïng löu tröõ treân caùc heä quaûn trò cô sôû döõ lieäu vaø truy xuaát thoâng qua ODBC, ADO.

ÖÙng duïng söû duïng döõ lieäu coù theå deã daøng phaùt trieån treân VC nhôø MFC cung caáp boä khung chuaån cho caùc döï aùn thao taùc döõ lieäu. Boä khung naøy bao goàm ba thaønh phaàn: Document-View-Frame (DVF). Trong ñoù:

Document: Quaûn lyù toaøn boä noäi dung döõ lieäu cuûa öùng duïng ñöôïc löu tröõ trong boä nhôù.

View: Thöïc hieän chöùc naêng hieån thò vaø quaûn lyù moät phaàn döõ lieäu cuûa document.

Frame Window: Chöùa view, ñieàu phoái command message töø ngöôøi duøng ñeán caùc view moät caùch thích hôïp.

Boä khung naøy ñöôïc thöïc hieän thoâng qua caùc lôùp lieân quan sau ñaây.

11.1 CDocument: CDocument laø lôùp ñoái tuôïng quaûn lyù moät noäi dung döõ lieäu (Document). CDocument( ); Taïo laäp ñoái töôïng roãng. void AddView (

CView* pView // Con troû ñoái töôïng view ); Boå sung view vaøo danh saùch caùc view cuûa document.

void RemoveView ( CView* pView // Con troû ñoái töôïng view ); Loaïi boû moät view ra khoûi danh saùch caùc view cuûa document.

void UpdateAllViews ( CView* pSender, // Ñoái töôïng view mieãn caäp nhaät LPARAM lHint = 0L, // Soá hieäu caäp nhaät CObject* pHint = NULL // Caáu truùc chöùa thoâng tin caäp nhaät ); Thoâng baùo caùc view trong danh saùch view cuûa document caäp nhaät laïi noäi dung hieån thò.

const CString& GetTitle( ); Traû veà noäi dung tieâu ñeà cuûa döõ lieäu. virtual void DeleteContents( ); Xoùa roãng noäi dung document.

Caùc kieán truùc Document & View 135

virtual BOOL OnNewDocument( ); Haønh vi ñöôïc thöïc hieän moãi khi ñoái töôïng CDocument ñöôïc taïo môùi; keá thöøa ñeå caøi ñaët khôûi taïo rieâng.

virtual BOOL OnOpenDocument ( LPCTSTR lpszPathFileName // Ñöôøng daãn vaø teân taäp tin ); Haønh vi ñöôïc thöïc hieän khi ñoái töôïng CDocument chuaån bò nhaän noäi dung töø taäp tin; keá thöøa ñeå caøi ñaët xöû lyù rieâng veà vieäc ñoïc taäp tin.

virtual BOOL OnSaveDocument ( LPCTSTR lpszPathName // Ñöôøng daãn vaø teân taäp tin ); Haønh vi ñöôïc thöïc hieän khi noäi dung cuûa document saép ñöôïc löu vaøo taäp tin. Vieäc keá thöøa haønh vi naøy nhaèm thöïc hieän xöû lyù löu tröõ theo caùch rieâng cuûa öùng duïng.

BOOL IsModified( ); Traû veà tình traïng caäp nhaät döõ lieäu trong document ; =TRUE (coù chænh söûa) hoaëc =FALSE (khoâng coù chænh söûa).

11.2 CView: CView, lôùp keá thöøa töø lôùp CWnd, giuùp quaûn lyù thaønh phaàn view cuûa öùng

duïng. Trong boä ba DVF, view laø thaønh phaàn giao dieän quan troïng cho pheùp ngöôøi duøng thao taùc döõ lieäu cuûa öùng duïng moät caùch deã daøng vaø hieäu quaû.

CView( ); Taïo laäp ñoái töôïng view. virtual void OnInitialUpdate( ); Haønh vi ñöôïc thöïc hieän khi ñoái töôïng

view ñöôïc keát vaøo danh saùch caùc ñoái töôïng view cuûa document. Vieäc keá thöøa nhaèm caøi ñaët caùc aán ñònh khôûi taïo thoâng soá cho view.

virtual void OnActivateView ( BOOL bActivate, // =TRUE: kích hoaït ; vaø ngöôïc laïi CView* pActivateView, // Ñoái töôïng view ñöôïc kích hoaït CView* pDeactiveView // Ñoái töôïng view bò ngöøng hoaït ñoäng ); Haønh vi ñöôïc thöïc hieän moãi khi ñoái töôïng view ñöôïc kích hoaït hoaëc thoâi kích hoaït.

virtual void OnActivateFrame ( UINT nState, // Traïng thaùi kích hoaït CFrameWnd* pFrameWnd // Con troû ñoái töôïng frame chöùa view ); Haønh vi ñöôïc thöïc hieän moãi khi ñoái töôïng frame chöùa view ñöôïc kích hoaït. Traïng thaùi kích hoaït cuûa frame chöùa view coù theå laø:

WA_INACTIVE : Frame chöùa view ngöøng hoaït ñoäng. WA_ACTIVE : Frame chöùa view ñöôïc kích hoaït.

Page 78: Mfc Tieng Viet

136 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

CDocument* GetDocument( ); Traû veà con troû ñoái töôïng CDocument ñang söû duïng view.

virtual void OnUpdate ( CView* pSender, // Ñoái töôïng view laøm thay ñoåi döõ lieäu LPARAM lHint, // Töông töï UpdateAllViews() CObject* pHint // cuûa CDocument ); Haønh vi ñöôïc thöïc hieän khi noäi dung döõ lieäu trong document lieân quan ñeán view ñöôïc caäp nhaät.

BOOL DoPreparePrinting( CPrintInfo* pInfo ); Môû hoäp in aán.

11.3 CFrameWnd: CFrameWnd laø lôùp ñoái töôïng quaûn lyù khung cöûa soå giao dieän chính cuûa

öùng duïng (chöông 10). Tham gia vaøo boä ba DVF cuûa öùng duïng söû duïng döõ lieäu, lôùp ñoái töôïng CFrameWnd coù caùc hoaït ñoäng xöû lyù boå sung nhö sau:

Khi frame ñöôïc kích hoaït, noù goïi haønh vi OnActivateView cuûa view. Neáu frame ñöôïc khôûi taïo vôùi thoâng soá daïng FWS_ADDTOTITLE thì

tieâu ñeà cuûa döõ lieäu (document) hieån thò trong view thuoäc farme seõ ñöôïc ñöa leân tieâu ñeà cuûa frame.

Frame thöïc hieän ñieàu phoái command message cho view.

11.4 CDocTemplate: CDocTemplate laø lôùp ñoái töôïng quaûn lyù boä ba DVF cuûa MFC. Boä ba naøy

bao goàm CDocument – CView – CFrameWnd. CDocTemplate (

UINT nIDResource, // Soá hieäu caùc resource lieân quan: CRuntimeClass* pDocClass, // menu, icon, phím taét, stringTable CRuntimeClass* pFrameClass, CRuntimeClass* pViewClass ); Taïo laäp vaø khôûi taïo thoâng soá cho ñoái töôïng CDocTemplate. - pDocClass: Con troû ñoái töôïng CRuntimeClass quaûn lyù thoâng tin cuûa

lôùp document taïi thôøi ñieåm thöïc thi chöông trình. - pFrameClass: Con troû ñoái töôïng CRuntimeClass quaûn lyù thoâng tin

cuûa lôùp frame window taïi thôøi ñieåm thöïc thi chöông trình. - pViewClass: Con troû ñoái töôïng CRuntimeClass quaûn lyù thoâng tin

cuûa lôùp view taïi thôøi ñieåm thöïc thi chöông trình. Con troû chöùa thoâng tin thi haønh cuûa moät lôùp nhaän ñöôïc töø macro sau: CRuntimeClass* RUNTIME_CLASS ( Teân_Lôùp )

Caùc kieán truùc Document & View 137

virtual BOOL GetDocString ( CString& rString, // Bieán chuoãi chöùa keát quaû enum DocStringIndex index // Chæ soá muïc thoâng tin caàn laáy. ); Chæ soá muïc thoâng tin caàn laáy coù theå laø: - CDocTemplate::windowTitle : Tieâu ñeà - CDocTemplate::docName : Teân document. - CDocTemplate::fileNewName : Teân maëc nhieân duøng cho taäp tin

döõ lieäu ñöôïc taïo môùi. Caû CDocument vaø CView trong boä DVF ñeàu coù theå ñoïc, ghi döõ lieäu treân ñoái töôïng löu tröõ döõ lieäu thoâng qua haønh vi keá thöøa ñöôïc: Serialize.

virtual void Serialize( CArchive& ar ); throw( CMemoryException ); // Duøng khi ar lieân quan boä nhôù trong. throw( CArchiveException ); // Duøng khi ar laø Archive treân ñóa. throw( CFileException ); // Duøng khi ar laø File.

11.5 HOÃ TRÔÏ TÖØ PHÍA ÑOÁI TÖÔÏNG QUAÛN LYÙ ÖÙNG DUÏNG: Lôùp CWinApp coù caùc haønh vi lieân quan vieäc khôûi taïo öùng duïng söû duïng döõ

lieäu vaø thao taùc döõ lieäu döïa treân boä khung DVF nhö sau: void AddDocTemplate (

CDocTemplate* pTemplate // Con troû ñoái töôïng quaûn lyù boä DVF ); Ñöa moät boä ba DVF vaøo danh saùch döõ lieäu quaûn lyù bôûi öùng duïng.

BOOL ProcessShellCommand ( CCommandLineInfo& rCmdInfo ); Thöïc hieän taùc vuï xöû lyù döõ lieäu theo yeâu caàu cuûa system shell. ÖÙng

duïng chæ cho pheùp xöû lyù döõ lieäu (taäp tin) phuø hôïp vôùi chöùc naêng cuûa caùc boä DVF trong danh saùch döõ lieäu quaûn lyù bôûi öùng duïng.

rCmdInfo : Chöùa caùc thoâng soá doøng leänh (neáu coù) bao goàm teân döõ lieäu, leänh thao taùc (edit, open, ...) treân döõ lieäu do shell chuyeån ñeán.

void ParseCommandLine ( CCommandLineInfo& rCmdInfo ); Chuaån bò thoâng soá caàn thieát trong rCmdInfo ñeå chuyeån cho haønh vi

ProcessShellCommand. Caùc thoâng soá naøy töông öùng vôùi noäi dung tham soá doøng leänh cuûa öùng duïng.

afx_msg void OnFileNew(); Haønh vi traû lôøi cho WM_COMMAND ñöôïc phaùt ra bôûi muïc menu coù soá hieäu ID_FILE_NEW.

afx_msg void OnFileOpen(); Haønh vi traû lôøi cho WM_COMMAND ñöôïc phaùt ra bôûi muïc menu coù soá hieäu ID_FILE_OPEN.

Page 79: Mfc Tieng Viet

138 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

afx_msg void OnFilePrintSetup(); Haønh vi xöû lyù WM_COMMAND ñöôïc phaùt ra bôûi muïc menu coù soá hieäu ID_FILE_PRINT_SETUP.

11.6 TRÌNH TÖÏ TAÏO LAÄP CAÙC ÑOÁI TÖÔÏNG THAM GIA BOÄ DVF: Ñoái töôïng document:

Ñoái töôïng Frame window:

Caùc kieán truùc Document & View 139

Ñoái töôïng view:

Nhaèm hoã trôï ngöôøi duøng thöïc hieän caùc döï aùn lieân quan ñeán vieäc söû duïng döõ lieäu, MFC cung caáp caùc boä DVF phoå bieán vaø caøi ñaët caùc boä naøy trong phaàn hoã trôï MFC Wizard. Sau ñaây laø moät soá boä DVF ñaëc tröng cuûa MFC.

11.7 TEXT DOCUMENT APPICATION: Choïn File / New:

AÁn ñònh nhö treân. Choïn OK.

Page 80: Mfc Tieng Viet

140 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

AÁn ñònh nhö treân. Choïn Next.

Choïn None (khoâng söû duïng cô sôû döõ lieäu). Choïn Next.

Caùc kieán truùc Document & View 141

Choïn None (döõ lieäu chæ chöùa vaên baûn). Choïn Next.

AÁn ñònh caùc muïc caàn caàn thieát:

Page 81: Mfc Tieng Viet

142 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

- Printing and print preview: Cho pheùp chöùc naêng in aán. - MAPI: Söû duïng dòch vuï mail cho döõ lieäu cuûa öùng duïng. Choïn Next.

Choïn MFC Standard: ÖÙng duïng coù giao dieän bình thöôøng hoaëc

Windows Explorer: ÖÙng duïng coù giao dieän nhö windows explorer. Choïn cô cheá lieân keát vôùi thö vieän MFC. Choïn Next.

Caùc kieán truùc Document & View 143

AÁn ñònh teân caùc taäp tin chöùa khai baùo vaø caøi ñaët cuûa caùc lôùp. Löu yù: Choïn lôùp CTxtDVFView, khai baùo lôùp cô sôû laø CEditView ñeå maøn hình view cho pheùp soaïn thaûo. Sau cuøng choïn Finish. ÖÙng duïng nhaän ñöôïc coù theå soaïn thaûo vaø quaûn lyù döõ lieäu vaên baûn.

Keá thöøa haønh vi Serialize( CArchive ar ) cuûa lôùp view, döïa treân giaù trò traû veà töø haønh vi IsStoring() cuûa ñoái töôïng tham soá ar, chuùng ta coù theå töï xöû lyù ñoïc/ghi döõ lieäu theo caáu truùc löu tröõ rieâng.

11.8 RICH TEXT FORMAT (RTF) DOCUMENT APPICATION: Choïn File / New: Trong hoäp hoäi thoaïi New:

- Project type = MFC AppWizard. - ProjectName = rtfDVF ( teân döï aùn ). - Location = Thö muïc chöùa döï aùn. Sau ñoù choïn OK.

AÁn ñònh nhö treân. Choïn Next.

Page 82: Mfc Tieng Viet

144 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

Choïn None (khoâng söû duïng cô sôû döõ lieäu). Choïn Next.

ÖÙng duïng söû duïng OLE (Container) töø öùng duïng khaùc. Choïn Next.

Caùc kieán truùc Document & View 145

Choïn caùc muïc caàn thieát (11.7). Choïn Next.

Choïn caùc muïc caàn thieát (11.7). Choïn Next.

Page 83: Mfc Tieng Viet

146 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

AÁn ñònh teân caùc taäp tin chöùa khai baùo vaø caøi ñaët cuûa caùc lôùp.

Löu yù: Choïn lôùp CRtfDVFView, khai baùo lôùp cô sôû laø CRichEditView ñeå maøn hình view cho pheùp soaïn thaûo vaø lieân keát vôùi caùc ñoái töôïng OLE. Sau cuøng choïn Finish. ÖÙng duïng laøm vieäc vôùi döõ lieäu rtf.

11.9 HTML DOCUMENT VIEW APPICATION: Choïn File / New. Khôûi ñaàu nhö (11.8); ProjectName = HtmlDVF.

AÁn ñònh nhö treân. Choïn Next.

Caùc kieán truùc Document & View 147

Choïn None (khoâng söû duïng cô sôû döõ lieäu). Choïn Next.

Choïn None. Choïn Next.

Page 84: Mfc Tieng Viet

148 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

AÁn ñònh caùc muïc caàn thieát; choïn chöùc naêng in aán. Choïn Next.

Choïn caùc muïc caàn thieát (11.7). Choïn Next.

Caùc kieán truùc Document & View 149

AÁn ñònh teân caùc taäp tin chöùa khai baùo vaø caøi ñaët cuûa caùc lôùp. Löu yù: Choïn lôùp CHtmlDVFView, khai baùo lôùp cô sôû laø CHtmlView ñeå maøn hình view hieån thò ñöôïc noäi dung trang HTML. Choïn Finish.

AÁn ñònh URL: Haønh vi OnInitialUpdate cuûa lôùp CHtmlDVFView thöïc hieän aán ñònh URL (ví duï: www.hcmueco.edu.vn) cho Navigate2. ÖÙng duïng nhaän ñöôïc coù theå ñaûm nhaän coâng vieäc Browser ñôn giaûn.

Ñeå caøi ñaët thanh coâng cuï nhö chöông trình Internet Explorer cho öùng duïng, ôû böôùc ‘Step 4 of 6’ ta choïn muïc: Internet Explorer Rebars.

11.10 MOÄT SOÁ LÔÙP VIEW ÑAËC BIEÄT: 11.10.1 CListView:

CListView laø lôùp ñoái töôïng quaûn lyù view daïng danh saùch (list). CListView(); Taïo laäp ñoái töôïng view. CListCtrl& GetListCtrl ( ); Traû veà ñoái töôïng CListCtrl laøm cô sôû cho

caùc taùc vuï lieân quan ListView.

Caùc haønh vi ñaëc tröng cuûa CListCtrl: BOOL SetBkColor( COLOREF cr ); Ñaët maøu neàn cho listview. COLORREF GetBkColor(); Traû veà giaù trò maøu neàn cuûa listview.

Page 85: Mfc Tieng Viet

150 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

CImageList* SetImageList ( CImageList* pImagelist, // Ñoái töôïng imagelist int imgStyle // Thoâng soá qui ñònh caùch söû duïng ); Choïn ñoái töôïng imagelist chöùa aûnh duøng cho caùc muïc cuûa listview. Caùch söû duïng coù theå laø:

LVSIL_NORMAL : AÛnh bình thöôøng. LVSIL_SMALL : AÛnh nhoû.

int InsertItem ( int nItem, // Chæ soá muïc ñöôïc theâm LPCTSTR lpszItem, // Noäi dung thoâng baùo cuûa muïc int nImage // Chæ soá aûnh trong Imagelist maø muïc söû duïng ); Theâm moät muïc vaøo listview.

BOOL DeleteItem ( int nItem // Soá hieäu cuûa muïc ); Xoùa moät muïc trong listview.

BOOL DeleteAllItems( ); Xoùa roãng listview. BOOL GetItem (

LVITEM* pItem // Con troû ñeán caáu truùc nhaän thoâng tin ); Laáy thoâng tin lieân quan ñeán muïc coù soá thöù töï nItem.

BOOL SetItem ( LVITEM* pItem // Con troû ñeán caáu truùc chöùa thoâng soá ); Ñaët thoâng soá cho muïc coù chæ soá laø pItem ->iItem.

BOOL EnsureVisible ( int nItem, // Chæ soá phaàn töû caàn nhìn thaáy. BOOL bPartialIsOK // =FALSE: Toaøn boä, =TRUE: Moät phaàn ); Cuoän danh saùch ñeå nhìn thaáy phaàn töû nItem neáu phaàn töû naøy khoâng ñöôïc nhìn thaáy trong vuøng hieån thò cho pheùp cuûa view.

11.10.2 CTreeView: CTreeView laø lôùp ñoái töôïng quaûn lyù maøn hình view coù caáu truùc caây. CTreeView( ); Taïo laäp ñoái töôïng treeview. CTreeCtrl& GetTreeCtrl( ); Traû veà ñoái töôïng CTreeCtrl laøm cô sôû cho

caùc taùc vuï lieân quan TreeView.

Caùc haønh vi ñaëc tröng cuûa CTreeCtrl: BOOL SetBkColor( COLOREF cr ); Ñaët maøu neàn cho treeview. COLORREF GetBkColor( ); Traû veà giaù trò maøu neàn cuûa treeview. CImageList* SetImageList (

Caùc kieán truùc Document & View 151

CImageList* pImagelist, // Con troû ñoái töôïng imagelist int imgStyle // Thoâng soá qui ñònh caùch söû duïng ); Choïn ñoái töôïng imagelist chöùa aûnh duøng cho caùc muïc cuûa treeview. Caùch söû duïng coù theå laø:

TVSIL_NORMAL : AÛnh duøng cho caùc muïc bình thöôøng. TVSIL_STATE : AÛnh duøng cho caùc muïc ñaëc tröng do ngöôøi

duøng ñònh nghóa. UINT GetCount( ); Traû veà soá muïc cuûa treeview. HTREEITEM GetRootItem( ); Traû veà handle cuûa phaàn töû ñaàu goác. HTREEITEM GetFirstVisibleItem( ); Traû veà handle cuûa phaàn töû hieån

thò ñaàu tieân trong vuøng nhìn thaáy cuûa treeview (NULL: Khoâng coù). HTREEITEM GetSelectedItem(); Traû veà handle cuûa phaàn töû ñang ñöôïc

choïn. HTREEITEM GetNextVisibleItem( HTREEITEM hItem ); Traû veà

handle cuûa phaàn töû hieån thò keá sau phaàn töû coù handle laø hItem. HTREEITEM GetPrevVisibleItem( HTREEITEM hItem ); Traû veà

handle cuûa phaàn töû hieån thò keá tröôùc phaàn töû coù handle laø hItem. HTREEITEM InsertItem (

LPCTSTR lpszItem, // Noäi dung thoâng baùo cuûa muïc int nImage, // Chæ soá aûnh duøng cho muïc ôû traïng thaùi int nImageSelected, // bình thöôøng vaø khi muïc ñöôïc choïn. HTREEITEM parent = TVI_ROOT, // Con troû muïc cha HTREEITEM hInsertAfter = TVI_LAST // Con troû muïc ñöùng tröôùc ); Theâm moät muïc vaøo treeview, traû veà handle cuûa phaàn töû môùi theâm.

BOOL DeleteItem ( HTREEITEM hItem /* handle cuûa muïc*/ ); Xoùa muïc cuûa treeview.

BOOL DeleteAllItems( ); Xoùa roãng noäi dung treeview. BOOL GetItem (

TVITEM* pItem // Con troû ñeán caáu truùc nhaän thoâng tin ); Laáy thoâng tin cuûa phaàn töû pItem->iItem.

BOOL SetItem ( TVITEM* pItem // Con troû ñeán caáu truùc chöùa thoâng soá ); Ñaët thoâng soá cho phaàn töû pItem->iItem.

BOOL SetItemImage ( HTREEITEM hItem, // handle cuûa phaàn töû int nImage, // Chæ soá aûnh duøng cho muïc ôû traïng thaùi

Page 86: Mfc Tieng Viet

152 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

int nSelectedImage // bình thöôøng vaø khi muïc ñöôïc choïn. ); AÁn ñònh chæ soá aûnh trong imagelist duøng cho muïc.

BOOL SetItemText ( HTREEITEM hItem, // handle cuûa muïc LPCTSTR lpszItem // Noäi dung thoâng baùo ); AÁn ñònh laïi noäi dung thoâng baùo cuûa muïc trong treeview.

11.10.3 CSplitterWnd: Vuøng client trong frame window cho pheùp caøi ñaët moät cöûa soå view duy

nhaát. Ñeå loàng ñöôïc nhieàu view vaøo frame ta phaûi phaân chia vuøng client cuûa frame. Vieäc phaân chia naøy ñöôïc hoã trôï bôûi coâng cuï splitter window.

Moãi splitter window cho pheùp taùch vuøng client cuûa frame window thaønh nhieàu haøng vaø coät. Sau ñoù, moãi oâ (pane) nhaän ñöôïc töø splitter naøy coù theå laïi ñöôïc taùch ra thaønh nhieàu haøng vaø coät bôûi moät splitter khaùc. Trong ví duï treân:

- Splitter thöù nhaát taùch frame window thaønh hai doøng vaø 1 coät. - Splitter thöù hai taùch pane thöù nhaát cuûa splitter thöù nhaát thaønh 2 coät

vaø 1 doøng. Moãi pane nhaän ñöôïc töø caùc splitter window cho pheùp gaén moät maøn hình

view. Nhö vaäy, thoâng qua caùc splitter window, frame window coù theå chöùa nhieàu maøn hình view ñoàng thôøi.

Nhaèm tieän vieäc thao taùc vôùi coâng cuï splitter window, MFC cung caáp lôùp ñoái töôïng CSplitterWnd cho pheùp quaûn lyù caùc spliiter window trong öùng duïng. Caùc haønh vi ñaëc tröng cuûa lôùp CSplitterWnd nhö sau:

CSplitterWnd( ); Taïo laäp ñoái töôïng splitter window.

Caùc kieán truùc Document & View 153

BOOL Create ( CWnd* pParentWnd, // Con troû ñoái töôïng cöûa soå cha int nMaxRows, // Soá haøng toái ña cuûa caùc pane int nMaxCols, // Soá coät toái ña cuûa caùc pane SIZE sizeMin, // Kích thöôùc toái thieåu cuûa moãi pane CCreateContext* pContext, // Thoâng soá lieân keát, laáy töø frame DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL | SPLS_DYNAMIC_SPLIT, UINT nID = AFX_IDW_PANE_FIRST ); Khôûi taïo thoâng soá spliiter window vôùi soá haøng, coät thay ñoåi ñöôïc.

BOOL CreateStatic ( CWnd* pParentWnd, // Con troû ñoái töôïng cöûa soå cha int nRows, // Soá haøng caùc pane ñöôïc taïo int nCols, // Soá coät caùc pane ñöôïc taïo DWORD dwStyle = WS_CHILD | WS_VISIBLE, // Daïng vaø UINT nID = AFX_IDW_PANE_FIRST // Soá hieäu ); Taïo spliiter window vôùi soá haøng vaø coät coá ñònh.

virtual BOOL CreateView ( int row, // Chæ soá haøng vaø int col, // chæ soá coät cuûa pane trong splitter CRuntimeClass* pViewClass, // Caáu truùc chöùa thoâng tin lôùp view SIZE sizeInit // Kích thöôùc khôûi ñaàu cuûa pane ); Caøi view vaøo moät pane xaùc ñònh trong splitter window. pViewClass : Con troû ñoái töôïng CRuntimeClass quaûn lyù thoâng tin cuûa lôùp view töông öùng taïi thôøi ñieåm thöïc thi chöông trình. Xem (11.4).

void SetColumnInfo ( int col, // Chæ soá coät trong splitter int cxIdeal, // Ñoä roäng mong muoán vaø int cxMin // ñoä roäng toái thieåu (tính baèng pixel) ); AÁn ñònh thoâng soá veà ñoä roäng cho coät trong splitter window.

void GetColumnInfo ( int col, // Chæ soá coät int& cxCur, // Tham bieán chöùa ñoä roäng hieän thôøi int& cxMin // Tham bieán chöùa ñoä roäng toái thieåu ); Laáy thoâng tin veà ñoä roäng cuûa coät.

void SetRowInfo (

Page 87: Mfc Tieng Viet

154 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

int row, // Chæ soá haøng int cyIdeal, // Ñoä cao mong muoán int cyMin // Ñoä cao toái thieåu ); AÁn ñònh thoâng soá veà ñoä cao cho haøng trong splitter window.

void GetRowInfo ( int row, // Chæ soá haøng int& cyCur, // Tham bieán chöùa ñoä cao hieän thôøi int& cyMin // Tham bieán chöùa ñoä cao toái thieåu ); Laáy thoâng tin veà ñoä cao cuûa haøng.

void RecalcLayout( ); Caäp nhaät thoâng soá aán ñònh môùi cuûa splitter. CWnd* GetPane (

int row, int col // Chæ soá haøng vaø coät cuûa pane ); Traû veà con troû ñoái töôïng view caøi trong pane.

11.10.4 SÖÛ DUÏNG SPLITTERWND TRONG FRAME WINDOW: Khai baùo ñoái töôïng thuoäc lôùp SplitterWnd nhö laø thuoäc tính cuûa frame.

CSplitterWnd m_splitter;

Duøng haønh vi OnCreateClient cuûa frame ñeå taïo caùc pane vaø caøi view:

BOOL CEmpFrame::OnCreateClient ( LPCREATESTRUCT lpcs, CCreateContext* pContext ) { if (!CFrameWnd::OnCreateClient(lpcs, pContext)) return FALSE;

// Duøng ñoái töôïng splitter taùch vuøng client cuûa frame m_splitter.CreateStatic ( this , 1, 2 ); // Ví duï: 1 haøng, 2 coät

// Gaén caùc view töông öùng vaøo caùc pane taïo ñöôïc: m_splitter.CreateView ( 0, 0, RUNTIME_CLASS(viewClass1), CSize(120,0), NULL); m_splitter.CreateView(0,1, RUNTIME_CLASS(viewClass2), CSize(0,0), NULL);

... // Thöïc hieän caùc caøi ñaët khaùc return TRUE; }

11.10.5 CAÙC VÍ DUÏ THÖÏC HAØNH:

Caùc kieán truùc Document & View 155

Thöïc haønh 1: Vieát öùng duïng nhö VD30. Taïo splitter trong CEmpFrame vôùi hai view: beân traùi laø treeview (duøng lôùp view keá thöøa töø CTreeView), beân phaûi laø list (duøng lôùp view keá thöøa töø ListView).

Taïo döï aùn VD35 töông töï VD30. Ñaêng kyù söû duïng CTreeView vaø CListView:

Trong taäp tin stdafh.h cuûa döï aùn, boå sung chæ thò: #include <afxcview.h>

Boå sung vaøo döï aùn hai lôùp môùi: CEmpTree keá thöøa töø CTreeView CEmpList keá thöøa töø CListView.

Caùch thöïc hieän töông töï nhö ñaõ laøm vôùi CEmpWnd, muïc (5.4.1). Khai baùo ñoái töôïng thuoäc tính protected m_splitter kieåu CSplitterWnd.

Haønh vi OnCreateClient cuûa CEmpFrame thöïc hieän khôûi taïo vaø caøi ñaët caùc pane, view caàn thieát:

BOOL CEmpFrame::OnCreateClient( LPCREATESTRUCT lpcs, CCreateContext* pContext ) { if (!CFrameWnd::OnCreateClient(lpcs, pContext)) return FALSE; m_splitter.CreateStatic(this, 1, 2); m_splitter.CreateView( 0, 0, RUNTIME_CLASS(CEmpTree), CSize(120,0), NULL ); m_splitter.CreateView(0,1, RUNTIME_CLASS(CEmpList), CSize(0,0), NULL ); return TRUE; }

Thöïc haønh 2: Thöïc hieän öùng duïng töông töï VD35. Töï ñoäng thöïc hieän boå sung ba phaàn töû trong treeview, moãi phaàn töû coù hai phaàn töû con. Caùc phaàn töû ñeàu coù hình minh hoïa cho traïng thaùi ñöôïc choïn vaø khoâng ñöôïc choïn.

Taïo döï aùn VD36 töông töï VD35. Boå sung bitmap resource chöùa hai aûnh cuøng kích thöôùc: . Ñaët soá

hieäu cho bitmap resource laø IDB_IMGTREE. Haønh vi OnCreate cuûa CEmpTree ñaêng kyù söû duïng aûnh vaø boå sung caùc

phaàn töû caàn thieát: int CEmpTree::OnCreate(LPCREATESTRUCT lpCreateStruct)

Page 88: Mfc Tieng Viet

156 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

{ if (CTreeView::OnCreate(lpCreateStruct) == -1) return -1; static CImageList img; // use only in this function img.Create(IDB_IMGTREE, 16, 2, RGB(255,255,255)); CTreeCtrl& myCtrl = GetTreeCtrl(); // Based control myCtrl.SetImageList(&img, TVSIL_NORMAL); HTREEITEM hihi; // Add needed items hihi = myCtrl.InsertItem("Muc 1", 0, 1); myCtrl.InsertItem("Muc 11", 0, 1, hihi); myCtrl.InsertItem("Muc 12", 0, 1, hihi); hihi = myCtrl.InsertItem("Muc 2", 0, 1); myCtrl.InsertItem("Muc 21", 0, 1, hihi); myCtrl.InsertItem("Muc 22", 0, 1, hihi); hihi = myCtrl.InsertItem("Muc 3", 0, 1); myCtrl.InsertItem("Muc 31", 0, 1, hihi); myCtrl.InsertItem("Muc 321", 0, 1, myCtrl.InsertItem("Muc 32", 0, 1, hihi)); return 0; }

Haønh vi keá thöøa PreCreateWindow aán ñònh thoâng soá daïng treeview:

BOOL CEmpTree::PreCreateWindow(CREATESTRUCT& cs) { cs.style |= TVS_HASLINES|TVS_LINESATROOT| TVS_HASBUTTONS; return CTreeView::PreCreateWindow(cs); }

Moät soá thoâng soá aán ñònh daïng cuûa treeview: TVS_HASLINES : Treeview coù ñöôøng noái giöõa caùc muïc. TVS_LINESATROOT : Ñöôøng noái töø goác. TVS_HASBUTTONS : Coù nuùt môû , ñoùng muïc. TVS_SINGLEEXPAND : Cho pheùp môû 1 muïc duy nhaát ôû moãi luùc. TVS_xxx : Xem MSDN.

THÖÏC HAØNH:

Caùc kieán truùc Document & View 157

1. Taïo öùng duïng soaïn thaûo vaên baûn (text). ÖÙng duïng cho pheùp ngöôøi duøng ñaët password baûo veä döõ lieäu. Chæ môû ñöôïc döõ lieäu neáu coù password hôïp leä. 2. Töông töï baøi taäp 1 cho öùng duïng RTF view. 3. Vieát öùng duïng HTMLView: Thanh coâng cuï rebar (nhö IE cuûa Microsoft); Backward, Forward, hoäp combobox nhaäp vaø ghi nhôù caùc URL ñaõ nhaäp. 4. Phaùt trieån VD36 thaønh öùng duïng cho pheùp xem caáu truùc oå ñóa, caây thö muïc treân maùy nhö windows explorer.

HD: Xem haøm FindFirstFile() vaø FindNextFile(). 5. Taïo cô sôû döõ lieäu Access. Duøng boä DVF (V = FormView) thích hôïp ñeå xem vaø caäp nhaät döõ lieäu cho caùc baûng trong cô sôû döõ lieäu. 6. Vieát öùng duïng RTF View. Trong maøn hình view, khi di chuyeån chuoät leân caùc noäi dung coù chænh daïng gaïch döôùi thì thöïc hieän chuyeån daïng con chuoät thaønh , ngöôïc laïi chænh daïng chuoät veà daïng maëc nhieân cuûa heä thoáng. 7. Vieát öùng duïng thi traéc nghieäm ñôn giaûn: Maøn hình view rtf cho pheùp hieån thò vaên baûn chænh daïng vaø hình aûnh phaûn aùnh noäi dung cuûa caùc caâu hoûi vaø caùc ñaùp aùn löïa choïn. Hieån thò daáu choïn khi ngöôøi duøng ñaùnh daáu ñaùp aùn. 8. Quan saùt chöông trình tra cöùu töø ñieån. Vieát öùng duïng RTF view söû duïng moät cuûa soå con kieåu CEdit. Khi thöïc hieän double treân moät töø baát kyø trong maøn hình view rtf thì kích hoaït cöûa soå con vaø ñieàn töø vöøa choïn vaøo cöûa soå con naøy. Khi ngöôøi duøng click vaøo view, cöûa soå con töï ñoäng bieán maát. 9. Quan saùt chöông trình thi traéc nghieäm TOEFL. Vieát öùng duïng nhö baøi taäp soá 8, Khi thöïc hieän double treân moät doøng baát kyø trong maøn hình view rtf thì kích hoaït cöûa soå con vaø ñieàn noäi dung doøng ñöôïc choïn vaøo cöûa soå con naøy, Khi click vaøo cöûa soå view, noäi dung chænh söûa ñöôïc caäp nhaät vaøo view. 10. Quan saùt Yahoo Messenger!. Thöïc hieän öùng duïng giao dieän rtf nhö sau:

Page 89: Mfc Tieng Viet

158 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

CHÖÔNG 12:

Moät soá vaán ñeà trong windows 12.1 TAÄP TIN INI:

Taäp tin INI laø taäp tin vaên baûn chöùa caùc noäi dung phuïc vuï cho hoaït ñoäng cuûa öùng duïng trong moâi tröôøng windows phieân baûn 3.x vaø 9x. Caùc noäi dung naøy ñöôïc chia thaønh caùc thaønh phaàn (section) phaân bieät theo chöùc naêng hoaëc theo nhoùm öùng duïng con. Moãi thaønh phaàn chöùa caùc muïc vôùi teân goïi xaùc ñònh vaø phaân bieät vôùi caùc muïc khaùc trong cuøng thaønh phaàn. Moãi muïc töông öùng vôùi moät giaù trò duy nhaát. Giaù trò cuûa muïc ñöôïc vieát ngay sau teân muïc, vaø ñöôïc ngaên caùch vôùi teân muïc baèng daáu "=".

Xeùt ví duï laø taäp tin WIN.INI noùi treân:

- windows : Teân thaønh phaàn (section). - NullPort : Teân muïc (entry). - None : Giaù trò cuûa muïc NullPort.

Vieäc truy xuaát giaù trò caùc muïc trong taäp tin INI ñöôïc hoã trôï bôûi lôùp ñoái töôïng quaûn lyù öùng duïng CWinApp thoâng qua caùc thuoäc tính, haønh vi sau:

const char* m_pszAppName : Löu chuoãi teân cuûa öùng duïng. Giaù trò thuoäc tính naøy coù theå ñöôïc thay ñoåi ñöôïc nhö sau: free( (void*) m_pszAppName ); // Giaûi phoùng vuøng nhôù m_pszAppName =_tcsdup( _T(“Teân_môùi_cuûa_öùng_duïng”) );

Moät soá vaán ñeà trong Windows 159

const char* m_pszProfileName : Löu ñöôøng daãn vaø teân taäp tin INI söû duïng bôûi öùng duïng. Coù theå thay ñoåi giaù trò naøy ñeå aán ñònh taäp tin INI: free((void*)m_pszProfileName); // Huûy boû vuøng nhôù caáp phaùt m_pszProfileName=_tcsdup(_T(“ÑöôøngDaãn-TeânTaäpTin_INI”));

BOOL WriteProfileString ( LPCTSTR lpszSection, // Teân thaønh phaàn LPCTSTR lpszEntry, // Teân muïc LPCTSTR lpszValue // Giaù trò cuûa muïc (kieåu chuoãi) ); Löu giaù trò kieåu chuoãi cuûa moät muïc trong thaønh phaàn xaùc ñònh.

BOOL WriteProfileInt ( LPCTSTR lpszSection, // Teân thaønh phaàn LPCTSTR lpszEntry, // Teân muïc int nValue // Giaù trò cuûa muïc (soá nguyeân) ); Löu giaù trò kieåu soá nguyeân cuûa moät muïc trong thaønh phaàn xaùc ñònh.

BOOL WriteProfileBinary ( LPCTSTR lpszSection, // Teân thaønh phaàn LPCTSTR lpszEntry, // Teân muïc LPBYTE pData, // Vuøng ñeäm chöùa giaù trò maõ UINT nBytes // Kích thöôùc vuøng ñeäm ); Löu khoái maõ nhò phaân cuûa moät muïc trong thaønh phaàn xaùc ñònh.

CString GetProfileString ( LPCTSTR lpszSection, // Teân thaønh phaàn LPCTSTR lpszEntry, // Teân muïc. Neáu muïc ñoïc khoâng LPCTSTR lpszDefault = NULL // coù thì söû duïng giaù trò naøy. ); Traû veà giaù trò kieåu chuoãi cuûa moät muïc trong thaønh phaàn töông öùng.

UINT GetProfileInt ( LPCTSTR lpszSection, // Teân thaønh phaàn LPCTSTR lpszEntry, // Teân muïc. Neáu muïc ñoïc khoâng int nDefault // coù thì söû duïng giaù trò naøy. ); Traû veà giaù trò kieåu soá nguyeân cuûa moät muïc trong thaønh töông öùng.

BOOL GetProfileBinary ( LPCTSTR lpszSection, // Teân thaønh phaàn LPCTSTR lpszEntry, // Teân muïc LPBYTE *pData, // Ñòa chæ con troû vuøng ñeäm UINT *nBytes // Ñòa chæ bieán nhaän kích thöôùc. ); Ñoïc khoái maõ nhò phaân cuûa moät muïc vaøo vuøng ñeäm.

Page 90: Mfc Tieng Viet

160 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

Haønh vi traû veà giaù trò TRUE neáu taùc vuï ñoïc thaønh coâng. Vôùi: pData : Ñòa chæ bieán con troû quaûn lyù vuøng ñeäm nhaän thoâng tin. nBytes : Ñòa chæ bieán chöùa kích thöôùc thoâng tin ñoïc ñöôïc.

ÖÙng duïng caàn giaûi phoùng vuøng ñeäm pData khi chaám döùt söû duïng.

Ñoaïn chöông trình sau thöïc hieän ghi xuoáng thaønh phaàn MY_TEST cuûa taäp tin INI cuûa öùng duïng: MyName = Mr.Emp vaø MyVer = 11. CWinApp* pApp = AfxGetApp(); // Ñoái töôïng quaûn lyù öùng duïng pApp->WriteProfileString ("MY_TEST", "MyName", "Mr.Emp"); pApp->WriteProfileInt ("MY_TEST", "MyVer", 11);

Ñoaïn chöông trình sau thöïc hieän ñoïc töø thaønh phaàn MY_TEST cuûa taäp tin INI giaù trò hai muïc noùi treân. CWinApp* pApp = AfxGetApp(); // Ñoái töôïng quaûn lyù öùng duïng CString myName = pApp->GetProfileString ( "MY_TEST", "MyName", "Mr.Emp" ); UINT myVer = pApp->GetProfileInt ("MY_TEST", "MyVer", 11);

12.2 SYSTEM REGISTRY: System Registry laø cô sôû döõ lieäu do windows quaûn lyù, ñöôïc söû duïng ñeå löu

tröõ caùc noäi dung phuïc vuï cho hoaït ñoäng cuûa heä thoáng vaø caùc öùng duïng. System registry coù caáu truùc nhö sau (chöông trình RegEdit.exe).

(System registry ôû moät maùy söû duïng phieân baûn Windows-Me )

Moät soá vaán ñeà trong Windows 161

- Moãi muïc trong caáu truùc caây (tree) goïi laø khoùa (key). - Khoùa laù (khoâng coù con) laø thaønh phaàn chöùa caùc muïc. - Moãi muïc coù moät teân ñeå nhaän bieát vaø coù moät giaù trò xaùc ñònh.

Haønh vi SetRegistryKey cuûa lôùp ñoái töôïng CWinApp cho pheùp ñònh höôùng vieäc ñoïc/ghi giaù trò caùc muïc leân system registry thay vì söû duïng taäp tin INI nhö (12.1). Haønh vi loaïi protected naøy coù cuù phaùp nhö sau:

void SetRegistryKey ( UINT lpszRegistryKey );

lpszRegistryKey : Thoâng thöôøng laø chuoãi chöùa teân haõng phaàn meàm; ví duï Netscape. Giaù trò naøy trôû thaønh khoùa con cuûa khoùa Software thuoäc khoùa goác HKEY_CURRENT_USER trong system registry.

Khi öùng duïng thöïc hieän ñoïc/ghi giaù trò muïc, teân cuûa öùng duïng (löu trong m_pszAppName cuûa ñoái töôïng öùng duïng) trôû thaønh khoùa con cuûa khoùa xaùc ñònh bôûi lpszRegistryKey, vaø caùc thaønh phaàn chöùa caùc muïc trôû thaønh khoùa con cuûa khoùa m_pszAppName. Moät thöù töï ñöôïc thieát laäp nhö sau: HKEY_CURRENT_USER\Software\<Teân_haõng_phaàn_meàm>\ <Teân_öùng_duïng>\<Teân_thaønh_phaàn>\<Caùc_muïc>.

Thöïc hieän öùng duïng IniReg. ÖÙng duïng ñaêng kyù söû duïng system registry vôùi khoùa "Mr.Emp", ñoàng thôøi tieán haønh caùc taùc vuï ñoïc / ghi hai giaù trò nhö ví duï muïc (12.1). Sau ñaây laø caùc böôùc thöïc hieän döï aùn cuûa öùng duïng: Duøng MFC Wizard taïo döï aùn IniReg vôùi giao dieän chính laø dialog. Haønh vi InitInstance cuûa lôùp ñoái töôïng quaûn lyù öùng duïng thöïc hieän ñaët

laïi teân cho öùng duïng vaø ñaêng kyù söû duïng registry vôùi khoùa "Mr.Emp":

BOOL CIniRegApp::InitInstance() { free((void*)m_pszAppName); // Giaûi phoùng vuøng nhôù m_pszAppName=_tcsdup( _T("IniReg") ); // Ñaët teân öùng duïng SetRegistryKey( _T("Mr.EMP") ); // Ñaêng kyù registry

CIniRegDlg dlg; m_pMainWnd = &dlg; dlg.DoModal(); // Thöïc hieän giao dieän return TRUE; }

Thöïc hieän caùc boå sung sau cho lôùp dialog giao dieän CIniRegDlg: - Môû dialog resource, caøi ñaët caùc control sau:

Page 91: Mfc Tieng Viet

162 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

- Hoäp nhaäp giaù trò muïc MyName Edit IDC_WRITE_NAME - Hoäp nhaäp giaù trò muïc MyVer Edit IDC_WRITE_VERSION - Hoäp hieån thò muïc MyName Static IDC_READ_NAME - Hoäp hieån thò muïc MyVer Static IDC_READ_VERSION - Nuùt choïn thöïc hieän ghi Button IDC_WRITE - Nuùt choïn thöïc hieän ñoïc Button IDC_READ

- Haønh vi OnWrite öùng vôùi nuùt IDC_WRITE löu giaù trò caùc muïc:

void CIniRegDlg::OnWrite() { CWinApp* pApp = AfxGetApp(); CString myName; UINT myVer;

GetDlgItemText(IDC_WRITE_NAME, myName); myVer = GetDlgItemInt(IDC_WRITE_VERSION);

pApp->WriteProfileString("MY_TEST", "MyName", myName); pApp->WriteProfileInt("MY_TEST", "MyVer", myVer); }

- Haønh vi OnRead öùng vôùi nuùt IDC_READ ñoïc giaù trò caùc muïc: void CIniRegDlg::OnRead() { CWinApp* pApp = AfxGetApp(); CString myName; UINT myVer;

myName = pApp->GetProfileString( "MY_TEST", "MyName", "NoName" ); myVer = pApp->GetProfileInt( "MY_TEST", "MyVer", 0 );

SetDlgItemText( IDC_READ_NAME, myName ); SetDlgItemInt( IDC_READ_VERSION, myVer ); }

Bieân dòch vaø chaïy öùng duïng.

12.3 VUØNG STATUS AREA TREÂN TASKBAR:

Moät soá vaán ñeà trong Windows 163

Taskbar laø thanh coâng cuï ñaëc bieät cuûa öùng duïng desktop trong windows. Noäi dung cuûa taskbar ñöôïc chia thaønh 4 thaønh phaàn chính:

- Start menu: Muïc kích hoaït heä thoáng menu caùc öùng duïng. - Quick Launch Bar: Danh muïc caùc öùng duïng thöôøng duøng. - Taskbar Buttons: Danh saùch caùc öùng duïng ñang chaïy. - Status Area: Chöùa icon giao dieän cuûa caùc öùng duïng ñang chaïy.

ÖÙng duïng coù theå nhaän ñöôïc tín hieäu nhaäp cuûa ngöôøi duøng khi hoï duøng phím hoaëc chuoät taùc ñoäng leân icon cuûa öùng duïng treân status area.

Vieäc caøi ñaët hoaëc huûy boû icon giao dieän cuûa öùng duïng treân status area ñuôïc thöïc hieän thoâng quan haøm sau:

BOOL Shell_NotifyIcon ( DWORD dwMessage, // Taùc vuï thöïc hieän PNOTIFYICONDATA lpdata // Caáu truùc chöùa thoâng soá lieân quan ); Traû veà giaù trò TRUE neáu taùc vuï thöïc hieän thaønh coâng. dwMessage : AÁn ñònh taùc vuï thöïc hieän. NIM_ADD : Taïo icon giao dieän cuûa öùng duïng treân status area. NIM_MODIFY : Thay ñoåi thoâng soá lieân quan icon giao dieän. NIM_DELETE : Xoùa icon giao dieän cuûa öùng duïng treân status area. lpdata : Ñòa chæ caáu truùc NOTIFYICONDATA chöùa caùc thoâng soá.

Caùc tröôøng trong caáu truùc NOTIFYICONDATA coù yù nghóa nhö sau: typedef struct _NOTIFYICONDATA { DWORD cbSize; // Kích thuôùc caáu truùc HWND hWnd; // Handle cuûa cöûa soå xöû lyù message töø icon UINT uID; // Soá hieäu cuûa icon treân status area UINT uFlags; // Qui ñònh caùc thoâng soá coù yù nghóa UINT uCallbackMessage; // Soá hieäu message cuûa icon göûi cöûa soå. HICON hIcon; // Handle cuûa icon ñöôïc söû duïng TCHAR szTip[64]; // Noäi dung chuù thích cuûa icon giao dieän. } NOTIFYICONDATA, *PNOTIFYICONDATA;

uFlags : Qui ñònh tröôøng thoâng soá trong caáu truùc coù yù nghóa söû duïng. NIF_MESSAGE : Tröôøng uCallbackMessage ñöôïc söû duïng. NIF_ICON : Tröôøng hIcon ñöôïc söû duïng. NIF_TIP : Tröôøng szTip ñöôïc söû duïng. uCallbackMessage : Soá hieäu message seõ göûi traû veà töø icon giao dieän.

Page 92: Mfc Tieng Viet

164 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

Khi ngöôøi duøng taùc ñoäng leân icon giao dieän cuûa öùng duïng, heä thoáng göûi moät message ñeán cöûa soå xöû lyù lieân quan icon vôùi noäi dung nhö sau: - message : Soá hieäu message cuûa icon (trong uCallbackMessage). - wParam : Soá hieäu cuûa icon. - lParam : Chöùa caùc traïng thaùi cuûa chuoät hoaëc phím maø ngöôøi

duøng ñaõ söû duïng ñeå taùc ñoäng leân icon giao dieän. Haønh vi WindowProc cuûa cöûa soå xöû lyù lieân quan seõ tuøy nghi xöû lyù: LRESULT CTaskbarIconDlg::WindowProc ( UINT message, WPARAM wParam, LPARAM lParam ) { if ( message == Icon_uCallbackMessage ) { switch ( lParam ) { … // Xöû lyù bieán coá phím / chuoät trong lParam } return 0 ; } return CDialog::WindowProc(message, wParam, lParam); }

Giaû söû caàn thöïc hieän öùng duïng nhö sau:

- Set Icon: Caøi icon cuûa öùng duïng leân status area. - Remove Icon: Xoùa icon cuûa öùng duïng khoûi status area. - Hoäp thoâng baùo cho bieát caùc bieán coá nhaäp taùc ñoäng leân icon.

Moät soá vaán ñeà trong Windows 165

Caùc böôùc thöïc hieän döï aùn cuûa öùng duïng: Duøng MFC Wizard taïo öùng duïng TaskbarIcon coù giao dieän laø dialog. Thöïc hieän caùc boå sung sau ñaây cho lôùp dialog CTaskbarIconDlg:

- Môû dialog resource, caøi ñaët caùc control sau: - Hoäp thoâng baùo traïng thaùi icon Static IDC_ICON_INFO - Nuùt thöïc hieän ñaët icon Button IDC_ICON_SET - Nuùt thöïc hieän xoùa icon Button IDC_ICON_REMOVE

- Khai baùo thuoäc tính protected m_isIconShow kieåu luaän lyù, ñeå ghi nhaän tình traïng ñaët icon; m_isIconShow = FALSE : icon chöa ñöôïc ñaët, m_isIconShow = TRUE : icon ñaõ ñöôïc ñaët.

- Haønh vi OnInitDialog chuaån bò caùc thoâng soá: BOOL CTaskbarIconDlg::OnInitDialog() { CDialog::OnInitDialog(); m_isIconShow = FALSE; // Baét ñaàu, icon chöa ñöôïc ñaët. return TRUE; }

- Haønh vi OnIconSet öùng vôùi nuùt choïn IDC_ICON_SET thöïc hieän caøi icon giao dieän leân status area:

void CTaskbarIconDlg::OnIconSet() { if ( m_isIconShow ) return; NOTIFYICONDATA dt;

memset(&dt, 0, sizeof( NOTIFYICONDATA ) ); dt.cbSize = sizeof(NOTIFYICONDATA); dt.uID = 100; dt.hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); dt.hWnd = this->GetSafeHwnd(); dt.uCallbackMessage = WM_USER + 10; dt.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; strcpy(dt.szTip,"Mr.Emp, hello world !");

if ( Shell_NotifyIcon( NIM_ADD, &dt ) ) m_isIconShow = TRUE; // Ñaët icon thaønh coâng }

- Haønh vi OnIconRemove öùng vôùi nuùt choïn IDC_ICON_REMOVE thöïc hieän xoùa icon giao dieän khoûi status area:

Page 93: Mfc Tieng Viet

166 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

void CTaskbarIconDlg::OnIconRemove() { if ( !m_isIconShow ) return; NOTIFYICONDATA dt; memset(&dt, 0, sizeof(NOTIFYICONDATA)); dt.cbSize = sizeof(NOTIFYICONDATA); dt.uID = 100; dt.hWnd = this->GetSafeHwnd(); if ( Shell_NotifyIcon( NIM_DELETE, &dt ) ) m_isIconShow = FALSE; // Xoùa icon thaønh coâng }

- Haønh vi WindowProc xöû lyù thoâng tin nhaäp taùc ñoäng leân icon: LRESULT CTaskbarIconDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { if ( message == WM_USER + 10 ) { // WM_USER + 10 : soá hieäu messge ñaêng kyù cho icon. // Xöû lyù caùc thao taùc baám nuùt chuoät (BT) cuûa ngöôøi duøng. switch (lParam) { case WM_MOUSEMOVE: SetDlgItemText(IDC_ICON_INFO, "Mouse moves!"); break; case WM_LBUTTONDOWN: SetDlgItemText(IDC_ICON_INFO, "Left BT down !"); break; case WM_LBUTTONUP: SetDlgItemText(IDC_ICON_INFO, "Left BT up !"); break; case WM_RBUTTONDOWN: SetDlgItemText(IDC_ICON_INFO, "Right BT down !"); break; case WM_RBUTTONUP: SetDlgItemText(IDC_ICON_INFO, "Right BT up !"); break; } return 0; } return CDialog::WindowProc(message, wParam, lParam); }

Bieân dòch vaø chaïy öùng duïng.

Moät soá vaán ñeà trong Windows 167

12.4 ÖÙNG DUÏNG SCREEN SAVER: ScreenSaver laø öùng duïng ñöôïc löu trong taäp tin chöông trình coù phaàn môû

roäng .SCR. Ñeå söû duïng öùng duïng ScreenSaver, ta cheùp taäp tin chöông trình cuûa öùng duïng vaøo thö muïc heä thoáng, sau ñoù söû duïng chöùc naêng Desktop cuûa Control Panel (Desktop Properties) caøi ñaët öùng duïng ScreenSaver cho heä thoáng thoâng qua trang Screen Saver:

Teân taäp tin chöông trình cuûa öùng duïng ScreenSaver ñöôïc duøng laøm teân ScreenSaver trong danh saùch löïa choïn caùc ScreenSaver. Neáu ta khai baùo moät haèng chuoãi vôùi soá hieäu laø 1 trong StringTable resource cuûa öùng duïng thì noäi dung haèng chuoãi naøy (khoâng ñöôïc nhieàu hôn 64 kyù töï) ñöôïc duøng laøm teân ScreenSaver trong danh saùch noùi treân.

Page 94: Mfc Tieng Viet

168 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

Khi khoaûng thôøi gian maø ngöôøi duøng ngöøng töông taùc vôùi heä thoáng vöôït quaù giaù trò aán ñònh Wait thì heä thoáng töï ñoäng thöïc hieän öùng duïng ScreenSaver.

12.4.1 Ñaëc ñieåm: Khaùc vôùi caùc öùng duïng thoâng thöôøng khaùc, öùng duïng ScreenSaver phaûi coù

khaû naêng öùng xöû khaùc nhau trong caùc tình huoáng khaùc nhau maø öùng duïng ñöôïc thöïc hieän. Caùc tình huoáng thöïc hieän coù theå xaûy ra ñoái vôùi moät öùng duïng ScreenSaver laø:

(a) Chaïy minh hoïa tröïc tieáp ScreenSaver trong maøn hình con cuûa hoäp hoäi thoaïi: Khi ngöôøi duøng click choïn öùng duïng ScreenSaver trong danh saùch caùc ScreenSaver cuûa hoäp hoäi thoaïi Display Properties / Screen Saver.

(b) Thöïc hieän chöùc naêng aán ñònh thoâng soá cuûa ScreenSaver: Khi ngöôøi duøng click choïn muïc Setting... sau khi ñaõ choïn öùng duïng ScreenSaver trong danh saùch caùc ScreenSaver.

(c) Thöïc hieän chöùc naêng ñaët Password cuûa ScreenSaver: Khi ngöôøi duøng click choïn muïc Password Setting... sau khi ñaõ choïn öùng duïng ScreenSaver trong danh saùch caùc ScreenSaver. Chæ söû duïng cho caùc phieân baûn Win9x trôû veà tröôùc.

(d) Chaïy minh hoïa ScreenSaver trong maøn hình thöïc: Khi ngöôøi duøng click choïn muïc Preview sau khi ñaõ choïn öùng duïng ScreenSaver trong danh saùch caùc ScreenSaver. Cheá ñoä chaïy naøy töông töï cheá ñoä chaïy thöïc nhaèm giuùp ngöôøi duøng hình dung ñöôïc hoaït ñoäng thöïc cuûa ScreenSaver.

(e) Chaïy ScreenSaver: Khi khoaûng thôøi gian maø heä thoáng ngöøng töông taùc vôùi ngöôøi duøng lôùn hôn khoaûng thôøi gian chôø cho pheùp. Ñaây laø cheá ñoä chaïy thöïc cuûa ScreenSaver.

12.4.2 Tham soá doøng leänh (Command Line Parameters): Moãi khi thöïc hieän öùng duïng ScreenSaver, heä thoáng cung caáp thoâng tin veà

tình huoáng cuï theå maø öùng duïng ñöôïc thöïc hieän thoâng qua noäi dung tham soá doøng leänh göûi ñeán cho chöông trình cuûa öùng duïng. ÖÙng duïng ScreenSaver phaûi laáy thoâng tin naøy töø tham soá doøng leänh nhaèm löïa choïn xöû lyù phuø hôïp.

Thuoäc tính m_lpCmdLine cuûa ñoái töôïng quaûn lyù tieåu trình chính trong öùng duïng chöùa chuoãi tham soá doøng leänh truyeàn cho öùng duïng. Noäi dung cuûa thuoäc tính naøy khaùc nhau tuøy theo tình huoáng thöïc hieän öùng duïng khaùc nhau. Töông öùng caùc tröôøng hôïp (12.4.1), noäi dung tham soá doøng leänh coù theå laø:

Moät soá vaán ñeà trong Windows 169

(a) Chaïy minh hoïa tröïc tieáp ScreenSaver: Vuøng chaïy maãu laø cöûa soå con trong hoäp hoäi thoaïi Display Properties. Handle cuûa cöûa soå naøy laø moät giaù trò trong tham soá doøng leänh coù noäi dung nhö sau:

"/p xxxx" Trong ñoù: - /p (hoaëc /P): Giaù trò phaûn aùnh tình huoáng thöïc hieän. - xxxx : Caùc chöõ soá phaûn aùnh giaù trò handle cuûa cöûa soå con. Caùch laáy giaù trò handle naøy töø tham soá doøng leänh nhö sau:

HWND parent; // Bieán chöùa handle sscanf(m_lpCmdLine+3, "%d", &parent);

ÔÛ cheá ñoä naøy, ScreenSaver ñöôïc thieát keá theo kieåu öùng duïng coù maøn hình giao dieän chính laø cöûa soå vôùi noäi dung hoaït ñoäng nhö chaïy thöïc. Cöûa soå naøy ñöôïc loàng vaøo vò trí cuûa cöûa soå con noùi treân.

(b) Thöïc hieän chöùc naêng aán ñònh thoâng soá: Noäi dung tham soá doøng leänh nhö sau:

"/c xxxx" Trong ñoù: - /c (hoaëc /C) : Giaù trò phaûn aùnh tình huoáng thöïc hieän. - xxxx : Handle cuûa hoäp hoäi thoaïi (dialog). ÔÛ cheá ñoä naøy, ScreenSaver ñöôïc thieát keá theo kieåu öùng duïng coù maøn hình giao dieän chính laø dialog vôùi caùc muïc nhaäp cho pheùp ñieàu chænh thoâng soá lieân quan ñeán caùch thöùc hoaït ñoäng cuûa ScreenSaver ôû cheá ñoä thöïc. Dialog giao dieän laø dialog khoùa (modal dialog) vaø ñoái töôïng cöûa soå cha cuûa noù laø hoäp hoäi thoaïi noùi treân.

(c) Thöïc hieän chöùc naêng ñaët Password: Noäi dung tham soá doøng leänh nhö sau:

"/a xxxx" Trong ñoù: - /a (hoaëc /A): Giaù trò nhaän dieän tình huoáng thöïc hieän. - xxxx : Handle cuûa cöûa soå hoäi thoaïi. ÔÛ cheá ñoä naøy, ScreenSaver ñöôïc thieát keá theo kieåu öùng duïng coù maøn hình giao dieän chính laø dialog. Dialog giao dieän coù theå laø dialog duøng ñaët password cuûa heä thoáng (thö vieän MPR.DLL) hoaëc dialog cuûa ngöôøi duøng.

(d) Chaïy minh hoïa ScreenSaver: Noäi dung tham soá doøng leänh nhö sau: "/s"

Page 95: Mfc Tieng Viet

170 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

Trong ñoù: - /s (hoaëc /S): Giaù trò nhaän dieän tình huoáng thöïc hieän. ÔÛ cheá ñoä naøy, ScreenSaver thöïc hieän xöû lyù nhö chaïy thöïc.

(e) Chaïy ScreenSaver: ÔÛ cheá ñoä naøy, ScreenSaver ñöôïc thieát keá theo kieåu öùng duïng coù maøn hình giao dieän chính laø cöûa soå vôùi noäi dung hoaït ñoäng. Cöûa soå naøy thöôøng coù cuøng kích thöôùc vaø vò trí vôùi cöûa soå desktop cuûa heä thoáng.

Phaàn löïa choïn trình huoáng xöû lyù cuûa öùng duïng ScreenSaver ñöôïc caøi ñaët trong haønh vi InitInstance cuûa ñoái töôïng quaûn lyù öùng duïng.

12.4.3 Ñaëc ñieåm giao taùc vôùi ngöôøi duøng: Caùc öùng duïng ScreenSaver coù ñaëc ñieåm chung laø chaám döùt hoaït ñoäng khi

nhaän ñöôïc tín hieäu nhaäp cuûa ngöôøi duøng (goõ phím, click hay di chuyeån chuoät). Do ñoù, chöông trình ScreenSaver phaûi xöû lyù caùc message lieân quan vieäc nhaäp lieäu:

- Caùc message do taùc ñoäng leân baøn phím: WM_KEYDOWN, WM_KEYUP

- Caùc message do taùc ñoäng leân chuoät: WM_MOUSEMOVE, WM_LBUTTONDOWN, WM_LBUTTONUP, WM_RBUTTONDOWN, WM_RBUTTONUP, WM_MBUTTONUP, WM_MBUTTONDOWN

Thoâng thöôøng, khi nhaän ñöôïc moät trong caùc message naøy thì öùng duïng töï ñoäng keát thuùc.

Trong luùc ScreenSaver hoaït ñoäng, caàn ngaên caám caám ngöôøi duøng goõ phím Ctrl+Alt+Del ñeå ‘qua maët’ öùng duïng. Vieäc ngaên caám naøy thöïc hieän nhö sau:

UINT oldval; // Duøng baûo löu traïng thaùi // Baét ñaàu, caám phím: SystemParametersInfo ( SPI_SETSCREENSAVERRUNNING, 1 , &oldval, 0 ); ... // Phaàn thöïc hieän cuûa ScreenSaver

// Cuoái cuøng, thoâi caám phím: SystemParametersInfo ( SPI_SETSCREENSAVERRUNNING, 0, &oldval, 0);

12.4.4 Thöïc hieän öùng duïng ScreenSaver ñôn giaûn:

Moät soá vaán ñeà trong Windows 171

Giaû söû caàn thöïc hieän öùng duïng ScreenSaver vôùi noäi dung hoaït ñoäng laø hieån thò caâu chaøo "Hello !". Caùc böôùc thöïc hieän nhö sau:

Taïo döï aùn ScreenSaver töông töï döï aùn VD01. Boå sung lôùp CEmpScreenSaverWnd keá thöøa töø lôùp CWnd cho döï aùn.

Thöïc hieän caøi ñaët cho lôùp CEmpScreenSaverWnd nhö sau: - Haønh vi OnPaint hieån thò thoâng baùo "Hello !" ôû chính giöõa vuøng

client cuûa cöûa soå.

void CEmpScreenSaverWnd::OnPaint() { CPaintDC dc(this); // device context ñeå veõ // Do ScreenSaver's works here : LOGFONT lf; CFont font, *oldFont; memset(&lf, 0, sizeof(LOGFONT)); strcpy(lf.lfFaceName, "Arial"); lf.lfHeight = 50; lf.lfWidth = 14; font.CreateFontIndirect(&lf); // Taïo font chöõ ñeå söû duïng oldFont = dc.SelectObject(&font); // vaø löu font chöõ cuõ. RECT rect; dc.GetClipBox(&rect); // Xoùa neàn DC dc.FillRect(&rect, &CBrush(RGB(0, 128,128))); dc.SetBkMode(TRANSPARENT); rect.top += 3; rect.left+= 3; dc.SetTextColor(RGB(0, 0, 128)); dc.DrawText("Hello !", 7, &rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE); rect.top -= 3; rect.left -= 3; rect.bottom -= 3; rect.right -= 3; dc.SetTextColor(RGB(255, 255, 0)); dc.DrawText("Hello !", 7, &rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE); dc.SelectObject(oldFont); // Khoâi phuïc laïi font chöõ cuõ }

Page 96: Mfc Tieng Viet

172 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

- Caùc haønh vi xöû lyù message cuûa chuoät vaø baøn phím: OnKeyDown, OnLButtonDown, OnMouseMove, OnRButtonDown thöïc hieän göûi message ñoùng cöûa soå:

PostMessage( WM_CLOSE, 0, 0 );

Taïo môùi dialog resource vaø lôùp CEmpScreenSaverDlg keá thöøa töø CDialog söû duïng dialog resource naøy. Dialog CEmpScreenSaverDlg cho pheùp ngöôøi duøng chænh söûa caùc thoâng soá lieân quan ñeán hoaït ñoäng cuûa öùng duïng ScreenSaver. Coù theå löu caùc thoâng soá aán ñònh bôûi ngöôøi duøng vaøo system registry (12.2).

Boå sung vaø chænh söûa lôùp quaûn lyù öùng duïng CEmpApp nhö sau: - Boå sung caùc thuoäc tính protected quaûn lyù hoaït ñoäng ScreenSaver:

BOOL m_bFullDemo; UINT Ctrl_Alt_Del_State;

- Haønh vi InitInstance löïa choïn xöû lyù ñeå thöïc hieän moät caùch phuø hôïp vôùi caùc tình huoáng hoaït ñoäng cuûa öùng duïng: BOOL CEmpApp::InitInstance() { m_bFullDemo = FALSE; // Löu cheá ñoä minh hoïa HWND parent; // Handle cöûa soå cha RECT rect; // Vò trí cöûa soå öùng duïng DWORD exstyle = 0, style; // Daïng cöûa soå öùng duïng

sscanf(m_lpCmdLine + 3, "%d", &parent);

switch (m_lpCmdLine[1]) { case 'c': case 'C': // Chöùc naêng aán ñònh thoâng soá CEmpScreenSaverDlg* main; CWnd* pr; pr = new CWnd(); pr->Attach(parent); main = new CEmpScreenSaverDlg(pr); m_pMainWnd = main; main->DoModal(); pr->Detach(); delete main; delete pr; return FALSE;

Moät soá vaán ñeà trong Windows 173

case 'a': case 'A': // Ñaët Password (khoâng duøng cho WinNT-Win2000) // Söû duïng hoäp Password cuûa heä thoáng cho töông thích. typedef VOID (WINAPI *PWDCHANGEPASSWORD) ( LPCSTR lpcRegkeyname, HWND hwnd,UINT uiReserved1, UINT uiReserved2 );

PWDCHANGEPASSWORD PwdChangePassword;

HINSTANCE hmpr; hmpr = ::LoadLibrary("MPR.DLL"); if (hmpr == NULL) return FALSE; PwdChangePassword = (PWDCHANGEPASSWORD) ::GetProcAddress(hmpr, "PwdChangePasswordA"); if (PwdChangePassword != NULL) PwdChangePassword("SCRSAVE",parent,0,0); FreeLibrary(hmpr); return FALSE; case 'p': case 'P': // Xem minh hoïa trong maøn hình con style = WS_CHILD | WS_VISIBLE | WS_DISABLED ; break; default: // Cheá ñoä chaïy thöïc cuûa ScreenSaver m_bFullDemo = TRUE; parent = GetDesktopWindow(); exstyle = WS_EX_TOOLWINDOW | WS_EX_TOPMOST; style = WS_POPUP | WS_VISIBLE; } // Xaùc ñònh cheá ñoä chaïy cuï theå CEmpScreenSaverWnd* main; main = new CEmpScreenSaverWnd; m_pMainWnd = main;

POINT p1, p2; // Goùc traùi treân, phaûi döôùi GetWindowRect (parent, &rect); // Xaùc ñònh vò trí cöûa soå cha p1.x = rect.left; p1.y = rect.top; p2.x = rect.right; p2.y = rect.bottom;

Page 97: Mfc Tieng Viet

174 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

if (!m_bFullDemo) { // Chaïy trong cöûa soå con : // Xaùc ñònh toïa ñoä cöûa soå con trong hoäp Display Properties ScreenToClient ( parent, &p1 ); ScreenToClient ( parent, &p2 ); }

// Cöûa soå giao dieän chính coù toïa ñoä vaø kích thöôùc thích hôïp main->CreateEx(exstyle, _T("STATIC"),"Emp.ScreenSaver", style, p1.x, p1.y, p2.x, p2.y, parent, NULL); // Daáu con chuoät vaø khoùa phím neáu chaïy ScreenSaver thöïc if (m_bFullDemo) { ShowCursor(FALSE); main->SetCapture(); SystemParametersInfo ( SPI_SETSCREENSAVERRUNNING, 1,&Ctrl_Alt_Del_State, 0 ); } main->UpdateWindow(); return TRUE; }

- Haønh vi ExitInstance thöïc hieän gôõ boû caùc caøi ñaët:

int CEmpApp::ExitInstance() { if (m_bFullDemo) { ReleaseCapture(); ShowCursor(TRUE); SystemParametersInfo ( SPI_SETSCREENSAVERRUNNING, 0, &Ctrl_Alt_Del_State, 0 ); } return CWinApp::ExitInstance(); }

Taïo haèng chuoãi tuøy yù coù soá hieäu laø 1 trong StringTable resource. Bieân dòch öùng duïng. Cheùp taäp tin chöông trình (.exe) vaøo thö muïc heä

thoáng vaø ñoåi teân taäp tin vôùi phaàn môû roäng laø .SCR. Söû duïng Control Panel / Display / ScreenSaver kieåm tra keát quaû.

Moät soá vaán ñeà trong Windows 175

12.5 ÖÙNG DUÏNG SÖÛ DUÏNG NHIEÀU TIEÅU TRÌNH: Vieäc thieát laäp caùc tieåu trình con hoã trôï cho tieåu trình chính trong chöông

trình cuûa öùng duïng cho pheùp öùng duïng ñoàng thôøi ñaùp öùng nhieàu yeâu caàu cuûa ngöôøi duøng. Caùc tieåu trình hoã trôï coù theå thöïc hieän caùc xöû lyù beân trong (tieåu trình xöû lyù noäi – worker thread) hoaëc tröïc tieáp nhaän vaø thöïc hieän caùc yeâu caàu cuûa ngöôøi duøng (tieåu trình giao dieän– user interface thread). 12.5.1 Tieåu trình xöû lyù noäi:

Tieåu trình xöû lyù noäi ñaûm nhaän caùc xöû lyù tính toaùn beân trong, khoâng tröïc tieáp töông taùc vôùi ngöôøi duøng. Vieäc thieát laäp tieåu trình xöû lyù noäi trong chöông trình ñöôïc thöïc hieän thoâng qua caùc noäi dung sau ñaây:

Xaây döïng haøm ñaûm nhaän vieäc ñieàu khieån toaøn boä hoaït ñoäng xöû lyù cuûa tieåu trình (Thread Procedure). Haøm naøy coù khai baùo nhö sau: UINT MyThreadProc ( LPVOID pParam );

pParam : Tham soá duy nhaát maø haøm ñieàu khieån nhaän ñöôïc khi tieåu trình ñöôïc kích hoaït.

Khi keát thuùc xöû lyù, haøm phaûi traûveà moät giaù trò soá nguyeân phaûn aùnh tình traïng keát thuùc cuûa haøm. Thoâng thöôøng, giaù trò 0 traû veà cho moät keát thuùc thaønh coâng, caùc giaù trò khaùc 0 laø caùc qui öôùc veà hieän töôïng loãi.

Thöïc hieän khôûi ñoäng tieåu trình xöû lyù noäi thoâng qua haøm sau: CWinThread* AfxBeginThread ( AFX_THREADPROC pfnThreadProc, // Haøm ñieàu khieån LPVOID pParam, // Tham soá cuûa haøm. int nPriority = THREAD_PRIORITY_NORMAL, UINT nStackSize = 0, DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL );

Sau ñaây laø boá cuïc thöïc hieän toaøn boä coâng vieäc treân: UINT MyThreadProc( LPVOID pParam ) { … // Khai thaùc noäi dung cuûa pParam … // Thöïc hieän caùc xöû lyù caàn thieát.

return ( coù_loãi ) ? 1 : 0; } … // Chuaån bò khôûi ñoäng tieåu trình pInfo = new MyInfo ; // Chæ ñeán vuøng chöùa caùc giaù trò thoâng soá AfxBeginThread( MyThreadProc, pInfo );

Page 98: Mfc Tieng Viet

176 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

Giaû söû caàn thöïc hieän öùng duïng sau:

- Tieåu trình xöû lyù noäi caøi ñaët bôûi moät haøm coù nhieäm vuï thöïc hieän chaïy doøng chöõ trong hoäp thoâng baùo cho ñeán khi coù tín hieäu ngöøng.

- Tieåu trình giao dieän quaûn lyù dialog nhaän yeâu caàu ngöôøi duøng: Muïc Start Text Scrolling khôûi ñoäng tieåu trình thöïc hieän chaïy chöõ.

Muïc choïn naøy sau ñoù ñoåi thaønh Stop Text Scrolling ñeå ñieàu khieån ngöøng tieåu trình noùi treân.

Muïc Close chaám döùt öùng duïng. Döï aùn cuûa öùng duïng ñöôïc thöïc hieän nhö sau: Taïo döï aùn WorkerThread vôùi giao dieän chính laø dialog. Thöïc hieän caùc caøi ñaët sau cho lôùp CWorkerThreadDlg laøm giao dieän:

- Môû dialog resource, caøi ñaët caùc control sau: - Hoäp chöùa doøng chöõ chaïy Static IDC_INFO - Nuùt leänh cho pheùp chöõ chaïy | ngöøng Button IDOK

- Thuoäc tính public m_isTextScrolled kieåu BOOL ghi nhaän thoâng tin veà hoaït ñoäng chaïy chöõ.

- Haønh vi OnInitDialog khôûi ñoäng caùc thoâng soá:

BOOL CWorkerThreadDlg::OnInitDialog() { CDialog::OnInitDialog(); SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon

m_isTextScrolled = FALSE; // Chöa thöïc hieän chaïy chöõ

return TRUE; }

- Haønh vi OnOK öùng vôùi nuùt leänh IDOK thöïc hieän khôûi ñoäng hoaëc thoâng baùo ngöøng tieåu trình xöû lyù chaïy chöõ:

Moät soá vaán ñeà trong Windows 177

void CWorkerThreadDlg::OnOK() { if (m_isTextScrolled) { SetDlgItemText( IDOK, "Start Text Scrolling" ); // Ñaët giaù trò thoâng baùo tieåu trình chaïy chöõ chaám döùt m_isTextScrolled = FALSE; } else { SetDlgItemText(IDOK, "Stop Text Scrolling"); // Ñaët giaù trò cho pheùp cho tieåu trình chaïy chöõ thöïc hieän m_isTextScrolled = TRUE; // Khôûi ñoäng tieåu trình vôùi tham soá laø dialog giao dieän AfxBeginThread( TextScrolling, this ); } }

TextScrolling laø haøm xöû lyù cuûa tieåu trình chaïy chöõ. Haøm nhaän tham soá void* laø con troû chæ ñeán ñoái töôïng dialog giao dieän. Coù theå khai baùo haøm trong phaàn caøi ñaët cuûa lôùp CWorkerThreadDlg ñeå tieän söû duïng.

UINT TextScrolling(void* pParam) { // Con troû pParam thöïc chaát laø con troû ñoái töôïng dialog giao dieän CWorkerThreadDlg* pDlg = (CWorkerThreadDlg*)pParam; static CString info = " Welcome to multi-thread programming";

while (pDlg->m_isTextScrolled) { // Giaù trò thoâng baùo cho pheùp tieåu trình tieáp tuïc thöïc hieän: info = info.Mid(1) + info.Left(1); pDlg->SetDlgItemText(IDC_INFO, info); Sleep(100); // Taïm nghæ } return 0; // Keát thuùc tieåu trình xöû lyù noäi }

Bieân dòch vaø chaïy thöû öùng duïng.

12.5.2 Tieåu trình giao dieän: Tieåu trình giao dieän coù khaû naêng tröïc tieáp nhaän vaø xöû lyù yeâu caàu cuûa

ngöôøi duøng moät caùch ñoäc laäp vôùi tieåu trình chính (cuõng laø tieåu trình giao dieän) cuûa öùng duïng. Vieäc thieát laäp tieåu trình giao dieän trong chöông trình ñöôïc thöïc hieän thoâng qua caùc noäi dung sau ñaây:

Page 99: Mfc Tieng Viet

178 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

Chuaån bò giao dieän (cöûa soå hoaëc dialog) cuûa tieåu trình giao dieän. Xaây döïng lôùp keá thöøa töø CWinThread ñeå quaûn lyù tieåu trình giao dieän.

Söû duïng giao dieän treân cho lôùp thoâng qua haønh vi InitInstance cuûa lôùp. Thöïc hieän khôûi ñoäng tieåu trình giao dieän thoâng qua haøm sau:

CWinThread* AfxBeginThread ( CRuntimeClass* pThreadClass, int nPriority = THREAD_PRIORITY_NORMAL, UINT nStackSize = 0, DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL ); pThreadClass : Con troû ñeán caáu truùc quaûn lyù thoâng tin thi haønh cuûa lôùp ñoái töôïng quaûn lyù tieåu trình giao dieän ñöôïc kích hoaït. Xem (11.4).

Giaû söû coù yeâu caàu thöïc hieän öùng duïng vôùi hai giao dieän hoaït ñoäng ñoàng haønh; giao dieän Sub Interface of program ñöôïc kích hoaït khi ngöôøi duøng click choïn muïc Run the sub user-interface thread dialog treân dialog giao dieän cuûa tieåu trình giao dieän chính.

Caùc böôùc thöïc hieän nhö sau: Taïo döï aùn UserIntThread vôùi giao dieän chính laø dialog. Thieát keá dialog resource cho giao dieän con. Treân dialog resource naøy,

caøi nuùt thoaùt vôùi soá hieäu IDCANCEL. Boå sung lôùp CSubUserDlg keá thöøa töø CDialog söû duïng resource treân. Boå sung lôùp ñoái töôïng CSubUserThread keá thöøa töø CWinThread cho

pheùp quaûn lyù caùc tieåu trình giao dieän con. Ñoái töôïng CSubUserThread nhaän ñoái töôïng CSubUserDlg laøm cöûa soå giao dieän chính thoâng qua haønh vi InitInstance cuûa noù.

Moät soá vaán ñeà trong Windows 179

BOOL CSubUserThread::InitInstance() { CSubUserDlg dlg; m_pMainWnd = &dlg; dlg.DoModal(); return TRUE; }

Thöïc hieän caùc caøi ñaët sau cho lôùp dialog CUserIntThreadDlg: - Môû dialog resource, caøi ñaët caùc control sau:

- Nuùt leänh kích hoaït tieåu trình giao dieän con Button IDOK - Nuùt leänh keát thuùc öùng duïng Button IDCANCEL

- Haønh vi OnOK cho nuùt choïn IDOK kích hoaït tieåu trình giao dieän: void CUserIntThreadDlg::OnOK() { AfxBeginThread( RUNTIME_CLASS(CSubUserThread) ); }

Bieân dòch vaø chaïy thöû öùng duïng.

12.5.3 Caùc haøm hoã trôï: void AfxEndThread (

UINT nExitCode // Giaù trò keát thuùc tieåu trình }; Chaám döùt hoaït ñoäng cuûa tieåu trình. Haøm chæ ñöôïc söû duïng trong phaàn caøi ñaët xöû lyù cuûa tieåu trình.

BOOL GetExitCodeThread ( HANDLE hThread, // Handle cuûa tieåu trình LPDWORD lpExitCode // Con troû ñeán bieán chöùa keát quaû. ); Laáy giaù trò keát thuùc cuûa moät tieåu trình. Traû veà giaù trò TRUE neáu taùc vuï thöïc hieän thaønh coâng. hThread cuûa moät tieåu trình coù theå laáy töø thuoäc tính m_hThread cuûa ñoái töôïng CWinThread quaûn lyù tieåu trình.

12.6 LAÄP TRÌNH MULTIMEDIA VÔÙI MCI: MCI (Media Control Interface) cung caáp boä leänh cô baûn coù tính thích nghi

cao vôùi nhieàu thieát bò media trong vieäc thöïc hieän caùc noäi dung multimedia. Moãi thieát bò media söû duïng cho vieäc thöïc hieän noäi dung multimedia ñöôïc

MCI quaûn lyù thoâng qua cöûa soå giao dieän MCI thuoäc lôùp MCIWnd. Ñaây laø lôùp cöûa soå do MCI ñaêng kyù tröôùc nhaèm phuïc vuï cho muïc ñích naøy.

Cöûa soå giao dieän MCI nhö sau:

Page 100: Mfc Tieng Viet

180 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

Sau ñaây laø caùc haøm MCI söû duïng phoå bieán (Vfw.h): HWND MCIWndCreate (

HWND hwndParent, // Handle cöûa soå cha cuûa cöûa soå MCI HINSTANCE hInstance, // Handle cuûa öùng duïng DWORD dwStyle, // Daïng cöûa soå giao dieän MCI LPSTR szFile // Ñöôøng daãn, teân taäp tin media. ); Môû thieát bò media vaø söû duïng noäi dung multimedia trong taäp tin töông öùng. Haøm traû veà con troû cöûa soå MCI quaûn lyù thieát bò ñöôïc môû. Thoâng soá dwStyle cuûa cöûa soå MCI ñöôïc keát hôïp töø caùc giaù trò sau: MCIWNDF_SHOWALL : Hieån thò caùc muïc cuûa cöûa soå. MCIWNDF_NOMENU : Khoâng hieån thò nuùt choïn menu. MCIWNDF_NOPLAYBAR : Khoâng hieån thò progressbar.

LONG MCIWndOpen ( // Traû veà giaù trò 0 neáu thaønh coâng. HWND hwnd, // Handle cöûa soå MCI LPSTR szFile // Ñöôøng daãn, teân taäp tin media. DWORD dwStyle = 0 ); Môû noäi dung multimedia môùi cho thieát bò media quaûn lyù bôûi hwnd.

LONG MCIWndClose( HWND hwnd ); Ñoùng noäi dung multimedia. LONG MCIWndPlay( HWND hwnd ); Thöïc hieän. LONG MCIWndStop( HWND hwnd ); Ngöøng thöïc hieän. LONG MCIWndPause( HWND hwnd ); Taïm ngöøng. LONG MCIWndResume( HWND hwnd ); Tieáp tuïc. VOID MCIWndDestroy( HWND hwnd ); Ñoùng thieát bò media.

Giaû söû thieát keá öùng duïng cho pheùp choïn taäp tin multimedia; muïc Play thöïc hieän noäi dung taäp tin, muïc Stop ngöøng thöïc hieän. Caùc böôùc tieán haønh nhö sau: Duøng MFC Wizard taïo döï aùn MCI vôùi giao dieän chính laø dialog. Khai baùo söû duïng thö vieän MCI trong taäp tin STDAFX.H:

#include <Vfw.h> #pragma comment (lib, "Vfw32.lib") // MCI library

Trong lôùp dialog giao dieän chính: CMCIDlg Moät soá vaán ñeà trong Windows 181

- Môû dialog resource, caøi caùc control sau: - Hoäp nhaäp ñöôøng daãn, teân taäp tin Edit IDC_FILE - Nuùt leänh thöïc hieän Play Button IDC_PLAY - Nuùt leänh thöïc hieän Stop Button IDC_STOP

- Boå sung thuoäc tính protected m_mciWnd kieåu HWND duøng quaûn lyù thieát bò media ñöôïc söû duïng.

- Haønh OnInitDialog khôûi ñoäng thieát bò media:

BOOL CMCIDlg::OnInitDialog() { CDialog::OnInitDialog();

SetDlgItemText(IDC_FILE, "HappyNewYear.rmi"); m_mciWnd = MCIWndCreate ( this->GetSafeHwnd(), AfxGetInstanceHandle(), /*invisible*/ ~WS_VISIBLE, NULL );

return TRUE; }

- Haønh vi OnPlay öùng vôùi nuùt IDC_PLAY thöïc hieän noäi dung media: void CMCIDlg::OnPlay() { char fName[1024]; // Laáy teân taäp tin multimedia GetDlgItemText(IDC_FILE, fName, 1023);

if ( MCIWndOpen( m_mciWnd, fName, 0 ) == 0 ) { MCIWndPlay( m_mciWnd ); } }

- Haønh vi OnStop ngöøng thöïc hieän: void CMCIDlg::OnStop() { MCIWndStop( m_mciWnd ); }

Bieân dòch vaø chaïy thöû öùng duïng.

12.7 AÁN ÑÒNH MOÄT SOÁ TÍNH NAÊNG CUÛA WINDOWS: Moâi tröôøng windows cho pheùp ngöôøi duøng aán ñònh moät soá tính naêng tieän

ích nhö cheá ñoä töï ñoäng ngaét nguoàn, taét maùy,…. Caùc tính naêng naøy coù theå ñöôïc caøi ñaët thoâng qua chöông trình tieän ích hoaëc laäp trình töï ñoäng vôùi haøm sau:

Page 101: Mfc Tieng Viet

182 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

BOOL SystemParametersInfo ( UINT uiAction, // Soá hieäu cuûa chöùc naêng caàn thöïc hieän UINT uiParam, // AÁn ñònh tuøy thuoäc uiAction PVOID pvParam, // Con troû vuøng ñeäm, tuøy thuoäc uiAction UINT fWinIni // Ñeà nghò caäp nhaät user profile. = 0: khoâng. ); Laáy hoaëc ñaët thoâng soá qui ñònh tính naêng töông öùng cuûa heä thoáng. Giaù trò uiAction coù theå laø: SPI_GETLOWPOWERTIMEOUT : Laáy thoâng soá low power timeout SPI_GETPOWEROFFTIMEOUT : Laáy thoâng soá power timeout SPI_GETSCREENSAVETIMEOUT : Laáy thoâng soá S.saver timeout SPI_SETLOWPOWERTIMEOUT : Ñaët thoâng soá low power timeout SPI_SETPOWEROFFTIMEOUT : Ñaët thoâng soá power timeout SPI_SETSCREENSAVETIMEOUT : Ñaët thoâng soá S.saver timeout.

Khi uiAction laø giaù trò coù yù nghóa laáy thoâng soá: uiParam : Coù giaù trò baèng 0 pvParam : Chæ ñeán vuøng ñeäm nhaän giaù trò thoâng soá hieän haønh. Khi uiAction laø giaù trò coù yù nghóa ñaët thoâng soá:

uiParam : Giaù trò thoâng soá aán ñònh. pvParam : = NULL

Ñoaïn chöông trình sau thöïc hieän caám tính naêng screen saver:

UINT oldStatus; // Laáy thoâng soá qui ñònh tính naêng ScreenSaver, löu vaøo oldStatus SystemParametersInfo( SPI_GETSCREENSAVETIMEOUT, 0, &oldStatus, 0 ); // Caám tính naêng ScreenSaver SystemParametersInfo( SPI_SETSCREENSAVETIMEOUT, 0, NULL, 0 );

… // Caùc xöû lyù trong ñieàu kieän ScreenSaver bò caám

// Traû laïi aán ñònh tröôùc ñoù cho tính naêng ScreenSaver : oldStatus SystemParametersInfo( SPI_SETSCREENSAVETIMEOUT, oldStatus, NULL, 0 );

12.8 BAÃY (HOOK) MESSAGE (WINDOWS HOOK): Hook laø moät khaâu trong cô cheá xöû lyù message cuûa windows maø öùng duïng

coù theå can thieäp ñeå caøi ñaët thuû tuïc xöû lyù message (hook procedure) tröôùc khi message ñoù ñeán ñöôïc ñoái töôïng xöû lyù message maø heä thoáng ñieàu phoái.

Moät soá vaán ñeà trong Windows 183

12.8.1 Caùc kieåu hook (Hook Type): Hook ñöôïc phaân chia thaønh caùc kieåu khaùc nhau tuøy thuoäc vaøo kieåu

message ñöôïc hook. Moät soá kieåu hook phoå bieán nhö sau: WH_KEYBOARD : Hook caùc message lieân quan baøn phím. WH_MOUSE : Hook caùc message lieân quan con chuoät. WH_CBT : Hook caùc thao taùc treân cöûa soå giao dieän. WH_CALLWNDPROCRET : Hook giaù trò traû veà töø haøm xöû lyù message

WindowProc coù kieåu CWPRETSTRUCT. WH_CALLWNDPROC : Hook caùc message tröôùc khi message ñöôïc

chuyeån ñeán thuû tuïc WindowProc.

12.8.2 Danh saùch hook (Hook Chain): Danh saùch hook laø danh saùch caùc con troû chæ ñeán caùc thuû tuïc hook. Moãi

kieåu hook coù moät danh saùch hook rieâng. Khi moät message phaùt sinh, noù ñöôïc chuyeån ñeán danh saùch hook lieân quan; töø thuû tuïc hook naøy ñeán ñeán thuû tuïc hook khaùc. Moãi thuû tuïc hook coù theå tuøy nghi thöïc hieän caùc xöû lyù khaùc nhau: ghi nhaän message, chænh söûa message, hoaëc ngaên caám message khoâng ñeå noù ñeán ñöôïc thuû tuïc hook keá tieáp.

12.8.3 Thuû tuïc hook (Hook Procedure): Thuû tuïc hook laø chöông trình con chuyeân duïng cho vieäc hook loaïi message

lieân quan. Chöông trình con xöû lyù hook coù khai baùo nhö sau: LRESULT CALLBACK HookProc ( int nCode, WPARAM wParam, LPARAM lParam ); Caùc tham soá göûi cho chöông trình con naøy khaùc nhau theo töøng kieåu hook: WH_KEYBOARD – xöû lyù message baøn phím - KeyboardProc:

code : - HC_ACTION: Message cuûa phím ñöôïc thöïc hieän. - HC_NOREMOVE: Message cuûa phím chöa ñöôïc laáy khoûi

message queue. wParam: Maõ phím lieân quan. lParam : - Caùc bit 0÷15 : Giaù trò cho bieát soá laàn goõ phím - Caùc bit 16÷23 : Maõ scan code cuûa phím. - Bit 29 : Baèng 1 neáu phím Alt ñöôïc nhaán keøm.

WH_MOUSE – xöû lyù message töø con chuoät - MouseProc: code : - HC_ACTION: Message cuûa chuoät ñöôïc thöïc hieän. - HC_NOREMOVE: Message cuûa chuoät chöa ñöôïc laáy khoûi

message queue. wParam : Soá hieäu message cuûa con chuoät

Page 102: Mfc Tieng Viet

184 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

lParam : Con troû ñeán caáu truùc MOUSEHOOKSTRUCT.

typedef struct tagMOUSEHOOKSTRUCT { POINT pt; // Vò trí chæ ñieåm cuûa con chuoät HWND hwnd; // Handle cöûa soå lieân quan. UINT wHitTestCode; // Xem (4.2): WM_SETCURSOR ULONG_PTR dwExtraInfo; // Caùc thoâng tin boå sung khaùc. } MOUSEHOOKSTRUCT, *PMOUSEHOOKSTRUCT;

WH_CBT – Xöû lyù thao taùc treân cöûa soå - CBTProc: Quan heä giöõa caùc thoâng soá nhö sau:

Code wParam lParam HCBT_ACTIVATE ( Kích hoaït cöûa soå )

Handle cuûa cöûa soå Con troû caáu truùc chöùa thoâng tin.

HCBT_CREATEWND ( Taïo môùi cöûa soå )

Handle cuûa cöûa soå. Con troû caáu truùc chöùa thoâng tin.

HCBT_DESTROYWND ( Huûy boû cöûa soå )

Handle cuûa cöûa soå. =NULL

HCBT_MINMAX ( Phoùng to hay Thu nhoû cöûa soå )

Handle cuûa cöûa soå. Word thaáp chöùa thoâng soá hieån thò cöûa soå ( SW_xxx ).

HCBT_MOVESIZE ( Di chuyeån hoaëc thay ñoåi kích thöôùc cöûa soå )

Handle cuûa cöûa soå. Con troû caáu truùc RECT quaûn lyù toïa ñoä, kích thöôùc môùi.

12.8.4 Caùc dòch vuï lieân quan hook: HHOOK SetWindowsHookEx (

int idHook, // Kieåu hook HOOKPROC lpfn, // Ñòa chæ thuû tuïc hook HINSTANCE hMod, // Handle cuûa ñôn theå chöùa hook DWORD dwThreadId // Soá hieäu tieåu trình söû duïng hook ); Caøi ñaët thuû tuïc hook vaøo danh saùch hook töông öùng. Haøm traû veà handle cuûa thuû tuïc hook ñöôïc caøi ñaët tröôùc thuû tuïc bò chieám quyeàn. dwThreadId : Tieåu trình söû duïng hook; =0: taát caû caùc tieåu trình. lpfn : Neáu thuû tuïc hook söû duïng cho taát caû caùc tieåu trình thì neân

ñaët noù trong moät taäp tin DLL.

Moät soá vaán ñeà trong Windows 185

hMod : Handle cuûa öùng duïng hoaëc DLL chöùa thuû tuïc hook. LRESULT CallNextHookEx (

HHOOK hhk, // Handle cuûa thuû tuïc hook chieám quyeàn int nCode, // Chuyeån giao giaù trò caùc tham soá WPARAM wParam, // maø thuû tuïc hook chieám quyeàn LPARAM lParam // nhaän ñöôïc töø heä thoáng ); Thöïc hieän thuû tuïc hook bò chieám quyeàn, giuùp oån ñònh cho windows.

BOOL UnhookWindowsHookEx ( HHOOK hhk // Handle cuûa thuû tuïc hook huûy boû. ); Huûy boû thuû tuïc hook trong danh saùch hook.

Neáu thuû tuïc hook ñöôïc caøi trong DLL thì caàn söû duïng caùc haøm sau: HMODULE LoadLibrary (

LPCTSTR lpFileName // Ñöôøng daãn, teân taäp tin DLL ); Traû veà giaù trò handle cuûa DLL.

FARPROC GetProcAddress ( HMODULE hModule, // Handle cuûa DLL chöùa thuû tuïc LPCSTR lpProcName // Teân thuû tuïc ); Traû veà con troû cuûa thuû tuïc töông öùng.

12.8.5 ÖÙng duïng hook messages cuûa keyboard: Trong phaàn naøy, ta thöïc hieän öùng duïng hook message cuûa baøn phím. Xöû lyù

hook cuûa öùng duïng baät tieáng beep ñeå thoâng baùo coù goõ phím vaø chuyeån message nhaän ñöôïc cho thuû tuïc xöû lyù hook ñaõ bò xöû lyù naøy chieám quyeàn.

Caùc böôùc thöïc hieän nhö sau: Duøng MFC Wizard taïo öùng duïng Hook vôùi giao dieän chính laø dialog. Thöïc hieän caøi ñaët caùc boå sung cho lôùp dialog CHookDlg nhö sau:

- Trong phaàn caøi ñaët, boå sung bieán löu vaø haøm xöû lyù hook: HHOOK oldHook; // Chöùa ñòa chæ thuû tuïc hook bò chieám quyeàn LRESULT CALLBACK myHook ( int code, WPARAM wParam, LPARAM lParam) { MessageBeep( -1 ); // Thöïc hieän beep ñeå thoâng tin // Thöïc hieän thuû tuïc bò chieám quyeàn. return CallNextHookEx(oldHook, code, wParam, lParam); }

- Haønh vi OnInitDialog xöû lyù caøi ñaët thuû tuïc hook: BOOL CHookDlg::OnInitDialog() {

Page 103: Mfc Tieng Viet

186 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

CDialog::OnInitDialog();

oldHook = SetWindowsHookEx ( WH_KEYBOARD, /* Hook messge phím */ myHook, /* Thuû tuïc hook */ AfxGetInstanceHandle(), /* Handle tieán trình chöùa thuû tuïc xöù lyù hook */ 0 /* Hook taát caû tieán trình */ );

return TRUE; }

- Haønh vi OnDestroy huûy boû thuû tuïc hook cuûa öùng duïng: void CHookDlg::OnDestroy() { UnhookWindowsHookEx(oldHook);

CDialog::OnDestroy(); }

Bieân dòch vaø chaïy thöû öùng duïng.

12.9 Caøi ñaët cheá ñoä thöïc hieän öùng duïng töï ñoäng: SOFTWARE\Microsoft\Windows\CurrentVersion\Run laø thaønh phaàn ñaëc

bieät cuûa system registry cho pheùp töï ñoäng thöïc hieän öùng duïng khi khôûi ñoäng windows thoâng qua vieäc caøi ñaët caùc muïc coù giaù trò laø chuoãi ñöôøng daãn ñeán chöông trình öùng duïng lieân quan. Trong ñoù:

HKEY_LOCAL_MACHINE\ AÙp duïng cho moïi ngöôøi duøng taïi host. HKEY_CURRENT_USER\ AÙp duïng cho moät ngöôøi duøng xaùc ñònh.

Ví duï: Muïc MyProg = "C:\Game\mci.exe" caøi trong thaønh phaàn : HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run

cho pheùp thöïc hieän töï ñoäng chöông trình mci.exe khi khôûi ñoäng windows.

THÖÏC HAØNH: 1. Duøng (12.3) vaø (12.6), thieát keá öùng duïng audio & video player. ÖÙng duïng coù theå thu nhoû thaønh icon treân status area ñeå vöøa laøm vieäc vöøa nghe nhaïc. 2. Caøi ñaët muïc trong RUN cho pheùp thöïc hieän töï ñoäng moät öùng duïng tuøy yù. 3. HKEY_CURRENT_USER\SOFTWARE\Microsoft\Internet Explorer\TypedURLs laø thaønh phaàn chöùa caùc URLs trong IE. Vieát öùng duïng xoùa moät URL baát kyø.

Page 104: Mfc Tieng Viet

MFC vôùi Internet 187

CHÖÔNG 13:

MFC vôùi Internet 13.1 GIAO THÖÙC TRUYEÀN THOÂNG TCP/IP: 13.1.1 Giôùi thieäu:

TCP/IP (Transmission Control Protocol/Internet Protocol) bao goàm giao thöùc truyeàn thoâng vaø caùc dòch vuï hoã trôï taùc vuï truyeàn thoâng giöõa caùc traïm (host) treân heä thoáng maïng ñònh vò ñòa chæ IP (IP Host Address Internetwork).

TCP/IP ra ñôøi töø naêm 1969 bôûi cô quan nghieân cöùu caùc döï aùn cao caáp thuoäc boä quoác phoøng Hoa Kyø (Department of Defence Advanced Research Projects Agency - DARPA) nhaèm muïc tieâu xaây döïng moät giao thöùc truyeàn thoâng chuaån cho vieäc phaùt trieån caùc heä thoáng maïng dieän roäng (WAN) vôùi cô cheá keát noái truyeàn thoâng toác ñoä cao treân cô sôû vaän duïng caùc kinh nghieäm töø thaønh quaû phaùt trieån maïng ARPANET, tieàn thaân cuûa Internet ngaøy nay.

13.1.2 Kieán truùc cuûa giao thöùc TCP/IP treân moâ hình DARPA: Moâ hình DARPA vôùi giao thöùc truyeàn thoâng TCP/IP laø moät kieán truùc bao

goàm 4 taàng töông öùng vôùi 7 taàng cuûa moâ hình maïng chuaån OSI nhö sau:

Taàng giao tieáp maïng (Network Interface Layer): Taàng giao tieáp maïng (taàng truy xuaát maïng) ñaûm nhaän nhieäm vuï nhaän vaø göûi caùc goùi chöùa thoâng tin (packet) theo caáu truùc TCP/IP treân thieát bò

188 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

keát noái maïng cuûa host. Caáu truùc packet cuûa TCP/IP ñöôïc thieát keá cho pheùp khoâng phuï thuoäc vaøo cô cheá truy xuaát cuõng nhö kieán truùc khung packet cuûa thieát bò maïng. Nhôø ñoù, TCP/IP coù theå laøm vieäc vôùi nhieàu kieåu maïng khaùc nhau, bao goàm caùc maïng cuïc boä (LAN): Ethernet hoaëc Token Ring; maïng dieän roäng (WAN): X.25 hoaëc Frame Relay. Söï ñoäc laäp ñoù cuõng giuùp TCP/IP nhanh choùng thích nghi vôùi caùc coâng ngheä maïng môùi nhö ATM (Asynchronous Transfer Mode).

Taàng Internet (Internet Layer): Taàng internet ñaûm nhaän chöùc naêng ñònh vò, ñoùng goùi thoâng tin vaø truyeàn tin ñònh tuyeán. Giao thöùc truyeàn thoâng coát loõi cuûa taàng naøy laø IP, ARP, ICMP, vaø IGMP. - Giao thöùc IP (Internet Protocol): Giao thöùc truyeàn thoâng ñònh tuyeán;

coù nhieäm vuï ñònh vò ñòa chæ IP, taùch vaø keát caùc packet. - Giao thöùc ARP (Address Resolution Protocol): Coù nhieäm vuï thöïc

hieän hoaùn chuyeån caùc giaù trò ñòa chæ moät caùch töông öùng giöõa taàng internet (logic address) vaø taàng giao tieáp maïng (physic address).

- Giao thöùc ICMP (Internet Control Message Protocol): Coù nhieäm vuï cung caáp caùc chöùc naêng kieåm soaùt vaø thoâng baùo tình hình göûi caùc IP packet.

- Giao thöùc IGMP (Internet Group Management Protocol): Coù nhieäm vuï quaûn lyù nhoùm caùc IP packet ñöôïc truyeàn ñeán moïi host.

Taàng truyeàn taûi (Transport Layer): Taàng truyeàn taûi coù nhieäm vuï cung caáp cho taàng öùng duïng caùc dòch vuï truyeàn thoâng tin theo doøng vaø theo goùi. Giao thöùc truyeàn thoâng coát loõi cuûa taàng truyeàn taûi laø TCP vaø UDP. - UDP (User Datagram Protocol): Laø giao thöùc cung caáp dòch vuï

truyeàn thoâng tin giöõa moät host vôùi moät hay nhieàu host khaùc treân cô sôû ñoùng goùi thoâng tin vaø göûi ñi theo töøng packet ñoäc laäp. Giao thöùc naøy khoâng thöïc hieän kieåm tra tình hình nhaän thoâng tin ôû host nhaän tin neân ñoä tin caäy thaáp, thoâng tin coù theå bò thaát laïc.

- TCP (Transmission Control Protocol): Laø giao thöùc cung caáp dòch vuï truyeàn thoâng tin treân cô sôû xaây döïng ñöôøng truyeàn (stream) giöõa hai host vaø thöïc hieän göûi-nhaän thoâng tin, ñoàng thôøi kieåm tra thoâng tin nhaän qua ñöôøng truyeàn naøy. Giao thöùc naøy ñaûm baûo thoâng tin ñöôïc chuyeån ñeán host nhaän chính xaùc vaø an toaøn.

Taàng öùng duïng (Application Layer):

Page 105: Mfc Tieng Viet

MFC vôùi Internet 189

Taàng öùng duïng cung caáp caùc chöùc naêng khai thaùc caùc dòch vuï cuûa caùc taàng khaùc, ñoàng thôøi ñònh nghóa caùc giao thöùc truyeàn thoâng maø öùng duïng cuûa ngöôøi duøng coù theå söû duïng ñeå truyeàn döõ lieäu qua heä thoáng maïng. Caùc giao thöùc truyeàn thoâng phoå bieán nhö sau: - Giao thöùc HTTP (HyperText Transfer Protocol): Duøng chuyeån taûi

caùc taäp tin tham gia vaøo noäi dung trang WEB (World Wide Web). - Giao thöùc FTP (File Transfer Protocol): Duøng chuyeån taûi caùc taäp tin

thoâng thöôøng. - Giao thöùc SMTP (Simple Mail Transfer Protocol): Duøng chuyeån taûi

noäi dung thö tín bao goàm thoâng ñieäp vaø caùc döõ lieäu keøm theo. - Giao thöùc Telnet: Duøng cho hoaït ñoäng thaâm nhaäp host töø xa thoâng

qua caùc thieát bò ñaàu cuoái (Terminal). Beân caïnh caùc giao thöùc truyeàn thoâng noùi treân, taàng öùng duïng coøn

cung caáp caùc dòch vuï sau: - Dòch vuï chuyeån ñoåi domain name thaønh ñòa chæ IP töông öùng. - Dòch vuï cung caáp thoâng tin ñònh vò ñòa chæ IP. - Dòch vuï quaûn lyù caùc thieát bò maïng (boä ñònh tuyeán, caàu noái, hub

thoâng minh) nhaèm thu thaäp vaø trao ñoåi thoâng tin quaûn lyù maïng.

13.1.3 Ñòa chæ IP: Ñòa chæ IP laø giaù trò giuùp xaùc ñònh moät host duy nhaát treân heä thoáng maïng.

Taát caû caùc ñòa chæ IP ñeàu coù daïng thoáng nhaát bao goàm ñòa chæ maïng vaø ñòa chæ cuûa host treân maïng ñoù.

- Ñòa chæ maïng (Network address - Network ID): Soá hieäu duøng cho moät heä thoáng maïng caùc host cuøng chung moät ñaëc ñieåm ñònh tuyeán. Caùc heä thoáng maïng keát vaøo internet phaûi coù ñòa chæ maïng phaân bieät.

- Ñòa chæ host (host address - host ID): Soá hieäu duøng cho moät host (workstation, server, router, TCP/IP host). Caùc host trong cuøng moät heä thoáng maïng coù cuøng ñòa chæ maïng nhöng ñòa chæ host phaûi phaân bieät.

Moãi ñòa chæ IP coù chieàu daøi 32 bits chia thaønh 4 bytes (4 octets). Moãi giaù trò nhò phaân trong moät byte töông öùng vôùi moät giaù trò thaäp phaân trong ñoaïn 0 ÷255. Boán giaù trò thaäp phaân naøy ñöôïc vieát ra theo thöù töï vaø ngaên caùch baèng daáu ‘.’ cho ta hình aûnh bieåu dieãn ñòa chæ IP theo daïng soá vaø daáu chaám (dotted decimal notation) maø töø ñaây ta seõ goïi taét laø num-dot. IP: 11000000 10101000 00000011 00011000 Hay: 192.168.3.24

190 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

Treân 4 bytes ñòa chæ IP, ta coù theå choïn moät soá bytes tuøy yù chöùa ñòa chæ maïng, soá bytes coøn laïi duøng chöùa ñòa chæ host. Moãi caùch choïn khaùc nhau taïo thaønh moät lôùp ñòa chæ IP. Coù 3 lôùp ñòa chæ IP phoå bieán:

- Lôùp A : 1 byte cho ñòa chæ maïng, 3 bytes cho ñòa chæ host - Lôùp B : 2 bytes cho ñòa chæ maïng, 2 bytes cho ñòa chæ host - Lôùp C : 3 bytes cho ñòa chæ maïng, 1 byte cho ñòa chæ host Löu yù: - Giaù trò ñòa chæ host vôùi taát caû caùc bits baèng 1 laø ñòa chæ chæ cho moïi

host treân heä thoáng maïng (host broadcast address) chöùa host. Khoâng moät host naøo ñöôïc söû duïng ñòa chæ naøy.

- Moät ñòa chæ IP coù phaàn ñòa chæ host vôùi taát caû caùc bits baèng 0 chính laø ñòa chæ cuûa heä thoáng maïng. Khoâng duøng ñòa chæ naøy cho host.

Address Class First Host ID Last Host ID Class A w.0.0.1 w.255.255.254 Class B w.x.0.1 w.x.255.254 Class C w.x.y.1 w.x.y.254

13.1.4 Subnet: Vôùi soá bits duøng cho ñòa chæ host trong caùc lôùp ñòa chæ, soá löôïng host cuûa

moät heä thoáng maïng coù theå leân ñeán con soá raát lôùn (lôùp A laø 16 trieäu). Khi ñoù, vieäc göûi moät thoâng ñieäp leân maïng cho taát caû caùc host (broadcast) seõ caàn moät khoaûng thôøi gian thöïc hieän khoâng nhoû, khoù ñaûm baûo xöû lyù thôøi gian thöïc. Hôn nöõa, 16 trieäu giaù trò ñòa chæ cho moät heä thoáng maïng laø quaù dö thöøa.

Nhaèm khaéc phuïc haïn cheá noùi treân, caùc host cuøng heä maïng ñöôïc chia thaønh nhoùm nhoû hôn goïi laø maïng con (SubNet). Moãi subnet töông öùng vôùi moät ñòa chæ maïng subnet vaø giôùi haïn ñòa chæ IP caùc host tröïc thuoäc. Ñòa chæ subnet laø giaù trò hình thaønh töø moät phaàn bits trong ñòa chæ host cuûa ñòa chæ IP thuoäc heä maïng ban ñaàu. Coù theå xem Subnet laø taäp con cuûa heä maïng.

Heä thoáng maïng trong hình treân söû duïng ñòa chæ lôùp B. Ñòa chæ cuûa heä maïng laø 139.12.0.0. Heä maïng naøy cho pheùp xaùc laäp 65535 ñòa chæ host. Thöïc

Page 106: Mfc Tieng Viet

MFC vôùi Internet 191

hieän chia heä maïng treân thaønh 256 subnet döïa treân byte thöù ba, ta ñöôïc caùc subnet 8-bit ñòa chæ lôùp B:

Caùc subnet ñöôïc taïo thaønh laø: 139.12.1.0, 139.12.2.0 vaø 139.12.3.0.

13.1.5 Subnet Mask: Subnet mask laø moät giaù trò 32 bits giuùp taùch giaù trò ñòa chæ maïng (hoaëc ñòa

chæ subnet) vaø ñòa chæ host töø moät ñòa chæ IP baát kyø (trong moät lôùp ñòa chæ baát kyø, caùch phaân chia subnet baát kyø). Giaù trò naøy ñöôïc xaây döïng nhö sau:

- Caùc giaù trò bit töông öùng vôùi ñòa chæ maïng coù giaù trò laø 1. - Caùc giaù trò bit töông öùng vôùi ñòa chæ host coù giaù trò laø 0.

Giaù trò subnet mask cuõng ñöôïc bieåu dieãn döôùi daïng num-dot. Ta coù subnet mask maëc nhieân cho caùc lôùp ñòa chæ nhö sau:

Class Bits for Subnet Mask Subnet Mask Class A 11111111 00000000 00000000 00000000 255.0.0.0 Class B 11111111 11111111 00000000 00000000 255.255.0.0 Class C 11111111 11111111 11111111 00000000 255.255.255.0

Caùc giaù trò subnet mask do ngöôøi duøng taïo ra töông öùng vôùi moãi lôùp ñòa chæ treân coù theå khaùc bieät so vôùi caùc giaù trò maëc nhieân vì chuùng chöùa caû giaù trò mask treân ñòa chæ subnet.

Ví duï: 138.96.58.0 laø moät ñòa chæ subnet 8-bit lôùp B. 8 bits ñòa chæ host cuûa heä maïng ban ñaàu ñöôïc duøng laøm giaù trò ñòa chæ subnet. Nhö vaäy subnet mask söû duïng toång coäng 24 bits (255.255.255.0) ñeå ñònh nghóa ñòa chæ maïng subnet. Ñòa chæ maïng subnet vaø giaù trò subnet mask töông öùng ñöôïc bieåu dieãn theo daïng num-dot nhö sau: 138.96.58.0, 255.255.255.0 Hay: 138.96.58.0/24 (24-bit mask)

192 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

Xaùc ñònh ñòa chæ maïng: Ñeå taùch ñòa chæ maïng töø moät ñòa chæ IP baát kyø thoâng qua giaù trò subnet mask, ta söû söû duïng pheùp toaùn AND bits:

Ví duï: Giaû söû IP = 129.56.189.41 vaøsubnet mask = 255.255.240.0 Ñòa chæ maïng ñöôïc xaùc ñònh nhö sau: IP Address : 10000001 00111000 10111101 00101001 Subnet Mask : 11111111 11111111 11110000 00000000 Network ID : 10000001 00111000 10110000 00000000

Xaùc ñònh giôùi haïn ñòa chæ IP: Giaû söû ñòa chæ maïng laø 192.168.0.0. Vôùi subnet 3-bit ñòa chæ lôùp B cuûa heä maïng noùi treân, ta coù 8 tröôøng hôïp löïa

choïn giaù trò cho 3 bits naøy. Töông öùng vôùi moãi tröôøng hôïp laø moät giôùi haïn caùc ñòa chæ IP cuûa caùc host trong subnet:

Stt Ñòa chæ Subnet theo heä nhò phaân Giôùi haïn ñòa chæ IP 1 11000000.10101000.00000000.00000001- 192.168.0.1 - 11000000.10101000.00011111.11111110 192.168.31.254 2 11000000.10101000.00100000.00000001- 192.168.32.1 - 11000000.10101000.00111111.11111110 192.168.63.254 3 11000000.10101000.01000000.00000001- 192.168.64.1 - 11000000.10101000.01011111.11111110 192.168.95.254 4 11000000.10101000.01100000.00000001- 192.168.96.1 - 11000000.10101000.01111111.11111110 192.168.127.254 5 11000000.10101000.10000000.00000001- 192.168.128.1 - 11000000.10101000.10011111.11111110 192.168.159.254 6 11000000.10101000.10100000.00000001- 192.168.160.1 - 11000000.10101000.10111111.11111110 192.168.191.254 7 11000000.10101000.11000000.00000001- 192.168.192.1 - 11000000.10101000.11011111.11111110 192.168.223.254 8 11000000.10101000.11100000.00000001- 192.168.224.1 - 11000000.10101000.11111111.11111110 192.168.255.254

13.1.6 Host domain name: Teân (name) laø moät giaûi phaùp höõu hieäu cho vieäc gôïi nhôù ñòa chæ cuûa host

thay vì duøng ñòa chæ IP vôùi 4 bytes giaù trò khoù nhôù noùi treân. Teân cuûa host (Host name) laø moät chuoãi kyù töï coù chieàu daøi toái ña 255, coù theå chöùa maãu töï, kyù soá, caùc kyù töï ‘-‘ vaø ‘.’ vaø coù yù nghóa töông ñöông vôùi ñòa chæ IP trong vieäc quaûn lyù ñòa chæ moät host treân heä thoáng maïng internet. Coù hai daïng phoå bieán cho teân cuûa host laø nick name vaø domain name:

Page 107: Mfc Tieng Viet

MFC vôùi Internet 193

- Nick name: Moät nhaõn ñöôïc duøng cho moät ñòa chæ IP duy nhaát. - Domain name: Teân ñöôïc hình thaønh töø caáu truùc phaân lôùp. Caáu truùc

phaân lôùp naøy ñöôïc qui ñònh phoå bieán thaønh luaät vaø ñöôïc goïi laø heä thoáng teân mieàn (Domain Name System – DNS) nhö sau:

Trong ñoù: Teân Domain YÙ nghóa söû duïng COM Caùc toå chöùc thöông maïi EDU Caùc cô quan giaùo duïc, nghieân cöùu GOV Toå chöùc chính phuû MIL Cô quan quaân söï NET cô quan quaûn lyù maïng chính ORG Caùc toå chöùc khaùc INT Caùc toå chöùc quoác teá <country code> Caùc nhaùnh cho caùc quoác gia tröø Hoa Kyø

Moät teân mieàn ñaày ñuû (Fully Qualified Domain Name – FQDN) chöùa ñöôøng ñi töø goác ñeán ñoái töôïng tham chieáu theo trình töï phaân caáp noùi treân. Ví duï: ftpsrv.wcoast.slate.com

Vieäc chuyeån ñoåi giöõa ñòa chæ IP vaø Domain name ñöôïc thöïc hieän döïa treân baûng chuyeån ñoåi IP-DomainName do DNS server, moät host chuyeân duïng cuûa heä thoáng maïng, quaûn lyù. ÖÙng duïng töø moät host baát kyø coù theå truy vaán baûng thoâng tin naøy thoâng qua caùc dòch vuï cung caáp bôûi windows socket. Windows socket truyeàn yeâu caàu cuûa öùng duïng ñeán boä phaän phaân giaûi domain name cuûa giao thöùc truyeàn thoâng TCP/IP. Boä phaän naøy chuyeån yeâu caàu ñeán DNS server. DNS server nhaän yeâu caàu vaø thöïc hieän; neáu

194 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

thoâng tin yeâu caàu khoâng xaùc ñònh ñöôïc thì noù seõ chuyeån ñeán DNS server cuøng caáp khaùc, keát quaû thöïc hieän ñöôïc hoaëc khoâng thöïc hieän ñöôïc ñeàu ñöôïc traû veà theo loä trình ngöôïc laïi.

13.1.7 IP Routing: IP routing laø tieán trình xöû lyù göûi packet ñeán host nhaän döïa treân ñòa chæ IP

cuûa host. Tieán trình naøy xaûy ra ôû host göûi thoâng tin theo giao thöùc TCP/IP vaø ôû thieát bò ñònh tuyeán (router device) nhaèm thöïc hieän quyeát ñònh löïa choïn vò trí maø packet seõ ñöôïc chuyeån ñeán.

Ñeå thöïc hieän quyeát ñònh treân, taàng IP tham khaûo baûng ñònh tuyeán ñöôïc löu tröõ trong boä nhôù. Noäi dung baûng ñònh tuyeán ñöôïc khôûi taïo maëc nhieân khi TCP/IP vöøa ñöôïc khôûi ñoäng. Caùc muïc boå sung coù theå ñöôïc thöïc hieän bôûi ngöôøi quaûn trò heä thoáng maïng (WinNT router table) hoaëc thöïc hieän moät caùch töï ñoäng trong quaù trình lieân laïc vôùi caùc boä ñònh tuyeán.

Coù hai daïng phoå bieán khi göûi packet; göûi tröïc tieáp vaø göûi giaùn tieáp. Göûi tröïc tieáp (Direct delivery): Xaûy ra khi host nhaän vaø host göûi ñöôïc

keát noái tröïc tieáp. Thoâng tin ñöôïc ñoùng goùi ôû host göûi theo caáu truùc qui ñònh cuûa taàng giao tieáp maïng vaø ñöôïc göûi ñi.

Göûi giaùn tieáp (Indirect delivery): Xaûy ra khi host nhaän vaø host göûi ñöôïc keát noái thoâng qua moät trung gian (boä ñònh tuyeán). Khi ñoù seõ coù moät quaù trình göûi giaùn tieáp töø host ñeán boä ñònh tuyeán, töø boä ñònh tuyeán tröïc tieáp ñeán host nhaän (hoaëc giaùn tieáp ñeán moät boä ñònh tuyeán khaùc).

Page 108: Mfc Tieng Viet

MFC vôùi Internet 195

A göûi tröïc tieáp ñeán B A göûi giaùn tieáp packet ñeán router1 , router 1 göûi giaùn tieáp ñeán

router 2, router 2 göûi tröïc tieáp ñeán C. Baûng ñònh tuyeán:

Baûng ñònh tuyeán ñöôïc xaùc laäp treân taát caû caùc host (node, router) vaø ñöôïc ñaët bôûi caùc giaù trò maëc nhieân trong quaù trình khôûi ñoäng cuûa giao thöùc TCP/IP. Noäi dung cuûa baûng chöùa thoâng tin veà heä thoáng caùc ñòa chæ IP treân maïng, caùch keát noái vôùi caùc ñòa chæ aáy.

Moãi khi moät goùi thoâng tin ñöôïc göûi ñi, baûng ñònh tuyeán seõ ñöôïc söû duïng ñeå xaùc ñònh:

- Ñòa chæ cuûa host nôi göûi ñeán: Neáu göûi tröïc tieáp thì ñoù chính laø ñòa chæ cuûa host nhaän packet, ngöôïc laïi, laø ñòa chæ cuûa boä ñònh tuyeán.

- Giao dieän söû duïng ñeå göûi: Bao goàm thoâng tin veà caáu truùc vaät lyù vaø logic cuûa thieát bò keát noái maïng ôû nôi göûi vaø nôi nhaän.

Caáu truùc noäi dung cuûa moät muïc trong baûng ñònh tuyeán: [ Network ID, Subnet Mask, Next Hop, Interface, Metric ]

Trong ñoù: - Network ID: Ñòa chæ maïng töông öùng vôùi tuyeán truyeàn tin. - Subnet Mask: Giaù trò duøng taùch ñòa chæ maïng töø ñòa chæ IP. - Next Hop: Ñòa chæ IP cuûa host trung gian keá tieáp.

196 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

- Interface: Thieát bò giao tieáp maïng ñöôïc söû duïng. - Metric: Chi phí cuûa tuyeán truyeàn, laøm cô sôû cho vieäc löïa

choïn tuyeán toái öu. Thoâng tin cuûa muïc trong baûng ñònh tuyeán qui ñònh ñaëc ñieåm tuyeán: - Tuyeán keát noái tröïc tieáp vôùi heä thoáng maïng: Giaù trò cuûa Next Hop

laø roãng hoaëc chöùa ñòa chæ IP cuûa thieát bò giao tieáp maïng. - Tuyeán keát noái trung gian vôùi heä thoáng maïng: Giaù trò cuûa Next

Hop chöùa ñòa chæ IP cuûa boä ñònh tuyeán trung gian giöõa host göûi vaø host nhaän.

- Tuyeán keát noái tröïc tieáp vôùi moät host cuï theå: Khi ñoù Network ID chöùa ñòa chæ cuûa host vaø giaù trò cuûa subnet mask laø 255.255.255.255.

- Tuyeán maëc nhieân: Tuyeán ñöôïc söû duïng khi coù moät taùc vuï ñònh tuyeán khoâng thaønh coâng. Giaù trò cuûa network ID laø 0.0.0.0 vaø subnet mask laø 0.0.0.0.

Network Address Netmask Gateway

Address Interface Metric Purpose

0.0.0.0 0.0.0.0 157.55.16.1 157.55.27.90 1 Default Route 127.0.0.0 255.0.0.0 127.0.0.1 127.0.0.1 1 Loopback Network

157.55.16.0 255.255.240.0 157.55.27.90 157.55.27.90 1 DirectyAttached Network

157.55.27.90 255.255.255.255 127.0.0.1 127.0.0.1 1 Local Host 157.55.255.255 255.255.255.255 157.55.27.90 157.55.27.90 1 Network Broadcast 224.0.0.0 224.0.0.0 157.55.27.90 157.55.27.90 1 Multicast Address 255.255.255.255 255.255.255.255 157.55.27.90 157.55.27.90 1 Limited Broadcast

( Moät baûng ñònh tuyeán cuûa Windows NT )

Xöû lyù ñònh tuyeán: Xöû lyù ñònh tuyeán laø xöû lyù thöïc hieän löïa choïn muïc ñònh tuyeán trong

baûng ñònh tuyeán vaø duøng noù cho vieäc göûi thoâng tin. Vieäc löïa choïn naøy ñöôïc thöïc hieän thoâng qua caùc böôùc sau:

- Treân moãi muïc ñònh tuyeán, thöïc hieän pheùp toaùn AND giöõa ñòa chæ host nhaän vaø giaù trò subnet mask. Kieåm tra keát quaû naøy vôùi Network ID ñeå ñaùnh giaù ñoä phuø hôïp (ñoä töông töï).

- Choïn ra caùc muïc ñònh tuyeán coù möùc ñoä phuø hôïp cao nhaát. Trong caùc muïc ñònh tuyeán naøy, choïn ra caùc muïc coù chi phí tuyeán truyeàn nhoû nhaát. Cuoái cuøng, töø caùc muïc ñònh tuyeán choïn ñöôïc, muïc ñònh tuyeán ñöôïc söû duïng laø muïc coøn roãi.

Xöû lyù ñònh tuyeán khaùc nhau treân caùc loaïi host khaùc nhau:

Page 109: Mfc Tieng Viet

MFC vôùi Internet 197

Host göûi: Packet ñöôïc göûi töø giao thöùc ôû taàng caáp cao hôn cuûa IP (TCP, UDP, ...). Khi ñoù vai troø IP ôû host göûi nhö sau: - Ñaët giaù trò cho tröôøng TTL (Times-To-Live) theo giaù trò qui ñònh cuûa

öùng duïng taàng caáp cao hoaëc laáy giaù trò maëc nhieân cuûa heä thoáng. - Xaùc ñònh tuyeán toái öu cho packet truyeàn ñi. - Neáu khoâng xaùc ñònh ñöôïc tuyeán truyeàn thì thoâng baùo loãi ñeán taàng

truyeàn thoâng ôû caáp cao hôn. Ngöôïc laïi, thöïc hieän truyeàn theo tuyeán.

Host ñònh tuyeán: Vai troø cuûa IP nhö sau: - Kieåm tra checksum cuûa packet. Neáu sai thì huûy packet. - Kieåm tra ñòa chæ IP cuûa host nhaän treân packet. Neáu ñòa chæ naøy laø ñòa

chæ moät boä ñònh tuyeán thì noäi dung packet (tröø phaàn noäi dung IP header) ñöôïc chuyeån cho giao thöùc taàng caáp cao töông öùng. Ngöôïc laïi, giaûm giaù trò tröôøng TTL ñi 1; neáu giaù trò tröôøng naøy baèng 0 thì huûy boû packet vaø göûi thoâng ñieäp "ICMP Time Expired-TTL Expired" cho host göûi, ngöôïc laïi xaùc ñònh tuyeán göûi vaø göûi packet.

Host nhaän: Vai troø cuûa IP nhö sau: - Kieåm tra checksum cuûa packet. Neáu sai thì huûy packet. - Neáu ñòa chæ host nhaän ghi treân packet khoâng phaûi laø ñòa chæ cuûa host

ñang xöû lyù thì huûy packet. - Göûi noäi dung packet (tröø IP header) leân giao thöùc taàng cao hôn.

13.2 LAÄP TRÌNH TCP/IP VÔÙI WINSOCK: Winsock (Windows Socket) coù xuaát xöù töø BSD (Berkeley Software

Distribution - UNIX), töông thích vôùi windows qua phieân baûn WinSock1.1. Winsock laø moät giao dieän vôùi caùc dòch vuï xaây döïng treân giao thöùc truyeàn thoâng TCP vaø UDP. Thoâng qua winsock, öùng duïng coù theå trieån khai deã daøng caùc taùc vuï truyeàn thoâng treân taàng truyeàn thoâng cuûa moâ hình maïng.

13.2.1 Port: Port laø khaùi nieäm ñöôïc dieãn taû baèng moät giaù trò soá (soá hieäu port) giuùp phaân

bieät caùc tieán trình treân cuøng moät host ñoàng söû duïng giao thöùc TCP/IP. Caùc öùng duïng khaùc nhau söû duïng TCP/IP coù theå thöïc hieän ñöôïc cuøng moät luùc treân moät host vôùi ñieàu kieän chuùng phaûi söû duïng caùc soá hieäu port khaùc nhau. 13.2.2 Socket:

198 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

Socket laø ñieåm truyeàn thoâng ñaàu cuoái cho pheùp öùng duïng göûi vaø nhaän caùc packet qua ñöôøng truyeàn maïng. Moãi socket coù moät kieåu xaùc ñònh vaø gaén lieàn vôùi moät tieán trình xöû lyù truyeàn thoâng. Coù hai loaïi socket:

Stream Socket: Cô cheá truyeàn döõ lieäu theo doøng. Datagram Socket: Cô cheá truyeàn döõ lieäu theo packet. Ñòa chæ socket laø moät giaù trò bao goàm ñòa chæ cuûa host vaø soá hieäu port

maø tieán trình xöû lyù truyeàn thoâng lieân quan socket ñaõ ñaêng kyù söû duïng.

13.2.3 Moät soá caáu truùc döõ lieäu cuûa Winsock API: Ñòa chæ num-dot cuûa host:

Ñöôïc bieåu dieãn bôûi moät giaù trò chuoãi coù noäi dung laø boán giaù trò soá coù ñoä lôùn baèng byte vaø ñöôïc ngaên caùch baèng daáu ‘.’ Ví duï: "127.0.0.1"

Caáu truùc khôûi ñoäng winsock :

typedef struct WSAData { WORD wVersion; WORD wHighVersion; char szDescription[WSADESCRIPTION_LEN+1]; char szSystemStatus[WSASYS_STATUS_LEN+1]; unsigned short iMaxSockets; unsigned short iMaxUdpDg; char FAR * lpVendorInfo; } WSADATA, *LPWSADATA;

szDescription: Thoâng tin veà phieân baûn winsock ñang söû duïng. szSystemStatus: Thoâng tin veà phieân baûn heä ñieàu haønh windows.

Caáu truùc chöùa thoâng tin cuûa host :

struct hostent { char FAR * h_name; // Domain name char FAR * FAR * h_aliases; // Teân duøng thay domain name short h_addrtype; // Kieåu ñòa chæ, vôùi TCP/IP laø AF_INET short h_length; // Kích thöôùc ñòa chæ, 4 bytes cho AF_INET char FAR * FAR * h_addr_list; // Danh saùch ñòa chæ. Phaàn töû // ñaàu danh saùch h_addr_list[0] // (hay h_addr) laø ñòa chæ host. } HOSTENT, *PHOSTENT;

Ñòa chæ socket treân moät host: struct sockaddr {

Page 110: Mfc Tieng Viet

MFC vôùi Internet 199

unsigned short sa_family; // Hoï ñòa chæ cuûa host. char sa_data[14]; // Ñòa chæ (cho pheùp nhieàu loaïi ñòa chæ) } SOCKADDR ;

Caáu truùc naøy ñöôïc töông thích bôûi SOCKADDR_IN cuûa MicroSoft:

struct sockaddr_in { short sin_family; // Coù giaù trò laø AF_INET unsigned short sin_port; // Soá hieäu port struct in_addr sin_addr; // Ñòa chæ IP 4 bytes cuûa host char sin_zero[8]; // Chæ ñeå töông thích vôùi SOCKADDR } SOCKADDR_IN ;

sin_addr : Ñòa chæ IP 4 bytes cuûa host, coù caùc caùch dieãn taû nhö sau: struct in_addr { union { struct { unsigned char s_b1, s_b2, s_b3, s_b4; } S_un_b; // Ñòa chæ IP baèng 4 bytes struct { unsigned short s_w1, s_w2; } S_un_w; // Ñòa chæ IP baèng 2 words unsigned long S_addr; // Ñòa chæ IP baèng 1 long } S_un; };

13.2.4 Moät soá dòch vuï cuûa Winsock API: char FAR * inet_ntoa (

struct in_addr in // Ñòa chæ IP 4 bytes ); Traû veà chuoãi ñòa chæ num-dot töông öùng.

unsigned long inet_addr ( const char FAR *cp // Ñòa chæ IP num-dot ); Haøm traû veà giaù trò kieåu long cuûa ñòa chæ IP 4 bytes töông öùng.

int WSAStartup ( // Haøm traû veà giaù trò 0 neáu thaønh coâng WORD version, // Phieân baûn winsock LPWSADATA pMyInfo // Con troû caáu truùc nhaän thoâng tin. ); Khôûi ñoäng, chuaån bò cho vieäc khai thaùc caùc dòch vuï cuûa winsock. version: Chöùa soá hieäu phieân baûn winsock caàn duøng

- High-order byte = winsock minor version number.

200 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

- Low-order byte = winsock major version number. - Ví duï: MAKEWORD (1, 1 ) Winsock version 1.1.

int gethostname ( // Haøm traû veà SOCKET_ERROR neáu coù loãi char FAR *name, // Vuøng ñeäm chöùa thoâng tin int namelen // Kích thöôùc vuøng ñeäm ); Laáy thoâng tin veà teân cuûa host.

PHOSTENT gethostbyname ( const char FAR *name // Tham soá chöùa teân host ); Haøm traû veà con troû ñeán caáu truùc HOSTENT chöùa thoâng tin cuûa host.

int WSACleanup( ); Chaám döùt söû duïng dòch vuï winsock.

13.3 MFC VÔÙI LAÄP TRÌNH WINSOCK: Thö vieän söû duïng: AfxSock.h

13.3.1 Khôûi ñoäng Winsock: BOOL AfxSocketInit ( WSADATA* lpwsaData = NULL );

AfxSocketInit ñaûm nhaän vieäc thöïc hieän WSAStartup khi baét ñaàu öùng duïng vaø WSACleanup khi öùng duïng keát thuùc. Lôøi goïi AfxSocketInit ñöôïc thöïc hieän trong haønh vi InitInstance cuûa ñoái töôïng quaûn lyù tieåu trình chính cuûa öùng duïng. Tham soá truyeàn cho haøm coù yù nghóa nhö vôùi WSAStartup.

13.3.2 Lôùp CAsyncSocket: CAsyncSocket laø lôùp ñoái töôïng quaûn lyù socket. Baèng söï bao haøm caùc dòch

vuï cuûa winsock API trong caùc haønh vi, lôùp CAsyncSocket cho pheùp taïo ra ñoái töôïng socket hoã trôï öùng duïng moät caùch hieäu quaû trong vieäc trieån khai caùc hoaït ñoäng truyeàn thoâng treân taàng truyeàn taûi cuûa giao thöùc TCP/IP.

Caùc haønh vi ñaëc tröng lôùp CAsyncSocket nhö sau: CAsyncSocket( ); Khôûi taïo ñoái töôïng socket roãng. BOOL Create (

UINT nSocketPort = 0, int nSocketType = SOCK_STREAM, long lEvent = FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE, LPCTSTR lpszSocketAddress = NULL ); Khôûi taïo thoâng soá ñoái töôïng socket vaø keát vôùi host ñoái taùc (neáu coù). Trong ñoù: - nSocketPort : Soá hieäu port cuûa socket. Giaù trò naøy coù theå xaùc ñònh

bôûi ngöôøi duøng (ví duï 2050) hoaëc ñaët baèng 0 ñeå winsock tìm giuùp moät giaù trò phuø hôïp.

Page 111: Mfc Tieng Viet

MFC vôùi Internet 201

- n SocketType : AÁn ñònh giao thöùc söû duïng; SOCK_STREAM cho TCP hoaëc SOCK_DGRAM cho UDP.

- lEvent : Bao goàm caùc thoâng soá lieân quan ñeán caùc bieán coá truyeàn thoâng maø öùng duïng muoán winsock phaûn hoài ngay treân socket quaûn lyù bôûi ñoái töôïng socket. FD_READ : Nhaän ñöôïc thoâng tin. FD_WRITE : Göûi ñöôïc thoâng tin. FD_ACCEPT : Ñoàng yù keát noái. FD_CONNECT : Ñeà nghò keát noái. FD_CLOSE : Chaám döùt keát noái. FD_OOB : Thoâng tin ngoaøi tuyeán.

- lpszSocketAddress : Chuoãi chöùa ñòa chæ num-dot cuûa host ñoái taùc maø socket ñöôïc keát (bind). INADDR_ANY laø ñòa chæ duøng keát vôùi taát caû caùc host trong heä thoáng maïng.

BOOL Bind ( UINT nSocketPort, // Soá hieäu port LPCTSTR lpszSocketAddress = NULL // Ñòa chæ num-dot cuûa host ); Keát socket vôùi moät host xaùc ñònh.

BOOL Bind ( const SOCKADDR* lpSockAddr, // Ñòa chæ socket host ñoái taùc int nSockAddrLen // Kích thöôùc lpSockAddr ); Keát socket vôùi moät host xaùc ñònh.

BOOL SetSockOpt ( int nOptionName, // Thuoäc tính caàn aán ñònh const void* lpOptionValue, // Ñòa chæ bieán chöùa giaù trò aán ñònh int nOptionLen, // Kích thöôùc bieán chöùa giaù trò int nLevel = SOL_SOCKET // Möùc ñaët thoâng soá cho socket ); AÁn ñònh ñaëc tính hoaït ñoäng cuûa socket. nOptionName cho pheùp löïa choïn thuoäc tính aán ñònh cuûa socket : - SO_BROADCAST : BOOL → Göûi message ñeán moïi host. - SO_DONTROUTE : BOOL → Göûi tröïc tieáp khoâng qua router. Ví duï: Neáu aán ñònh ñaëc tính cuûa socket laø cho pheùp göûi message ñeán moïi host thì haønh vi treân ñöôïc thöïc hieän vôùi tham soá nhö sau: int nOptionName, = SO_BROADCAST const void* lpOptionValue, = Ñòa chæ bieán luaän lyù baèng TRUE int nOptionLen, = sizeof (BOOL)

202 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

int nLevel = SOL_SOCKET BOOL Listen (

int nConnectionBacklog = 5 // Chieàu daøi doøng chôø keát noái ); Chôø nhaän keát noái töø host ñoái taùc (server chôø caùc clients).

BOOL Connect ( LPCTSTR lpszHostAddress, // Ñòa chæ num.dot cuûa host ñoái taùc UINT nHostPort // Soá hieäu port treân host ñoái taùc ); Xin keát noái vôùi host ñoái taùc (clients keát noái vôùi server).

BOOL Connect ( const SOCKADDR* lpSockAddr, // Ñòa chæ socket host ñoái taùc int nSockAddrLen // Kích thöôùc lpSockAddr ); Xin keát noái vôùi host ñoái taùc (clients keát noái vôùi server).

virtual BOOL Accept ( CAsyncSocket& rConnectedSocket, SOCKADDR* lpSockAddr = NULL, int* lpSockAddrLen = NULL ); Chaáp nhaän keát noái vôùi host ñoái taùc (server chaáp nhaän keát noái client). Trong ñoù: - rConnectedSocket : Bieán chöùa ñoái töôïng socket ñöôïc taïo môùi vôùi

caùc ñaëc tính gioáng nhö ñoái töôïng chuû theå vaø duøng ñeå quaûn lyù lieân keát vöøa thieát laäp.

- lpSockAddr : Ñòa chæ bieán kieåu SOCKADDR ñöôïc duøng ñeå nhaän ñòa chæ host ñoái taùc.

- lpSockAddrLen : Ñòa chæ bieán ñöôïc duøng ñeå nhaän kích thöôùc cuûa ñòa chæ traû veà trong lpSockAddr.

virtual int Send ( // Söû duïng cho Stream Socket const void* lpBuf, // Ñòa chæ vuøng ñeäm chöùa döõ lieäu truyeàn int nBufLen, // Kích thöôùc vuøng ñeäm int nFlags = 0 // Thoâng soá aán ñònh ñaëc tính göûi ); Göûi döõ lieäu thoâng qua moät socket ñöôïc keát noái. Thoâng soá duøng cho ñaëc tính göûi: - MSG_DONTROUTE = Göûi thaúng khoâng qua router. - MSG_OOB = Göûi ngoaïi tuyeán (khaån caáp)

int SendTo ( // Söû duïng cho Datagram const void* lpBuf, // Vuøng ñeäm döõ lieäu int nBufLen, // Kích thöôùc vuøng ñeäm

Page 112: Mfc Tieng Viet

MFC vôùi Internet 203

UINT nHostPort, // Soá hieäu port ñoái taùc LPCTSTR lpszHostAddress = NULL, // Ñòa chæ num-dot ñoái taùc int nFlags = 0 // Ñaëc tính göûi. ); Göûi packet ñeán host ñoái taùc. Haøm traû veà soá bytes döõ lieäu göûi ñöôïc. Ñeå göûi packet ñeán taát caû caùc host, ñaët lpszHostAddress = NULL.

int SendTo ( // Söû duïng cho Datagram const void* lpBuf, // Nhö treân … int nBufLen, const SOCKADDR* lpSockAddr, // Ñòa chæ socket ñoái taùc int nSockAddrLen, // Kích thöôùc ñòa chæ int nFlags = 0 ); Göûi packet ñeán host ñoái taùc. Haøm traû veà soá bytes döõ lieäu ñöôïc göûi. Ñeå göûi packet ñeán taát caû caùc host, giaù trò ñòa chæ ñoái taùc ñaët nhö sau: lpSockAddr->sin_addr.s_addr = htonl ( INADDR_BROADCAST );

virtual int Receive ( // Söû duïng cho Stream Socket void* lpBuf, // Ñòa chæ vuøng ñeäm nhaän döõ lieäu int nBufLen, // Kích thöôùc vuøng ñeäm int nFlags = 0 // Ñaëc tính nhaän döõ lieäu. ); Nhaän döõ lieäu thoâng qua moät socket ñöôïc keát noái.

int ReceiveFrom ( // Söû duïng cho Datagram void* lpBuf, // Ñòa chæ vuøng ñeäm chöùa döõ lieäu int nBufLen, // Kích thöôùc vuøng ñeäm CString& rSocketAddress, // Ñòa chæ num-dot ñoái taùc UINT& rSocketPort, // Soá hieäu port ñoái taùc int nFlags = 0 // Ñaëc tính göûi ); Nhaän döõ lieäu töø host ñoái taùc.

int ReceiveFrom ( // Söû duïng cho Datagram void* lpBuf, // Ñòa chæ vuøng ñeäm chöùa döõ lieäu int nBufLen, // Kích thöôùc vuøng ñeäm SOCKADDR* lpSockAddr, // Ñòa chæ socket ñoái taùc int* lpSockAddrLen, // Kích thöôùc ñòa chæ int nFlags = 0 // Ñaëc tính göûi ); Nhaän döõ lieäu töø host ñoái taùc.

BOOL AsyncSelect ( long lEvent = FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE );

Ñaêng kyù bieán coá truyeàn thoâng mong muoán (xem Create ).

204 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

virtual void OnConnect ( int nErrorCode // Maõ loãi ); Nhaän ñöôïc yeâu caàu xin keát noái cuûa host ñoái taùc.

virtual void OnAccept ( int nErrorCode // Maõ loãi, = 0 is OK ); Nhaän ñöôïc söï ñoàng yù keát noái cuûa host ñoái taùc.

virtual void OnSend ( int nErrorCode ); Socket ñaõ saün saøng cho vieäc göûi döõ lieäu.

virtual void OnReceive ( int nErrorCode ); Döõ lieäu ñaõ saün saøng chôø nhaän thoâng qua socket.

virtual void OnOutOfBandData ( int nErrorCode ); Coù döõ lieäu khaån caáp saün saøng chôø nhaän thoâng qua socket.

virtual void OnClose ( int nErrorCode ); Socket chuaån bò chaám döùt hoaït ñoäng.

BOOL ShutDown ( int nHow // 0 = receive, 1 = send ; 2 = both ); Chaám döùt taùc vuï truyeàn thoâng töông öùng treân socket.

virtual void Close( ); Huûy boû socket.

13.4 LAÄP TRÌNH WINSOCK CHO GIAO THÖÙC UDP: Trong phaàn naøy ta söû duïng giao thöùc UDP ñeå thöïc hieän truyeàn thoâng ñieäp

giöõa hai hay nhieàu host. ÖÙng duïng thieát keá cho pheùp ngöôøi duøng soaïn thaûo noäi dung thoâng ñieäp, tuøy yù choïn göûi ñeán host xaùc ñònh hoaëc taát caû caùc host.

Caùch thöïc hieän nhö sau: Duøng MFC Wizard taïo döï aùn Udp vôùi cöûa soå giao dieän chính laø dialog. ÔÛ böôùc ‘Step 2 of 4’: Choïn hoã trôï Windows Sockets:

Page 113: Mfc Tieng Viet

MFC vôùi Internet 205

Choïn Finish hoaøn ñeå hoaøn taát vieäc khôûi taïo döï aùn. Tieáp tuïc thöïc hieän caùc boå sung sau :

Boå sung lôùp CEmpUdp keá thöøa lôùp CAsyncSocket cuûa MFC. Thöïc hieän caùc caøi ñaët cho lôùp nhö sau: - Khai baùo caùc haèng, soá hieäu port söû duïng trong öùng duïng:

const BUF_LEN = 512; // Chieàu daøi vuøng ñeäm const SENT_PORT = 2051; // port göûi thoâng tin const RECEIV_PORT = 2050; // port nhaän thoâng tin

- Caùc ñoái töôïng thuoäc tính söû duïng trong lôùp: char *m_Buffer; // Vuøng ñeäm chöùa thoâng tin nhaän-göûi CDialog *m_Parent; // Con troû ñoái töôïng dialog lieân quan

- Haønh vi khôûi taïo cuûa lôùp nhaän tham soá laø con troû ñoái töôïng dialog giao dieän lieân quan; thöïc hieän löu giaù trò con troû vaøo thuoäc tính cuûa lôùp vaø ñaêng kyù vuøng nhôù laøm vuøng ñeäm nhaän-göûi thoâng tin: CEmpUdp::CEmpUdp(CDialog *parent) { m_Parent = parent; m_Buffer = new char[BUF_LEN + 1];

206 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

} - Haønh vi huûy boû thöïc hieän giaûi phoùng vuøng nhôù ñaõ xin caáp phaùt:

CEmpUdp::~CEmpUdp() { delete m_Buffer; }

- Haønh vi keá thöøa OnSend laáy thoâng tin nhaäp trong hoäp nhaäp coù soá hieäu laø IDC_EDIT cuûa dialog lieân quan vaø thöïc hieän göûi ñeán host (neáu ñòa chæ xaùc ñònh) hoaëc göûi cho taát caû host treân maïng: void CEmpUdp::OnSend(int nErrorCode) { CString peerAddr; m_Parent->GetDlgItemText(IDC_EDIT, m_Buffer, BUF_LEN);

((CUDPDlg*)m_Parent)->m_ip.GetWindowText(peerAddr); if (peerAddr == "0.0.0.0") { // Send to everyones BOOL toAll = TRUE; SetSockOpt (SO_BROADCAST, &toAll, sizeof(BOOL)); SendTo(m_Buffer, BUF_LEN, RECEIV_PORT); } else SendTo(m_Buffer, BUF_LEN, RECEIV_PORT, peerAddr); }

- Haønh vi keá thöøa OnReceive nhaän thoâng tin göûi ñeán vaø hieån thò trong hoäp thoâng baùo coù soá hieäu laø IDC_READ cuûa dialog lieân quan: void CEmpUdp::OnReceive(int nErrorCode) { CString peerAddr; // Ñòa chæ host ñoái taùc vaø UINT port; // soá hieäu port söû duïng

ReceiveFrom(m_Buffer, BUF_LEN, peerAddr, port); sprintf (m_Buffer, "%s\n(from %s)", m_Buffer, peerAddr );

m_Parent->SetDlgItemText ( IDC_READ, m_Buffer );

AsyncSelect(FD_READ); // Duy trì vieäc nhaän thoâng tin }

Môû resource cuûa dialog giao dieän, boå sung hoäp edit (IDC_EDIT) cho pheùp nhaäp noäi dung thoâng tin göûi, hoäp thoâng baùo (IDC_READ) hieån thò thoâng tin nhaän, vaø hoäp nhaäp IP vôùi bieán m_IP duøng nhaäp ñòa chæ IP.

Page 114: Mfc Tieng Viet

MFC vôùi Internet 207

Thöïc hieän caùc boå sung cho lôùp CUDPDlg quaûn lyù dialog giao dieän: - Khai baùo caùc ñoái töôïng thuoäc tính quaûn lyù socket nhaän vaø göûi thoâng

tin cuûa öùng duïng: CEmpUdp *m_sentUDP; // Quaûn lyù socket göûi thoâng tin CEmpUdp *m_receivUDP; // Quaûn lyù socket nhaän thoâng tin

- Haønh vi OnInitDialog: Caáp phaùt vaø khôûi taïo thoâng soá cho caùc ñoái töôïng CEmpUdp: m_sentUDP = new CEmpUdp(this); m_receivUDP = new CEmpUdp(this);

m_sentUDP->Create(SENT_PORT, SOCK_DGRAM, 0); m_receivUDP->Create(RECEIV_PORT,SOCK_DGRAM,FD_READ);

- Haønh vi OnOK (töông öùng nuùt choïn OK) thöïc hieän göûi thoâng ñieäp: void CUDPDlg::OnOK() { m_sentUDP->AsyncSelect(FD_WRITE); // Ñaêng kyù göûi }

Bieân dòch vaø chaïy thöû öùng duïng.

13.5 LAÄP TRÌNH WINSOCK CHO GIAO THÖÙC TCP: Trong phaàn naøy, ta söû duïng giao thöùc TCP ñeå thöïc hieän truyeàn döõ lieäu laø

noäi dung cuûa moät taäp tin. Vieäc truyeàn döõ lieäu dieãn ra giöõa host quaûn lyù noäi dung taäp tin : server vaø host nhaän noäi dung taäp tin : client.

Thöù töï thöïc hieän caùc taùc vuï keát noái vaø truyeàn döõ lieäu giöõa host server vaø host client nhö sau:

Server Client

// Khai baùo socket // Khai baùo socket

208 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

CSocket sockSrvr; CSocket sockClient;

// Taïo socket 1,2 sockSrvr.Create(nPort);

// Taïo socket 2 sockClient.Create( );

// Chôø nhaän keát noái sockSrvr.Listen( );

// Xin pheùp keát noái 3,4 sockClient.Connect(strAddr,nPort);

// Chuaån bò socket keát noái CSocket sockRecv; // Ñoàng yù keát noái 5 sockSrvr.Accept( sockRecv );

// Truyeàn döõ lieäu 6 . ...

// Truyeàn döõ lieäu 6 . ...

// Keát thuùc keát noái 7 . sockSrvr.Close();

sockClient.Close()

Caùch thöïc hieän: Taïo taäp döï aùn roãng (Blank Workspace):

- Choïn muïc File / New

- Thöïc hieän caùc aán ñònh nhö treân. Choïn OK.

Boå sung vaøo Workspace döï aùn TcpServer. Ñaây laø döï aùn cuûa öùng duïng server coù nhieäm vuï chôø keát noái vaø cung caáp döõ lieäu cho caùc client. - Trong maøn hình Worksapce, right-click treân muïc Workspace.

Page 115: Mfc Tieng Viet

MFC vôùi Internet 209

- Choïn Add New Project to Workspace. - Duøng Wizard taïo döï aùn TcpServer vôùi giao dieän chính laø dialog, vaø

coù söû duïng windows socket. Caùch thöïc hieän töông töï (13.4). Thöïc hieän caùc coâng vieäc sau cho döï aùn TcpServer : Boå sung lôùp CEmpTcpWriter keá thöøa CAsyncSocket cuûa MFC. Lôùp boå

sung naøy ñaûm nhaän caùc chöùc naêng truyeàn noäi dung taäp tin cho client ñöôïc keát noái (OnSend), vaø chaám döùt keát noái khi ñaõ truyeàn xong (Close). Caøi ñaët cuûa lôùp CEmpTcpWriter nhö sau: - Khai baùo kieåu caáu truùc cho vuøng ñeäm chöùa döõ lieäu göûi:

const BUFFER_LEN = 1024; // Kích thöôùc vuøng chöùa döõ lieäu typedef struct _tagBuf { int length; // Kích thöôùc döõ lieäu thöïc char info[BUFFER_LEN]; // Vuøng chöùa döõ lieäu } BUFFER;

- Caùc thuoäc tính protected: BOOL m_isBusy; // Traïng thaùi phuïc vuï. CDialog* m_Parent; // Ñoái töôïng dialog lieân quan

- Haønh vi taïo laäp nhaän tham soá laø con troû ñoái töôïng dialog lieân quan, vaø xaùc ñònh traïng thaùi saün saøng: CEmpTcpWriter::CEmpTcpWriter( CDialog* parent ) { m_Parent = parent; // Ñoái töôïng dialog lieân quan m_isBusy = FALSE; // Saün saøng nhaän döõ lieäu }

- Haønh vi OnSend thöïc hieän göûi döõ lieäu cho client lieân keát: void CEmpTcpWriter::OnSend( int nErrorCode ) { static BOOL fileOK = TRUE;

210 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

static BOOL fileReady = FALSE; static CFile file; static long total; BUFFER buf; m_isBusy = TRUE; // Ñaõ keát noái buf.length = 0; // Döõ lieäu nhaän thöïc söï if ( fileOK && (!fileReady) ) { m_Parent->SetDlgItemText(IDC_INFO, "\nTransfering..."); fileReady = TRUE; CString fileName; // Teân taäp tin ñöôïc göûi // IDC_FILE : Soá hieäu hoäp nhaäp teân taäp tin treân dialog m_Parent->GetDlgItemText(IDC_FILE, fileName); fileOK = file.Open(fileName, CFile::modeRead); total = 0; // Chöùa kích thöôùc thoâng tin göûi }

if (!fileOK || ( buf.length = file.Read( buf.info, BUFFER_LEN ) ) < BUFFER_LEN ) fileReady = FALSE; // Khoâng coù file hoaëc ñaõ göûi heát Send( &buf, BUFFER_LEN + sizeof(int) ); total += buf.length; if (fileReady) { Sleep( 300 ); // Thôøi gian nghæ cho client AsyncSelect( FD_WRITE ); // Göûi tieáp } else { if ( fileOK ) file.Close(); Close(); m_isBusy = FALSE; // Saün saøng nhaän döõ lieäu CString result; result.Format( "\nReady to connect to clients !\n" "%d (bytes) transfered completed", total ); m_Parent->SetDlgItemText( IDC_INFO, result ); } }

Boå sung lôùp CEmpTcpServer keá thöøa CAsyncSocket ñaûm nhaän caùc chöùc naêng nhaän keát noái (accept), vaø khôûi taïo ñoái töôïng göûi döõ lieäu: - Caùc thuoäc tính protected cuûa lôùp CEmpTcpServer:

CEmpTcpWriter* m_pDoSendObject; // Ñoái töôïng göûi döõ lieäu

Page 116: Mfc Tieng Viet

MFC vôùi Internet 211

CDialog* m_Parent; // Dialog lieân quan

- Haønh vi taïo laäp nhaän tham soá laø con troû ñoái töôïng dialog lieân quan: CEmpTcpServer::CEmpTcpServer( CDialog* parent ) { m_Parent = parent; // Con troû ñoái töôïng dialog lieân quan m_pDoSendObject = new CEmpTcpWriter( m_Parent ); }

- Haønh vi huûy boû giaûi phoùng ñoái töôïng m_pDoSendObject: CEmpTcpServer::~CEmpTcpServer( ) { delete m_pDoSendObject; }

- Haønh vi OnAccept chaáp nhaän keát noái neáu ñang roãi: void CEmpTcpServer::OnAccept( int nErrorCode ) { if ( m_pDoSendObject->m_isBusy ) return ; // Ñang baän phuïc vuï

SOCKADDR_IN Addr; int Len = sizeof(SOCKADDR_IN); if (Accept(*m_pDoSendObject, (SOCKADDR*) &Addr, &Len)) // Khôûi ñoäng hoaït ñoäng göûi döõ lieäu treân m_pDoSendObject m_pDoSendObject->AsyncSelect(FD_WRITE); }

Thöïc hieän caùc caøi ñaët boå sung cho lôùp ñoái töôïng dialog CTcpServerDlg laøm giao dieän chính cuûa öùng duïng server: - Môû dialog resource, caøi ñaët caùc control sau:

- Hoäp nhaäp teân taäp tin : Edit Soá hieäu IDC_FILE - Hoäp hieån thò traïng thaùi heä thoáng : Static IDC_INFO - Hoäp hieån thò IP cuûa host laøm server : Static IDC_HOSTIP

- Ñoái töôïng thuoäc tính protected laøm nhieäm vuï truyeàn thoâng: CEmpTcpServer* m_Tcp;

- Haønh vi OnInitDialog cuûa dialog khôûi taïo thoâng soá cho dialog vaø caùc thoâng soá caàn thieát cho hoaït ñoäng truyeàn thoâng vôùi m_Tcp: BOOL CTcpServerDlg::OnInitDialog() { CDialog::OnInitDialog(); SetIcon( m_hIcon, TRUE ); SetDlgItemText( IDC_FILE, "C:/AUTOEXEC.BAT" );

212 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

// Xaùc ñònh ñòa chæ IP cuûa server host char name[1024]; gethostname( name, 1024 ); PHOSTENT phost = gethostbyname( name ); SetDlgItemText( IDC_HOSTIP, inet_ntoa(*(in_addr*)phost->h_addr) ); m_Tcp = new CEmpTcpServer( this ); m_Tcp->Create( PORT_NO ); // Khôûi taïo thoâng soá m_Tcp->Listen(); // Chôø keát noái return TRUE; }

- Haønh vi OnDestroy thöïc hieän giaûi phoùng ñoái töôïng truyeàn thoâng void CTcpServerDlg::OnDestroy() { CDialog::OnDestroy(); delete m_Tcp; }

Taïo döï aùn TcpClient. Thao taùc töông töï döï aùn TcpServer.

Thöïc hieän caùc coâng vieäc sau ñaây vôùi döï aùn TcpClient : Boå sung lôùp CEmpTcpReader keá thöøa CAsyncSocket ñaûm nhaän chöùc

naêng xin keát noái (Connect), vaø nhaän döõ lieäu (OnReceive) töø server: - Thuoäc tính public chöùa traïng thaùi truyeàn thoâng:

BOOL m_isBusy; // = TRUE : Ñang baän - Thuoäc tính protected chöùa con troû ñoái töôïng dialog lieân quan:

CDialog* m_Parent;

- Haønh vi taïo laäp nhaän tham soá laø ñoái töôïng dialog lieân quan: CEmpTcpReader::CEmpTcpReader(CDialog* parent) { m_isBusy = FALSE; // Saün saøng laøm vieäc m_Parent = parent; }

- Haønh vi OnReceive nhaän döõ lieäu vaø löu xuoáng taäp tin: void CEmpTcpReader::OnReceive(int nErrorCode) { static BOOL fileOK = TRUE; static BOOL fileReady = FALSE; static CFile file; static long total;

Page 117: Mfc Tieng Viet

MFC vôùi Internet 213

BUFFER buf;

Receive(&buf, BUFFER_LEN + sizeof(int));

if ( fileOK && (!fileReady) ) { m_Parent->SetDlgItemText(IDC_INFO, "\nDownloading..."); fileReady = TRUE; CString fileName; // Teân taäp tin chöùa döõ lieäu nhaän // IDC_FILE : Soá hieäu hoäp nhaäp teân taäp tin treân dialog m_Parent->GetDlgItemText( IDC_FILE, fileName ); fileOK = file.Open ( fileName, CFile::modeWrite | CFile::modeCreate ); total = 0; // Kích thöôùc döõ lieäu nhaän ñöôïc } if ( fileOK && buf.length > 0 ) { file.Write( buf.info, buf.length ); total += buf.length; if ( buf.length < BUFFER_LEN ) fileReady = FALSE; // Ñaõ nhaän ñuû döõ lieäu töø server } else fileReady = FALSE;

if (fileReady) CAsyncSocket::OnReceive(nErrorCode); // Nhaän tieáp else { m_isBusy = FALSE; // Trôû laïi traïng thaùi saün saøng @ Close(); if (fileOK) file.Close(); CString result; result.Format( "\nReady to connect to server !\n" "%d (bytes) download completed.", total ); m_Parent->SetDlgItemText(IDC_INFO, result); } }

Thöïc hieän caùc caøi ñaët boå sung cho lôùp ñoái töôïng dialog CTcpClientDlg laøm giao dieän chính cuûa öùng duïng client: - Môû dialog resource, caøi ñaët caùc control sau:

- Hoäp nhaäp teân taäp tin : Edit IDC_FILE - Hoäp hieån thò traïng thaùi heä thoáng : Static IDC_INFO - Hoäp nhaäp ñòa chæ IP cuûa server : IPControl IDC_HOSTIP

214 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

- Nuùt leänh download taäp tin töø server : Button IDOK - Taïo thuoäc tính bieán m_serverIP cho hoäp nhaäp IDC_HOSTIP. - Ñoái töôïng thuoäc tính protected laøm nhieäm vuï truyeàn thoâng:

CEmpTcpReader *m_readTcp;

- Haønh vi OnInitDialog cuûa dialog khôûi taïo thoâng soá cho dialog vaø caùc thoâng soá caàn thieát cho hoaït ñoäng truyeàn thoâng vôùi m_readTcp: BOOL CTcpClientDlg::OnInitDialog() { CDialog::OnInitDialog(); SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon

m_serverIP.SetWindowText( "127.0.0.1" ); // local host SetDlgItemText( IDC_FILE, "C:/Autoexec.000" ); m_readTcp = new CEmpTcpReader( this ); return TRUE; }

- Haønh vi OnDestroy giaûi phoùng ñoái töôïng truyeàn thoâng: void CTcpClientDlg::OnDestroy() { CDialog::OnDestroy(); delete m_readTcp; }

- Haønh vi OnOK öùng vôùi nuùt choïn download baét ñaàu nhaän döõ lieäu: void CTcpClientDlg::OnOK() { CString s; m_serverIP.GetWindowText(s); if ( m_readTcp->m_isBusy || s == "0.0.0.0" ) return; m_readTcp->m_isBusy = TRUE; // Traïng thaùi baän @ m_readTcp->Create(); m_readTcp->Connect(s, PORT_NO); }

Bieân dòch caùc döï aùn vaø thöû nghieäm treân moät hoaëc nhieàu maùy. Choïn muïc : Project / Set Active Project ñeå aán ñònh döï aùn laøm vieäc

trong taäp döï aùn (Workspace) nhö tröôøng hôïp noùi treân. Söû duïng CSocket vaø CSocketFile cho taùc vuï truyeàn taäp tin noùi treân.

Page 118: Mfc Tieng Viet

MFC vôùi Internet 215

Lôùp CSocket: CSocket laø lôùp keá thöøa CAsyncSocket maø caùc haønh vi göûi vaø nhaän

döõ lieäu cuûa noù töï ñoäng thöïc hieän cô cheá chôø cho taùc vuï tröôùc ñoù hoaøn taát. Nhö vaäy, seõ khoâng gaëp loãi taùc vuï ngheõn (WSAEWOULDBLOCK) khi thöïc hieän truyeàn döõ lieäu vôùi CSocket. Ñieàu naøy raát quan troïng vôùi caùc öùng duïng truyeàn taûi döõ lieäu coù kích thöôùc lôùn nhö öùng duïng (13.5).

Trong phaàn noäi dung tieáp theo, CSocket seõ ñöôïc söû duïng ñeå thay theá cho CAsyncSocket trong caùc ví duï minh hoïa.

13.6 TCP VÔÙI SMTP (SIMPLE MAIL TRANSFER PROTOCOL): SMTP laø giao thöùc ñôn giaûn vaø hieäu quaû cho vieäc truyeàn taûi e-mail töø host

göûi ñeán host nhaän mail; ví duï töø moät mail client ñeán moät mail server. Quaù trình truyeàn taûi mail ñöôïc thöïc hieän treân cô sôû thieát laäp moät keânh lieân laïc hai chieàu giöõa hai host. Host göûi laàn löôït phaùt caùc chæ thò keát noái vaø göûi döõ lieäu. Host nhaän tieáp nhaän döõ lieäu vaø traû lôøi ñeå host göûi coù cô sôû xaùc ñònh thao taùc thích hôïp keá tieáp. Moâ hình hoaït ñoäng truyeàn taûi mail giöõa hai host nhö sau:

Khi nhaän ñöôïc yeâu caàu cuûa ngöôøi duøng, host göûi phaùt tín hieäu ñeán host

nhaän ñeå xin keát noái. Moãi khi nhaän ñöôïc moät xaùc nhaän ñoàng yù cuûa host nhaän, host göûi tieáp

tuïc chuyeån phaàn noäi dung keá tieáp cuûa mail. Quaù trình treân keát thuùc khi mail ñaõ göûi xong hoaëc coù söï traû lôøi vôùi noäi

dung töø choái töø phía host nhaän.

13.6.1 Qui öôùc giao taùc giöõa öùng duïng göûi mail vaø öùng duïng nhaän mail: Thieát laäp lieân keát: Ñaàu tieân, öùng duïng göûi mail treân host göûi söû duïng

giao thöùc TCP keát noái vôùi öùng duïng nhaän mail treân host nhaän thoâng qua ñòa chæ IP cuûa host nhaän vaø soá hieäu port cuûa öùng duïng nhaän mail. Göûi: Môû socket vaø lieân laïc vôùi öùng duïng nhaän mail (port = 25). Nhaän: 220 <Domain> <ServerName> ready

216 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

Sau khi nhaän ñöôïc tín hieäu traû lôøi nhö treân töø öùng duïng nhaän mail, öùng duïng göûi mail tieáp tuïc thöïc hieän caùc taùc vuï sau ñaây theo thöù töï.

‘Trình dieän’ vôùi öùng duïng nhaän mail: Göûi: HELO <SP> <domain> <CRLF>

Trong ñoù: SP : Kyù töï khoaûng traéng CRLF : \r\n // return & newline in C

Nhaän: OK : 250 BBN-UNIX.ARPA ERROR : Soá hieäu loãi (keát noái bò töø choái).

Neáu nhaän ñöôïc traû lôøi “250 <Server Name>” töø öùng duïng nhaän mail, öùng duïng göûi mail coù theå tieáp tuïc caùc coâng vieäc keá tieáp.

Ñaêng kyù ñòa chæ ngöôøi göûi mail: Göûi: MAIL <SP> FROM:<ñòa_chæ_nôi_göûi> <CRLF> Nhaän: OK : 250 OK

ERROR : Ñaêng kyù khoâng ñöôïc chaáp nhaän keát thuùc. Ñaêng kyù ñòa chæ ngöôøi nhaän mail: Neáu mail ñöôïc göûi cho nhieàu ñòa chæ

thì thöïc hieän thao taùc naøy nhieàu laàn cho caùc ñòa chæ nhaän ñoù. Göûi: RCPT <SP> TO:<ñòa_chæ_nôi_nhaän> <CRLF> Nhaän: OK : 250 OK

ERROR : 550 Failure Info Chuaån bò truyeàn noäi dung cuûa mail:

Göûi: DATA <CRLF> Nhaän: OK : 354 Intermediate reply

ERROR : 550 Failure Truyeàn noäi dung cuûa mail: Coù theå laëp nhieàu laàn thao taùc sau ñaây tuøy

theo soá ñoaïn vaên baûn trong noäi dung cuûa mail. Göûi: Noäi dung ñoaïn vaên baûn thöù (i) cuûa mail Nhaän: Khoâng coù traû lôøi cuûa host nhaän.

Chaám döùt truyeàn noäi dung cuûa mail: Göûi: <CRLF> . <CRLF> Nhaän: 250 OK

Keát thuùc keát noái vôùi host nhaän: Göûi: QUIT <CRLF> Nhaän: 221 Terminated Info

Chaám döùt lieân keát giöõa hai öùng duïng göûi mail vaø nhaän mail. 13.6.2 Thieát keá öùng duïng göûi mail:

Page 119: Mfc Tieng Viet

MFC vôùi Internet 217

Trong phaàn naøy, ta xaây döïng öùng duïng söû duïng giao thöùc TCP ñeå keát noái vaø göûi mail leân moät mail server. Noäi dung mail vaø caùc aán ñònh lieân quan ñöôïc theå hieän treân dialog giao dieän chính cuûa öùng duïng.

Duøng MFC Wizard taïo döï aùn vôùi cöûa soå giao dieän chính laø dialog, coù söû duïng winsock (xem muïc 13.4). Ñaët teân cho döï aùn laø SMTP.

Thöïc hieän caùc caøi ñaët sau ñaây cho dialog giao dieän (CSMTPDlg): - Môû dialog resource, caøi ñaët caùc control sau:

- Hoäp nhaäp ñòa chæ mail server : Edit IDC_SERVER_IP - Hoäp nhaäp soá hieäu port : Edit IDC_SERVER_PORT - Hoäp nhaäp ñòa chæ ngöôøi nhaän : Edit IDC_MAIL_TO - Hoäp nhaäp tieâu ñeà cuûa mail : Edit IDC_MAIL_SUBJECT - Hoäp soaïn thaûo noäi dung mail : Edit IDC_MAIL - Nuùt leänh thöïc hieän göûi mail : Button IDOK

- Haønh vi OnInitDialog thöïc hieän caùc khôûi taïo caàn thieát: BOOL CSMTPDlg::OnInitDialog() { CDialog::OnInitDialog();

SetIcon(m_hIcon, TRUE); SetIcon(m_hIcon, FALSE);

SetDlgItemText(IDC_SERVER_IP, "omail.hcmueco.edu.vn"); SetDlgItemText(IDC_SERVER_PORT, "25"); SetDlgItemText(IDC_MAIL_TO, "[email protected]"); SetDlgItemText(IDC_MAIL_SUBJECT, "A Lesson of Mr.Emp"); SetDlgItemText(IDC_MAIL, "Hello Mr.Emp!\r\n\r\n" "It's nice to meet You.\r\n\r\n" "Thanks for your lessons."); return TRUE; }

- Haønh vi kieåm tra loãi treân giaù trò nhaän ñöôïc töø öùng duïng nhaän mail: Caøi ñaët haønh vi protected: GetErrorCode cho lôùp CSMTPDlg: UINT CSMTPDlg::GetErrorCode(char *sReply) { UINT rs = 0; sscanf(sReply, "%d", &rs); return rs; // Traû veà soá hieäu loãi ghi trong döõ lieäu nhaän ñöôïc }

- Haønh vi OnOK öùng vôùi nuùt choïn IDOK thöïc hieän göûi mail:

218 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

void CSMTPDlg::OnOK() { char s[1025]; UINT port; CSocket m_sock;

GetDlgItemText(IDC_SERVER_IP, s, 1024); port = GetDlgItemInt(IDC_SERVER_PORT);

m_sock.Create(); if (!m_sock.Connect(s, port)) return;

if (!m_sock.Receive(s, 1024) || GetErrorCode(s) != 220) return;

strcpy(s, "HELO Mr.Emp\r\n"); m_sock.Send(&s, strlen(s)); if (!m_sock.Receive(s, 1024) || GetErrorCode(s) != 250) return; // Ñòa chæ ngöôøi göûi strcpy(s, "MAIL FROM:Mr.Emp\r\n"); m_sock.Send(&s, strlen(s)); if (!m_sock.Receive(s, 1024) || GetErrorCode(s) != 250) return;

// Ñòa chæ ngöôøi nhaän strcpy(s, "RCPT TO:"); GetDlgItemText(IDC_MAIL_TO, s + strlen(s), 1024); strcpy(s + strlen(s), "\r\n"); m_sock.Send(&s, strlen(s)); if (!m_sock.Receive(s, 1024) || GetErrorCode(s) == 550) return;

// Chuaån bò truyeàn noäi dung mail strcpy(s, "DATA\r\n"); m_sock.Send(&s, strlen(s)); if (!m_sock.Receive(s, 1024) || GetErrorCode(s) != 354) return;

// Chuû ñeà mail strcpy(s, "Subject:"); GetDlgItemText(IDC_MAIL_SUBJECT, s + strlen(s), 1024); strcpy(s + strlen(s), "\r\n"); m_sock.Send(&s, strlen(s));

// Noäi dung mail

Page 120: Mfc Tieng Viet

MFC vôùi Internet 219

GetDlgItemText(IDC_MAIL, s, 1024); sprintf(s, "%s%s", s, "\r\n"); m_sock.Send(&s, strlen(s));

// Keát thuùc strcpy(s, "\r\n.\r\n"); m_sock.Send(&s, strlen(s));

strcpy(s, "QUIT\r\n"); m_sock.Send(&s, strlen(s));

m_sock.Close(); MessageBox("The Mail was sent OK !", "Send mail"); }

13.7 TCP VÔÙI POP3 (Post Office Protocol - Version 3): POP3 laø giao thöùc cho pheùp mail client host keát noái vôùi mail server host ñeå

laáy thoâng tin veà hoäp mail cuûa ngöôøi duøng treân mail server. Hoaït ñoäng truy xuaát naøy nhaèm taûi mail cuûa ngöôøi duøng veà client host vaø xoùa mail aáy khoûi hoäp mail cuûa hoï treân mail server. Töông töï SMTP, quaù trình taûi mail töø server cuûa POP3 ñöôïc thöïc hieän treân cô sôû thieát laäp moät keânh lieân laïc hai chieàu giöõa client vaø server. Client göûi laàn löôït göûi caùc chæ thò keát noái vaø nhaän döõ lieäu. Mail server tieáp nhaän yeâu caàu cuûa client vaø traû lôøi hoaëc göûi döõ lieäu.

13.7.1 Qui öôùc giao taùc giöõa hai öùng duïng mail client vaø mail server: Thieát laäp lieân keát: Ñaàu tieân, öùng duïng mail client söû duïng giao thöùc

TCP keát noái vôùi öùng duïng mail server thoâng qua ñòa chæ IP cuûa mail server host vaø soá hieäu port cuûa öùng duïng mail server. Göûi: Môû socket vaø lieân laïc vôùi öùng duïng mail server (port=110). Nhaän: +OK ok_message

-ERR error_message Sau khi nhaän ñöôïc tín hieäu traû lôøi ‘OK’ töø öùng duïng mail server, öùng duïng mail client tieáp tuïc thöïc hieän caùc taùc vuï sau theo thöù töï.

Ñaêng kyù taøi khoaûn truy caäp mail server: Khai baùo user name:

Göûi: USER <SP> <teân_ngöôøi_söû_duïng> <CRLF> Nhaän: +OK ok_message

-ERR error_message keát thuùc. Khai baùo password:

Göûi: PASS <SP> <noäi_dung_password> <CRLF> Nhaän: +OK ok_message

220 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

-ERR error_message keát thuùc. Sau khi ñaêng nhaäp thaønh coâng, coù theå tuøy yù thöïc hieän caùc coâng vieäc sau: Laáy thoâng tin veà hoäp mail:

Göûi: STAT <CRLF> Nhaän: +OK <SP> <number_of_mail> <SP> <mail_total_size>

-ERR error_message Laáy thoâng tin chi tieát cuûa caùc mail trong hoäp mail:

Göûi: LIST <CRLF> Nhaän: +OK <SP> Mailbox scan listing follows

-ERR error_message Ñoïc mail:

Göûi: RETR <SP> <soá_hieäu_mail_ñöôïc_ñoïc> <CRLF> Nhaän: +OK kích_thöôùc_message octets

… message do mail server göûi veà, keát thuùc bôûi daáu ‘.’ -ERR error_message

Xoùa mail: Göûi: DELE <SP> <soá_hieäu_mail_xoùa> <CRLF> Nhaän: +OK message <n> deleted

-ERR error_message Chaám döùt lieân keát vôùi mail server:

Göûi: QUIT <CRLF> Nhaän: + OK goodbye_message

- ERR error_message

13.7.2 Thieát keá öùng duïng nhaän mail: Trong phaàn naøy, ta xaây döïng öùng duïng söû duïng giao thöùc TCP ñeå keát noái

vaø laáy mail töø moät POP mail server. Thoâng soá lieân quan mail server vaø thoâng tin nhaän ñöôïc seõ ñöôïc theå hieän treân dialog giao dieän chính cuûa öùng duïng.

Duøng MFC Wizard taïo döï aùn vôùi cöûa soå giao dieän chính laø dialog, coù söû duïng winsock (xem muïc 13.4). Ñaët teân cho döï aùn laø POP3.

Thöïc hieän caùc caøi ñaët sau cho dialog giao dieän chính (CPOP3Dlg): - Môû dialog resource, caøi ñaët caùc control sau:

- Hoäp nhaäp ñòa chæ mail server : Edit IDC_SERVER_IP - Hoäp nhaäp soá hieäu port : Edit IDC_SERVER_PORT - Hoäp nhaäp teân ngöôøi truy caäp : Edit IDC_USER_NAME - Hoäp nhaäp password truy caäp : Edit IDC_USER_PASSWORD

Page 121: Mfc Tieng Viet

MFC vôùi Internet 221

- Hoäp nhaäp soá hieäu mail nhaän veà : Edit IDC_MAIL_NO - Hoäp hieån thò noäi dung mail : Edit IDC_MAIL - Nuùt leänh laáy thoâng tin veà mail : Button IDOK - Nuùt leänh thöïc hieän nhaän mail : Button IDC_READ_MAIL

- Haønh vi OnOK öùng vôùi nuùt OK thöïc hieän laáy thoâng tin veà hoäp mail: void CPOP3Dlg::OnOK() { char s[1025]; UINT port; CSocket m_sock;

GetDlgItemText (IDC_SERVER_IP, s, 1024); port = GetDlgItemInt(IDC_SERVER_PORT);

m_sock.Create(); if (!m_sock.Connect(s, port)) return;

if ( !m_sock.Receive(s, 1024) || !isOK(s) ) return;

strcpy(s, "USER "); // Ñaêng nhaäp GetDlgItemText(IDC_USER_NAME, s + strlen(s), 1024); strcat(s, "\r\n"); m_sock.Send(&s, strlen(s)); if ( !m_sock.Receive(s, 1024) || !isOK(s) ) return;

strcpy(s, "PASS "); // Ñaêng kyù password GetDlgItemText(IDC_USER_PASSWORD, s+strlen(s), 1024); strcat(s, "\r\n"); m_sock.Send(&s, strlen(s)); if ( !m_sock.Receive(s, 1024) || !isOK(s) ) return;

strcpy(s, "LIST\r\n"); // Laáy thoâng tin hoäp mail m_sock.Send(&s, strlen(s)); if ( (port = m_sock.Receive(s, 1024)) < 1 || !isOK(s) ) return;

s[port] = '\0'; SetDlgItemText(IDC_MAIL, s+4); // Boû qua +OK<SP>

// Keát thuùc... strcpy(s, "QUIT\r\n"); m_sock.Send(&s, strlen(s));

m_sock.Close(); }

222 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

- Haønh vi protected : isOK kieåm tra traû lôøi cuûa mail server treân döõ lieäu nhaän ñöôïc sau moãi taùc vuï lieân laïc: BOOL CPOP3Dlg::isOK(char *result) { return ( result[0] == '+' && result[1] == 'O' && result[2] == 'K' ); // +OK : Thaønh coâng }

- Haønh vi OnReadMail (nuùt choïn IDC_READ_MAIL) taûi mail veà: void CPOP3Dlg::OnReadMail() { char s[10241]; UINT port; CSocket m_sock;

GetDlgItemText(IDC_SERVER_IP, s, 1024); port = GetDlgItemInt(IDC_SERVER_PORT);

m_sock.Create(); if (!m_sock.Connect(s, port)) return; if ( !m_sock.Receive(s, 1024) || !isOK(s) ) return;

strcpy(s, "USER "); // Ñaêng nhaäp GetDlgItemText(IDC_USER_NAME, s + strlen(s), 1024); strcat(s, "\r\n"); m_sock.Send(&s, strlen(s)); if ( !m_sock.Receive(s, 1024) || !isOK(s) ) return;

strcpy(s, "PASS "); // Hôïp leä ? GetDlgItemText(IDC_USER_PASSWORD, s+strlen(s), 1024); strcat(s, "\r\n"); m_sock.Send(&s, strlen(s)); if ( !m_sock.Receive(s, 1024) || !isOK(s) ) return;

strcpy(s, "RETR "); // Taûi mail veà GetDlgItemText (IDC_MAIL_NO, s + strlen(s), 1024); strcat(s, "\r\n"); m_sock.Send(&s, strlen(s)); if ( (port = m_sock.Receive(s, 10240)) == 0 || !isOK(s) ) return;

s[port] = '\0'; SetDlgItemText(IDC_MAIL, strstr(s, "From"));

strcpy(s, "QUIT\r\n"); // Keát thuùc m_sock.Send(&s, strlen(s)); m_sock.Close(); }

Page 122: Mfc Tieng Viet

MFC vôùi Internet 223

13.8 TCP VÔÙI HTTP & FTP: HTTP vaø FTP laø caùc giao thöùc taàng öùng duïng ñöôïc xaây döïng döïa treân giao

thöùc TCP ôû taàng truyeàn taûi (moâ hình DARPA). HTTP: Giao thöùc phuïc vuï moâ hình öùng duïng Client/Server, duøng phoå

bieán trong vieäc truyeàn taûi caùc noäi dung HTML (www) giöõa client vaø server. Trong ñoù öùng duïng client keát noái vôùi öùng duïng server thoâng qua coång TCP xaùc ñònh, thoâng thöôøng laø 80.

FTP: Giao thöùc truyeàn taûi taäp tin. ÖÙng duïng client keát noái vôùi öùng duïng server thoâng qua hai coång TCP; moät duøng ñieàu khieån truyeàn, moät duøng truyeàn döõ lieäu; thoâng thöôøng laø 20 vaø 21.

MFC hoã trôï raát maïnh cho vieäc khai thaùc caùc giao thöùc noùi treân thoâng qua caùc lôùp ñoái töôïng trong thö vieän AfxInet.h.

13.8.1 CInternetSession: CInternetSession laø lôùp ñoái töôïng quaûn lyù moät giao taùc xaùc ñònh vôùi maïng

internet, keå caû vieäc thöïc hieän keát noái vôùi proxy server. Moãi giao taùc internet cho pheùp thöïc hieän caùc taùc vuï lieân quan ñeán taäp tin

treân caùc internet server thoâng qua caùc dòch vuï ñaëc bieät nhö FTP, HTTP. CInternetSession (

LPCTSTR pstrAgent = NULL, DWORD dwContext = 1, DWORD dwAccessType = INTERNET_OPEN_TYPE_PRECONFIG, LPCTSTR pstrProxyName = NULL, LPCTSTR pstrProxyBypass = NULL, DWORD dwFlags = 0 ); Haønh vi taïo laäp vaø khôûi taïo thoâng soá cho ñoái töôïng giao taùc internet. pstrAgent : Teân öùng duïng. Moät soá öùng duïng duøng teân laøm giaù

trò nhaän dieän ñoái vôùi server. dwContext : Soá hieäu nhaän dieän dieãn tieán cuûa taùc vuï. dwAccessType : Kieåu truy xuaát.

INTERNET_OPEN_TYPE_PRECONFIG : Theo aán ñònh maëc nhieân cuûa heä thoáng.

INTERNET_OPEN_TYPE_DIRECT : Tröïc tieáp khoâng thoâng qua proxy.

INTERNET_OPEN_TYPE_PROXY : Thoâng qua proxy.

224 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

pstrProxyName : Proxy. Söû duïng cho truy xuaát thoâng qua proxy. pstrProxyBypass : Danh saùch ñòa chæ caùc server ñöôïc truy xuaát tröïc

tieáp (duøng cho aán ñònh truy xuaát qua proxy). dwFlags : Thoâng soá veà cheá ñoä toái öu trong truy xuaát server.

INTERNET_FLAG_DONT_CACHE : Khoâng söû duïng cache ôû taát caû caùc host lieân quan ñeán caùc taùc vuï taäp tin cuûa giao taùc.

INTERNET_FLAG_OFFLINE : Söû duïng cache cho caùc taùc vuï taäp tin.

CFtpConnection* GetFtpConnection ( LPCTSTR pstrServer, // Ñòa chæ FTP server LPCTSTR pstrUserName = NULL, // Teân ñaêng nhaäp LPCTSTR pstrPassword = NULL, // password hôïp leä INTERNET_PORT nPort = /* soá hieäu port keát noái */ INTERNET_INVALID_PORT_NUMBER, BOOL bPassive = FALSE // Cô cheá keát noái ); Traû veà con troû ñoái töôïng quaûn lyù lieân keát vôùi FTP server. bPassive : Qui ñònh cô cheá choïn port cho keát noái. - TRUE : Do ngöôøi duøng choïn. - FALSE: Do FTP Server choïn (laø cô cheá maëc nhieân).

CHttpConnection* GetHttpConnection ( LPCTSTR pstrServer, // Ñòa chæ HTTP server INTERNET_PORT nPort = /* soá hieäu port */ INTERNET_INVALID_PORT_NUMBER, LPCTSTR pstrUserName = NULL, // Teân ñaêng nhaäp LPCTSTR pstrPassword = NULL // password hôïp leä ); Traû veà con troû ñoái töôïng quaûn lyù lieân keát vôùi HTTP server.

13.8.2 CInternetFile: CInternetFile laø lôùp ñoái töôïng quaûn lyù moät taäp tin treân maïng internet. CInternetFile( ); Taïo laäp ñoái töôïng quaûn lyù taäp tin. virtual LONG Seek (

LONG lOffset, // Cöï ly dôøi töông ñoái UINT nFrom // Vò trí laøm moác. ); AÁn ñònh vò trí con troû (ñaàu ñoïc/ghi döõ lieäu) trong taäp tin. Caùc giaù trò duøng cho nFrom coù theå laø: - CFile::current : Tính töø vò trí hieän haønh cuûa con troû taäp tin.

Page 123: Mfc Tieng Viet

MFC vôùi Internet 225

- CFile::begin : Tính töø ñaàu taäp tin. - CFile::end : Tính töø cuoái taäp tin.

virtual UINT Read ( void* lpBuf, // Ñòa chæ vuøng ñeäm chöùa döõ lieäu ñoïc UINT nCount // Kích thöôùc döõ lieäu ñoïc vaøo ); Ñoïc döõ lieäu töø taäp tin.

virtual void Write ( const void* lpBuf, // Ñòa chæ vuøng ñeäm chöùa döõ lieäu ghi ra UINT nCount // Kích thöôùc döõ lieäu ñöôïc ghi ); Ghi döõ lieäu ra taäp tin.

virtual BOOL ReadString ( CString& rString // Bieán chöùa chuoãi ñoïc vaøo ); Ñoïc moät chuoãi töø taäp tin.

virtual void WriteString ( LPCTSTR pstr // Bieán chöùa chuoãi ñöôïc ghi ra ); Ghi moät chuoãi ra taäp tin.

virtual void Close( ); Ñoùng taäp tin, chaám döùt moïi taùc vuï lieân quan.

13.8.3 CFtpConnection: CFtpConnection laø lôùp ñoái töôïng quaûn lyù moät lieân keát vôùi FTP server. Ñoái

töôïng naøy coù theå nhaän ñöôïc töø ñoái töôïng quaûn lyù giao taùc vôùi maïng internet thoâng qua haønh vi GetFtpConnection vôùi thoâng soá thích hôïp (13.8.1). Caùc haønh vi ñaëc tröng cuûa lôùp ñoái töôïng CFtpConnection nhö sau:

BOOL SetCurrentDirectory ( LPCTSTR pstrDirName // Ñöôøng daãn cuûa thö muïc. ); AÁn ñònh thö muïc laøm vieäc maëc nhieân treân FTP server.

BOOL GetCurrentDirectory ( CString& strDirName // Bieán chöùa keát quaû ); Laáy ñöôøng daãn cuûa thö muïc laøm vieäc treân FTP server.

BOOL RemoveDirectory ( LPCTSTR pstrDirName // Ñöôøng daãn thö muïc ); Xoùa thö muïc treân FTP server.

BOOL CreateDirectory ( LPCTSTR pstrDirName // Ñöôøng daãn vaø teân thö muïc ); Taïo môùi thö muïc treân FTP server.

BOOL Rename ( LPCTSTR pstrExisting, // Ñöôøng daãn vaø teân cuõ cuûa thö muïc

226 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

LPCTSTR pstrNew // Teân môùi cuûa thö muïc ); Ñoåi teân thö muïc treân FTP server.

BOOL Remove ( LPCTSTR pstrFileName // Ñöôøng daãn vaø teân taäp tin ); Xoùa taäp tin treân FTP server.

CInternetFile* OpenFile ( LPCTSTR pstrFileName, // Ñöôøng daãn vaø teân taäp tin ñöôïc môû DWORD dwAccess = GENERIC_READ, DWORD dwFlags = FTP_TRANSFER_TYPE_BINARY, DWORD dwContext = 1 ); Môû taäp tin treân FTP server. Traû veà con troû ñoái töôïng CInternetFile quaûn lyù taäp tin ñöôïc môû. dwAccess : Cheá ñoä môû taäp tin, choïn moät trong caùc cheá ñoä môû sau:

GENERIC_WRITE : Môû ñeå ghi. GENERIC_READ : Môû ñeå ñoïc.

dwFlags : Kieåu noäi dung taäp tin. FTP_TRANSFER_TYPE_ASCII : Maõ ASCII FTP_TRANSFER_TYPE_BINARY : Maõ nhò phaân

BOOL PutFile ( LPCTSTR pstrLocalFile, // Ñöôøng daãn vaø teân taäp tin ôû client LPCTSTR pstrRemoteFile, // Ñöôøng daãn vaø teân taäp tin ôû server DWORD dwFlags = /* Kieåu noäi dung taäp tin */ FTP_TRANSFER_TYPE_BINARY, DWORD dwContext = 1 // Soá hieäu nhaän dieän taùc vuï ); Taûi moät taäp tin töø host laøm vieäc leân FTP server (upload).

BOOL GetFile ( LPCTSTR pstrRemoteFile, // Ñöôøng daãn teân taäp tin treân server LPCTSTR pstrLocalFile, // Ñöôøng daãn teân taäp tin treân client BOOL bFailIfExists = TRUE, // Cheá ñoä xöû lyù truøng teân taäp tin. DWORD dwAttributes = FILE_ATTRIBUTE_NORMAL, DWORD dwFlags = /* Kieåu noäi dung taäp tin */ FTP_TRANSFER_TYPE_BINARY, DWORD dwContext = 1 ); Taûi moät taäp tin töø FTP server veà host laøm vieäc. bFailIfExists : Qui ñònh caùch thöïc hieän khi teân duøng cho taäp tin ghi truøng vôùi teân moät taäp tin ñaõ coù treân host laøm vieäc.

Page 124: Mfc Tieng Viet

MFC vôùi Internet 227

TRUE Thoâng baùo loãi. FALSE Töï ñoäng ghi choàng leân noäi dung ñaõ coù. dwAttributes : Thuoäc tính taäp tin. Coù theå keát hôïp caùc giaù trò sau: FILE_ATTRIBUTE_ARCHIVE : Taäp tin ñöôïc caäp nhaät. FILE_ATTRIBUTE_DIRECTORY : Thö muïc. FILE_ATTRIBUTE_NORMAL : Taäp tin bình thöôøng. FILE_ATTRIBUTE_HIDDEN : Taäp tin aån maët. FILE_ATTRIBUTE_READONLY : Taäp tin chæ ñoïc. FILE_ATTRIBUTE_SYSTEM : Taäp tin heä thoáng. FILE_ATTRIBUTE_TEMPORARY : Taäp tin söû duïng taïm thôøi.

virtual void Close( ); Keát thuùc lieân keát vôùi FTP server.

13.8.4 CFtpFindFile: CFtpFindFile laø lôùp ñoái töôïng quaûn lyù moät coâng cuï tìm kieám taäp tin treân

FTP server. Caùc haønh vi ñaëc tröng cuûa lôùp nhö sau: CFtpFileFind( CFtpConnection* pConnection ); Taïo laäp vaø khôûi taïo

thoâng soá cho ñoái töôïng tìm kieám taäp tin. virtual BOOL FindFile (

LPCTSTR pstrName = NULL, // Daïng teân taäp tin caàn tìm DWORD dwFlags = INTERNET_FLAG_RELOAD ); Khôûi ñoäng quaù trình tìm kieám taäp tin. Traû veà giaù trò TRUE neáu khôûi ñieåm tìm kieám thaønh coâng. Coù theå söû duïng ? , * ñeå aán ñònh daïng teân cuûa taäp tin caàn tìm. dwFlags = INTERNET_FLAG_DONT_CACHE khoâng söû duïng cache.

virtual BOOL FindNextFile( ); Tìm taäp tin keá tieáp thoûa ñieàu kieän. Traû veà giaù trò TRUE neáu taùc vuï tìm kieám thaønh coâng, neáu ngöôïc laïi thì xem nhö ñaõ tìm heát caùc taäp tin thoûa ñieàu kieän tìm kieám.

CString GetFileURL( ); Traû veà chuoãi ñöôøng daãn cuûa taäp tin vöøa tìm ñöôïc theo yeâu caàu. Ñoaïn chöông trình sau thöïc hieän tìm kieám caùc taäp tin vôùi teân coù phaàn môû roäng laø ‘txt’ treân FTP server: CInternetSession sess(_T("FTP - Example")); // Quaûn lyù giao taùc CFtpConnection* pConnect = NULL; // Lieân keát vôùi server try { pConnect = sess.GetFtpConnection(“ftp.hcmueco.edu.vn”); CFtpFileFind TimFile ( pConnect ); // Ñoái töôïng tìm kieám

228 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

BOOL TimThay = TimFile.FindFile(_T("*.TXT")); while (TimThay) { TimThay = TimFile.FindNextFile(); … // Xöû lyù taäp tin tìm thaáy } } catch (CInternetException* pEx) { … // Coù loãi } if (pConnect != NULL) pConnect->Close(); delete pConnect;

13.8.5 CHttpConnection: CHttpConnection laø lôùp ñoái töôïng quaûn lyù moät lieân keát vôùi HTTP server.

Ñoái töôïng naøy coù theå nhaän ñöôïc töø ñoái töôïng quaûn lyù giao taùc vôùi maïng internet thoâng qua haønh vi GetHttpConnection vôùi thoâng soá thích hôïp (13.8.1). Lôùp CHttpConnection coù haønh vi ñaëc tröng sau:

CHttpFile* OpenRequest ( int nVerb, LPCTSTR pstrObjectName, LPCTSTR pstrReferer = NULL, DWORD dwContext = 1, LPCTSTR* pstrAcceptTypes = NULL, LPCTSTR pstrVersion = NULL, DWORD dwFlags = INTERNET_FLAG_EXISTING_CONNECT ); Traû veà con troû ñoái töôïng CHttpFile quaûn lyù taäp tin döõ lieäu caàn truy xuaát treân HTTP server. nVerb: AÁn ñònh loaïi taùc vuï truy xuaát ñoái vôùi taäp tin döõ lieäu. CHttpConnection::HTTP_VERB_POST : Ghi döõ lieäu CHttpConnection::HTTP_VERB_GET : Ñoïc döõ lieäu CHttpConnection::HTTP_VERB_DELETE : Xoùa taäp tin döõ lieäu. pstrObjectName : Ñöôøng daãn vaø teân taäp tin döõ lieäu treân HTTP server. pstrReferer : Ñòa chæ (root) cuûa taäp tin döõ lieäu. dwContext : Soá hieäu nhaän dieän taùc vuï truy xuaát. pstrAcceptTypes : Chöùa caùc kieåu döõ lieäu maø client mong muoán khai

thaùc trong noäi dung cuûa taäp tin döõ lieäu ñöôïc truy xuaát. Ví duï: "text/*" = Chæ laáy noäi dung text, khoâng nhaän döõ lieäu laø hình aûnh, maõ,…

Page 125: Mfc Tieng Viet

MFC vôùi Internet 229

pstrVersion: Giao thöùc söû duïng, maëc nhieân laø "HTTP/1.0" dwFlags : Toái öu trong truy xuaát INTERNET_FLAG_RELOAD : Khoâng ñoïc töø cache. INTERNET_FLAG_DONT_CACHE : Khoâng ñeå laïi cache.

13.8.6 CHttpFile: CHttpFile laø lôùp ñoái töôïng quaûn lyù moät taäp tin döõ lieäu ñoäc laäp ñang ñöôïc

truy xuaát treân HTTP server. BOOL QueryInfo (

DWORD dwInfoLevel, // Thoâng soá truy vaán LPVOID lpvBuffer, // Vuøng ñeäm nhaän keát quaû LPDWORD lpdwBufferLength, // Chieàu daøi vuøng ñeäm LPDWORD lpdwIndex = NULL ); Truy vaán thoâng tin lieân quan ñeán taäp tin döõ lieäu. Traû veà giaù trò TRUE neáu taùc vuï truy vaán thaønh coâng. Thoâng soá truy vaán coù theå laø: HTTP_QUERY_FLAG_REQUEST_HEADERS : Thoâng tin header. HTTP_QUERY_LAST_MODIFIED : Ngaøy caäp nhaät cuoái cuøng.

BOOL AddRequestHeaders ( CString& str, // Noäi dung thoâng soá yeâu caàu DWORD dwFlags = HTTP_ADDREQ_FLAG_ADD_IF_NEW ); Caäp nhaät moät yeâu caàu môùi vaøo danh saùch caùc yeâu caàu ñoái vôùi taäp tin döõ lieäu. Caùc yeâu caàu naøy seõ ñöôïc göûi leân HTTP server thöïc hieän. Noäi dung moãi yeâu caàu phaûi keát thuùc baèng <CRLF>. Xem (RFC2616): - Accept : Ñeà nghò kieåu döõ lieäu truy xuaát trong taäp tin.

Cuù phaùp: "Accept: (media-range [ accept-params ][,])* " Ví duï: "Accept: audio/*" , "Accept: text/plain"

- User-Agent : Teân, duøng nhaän dieän öùng duïng yeâu caàu. Cuù phaùp : "User-Agent" ":" Name( product | comment )*" Ví duï : "User-Agent: Mr.EMP"

- Content-Type : Kieåu noäi dung taäp tin döõ lieäu. Cuù phaùp : "Content-Type: media-type*" Ví duï: "Content-Type: text/html; charset=ISO-8859-4"

dwFlags : Thoâng soá aán ñònh cô cheá caäp nhaät: HTTP_ADDREQ_FLAG_COALESCE : Troän caùc noäi dung cuûa

cuøng moät loaïi yeâu caàu: "Accept: text/*" vaø "Accept: audio/*" "Accept: text/*, audio/*"

230 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

HTTP_ADDREQ_FLAG_REPLACE : Thay theá noäi dung tröôùc bôûi noäi dugn sau coù cuøng loaïi yeâu caàu.

"Accept: text/*" vaø "Accept: audio/*" "Accept: audio/*" HTTP_ADDREQ_FLAG_ADD : Nhö _REPLACE vaø töï

ñoäng boå sung neáu loaïi yeâu caàu môùi laø chöa coù.

BOOL SendRequest ( CString& strHeaders, // Noäi dung yeâu caàu. LPVOID lpOptional = NULL, // Caùc dieãn giaûi cuûa client (khoâng DWORD dwOptionalLen = 0 // baét buoäc ) ); Göûi yeâu caàu lieân quan taäp tin döõ lieäu leân HTTP server. Neáu khoâng chæ ra noäi dung yeâu caàu thì maëc nhieân duøng yeâu caàu aán ñònh bôûi haønh vi AddRequestHeaders.

BOOL SendRequestEx ( LPINTERNET_BUFFERS lpBuffIn, // Kích thöôùc döõ lieäu LPINTERNET_BUFFERS lpBuffOut, // Vuøng ñeäm chöùa döõ lieäu DWORD dwFlags = HSR_INITIATE, DWORD dwContext = 1 ); Ghi thoâng tin leân taäp tin döõ lieäu treân HTTP server.

BOOL EndRequest ( DWORD dwFlags = 0, LPINTERNET_BUFFERS lpBuffIn = NULL, DWORD dwContext = 1 ); Ngöøng taùc vuï ghi treân taäp tin döõ lieäu cuûa HTTP server.

virtual CString GetFileURL( ); Traû veà ñöôøng daãn vaø teân cuûa taäp tin döõ lieäu treân HTTP server.

virtual void Close( ); Keát thuùc truy xuaát taäp tin döõ lieäu.

Ví duï: Ñoaïn chöông trình sau thöïc hieän keát noái vôùi HTTP server. Ñoïc vaø hieån thò noäi dung cuûa taäp tin /index.html treân server naøy.

Page 126: Mfc Tieng Viet

MFC vôùi Internet 231

CInternetSession session("HTTP - Example"); CHttpFile* file=NULL; CString strServer = "www.hcmueco.edu.vn"; CString strObject("/index.html"); INTERNET_PORT port = INTERNET_DEFAULT_HTTP_PORT; CString strHeaders ( "Accept: text/*\r\n” “User-Agent: Mr.Emp\r\n" "Content-Type: application/x-www-form-urlencoded\r\n"); CHttpConnection* server = NULL; try { server=session.GetHttpConnection(strServer, port); file=server->OpenRequest ( CHttpConnection::HTTP_VERB_POST,strObject ); } catch (CInternetException* pEx) { … // Coù loãi } if (server==NULL) return; if (file!=NULL) { file->AddRequestHeaders(strHeaders); file->SendRequest(); // Xaùc laäp yeâu caàu truy xuaát CString line; // Söû duïng cho ñoïc chuoãi while (file->ReadString(line)) { … // Xöû lyù noäi dung ñoïc ñöôïc } file->Close(); delete file; } server->Close(); delete server;

13.8.7 Thöïc hieän öùng duïng FTP client ñôn giaûn: Trình töï tieán haønh caùc xöû lyù cuûa öùng duïng nhö sau: - Thieát laäp giao taùc internet, taïo lieân keát FTP töø giao taùc naøy. - Taïo ñoái töôïng CFtpFileFind töø lieân keát FTP, tìm taäp tin treân ftp server. - Taïo ñoái töôïng CInternetFile töø taäp tin tìm ñöôïc. Thöïc hieän caùc taùc vuï

ñoïc ghi moät caùch thích hôïp. - Ñoùng caùc ñoái töôïng.

232 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

Sau ñaây laø caùc böôùc thöïc hieän döï aùn cuûa öùng duïng noùi treân: Duøng MFC Wizard, taïo döï aùn Ftp vôùi giao dieän chính laø dialog. Boå sung chæ thò: #include <afxinet.h> cho taäp tin stdafx.h cuûa döï aùn. Thöïc hieän caùc caøi ñaët sau cho lôùp dialog CFtpDlg cuûa döï aùn:

- Môû dialog resource, caøi ñaët caùc control sau: - Hoäp nhaäp ñòa chæ FTP server : Edit IDC_URL - Hoäp hieån thò danh saùch caùc taäp tin : ListBox IDC_FILE_LIST - Nuùt leänh thöïc hieän tìm kieám taäp tin : Button IDOK

- Taïo bieán m_fileList cho control IDC_FILE_LIST. - Haønh vi OnOK öùng vôùi nuùt choïn IDOK thöïc hieän tìm taát caû caùc taäp

tin trong thö muïc goác cuûa FTP server vaø ñöa vaøo danh saùch: Caøi ñaët töông töï ví duï muïc (13.8.4) Phaàn caøi ñaët cuûa Xöû lyù taäp tin tìm thaáy nhö sau: m_fileList.ResetContent(); while (TimThay) { bWorking = TimFile.FindNextFile(); m_fileList.AddString(TimFile.GetFileURL()); }

Bieân dòch vaø chaïy öùng duïng.

13.8.8 Thöïc hieän öùng duïng HTTP client ñôn giaûn: Trình töï tieán haønh caùc xöû lyù cuûa öùng duïng nhö sau: - Thieát laäp giao taùc internet, taïo lieân keát HTTP töø giao taùc naøy. - Taïo ñoái töôïng CHttpFile cho taäp tin quan taâm treân HTTP server. - Söû duïng ñoái töôïng CHttpFile ñeå QueryInfo hoaëc aán ñònh truy xuaát vôùi

AddRequestHeaders vaø SendRequest treân noäi dung taäp tin. - Truy xuaát döõ lieäu: Read, ReadString hoaëc Write, WriteString.

Sau ñaây laø caùc böôùc thöïc hieän döï aùn cuûa öùng duïng noùi treân: Duøng MFC Wizard, taïo döï aùn Http vôùi giao dieän chính laø dialog. Boå sung chæ thò: #include <afxinet.h> cho taäp tin stdafx.h cuûa döï aùn. Thöïc hieän caùc caøi ñaët sau cho lôùp dialog CHttpDlg cuûa döï aùn:

- Môû dialog resource, caøi ñaët caùc control sau: - Hoäp nhaäp ñòa chæ HTTP server : Edit IDC_URL - Hoäp hieån thò noäi dung taäp tin : Edit IDC_SOURCE - Nuùt leänh thöïc hieän taûi taäp tin veà : Button IDOK

Page 127: Mfc Tieng Viet

MFC vôùi Internet 233

- Haønh vi OnOK öùng vôùi nuùt choïn IDOK thöïc hieän taûi noäi dung taäp tin töø ñòa chæ nhaäp trong hoäp nhaäp: Caøi ñaët töông töï ví duï muïc (13.8.6) Phaàn caøi ñaët cuûa Xöû lyù noäi dung ñoïc ñöôïc nhö sau: CString line, info; info.Empty(); while (file->ReadString(line)) { info = info + line; info = info + "\r\n"; } SetDlgItemText(IDC_SOURCE, info);

Bieân dòch vaø chaïy öùng duïng. THÖÏC HAØNH: 1. Xaây döïng öùng duïng CHAT vôùi moät trong caùc giao thöùc TCP vaø UDP. 2. Xaây döïng öùng duïng FTP explorer (xem windows explorer). 3. Xaây döïng öùng duïng chôi baøi tieán leân treân maïng (moâ hình client/server). 4. Xaây döïng öùng duïng thi traéc nghieäm treân maïng.

- ÖÙng duïng giaùm thò laø trung taâm keát noái vôùi caùc öùng duïng kieåm tra chaïy treân caùc host laøm baøi. ÖÙng duïng giaùm thò ñieàu khieån ñoàng boä caùc öùng duïng kieåm tra.

- ÖÙng duïng kieåm tra chôø chæ thò töø öùng duïng giaùm thò, taïo giao dieän laøm baøi vôùi ngöôøi duøng, thöôøng xuyeân thoâng baùo tình traïng baøi laøm cuûa ngöôøi duøng cho öùng duïng giaùm thò quaûn lyù vaø baûo löu.

- Khi baét ñaàu, öùng duïng gíam thò chuû ñoäng keát noái, öùng duïng laøm baøi chôø keát noái ñeå laáy thoâng tin veà öùng duïng giaùm thò vaø caùc thoâng tin khaùc veà ñeà thi, thoâng tin baûo löu neáu tröôùc ñoù coù söï coá.

5. Quan saùt öùng duïng Yahoo Messenger!. Keát hôïp hai kieåu öùng duïng rtf view (11.8) vaø öùng duïng TCP (13.5) ñeå thöïc hieän öùng duïng töông töï. 6. Vieát öùng duïng mail server vaø mail client ñôn giaûn. 7. Vieát öùng duïng ftp server ñôn giaûn. 8. Vieát öùng duïng http server ñôn giaûn (RFC1945). 9. Vieát öùng duïng voice chat ñôn giaûn.

Page 128: Mfc Tieng Viet

234 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

PHUÏ LUÏC A:

Moät soá vaán ñeà laäp trình höôùng ñoái töôïng

A.1 LAÄP TRÌNH HÖÔÙNG ÑOÁI TÖÔÏNG (OOP):

Laäp trình höôùng ñoái töôïng (Object-Oriented Programming) laø phöông phaùp laäp trình giaûi quyeát baøi toaùn döïa treân söï phoái hôïp caùc ñoái töôïng khaùch quan trong khoâng gian baøi toaùn. Caùc ñoái töôïng naøy hoaït ñoäng vaø töông taùc laãn nhau ñeå ñöa baøi toaùn veà traïng thaùi mong muoán.

Phöông phaùp tieáp caän naøy cho pheùp taùch khoâng gian baøi toaùn thaønh caùc taäp hôïp nhieàu ñoái töôïng, caùc ñoái töôïng coù tính ñoäc laäp töông ñoái vôùi nhau. Do ñoù, töø moät coâng vieäc lôùn phöùc taïp ta coù theå phaân chia thaønh nhieàu coâng vieäc nhoû ñôn giaûn vaø deã thöïc hieän hôn, ñoàng thôøi vieäc ñieàu chænh boå sung tính naêng cho moãi ñoái töôïng cuõng khoâng aûnh höôûng ñeán hoaït ñoäng cuûa caùc ñoái töôïng khaùc. Nhôø ñoù, khi coù nhu caàu phaùt trieån baøi toaùn thì ta khoâng phaûi xaây döïng laïi töø ñaàu maø coù theå döïa treân nhöõng noäi dung ñaõ coù. Ñaây chính laø moät öu ñieåm lôùn so vôùi laäp trình caáu truùc.

A.2 CAÙC KHAÙI NIEÄM: A.2.1 Lôùp (Class):

Lôùp laø moät taäp hôïp caùc ñoái töôïng coù cuøng moät soá tính chaát khaûo saùt. Caùc tính chaát naøy coù theå laø traïng thaùi (thuoäc tính) hay hoaït ñoäng cuûa ñoái töôïng.

Ví duï: Lôùp caù laø taäp hôïp bao goàm nhöõng ñoäng vaät coù cuøng ñaëc ñieåm: vaây, mang, maùu laïnh vaø coù caùc haønh vi: soáng döôùi nöôùc, thôû baèng mang, ñeû tröùng.

A.2.2 Ñoái töôïng (Object): Ñoái töôïng laø moät theå hieän cuï theå cuûa lôùp. Moät ñoái töôïng thuoäc lôùp naøo seõ

coù nhöõng thuoäc tính, haønh vi cuûa lôùp ñoù. Söï khaùc nhau veà caùch theå hieän thuoäc tính, haønh vi cuûa ñoái töôïng laø cô sôû

phaân bieät ñoái töôïng vôùi caùc ñoái töôïng khaùc trong cuøng moät lôùp.

A.2.3 Thuoäc tính (Attribute): Thuoäc tính laø giaù trò phaûn aùnh traïng thaùi cuûa ñoái töôïng taïi moät thôøi ñieåm

xaùc ñònh, giuùp theå hieän ñoái töôïng. Ñoái töôïng coù moät hoaëc nhieàu thuoäc tính. A.2.4 Haønh vi (Method):

Phuï luïc A: Moät soá vaán ñeà laäp trình höôùng ñoái töôïng 235

Haønh vi laø khaû naêng öùng xöû cuûa ñoái töôïng vôùi moâi tröôøng xung quanh, noù taùc ñoäng vaø thay ñoåi thuoäc tính cuûa baûn thaân ñoái töôïng vaø caùc ñoái tuôïng lieân quan. Haønh vi theå hieän maët hoaït ñoäng cuûa ñoái töôïng. Ví duï:

Hoaït ñoäng soáng cuûa con ngöôøi laø quaù trình vaän ñoäng thay ñoåi baûn thaân con ngöôøi vaø taùc ñoäng (cuõng nhö bò taùc ñoäng) ñeán moâi tröôøng xung quanh.

Ta coù moâ hình cuûa ñoái töôïng nhö sau:

A.2.5 Chöông trình (Program):

Döôùi goùc ñoä OOP, chöông trình laø chuoãi thao taùc phoái hôïp cuûa moät hay nhieàu ñoái töôïng nhaèm ñaït ñeán moät keát cuïc mong muoán. Caùc thao taùc naøy cuûa caùc ñoái töôïng phaûi ñöôïc daøn döïng tröôùc, ta coù theå goïi ñoù laø kòch baûn.

A.3 ÑAËC ÑIEÅM LAÄP TRÌNH HÖÔÙNG ÑOÁI TÖÔÏNG:

- Tính khaùch quan (Objective): Moät lôùp ñoái töôïng hình thaønh laø xuaát phaùt töø moät chuû theå khaùch quan vôùi nhöõng thuoäc tính vaø haønh vi theå hieän baûn chaát vaø chöùc naêng cuûa noù. Kòch baûn cuûa chöông trình vaän duïng nhöõng yeâu toá khaùch quan naøy moät caùch hôïp lyù ñeå ñaït ñöôïc muïc ñích cuûa chöông trình.

- Tính ñoùng goùi (Encapsulation): Vieäc bao haøm caùc thuoäc tính vaø haønh vi trong ñoái töôïng giuùp ñoái töôïng coù theå hoaït ñoäng phoái hôïp trong ñoäc laäp vôùi caùc lôùp ñoái töôïng khaùc.

- Tính keá thöøa (Inheritance): Vieäc ñònh nghóa moät lôùp ñoái töôïng döïa treân caùc lôùp ñoái töôïng ñaõ coù goïi laø söï keá thöøa. Caùc lôùp ñaõ coù goïi laø lôùp cô sôû (based class), lôùp ñöôïc ñònh nghóa goïi laø lôùp keá thöøa (derived class). Beân caïnh vieäc keá thöøa, lôùp keá thöøa coù theå ñöôïc boå sung nhöõng haønh vi vaø thuoäc tính caàn thieát ñeå phuïc vuï cho nhu caàu môùi phaùt sinh. Cô cheá ñoù ñaõ taïo söï phaùt trieån cho öùng duïng maø ñoái töôïng tham gia.

- Tính ña hình (Polymorphism):

Ñoái töôïng = Thuoäc tính + Haønh vi

Chöông trình = Taäp hôïp caùc ñoái töôïng + Kòch baûn

Page 129: Mfc Tieng Viet

236 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

Cô cheá trieån khai nhieàu caùch theå hieän khaùc nhau cho moät haønh vi theo nguyeân taéc xaây döïng lôùp cô sôû chöùa haønh vi caàn trieån khai vaø caùc lôùp keá thöøa. Moãi lôùp keá thöøa seõ phaùt trieån haønh vi ñoù theo moät caùch khaùc nhau. Moät ñoái töôïng ñaïi dieän lôùp cô sôû seõ ñöôïc kieán taïo töø lôùp keá thöøa phuø hôïp ñeå coù caùch theå hieän haønh vi caàn trieån khai theo yù muoán. Cô cheá naøy taïo khaû naêng öùng xöû phong phuù cuûa ñoái töôïng.

A.4 PHAÂN LOAÏI THUOÄC TÍNH VAØ HAØNH VI: Caùc thuoäc tính vaø haønh vi cuûa ñoái töôïng coù theå ñöôïc chia thaønh ba loaïi: - Public: Caùc thuoäc tính, haønh vi ñöôïc ñoái töôïng theå hieän beân ngoaøi. - Protected: Caùc thuoäc tính, haønh vi aån chöùa beân trong ñoái töôïng, hoã trôï

caùc hoaït ñoäng cuûa ñoái töôïng vaø coù theå truyeàn laïi cho caùc lôùp ñoái töôïng keá thöøa.

- Private: Caùc thuoäc tính, haønh vi aån chöùa beân trong ñoái töôïng, hoã trôï caùc hoaït ñoäng cuûa ñoái töôïng vaø khoâng theå truyeàn laïi cho caùc lôùp ñoái töôïng keá thöøa.

A.5 CAÙC HAØNH VI ÑAËC BIEÄT: - Haønh vi taïo taäp: Haønh vi ñöôïc thöïc hieän ngay khi ñoái töôïng vöøa hình

thaønh. Haønh vi naøy duøng ñeå caøi ñaët caùc xöû lyù khôûi taïo caùc giaù trò thuoäc tính cuûa ñoái töôïng.

Moät lôùp ñoái töôïng coù theå coù moät hoaëc nhieàu haønh vi taïo laäp. Teân haønh vi taïo laäp truøng vôùi teân lôùp. Caùc haønh vi taïo laäp ñöôïc phaân bieät laãn nhau bôûi caáu truùc caùc tham soá cuûa chuùng.

- Haønh vi huûy boû: Haønh vi ñöôïc thöïc hieän tröôùc khi ñoái töôïng chaám döùt söï toàn taïi cuûa noù.

Moät lôùp ñoái töôïng coù moät haønh vi huûy boû duy nhaát. Teân haønh vi huûy boû truøng vôùi teân cuûa lôùp nhöng ñöôïc baét ñaàu baèng daáu ‘~’. Haønh vi huûy boû khoâng coù tham soá.

Caû haønh vi taïo laäp vaø huûy boû ñeàu khoâng coù kieåu traû veà.

A.6 KHAI BAÙO LÔÙP, ÑOÁI TÖÔÏNG TRONG C++: A.6.1 Khai baùo lôùp:

Lôùp ñoái töôïng ñöôïc khai baùo trong C++ nhö sau: // Phaàn khai baùo cuûa lôùp:

Phuï luïc A: Moät soá vaán ñeà laäp trình höôùng ñoái töôïng 237

class Teân_lôùp { public: [ Khai baùo caùc thuoäc tính, haønh vi kieåu public ] protected: [ Khai baùo caùc thuoäc tính, haønh vi kieåu private ] privated: [ Khai baùo caùc thuoäc tính, haønh vi kieåu private ] };

// Phaàn caøi ñaët cuûa lôùp: kieåu Teân_lôùp::Teân_haønh_vi_1( [ Danh_saùch_tham_soá ] ) { … // Caùc xöû lyù trong haønh vi } … kieåu Teân_lôùp::Teân_haønh_vi_n( [ Danh_saùch_tham_soá ] ) { … // Caùc xöû lyù trong haønh vi }

Noäi dung phaàn khai baùo vaø caøi ñaët cuûa lôùp ñöôïc ñaët trong hai taäp tin khai baùo (.h) vaø caøi ñaët (.cpp). Trong ñoù: - Taäp tin .H : Chöùa toaøn boä phaàn khai baùo cuûa lôùp vaø caùc chæ thò

ñònh höôùng bieân dòch (neáu caàn). - Taäp tin .CPP : Chöùa toaøn boä phaàn caøi ñaët cuûa lôùp. ÔÛ ñaàu taäp tin

naøy khai baùo chæ thò söû duïng taäp tin .H: #include "Teân_taäp_tin_h_lieân_quan"

Thöïc haønh 1: Xeùt baøi toaùn quaûn lyù chuoãi, khoâng gian baøi toaùn laø caùc giaù trò kieåu chuoãi cuûa C caàn quaûn lyù vaø truy xuaát.

Döôùi goùc ñoä OOP, lôùp ñoái töôïng chuoãi giuùp bieåu dieãn chuoãi coù caùc thuoäc tính vaø haønh vi nhö sau: - Thuoäc tính: char* info ñöôïc söû duïng ñeå xin caáp phaùt vuøng nhôù

chöùa noäi dung chuoãi. - Haønh vi: - Haønh vi taïo laäp vôùi moät tham soá laø giaù trò chuoãi

laøm noäi dung khôûi ñaàu cho ñoái töôïng chuoãi. - Haønh vi huûy boû giaûi phoùng vuøng nhôù info. - Haønh vi laáy ñòa chæ vuøng chöùa noäi dung chuoãi.

Lôùp chuoãi ñöôïc khai baùo trong C++ nhö sau:

Page 130: Mfc Tieng Viet

238 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

// Taäp tin String1.h class CString1 { public: CString1 ( char* s ); // Haønh vi taïo laäp ~CString1 ( void ); // Haønh vi huûy boû char* GetInfo( void ); protected: char* info; };

// Taäp tin String1.cpp CString1::CString1( char* s ) { info = new char[ strlen( s ) + 1 ]; strcpy( info, s ); }

CString1::~CString1( ) { delete info; }

char* CString1::GetInfo( void ) { return info; }

A.6.2 Khai baùo ñoái töôïng: Ñoái töôïng ñöôïc khai baùo nhôø lôùp töông öùng. Lôùp coù theå xem nhö laø moät

kieåu döõ lieäu vaø ñoái töôïng chính laø bieán öùng vôùi kieåu ñoù. Cuù phaùp khai baùo bieán ñoái töôïng trong C++ nhö sau:

Teân_lôùp Teân_bieán_ñoái_töôïng( [Danh saùch giaù trò laøm tham soá ] );

A.6.3 Söû duïng ñoái töôïng trong chöông trình: Thöïc hieän haønh vi cuûa bieán ñoái töôïng (caùc haønh vi public) nhö sau:

Teân_bieán_ñoái_töôïng.Teân_haønh_vi( [Danh saùch giaù trò laøm tham soá ] );

// Chöông trình Main.cpp söû duïng lôùp CString1 khai baùo ôû treân. #include "String1.h" void main( void ) { CString1 a( “Vo Van A” ); printf( "Gia tri chuoi luu la: %s ", a.GetInfo() ); }

A.7 KEÁ THÖØA TRONG C++:

Phuï luïc A: Moät soá vaán ñeà laäp trình höôùng ñoái töôïng 239

C++ cho pheùp ñònh nghóa lôùp keá thöøa töø moät hoaëc nhieàu lôùp cô sôû. Cuù phaùp thöïc hieän khai baùo naøy nhö sau:

class Teân_lôùp_keá_thöøa: [ public | private ] Teân_lôùp_cô_sôû1 [, [public | private ] Teân_lôùp_cô_sôû2 [ , … ] { … // Caùc khai baùo boå sung cuûa lôùp keá thöøa };

Ñaëc ñieåm keá thöøa qui ñònh möùc ñoä keá thöøa cuûa lôùp keá thöøa töø lôùp cô sôû. Coù hai kieåu khaùc nhau cuûa ñaëc ñieåm keá thöøa vaø coù yù nghóa nhö sau:

Thuoäc tính lôùp cô sôû Thuoäc tính nhaän ñöôïc cho lôùp keá thöøa

public public private

protected protected private

private Khoâng truy xuaát ñöôïc Khoâng truy xuaát ñöôïc

Ñaëc ñieåm keá thöøa public Private

Ví duï: Khai baùo lôùp CString1B keá thöøa hoaøn toaøn töø lôùp CString1.

class CString1B : public CString1 { };

A.7.1 Keá thöøa haønh vi taïo laäp: Moãi haønh vi taïo laäp boå sung cuûa lôùp keá thöøa chæ ñöôïc pheùp söû duïng moät

haønh vi taïo laäp duy nhaát töø moät lôùp cô sôû. Khai baùo coù cuù phaùp nhö sau:

Haønh_vi_taïo_laäp_cuûa_lôùp_keá_thöøa( [ Danh saùch thamm soá ] ) : Haønh_vi_taïo_laäp_cuûa_lôùp_sô_sôû_1( [ Caùc giaù trò thamm soá ] ) [ , Haønh_vi_taïo_laäp_cuûa_lôùp_sô_sôû_2( [ Caùc giaù trò thamm soá ] ) [ , … ] ] { … };

Khi moät ñoái töôïng thuoäc lôùp keá thöøa hình thaønh, xöû lyù trong haønh vi taïo laäp cuûa lôùp keá thöøa vaø xöû lyù trong caùc haønh vi taïo laäp cuûa caùc lôùp cô sôû maø lôùp ñaêng kyù keá thöøa seõ ñöôïc thöïc hieän theo thöù töï nhö sau:

Haønh_vi_taïo_laäp_cuûa_lôùp_sô_sôû_1

Page 131: Mfc Tieng Viet

240 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

Haønh_vi_taïo_laäp_cuûa_lôùp_sô_sôû_2

Haønh_vi_taïo_laäp_cuûa_lôùp_sô_sôû_n

Haønh_vi_taïo_laäp_cuûa_lôùp_keá_thöøa

A.7.2 Keá thöøa haønh vi huûy boû: Haønh vi huûy boû cuûa lôùp keá thöøa (maëc nhieân thuoäc loaïi public) töï ñoäng keá

thöøa haønh vi huûy boû cuûa lôùp cô sôû maø khoâng caàn phaûi khai baùo.

Khi moät ñoái töôïng thuoäc lôùp keá thöøa chaám döùt hoaït ñoäng, xöû lyù trong haønh vi huûy boû cuûa cuûa lôùp keá thöøa vaø xöû lyù trong caùc haønh vi huûy boû cuûa caùc lôùp cô sôû seõ ñöôïc thöïc hieän theo thöù töï nhö sau:

Haønh_vi_huûy_boû_cuûa_lôùp_keá_thöøa

Haønh_vi_huûy_boû_cuûa_lôùp_sô_sôû_(n)

Haønh_vi_huûy_boû_cuûa_lôùp_sô_sôû_(n-1)

Haønh_vi_taïo_laäp_cuûa_lôùp_sô_sôû_1

A.7.3 Thöïc hieän haønh vi lôùp cô sôû: Haønh vi cuûa lôùp keá thöøa ñöôïc pheùp chuû ñoäng söû duïng haønh vi cuûa lôùp cô

sôû cuûa noù. Caùch thöïc hieän haønh vi cuûa lôùp cô sôû nhö sau:

Teân_lôùp_cô_sôû::Teân_haønh_vi( [ Danh_saùch_giaù_trò_tham_soá ] );

Thöïc haønh 2: Môû roäng khoâng gian baøi toaùn thöïc haønh 1, vôùi lôùp ñoái töôïng CString2 keá thöøa töø CString1 vaø boå sung haønh vi taïo laäp nhaän tham soá laø moät ñoái töôïng CString1. Lôùp CString2 ñöôïc khai baùo trong C++ nhö sau: // Taäp tin String2.h #include “String1.h”

Phuï luïc A: Moät soá vaán ñeà laäp trình höôùng ñoái töôïng 241

class CString2 : public CString1 { public: // Haønh vi taïo laäp boå sung nhaän moät tham soá laø ñoái töôïng CString1 CString2( CString1* s ) : CString1( s->GetInfo() ) { } };

// Chöông trình Main2.cpp söû duïng lôùp CString2 khai baùo ôû treân. #include "String2.h" void main( void ) { CString2 a( “Vo Van B” ); CString2 b( &a ); printf( "Gia tri chuoi luu la: %s ", b.GetInfo() ); // Keát quaû nhaän ñöôïc: Gia tri chuoi luu la: Vo Van B }

A.8 KHAI BAÙO HAØNH VI TOAÙN TÖÛ SOÁ HOÏC: Khai baùo haønh vi toaùn töû soá hoïc laø hình thöùc thay theå hieän haønh vi theo

daïng haøm (kieåu ñaïi soá) thaønh daïng toaùn töû (kieåu soá hoïc). Coù hai loaïi haønh vi toaùn töû: Haønh vi toaùn töû hai ngoâi: Laø haønh vi coù moät tham soá ñoái taùc.

Khai baùo:

Kieåu Teân lôùp::operator Kyù_ hieäu_haønh_vi ( [ Danh saùch tham soá ] );

Haønh vi toaùn töû moät ngoâi: Laø haønh vi khoâng coù tham soá ñoái taùc naøo. Haønh vi naøy coù theå ñöôïc söû duïng cho pheùp chuyeån kieåu ñoái töôïng. Khai baùo:

Teân lôùp::operator Kyù_hieäu_haønh_vi ( void );

Thöïc haønh 3: Môû roäng khoâng gian baøi toaùn thöïc haønh 1, vôùi caùc toaùn töû gaùn ( = ), coäng ( + ), vaø chuyeån kieåu lôùp ñoái töôïng chuoãi veà kieåu chuoãi cuûa C (char*) thay cho haønh vi GetInfo.

Taïo lôùp keá thöøa CString3 töø lôùp cô sôû CString1. Thöïc hieän boå sung caùc haønh vi toaùn töû sau ñaây: - Toaùn töû chuyeån kieåu: char * - Toaùn töû gaùn ( = ) vôùi tham soá laø moät giaù trò kieåu chuoãi cuûa C. - Toaùn töû coäng ( + ) vôùi tham soá laø moät giaù trò kieåu chuoãi cuûa C vaø

traû veà con troû ñeán ñoái töôïng chuoãi môùi. Lôùp CString3 ñöôïc khai baùo trong C++ nhö sau: // Taäp tin String3.h

Page 132: Mfc Tieng Viet

242 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

#include “String1.h” class CString3 : public CString1 { public: CString3( char* s ) : CString1( s ) { } // Toaùn töû chuyeån kieåu operator char* ( void ) { return info; } void operator = ( char* s ); CString3* operator + ( char* s ); };

// Taäp tin String3.cpp #include "String3.h" void CString3::operator = ( char* s ) { delete info; info = new char[ strlen( s ) + 1 ]; strcpy( info, s ); }

CString3* CString3::operator + ( char* s ) { char* ketqua; ketqua = new char[ strlen(info) + strlen( s ) + 1 ]; sprintf( ketqua, "%s%s", info, s ); CString3* kq = new CString3( ketqua ); delete ketqua;

return kq; }

// Chöông trình Main3.cpp söû duïng lôùp CString3 khai baùo ôû treân. #include "String3.h" void main( void ) { CString3 s1( "Chao Cac " ); CString3 s2( "Ban" ); CString3 *s = (s1 + s2); printf( "Cong hai chuoi la: %s", *s ); delete s; // Keát quaû nhaän ñöôïc: Cong hai chuoi la: Chao Cac Ban }

A.9. CON TROÛ this:

Phuï luïc A: Moät soá vaán ñeà laäp trình höôùng ñoái töôïng 243

this laø con troû duøng tham chieáu ñeán baûn thaân ñoái töôïng trong noäi dung caøi ñaët cuûa noù. Haønh vi toaùn töû = cuûa lôùp CString3 coù theå vieát nhö sau:

void CString3::operator = ( char* s ) { delete this->info; this->info = new char[ strlen( s ) + 1 ]; strcpy( this->info, s ); }

A.10 HAØNH VI virtual: Haønh vi virtual ñöôïc caøi ñaët trong lôùp cô sôû nhaèm muïc ñích trieån khai

nhieàu caùch theå hieän khaùc nhau cuûa haønh vi naøy treân caùc lôùp keá thöøa. Trong ví duï sau, lôùp A ñöôïc caøi ñaët vôùi haønh vi khung Action. Trong caùc

lôùp B vaø C keá thöøa töø A, haønh vi naøy ñöôïc theå hieän khaùc nhau nhö sau: - Lôùp B : Baät tieáng beep cuûa PC speaker. - Lôùp C : Baät hoaëc taét kyù töï x.

class A { public: void Action( void ) { } // Haønh vi khung cô sôû }

class B : public A { public: void Action( void ) { // Caùch theå hieän Action cuûa lôùp B putch( 7 ); } }

class C : public A { public: void Action( void ) { // Caùch theå hieän Action cuûa lôùp C ; baät, taét chöõ x static char ch = ‘x’; putch(x); ch = ( ch == ‘x’ )? ‘ ‘ : ‘x’ ; } }

void main ( void ) {

Page 133: Mfc Tieng Viet

244 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - [email protected]

A* a[5]; // 5 phaàn töû kieåu lôùp A for ( int i = 0; i<5; i++ ) { if ( i % 2 ) a[ i ] = new B(); // Khôûi taïo ngaãu nhieân theo kieåu lôùp B else a[ i ] = new C(); // hoaëc lôùp C } while ( !kbhit() ) { for ( i = 0; i < 5 ; i++ ) a[ i ]->Action( ); // Haønh ñoäng theo caùch cuûa lôùp B hoaëc C delay( 100 ); // Taïm döøng } for ( i = 0; i < 5 ; i++ ) delete a[ i ]; }

A.11 THUOÄC TÍNH VAØ HAØNH VI TÓNH: Thuoäc tính vaø haønh vi tónh laø nhöõng thuoäc tính vaø haønh vi coù theå khai thaùc

ñöôïc maø khoâng caàn söû duïng ñoái töôïng cuï theå cuûa lôùp. Trong phaàn khai baùo cuûa lôùp:

static Kieåuthuoäctính Thuoäctính; static Kieåutraûveà Haønhvi ( [ Danh_saùch_tham_soá ] );

Trong phaàn caøi ñaët cuûa lôùp:

Kieåuthuoäctính Teânlôùpsôûhöõu::Thuoäctính = Giaù_trò_khôûi_ñaàu; Kieåutraûveà Teânlôùpsôûhöõu::Haønhvi ( [ Danh_saùch_tham_soá ] ) { … // Noäi dung caøi ñaët cuûa haønh vi }

Löu yù: Haønh vi static chæ ñöôïc pheùp söû duïng caùc thuoäc tính static vaø haønh vi static cuûa lôùp.

Trong ví duï sau, ta caøi ñaët lôùp Duongtron vôùi thuoäc tính baùn kính, thuoäc tính pi, vaø haønh vi Chuvi coù hai theå hieän nhö sau:

- Chuvi( float R ) : Traû veà chu vi cuûa moät ñöôøng troøn coù baùn kính R. - Chuvi( void ) : Traû veà chu vi cuûa ñöôøng troøn quaûn lyù bôûi ñoái töôïng. Coù theå söû duïng haønh vi Chuvi(R) maø khoâng duøng ñoái töôïng thuoäc lôùp. Lôùp Duongtron ñöôïc khai baùo nhö sau:

Phuï luïc A: Moät soá vaán ñeà laäp trình höôùng ñoái töôïng 245

class Duongtron { protected: float R; static float pi; public: Duongtron( float bankinh ) { R = bankinh; }

float Chuvi( void ) { return R * R * pi; }

static float Chuvi( float bankinh ) { return R * R * pi; } }; float Duongtron::pi =3.14159;

// Chöông trình minh hoïa söû duïng lôùp Duongtron

void main( void ) { // Duøng haønh vi tónh Chuvi( . ) cuûa Duongtron ñeå tính chu vi // cuûa moät ñöôøng troøn baát kyø printf( “Chu vi duong tron ban kinh R = 10 la : %0.2f” , Duongtron::Chuvi( 10 ) );

// Duøng haønh vi Chuvi() ñeå tính chu vi cuûa ñoái töôïng Duongtron Duongtron a( 20 ); printf( “Chu vi duong tron ban kinh R = 20 la : %0.2f”, a.Chuvi() ); }

Neáu thuoäc tính pi cuûa Duongtron khoâng phaûi laø thuoäc tính static thì haønh vi Chuvi( float Bankinh ) cuûa Duongtron seõ khoâng hôïp leä vì haønh vi naøy ñaõ söû duïng moät thuoäc tính khoâng phaûi static.