LEÂ NGOÏC THAÏNH
          lntmail@yahoo.com




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




      NHAØ XUAÁT BAÛN THOÁNG KEÂ
MUÏC LUÏC                                     3.4.2 Lôùp Cpen                                                         31
                                                                            3.4.3 Lôùp CBrush                                                       31
CHÖÔNG 1 : MOÄT SOÁ KHAÙI NIEÄM LAÄP TRÌNH                      Trang       3.4.4 Lôùp CFont                                                        32
                  TRONG MOÂI TRÖÔØNG WINDOWS                    1           3.4.5 Lôùp CBitmap                                                      32
1.1 Chöông trình ( Program )                                    1           3.4.6 Lôùp CPalette                                                     33
1.2 ÖÙng duïng ( Application )                                  1           3.4.7 Lôùp CRgn                                                         34
1.3 Tieán trình ( Process )                                     1       3.5 Lôùp CDC                                                                35
1.4 Tieåu trình (Thread )                                       1       3.6 Lôùp CImageList                                                         38
1.5 Thoâng ñieäp ( Message )                                    2
    1.5.1 Nguoàn goác cuûa message                              2       CHÖÔNG 4 : CÖÛA SOÅ GIAO DIEÄN LÔÙP VAØ LÔÙP CWnd                           40
    1.5.2 Caùc loaïi message                                    2       4.1 Cöûa soå giao dieän                                                     40
    1.5.3 Soá hieäu message (Message Indentifier – MessageID)   3       4.2 Lôùp CWnd                                                               40
    1.5.4 Ñaëc taû message                                      3       4.3 Söû duïng ñoái töôïng CWnd                                              49
1.6 Cöûa soå giao dieän (window) cuûa öùng duïng                3           4.3.1 Söû duïng CWnd laøm giao dieän chính cuûa öùng duïng              49
1.7 Message queue                                               5           4.3.2 ÖÙng duïng chæ chaïy moät baûn (instance) taïi moãi thôøi ñieåm   50
1.8 Kieán truùc xöû lyù cuûa öùng duïng trong Windows           7
1.9 Resource cuûa öùng duïng                                    8       CHÖÔNG 5 : XÖÛ LYÙ MESSAGES                                                 51
                                                                        5.1 Lôùp xöû lyù message CCmdTarget:                                        51
CHÖÔNG 2 : THÖ VIEÄN MFC CUÛA MICROSOFT                                 5.2 Khai baùo muïc xöû lyù message trong MessageMap                         52
                 & ÖÙNG DUÏNG CÔ BAÛN TRONG WINDOWS             10      5.3 Caùc lôùp keá thöøa CCmdTarget                                          55
2.1 Thö vieän MFC (Microsoft Foundation Class)                  10      5.4 MessageMap cuûa lôùp keá thöøa CWnd trong öùng duïng                    55
2.2 Tieáp an MFC                                                10          5.4.1 Cöûa soå cuûa öùng duïng coù chöùc naêng hoaït ñoäng              55
2.3 Taïo öùng duïng windows vôùi MFC nhö theá naøo ?            10          5.4.2 WM_PAINT vaø haønh vi OnPaint cuûa CWnd                           58
2.4 Lôùp quaûn lyù tieåu trình CwinThread                       11
2.5 Lôùp quaûn lyù tieåu trình giao dieän chính CwinApp         12      CHÖÔNG 6 : ÖÙNG DUÏNG COÂNG CUÏ GDI                                         60
2.6 Thöïc hieän öùng duïng ñôn giaûn                            14      6.1 DC vaø BITMAP                                                           60
2.7 Thöïc hieän öùng duïng giao taùc ñôn giaûn                  20      6.2 ÖÙng duïng vôùi cöûa soå chính hieån thò aûnh                           60
2.8 Taïo môùi Icon Resource cho öùng duïng                      25      6.3 Sao cheùp aûnh töøø DC ñeán DC, phoùng to & thu nhoû aûnh               63
2.9 Löu tröõ chöông trình nguoàn                                27      6.4 DC trong boä nhôù ( DC aûo) – vuøng veõ ñeäm lyù töôûng                 64
2.10 Lôùp Cstring cuûa MFC                                      27      6.5 AÛnh chuyeån ñoäng trong vuøng client                                   65
                                                                        6.6 CImageList – coâng cuï quaûn lyù boä aûnh cuøng côõ                     66
CHÖÔNG 3 : CAÙC LÔÙP GIAO DIEÄN ÑOÀ HOÏA CUÛA MFC               29      6.7 CRgn – Cöûa soå coù hình daïng tuøy yù                                  67
3.1 Caùc coâng cuï giao dieän ñoà hoïa                          29
3.2 Device Context                                              29      CHÖÔNG 7 : MENU – PHÍM TAÉT                                                 69
3.3 Toïa ñoä treân giao dieän ñoà hoïa                          29      7.1 Ñònh nghóa                                                              69
3.4 Caùc lôùp MFC hoã trôï GDI                                  30      7.2 Menu resoure                                                            69
    3.4.1 Caùc lôùp ñoái töôïng ñieåm, hình chöõ nhaät          30
7.3   Söû duïng menu resource                                          71         10.3.1 Thieát keá ToolBar resource                               120
7.4   Muïc xöû lyù command message töø muïc choïn cuûa menu            72         10.3.2 Duøng toolbar resource cho CToolBar cuûa FrameWnd         121
7.5   Phím taét (hot key ) cho muïc choïn treân menu                   73    10.4 Lôùp CFrameWnd                                                   121
7.6   Lôùp quaûn lyù menu – CMenu                                      75    10.5 Söû duïng frame window laøm giao dieän chính                     123
7.7   Xöû lyù ñieàu khieån muïc choïn cuûa menu                        77         10.5.1 Thöïc hieän öùng duïng vôùi giao dieän frame window       123
                                                                                  10.5.2 String Table vaø CFrameWnd                                124
CHÖÔNG 8 : CAÙC LÔÙP ÑOÁI TÖÔÏNG NHAÄP LIEÄU                                      10.5.3 Duøng MFC wizard taïo öùng duïng giao dieän framewindow   130
               ( WINDOWS CONTROLS )                                    78
8.1 CStatic                                                            78    CHÖÔNG 11 : CAÙC KIEÁN TRUÙC DOCUMENT – VIEW                          134
8.2 CEdit                                                              80    11.1  CDocument                                                       134
8.3 CButton                                                            84    11.2  CView                                                           135
8.4 ClistBox                                                           85    11.3  CFrameWnd                                                       136
8.5 CComboBox                                                          88    11.4  CDoctemplate                                                    136
8.6 CSpinButtonCtrl                                                    91    11.5  Hoã trôï töø phía ñoái töôïng quaûn lyù öùng duïng              137
8.7 CProgressCtrl                                                      93    11.6  Trình töï taïo laäp caùc ñoái töôïng tham gia boä DVF           138
8.8 CscrollBar                                                         94    11.7  Text Document Appication                                        139
8.9 CSliderBar                                                         96    11.8  Rich Text Format (rtf) Document Appication                      143
                                                                             11.9  HTML Document View Appication                                   146
CHÖÔNG 9 : HOÄP HOÄI THOAÏI                                            97    11.10 Moät soá lôùp view ñaëc bieät                                   149
9.1 Hoäp hoäi thoaïi (Dialog)                                          97          11.10.1 CListView                                               149
9.2 Lôùp CDialog                                                       97          11.10.2 CTreeView                                               150
9.3 Taïo vaø söû duïng dialog trong chöông trình                       99          11.10.3 CSplitterWnd                                            152
    9.3.1 Taïo dialog resource                                         99          11.10.4 Söû duïng splitterwnd trong frame window                154
    9.3.2 Khai baùo lôùp keá thöøa CDialog söû duïng dialog resource   103         11.10.5 Caùc ví duï thöïc haønh                                 155
    9.3.3 Söû duïng dialog trong chöông trình                          104
9.4 Lieân keát giöõa dialog vaø caùc thaønh phaàn khaùc                104   CHÖÔNG 12 : MOÄT SOÁ VAÁN ÑEÀ TRONG WINDOWS                           158
9.5 Söû duïng dialog laøm giao dieän chính cuûa öùng duïng             106   12.1 Taäp tin INI                                                     158
    9.5.1 Thöïc hieän öùng duïng vôùi giao dieän chính laø dialog      106   12.2 System Registry                                                  160
    9.5.2 Duøng MFC wizard taïo öùng duïng vôùi giao dieän dialog      107   12.3 Vuøng Status Area treân Taskbar                                  162
9.6 Khai baùo bieán cho control treân dialog                           109   12.4 ÖÙng duïng ScreenSaver                                           167
9.7 Khai thaùc caùc tieän ích hoã trôï                                 112        12.4.1 Ñaëc ñieåm                                                168
                                                                                  12.4.2 Tham soá doøng leänh                                      168
CHÖÔNG 10 : KHUNG CÖÛA SOÅ GIAO DIEÄN CHÍNH                            117        12.4.3 Ñaëc ñieåm giao taùc vôùi ngöôøi duøng                    170
10.1 Khung cöûa soå giao dieän (Frame Window)                          117        12.4.4 Thöïc hieän öùng duïng ScreenSaver ñôn giaûn              171
10.2 Thanh traïng thaùi (statusbar) & lôùp CStatusbar                  117   12.5 ÖÙng duïng söû duïng nhieàu tieåu trình                          175
10.3 Thanh coâng cuï (toolbar) & lôùp CToolBar                         119        12.5.1 Tieåu trình xöû lyù noäi                                  175
12.5.2 Tieåu trình giao dieän                                  177        13.7.2 Thieát keá öùng duïng nhaän mail               220
       12.5.3 Caùc haøm hoã trôï                                      179   13.8 TCP vôùi HTTP vaø FTP                                 223
12.6   Laäp trình Multimedia vôùi MCI                                 179        13.8.1 Lôùp CInternetSession                          223
12.7   AÁn ñònh moät soá tính naêng cuûa Windows                      181        13.8.2 Lôùp CInternetFile                             224
12.8   Baãy (hook) message (Windows Hook)                             182        13.8.3 Lôùp CFtpConnection                            225
       12.8.1 Caùc kieåu hook (Hook Type)                             183        13.8.4 Lôùp CFtpFindFile                              227
       12.8.2 Danh saùch hook (Hook Chain)                            183        13.8.5 Lôùp CHttpConnection                           228
       12.8.3 Thuû tuïc hook (Hook Procedure)                         183        13.8.6 Lôùp CHttpFile                                 229
       12.8.4 Caùc dòch vuï lieân quan hook                           184        13.8.7 Thöïc hieän öùng duïng FTP client ñôn giaûn    231
       12.8.5 ÖÙng duïng hook messages cuûa keyboard                  185        13.8.8 Thöïc hieän öùng duïng HTTP client ñôn giaûn   232
12.9   Caøi ñaët cheá ñoä thöïc hieän öùng duïng töï ñoäng            186
                                                                            Phuï luïc A:       MOÄT SOÁ VAÁN ÑEÀ
CHÖÔNG 13 : MFC VÔÙI INTERNET                                         187                      LAÄP TRÌNH HÖÔÙNG ÑOÁI TÖÔÏNG           234
13.1 Giao thöùc truyeàn thoâng TCP/IP                                 187   A.1    Laäp trình höôùng ñoái töôïng (OOP)                 234
     13.1.1 Giôùi thieäu                                              187   A.2    Caùc khaùi nieäm                                    234
     13.1.2 Kieán truùc cuûa giao thöùc TCP/IP treân moâ hình DARPA   187          A.2.1 Lôùp (Class)                                  234
     13.1.3 Ñòa chæ IP                                                189          A.2.2 Ñoái töôïng (Object)                          234
     13.1.4 Subnet                                                    190          A.2.3 Thuoäc tính (Attribute)                       234
     13.1.5 Subnet Mask                                               191          A.2.4 Haønh vi (Method)                             235
     13.1.6 Host domain name                                          192          A.2.5 Chöông trình (Program)                        235
     13.1.7 IP Routing                                                194   A.3    Ñaëc ñieåm laäp trình höôùng ñoái töôïng            235
13.2 Laäp trình TCP/IP vôùi Winsock                                   197   A.4    Phaân loaïi thuoäc tính vaø haønh vi                236
     13.2.1 Port                                                      197   A.5    Caùc haønh vi ñaëc bieät                            236
     13.2.2 Socket                                                    198   A.6    Khai baùo lôùp, ñoái töôïng trong C++               236
     13.2.3 Moät soá caáu truùc döõ lieäu cuûa Winsock API            198          A.6.1 Khai baùo lôùp                                236
     13.2.4 Moät soá dòch vuï cuûa Winsock API                        199          A.6.2 Khai baùo ñoái töôïng                         238
13.3 MFC vôùi laäp trình Winsock                                      200          A.6.3 Söû duïng ñoái töôïng trong chöông trình      238
     13.3.1 Khôûi ñoäng Winsock                                       200   A.7    Keá thöøa trong C++                                 239
     13.3.2 Lôùp CAsyncSocket                                         200          A.7.1 Keá thöøa haønh vi taïo laäp                  239
13.4 Laäp trình Winsock cho giao thöùc UDP                            204          A.7.2 Keá thöøa haønh vi huûy boû                   240
13.5 Laäp trình Winsock cho giao thöùc TCP                            207          A.7.3 Thöïc hieän haønh vi lôùp cô sôû              240
13.6 TCP vôùi SMTP (Simple Mail Transfer Protocol)                    215   A.8    Khai baùo haønh vi toaùn töû soá hoïc               241
      13.6.1 Qui öôùc giöõa öùng duïng göûi mail vaø nhaän mail       215   A.9    Con troû this                                       243
     13.6.2 Thieát keá öùng duïng göûi mail                           217   A.10   Haønh vi virtual                                    243
13.7 TCP vôùi Pop3 (Post Office Protocol – Version 3)                 219   A.11   Thuoäc tính vaø haønh vi tónh                       244
      13.7.1 Qui öôùc giöõa öùng duïng mail client vaø mail server    219
LÔØI MÔÛ ÑAÀU                                                                      TAØI LIEÄU THAM KHAÛO
                                                                                             [1] Richard Simon, Windows 95 - Win32 Programming API-BIBLE,
Ngoân ngöõ laäp trình C++ ñöôïc bieát ñeán nhö laø moät trong nhöõng ngoân ngöõ                  Waite Group Press 1996.
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           [2] Jeff Prosise, Programming Windows 95 with MFC, Microsoft Press.
ôû 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        [3] M. Tracy, Professional Visual C++ ISAPI Programming, Wrox Press.
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   [4] Dr. GUI, Microsoft Developer Network - MSDN,
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ôû       Microsoft Corporation Software.
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         [5] Dino Esposito,Visual C++ Windows Shell Programming, Wrox Press.
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            PHAÀN MEÀM CAÀN CAØI ÑAËT:
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         - Microsoft Visual C++ 6.0 hoaëc Microsoft Visual C++ .NET.
höôùng söû duïng heä ñieàu haønh Microsoft Windows nhö hieän nay, chuùng ta                   - MSDN ( Microsoft Developer Network ), baûn thaùng 10/2003.
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           MAÕ NGUOÀN:
vaø khai thaùc noù sao cho öùng duïng hoaït ñoäng hieäu quaû nhaát.                           Source Code cuûa caùc ví duï minh hoïa trong cuoán saùch naøy vaø cuûa moät soá
Microsoft Visual C++, saûn phaåm cuûa Microsoft, vôùi khaû naêng bieân dòch öu                chöông trình troø chôi maø chuùng toâi mong muoán chia xeû cuøng baïn ñoïc
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 löu trong ñóa meàm ñính keøm, vaø coù theå download töø ñòa chæ:
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                  http://thanh.andisw.com/?id=16&id2=85
Windows haàu phuïc vuï cho öùng duïng cuûa mình.
                                                                                             WEB SITE:
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           Source Code ñaëc saéc cuûa nhieàu taùc giaû treân theá giôùi coù theå download:
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             - http://msdn.microsoft.com
höôùng ñoái töôïng vôùi C++, nhaèm khai thaùc hieäu quaû thö vieän MFC vaø töøng              - http://www.codeguru.com
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         - http://www.codeproject.com
xeáp theo caùc caáp ñoä tieán trieån phuø hôïp.                                               - http://www.softechsoftware.it
                                                                                              - http://www.flipcode.com
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           - http://nps.vnet.ee
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           LIEÂN HEÄ:
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         - Taùc giaû:             Leâ Ngoïc Thaïnh
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              - Cô quan:               Khoa Tin Hoïc Quaûn Lyù, Tröôøng ÑHKT TP.HCM
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                                     Ñòa chæ: 279 Nguyeãn Tri Phöông Q10, TP.HCM.
söûa cuoán saùch kòp thôøi.                                                                   - Ñòa chæ e-mail:        lntmail@yahoo.com
                                    Thaønh phoá Hoà Chí Minh, ngaøy 19.11.2002                                         emp@ueh.edu.vn
                                                        Taùc giaû
CHƯƠNG 1:                                                                          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ọ.
                            Một số khái niệm Lập trình                             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.
                            Trong môi trường Windows                               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.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       1.5 THÔNG ÐIỆP (MESSAGE):
máy, được bố trí theo một trình tự logic nhằm phối hợp thực hiện một              Thông điệp (message) là giá trị phản ánh một nội dung giao tiếp hay
công việc xác định. Các chỉ thị được thể hiện dưới dạng mã nguồn               yêu cầu xử lý giữa hệ thống (windows) và ứng dụng, giữa các ứng dụng
(source code) hay mã máy (machine code). Chương trình mã máy có thể            với nhau hoặc giữa các thành phần trong cùng một ứng dụng.
thực hiện được trên máy có bộ lệnh tương thích, với chương trình mã            1.5.1 Nguồn gốc message:
nguồn thì phải sử dụng một ứng dụng chuyên dụng để chuyển sang mã                 Cả windows và ứng dụng đều có thể phát sinh message.
máy trước khi thực hiện.                                                            Windows phát sinh message khi cần thông tin cho ứng dụng các
   Việc chuyển các chỉ thị dạng mã nguồn sang chỉ thị mã máy để thực                hoạt động nhập-xuất (hoạt động gõ phím, di chuyển hay click chuột,
hiện được tiến hành bằng một trong hai cơ chế sau:                                  . của người dùng), các thay đổi của hệ thống (font chữ, chế độ phân
   Thông dịch: Mỗi chỉ thị mã nguồn được chuyển sang chỉ thị mã máy                 giải màn hình, màu sắc,...) hoặc những biến đổi khác liên quan đến
   tương ứng và được thực hiện ngay, sau đó tiếp tục với chỉ thị kế tiếp.           ứng dụng.
   Biên dịch: Tất cả các chỉ thị mã nguồn được chuyển sang các chỉ thị              Ứng dụng phát sinh message khi xử lý điều khiển các thành phần
   mã máy tướng ứng. Tập hợp các chỉ thị mã máy này gọi là chương                   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
   trình mã máy. Chương trình mã máy được lưu lại trong tập tin chương              dùng, hoặc khi ứng dụng thực hiện giao tiếp với windows hay với các
   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.             ứng dụng khác đang thực hiện trong cùng hệ thống.
1.2 ỨNG DỤNG (APPLICATION):                                                    1.5.2 Các loại message:
   Khi một chương trình được cài đặt trên máy tính để sử dụng, ta gọi đó            Message được định nghĩa bởi hệ thống: Là các message do hệ điều
là ứng dụng, ví dụ như ứng dụng NotePad, ứng dụng Microsoft Word,....               hành windows tạo ra nhằm phục vụ hoạt động điều khiển toàn bộ hệ
   Trong môi trường windows, mỗi ứng dụng có thể được thi hành nhiều                thống, xử lý thông tin vào-ra hoặc các thông tin khác cho ứng dụng.
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                   Khi có nhu cầu, ứng dụng có thể sử dụng những message này để
dụng gọi là thể hiện (instance) của ứng dụng đó.                                    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
1.3 TIẾN TRÌNH (PROCESS):                                                           viết ứng dụng định nghĩa nhằm tạo kênh liên lạc đặc thù giữa các
   Tiến trình là khái niệm chỉ một instance đang hoạt động của ứng                  thành phần trong ứng dụng, giữa ứng dụng với windows hoặc với
dụng. Khi ta double-click trên biểu tượng NotePad để chạy ứng dụng                  các ứng dụng khác đang thực hiện trong cùng hệ thố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:

Moät soá khaùi nieäm laäp trình trong moâi tröôøng Windows                1    2    Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
1.5.3 Số hiệu message (Message Indentifier - MessageID):                                  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
   Có rất nhiều message khác nhau được sử dụng trong môi trường                           người dùng.
windows. Ứng với mỗi message xác định, windows sử dụng một giá trị                         Dạng thông thường của một cửa sổ giao diện trong windows:
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 {                                                                   System Menu Box: Chứa biểu tượng của ứng dụng, là nút mở hộp
       HWND         hwnd;                 // Giá trị có kích thước 4 bytes (long)             menu hệ thống với các mục di chuyển, thay đổi kích thước hoặc đóng
       UINT         message;              // Số hiệu của message                              cửa sổ.
       WPARAM wParam;                     // Giá trị không âm có kích thước 2 bytes           Caption bar: Thanh tiêu đề của ứng dụng.
       LPARAM lParam;                     // Giá trị không âm có kích thước 4 bytes           Menu bar: Hệ thống menu với các mục lựa chọn xử lý.
       DWORD time;                        // Thời điểm sinh ra messsge                        Minimize / Maximize Box : Nút điều khiển thu nhỏ / phóng to cửa sổ.
       POINT        pt;                   // Tọa độ cursor khi message được gửi.              Restore Box : Nút khôi phục kích thước trước đó của cửa số.
    } MSG;                                                                                    Border: Ðường viền bao quanh cửa sổ.
   Trường hwnd (window handle) của cấu trúc chứa thẻ (handle) quản lý                         Client area: Vùng làm việc của cửa sổ, dùng để hiển thị thông tin.
cửa sổ giao diện liên quan đến message. wParam và lParam là hai tham                          Scroll bar: Thanh cuộn nội dung vùng làm việc của cửa sổ.
số gửi kèm theo message làm nhiệm vụ chứa thông tin bổ sung. Hai                              Window Procedure: Ngoài giao diện đồ họa, cửa sổ của windows có
tham số này được dùng khi message có nhiều ý nghĩa thực tế khác nhau.                         khả năng tiếp nhận và xử lý message. Khả năng này được thực hiện
   Windows sử dụng giá trị có kích thước 4 bytes để quản lý các đối                           thông qua hàm xử lý message mà ta đã gắn cho cửa sổ. Hàm xử lý
tượng của nó. Giá trị này gọi là thẻ quản lý đối tượng (object handle).                       này có khai báo như sau:
Ứng với mỗi loại đối tượng cụ thể, windows sử dụng một kiểu handle                            LRESULT CALLBACK WindowProc (
riêng. HWND là kiểu handle dùng quản lý đối tượng cửa sổ giao diện                                HWND hwnd,              // Tham số chứa Handle của cửa sổ liên
trong windows.                                                                                quan
                                                                                                  UINT uMsg,              // Tham số chứa số hiệu message
1.6 CỬA SỔ GIAO DIỆN (WINDOW) CỦA ỨNG DỤNG:                                                       WPARAM wParam,          // Tham số bổ sung thứ nhất kiểu WORD
   Cửa sổ giao diện là thành phần quan trọng trong việc tạo ra môi                                LPARAM lParam           // Tham số bổ sung thứ hai kiểu LONG
trường giao diện đồ họa của các ứng dụng trong windows. Cùng với sự                           ) ; Hàm trả về một giá trị có kích thước là 32 bits.
phát triển của hệ điều hành windows, hình ảnh cửa sổ giao diện cũng                           Khi một yêu cầu xử lý được chuyển đến cửa sổ dưới dạng message,
thay đổi theo với chiều hướng sinh động hơn về hình thức và phong phú                         hàm WindowProc gắn với cửa sổ sẽ căn cứ trên số hiệu message
hơn về chức năng. Ðiều đó không chỉ góp phần tăng tính thẩm mỹ mà                             (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
Moät soá khaùi nieäm laäp trình trong moâi tröôøng Windows                            3   4    Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
khả năng xử lý của cửa sổ) hàm phải chuyển message cho windows              con trỏ tham số plMSG. Khi đã lấy được một message, hàm kết thúc
    xử lý thông qua lời gọi hàm xử lý message mặc nhiên của windows.            và trả về một giá trị nguyên. Nếu message nhận được là message kết
    Hàm xử lý này có tên gọi là DefWindowProc với khai báo như sau:             thúc ứng dụng (số hiệu WM_QUIT) thì hàm trả về giá trị 0. Ngược lại,
    LRESULT DefWindowProc( // Default Window Procedure                          hàm trả về giá trị khác 0.
       HWND       hWnd,         // Với các tham số có ý nghĩa như trên          Kiểm tra và lấy một message trong message queue của ứng dụng:
       UINT       Msg,                                                          BOOL PeekMessage(
       WPARAM wParam,                                                              LPMSG lpMsg;               // . Như GetMessage
       LPARAM lParam                                                               HWND hWnd;
    );                                                                             UINT     wMsgFilterMin;
    Khi đó, kết quả trả về của DefWindowProc được dùng làm kết quả                 UINT     wMsgFilterMax;
    của hàm WindowProc. Qui tắc nói trên cần phải được đảm bảo, nếu                UINT     wRemoveMsg; // Có thực hiện xóa message không ?
    không, ứng dụng có thể làm rối loạn hoạt động của hệ điều hành                                            // PM_NOREMOVE: không xóa
    windows.                                                                    );
                                                                                Hàm trả về giá trị 0 nếu message queue rỗng. Ngược lại, hàm trả về
1.7 MESSAGE QUEUE:                                                              một giá trị khác không và thông tin về message được điền vào biến
   Message queue là danh sách thứ tự các message do windows tạo ra              kiểu MSG được chỉ bởi tham số kiểu con trỏ lpMSG.
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        Diễn dịch message của bàn phím sang mã phím ASCII:
trước). Có hai loại message queue trong windows:                                BOOL TranslateMessage(
   Message queue của hệ thống (system queue): Ðược windows dùng                    CONST MSG *lpMsg;          // con trỏ đến biến chứa message
   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           Tham số lpMsg là con trỏ chỉ đến biến kiểu MSG chứa nội dung đặc
   dùng.                                                                        tả message được lấy từ message queue và cần diễn dịch.
   Message queue của ứng dụng (application queue): Ðược windows tạo             Hàm trả về giá trị khác 0 nếu message nhận được tương ứng với một
   ra và cấp cho các thể hiện của ứng dụng. Windows tự động điều phối           thao tác trên bàn phím (nhấn phím: WM_KEYDOWN,
   các message từ system queue sang application queue một cách phù              WM_SYSKEYDOWN;              thôi  nhấn      phím:      WM_KEYUP,
   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           WM_SYSKEYUP) hoặc một message có ý nghĩa tương đương mà
   xử lý của người dùng thông qua hệ thống. Cơ chế này ngăn các ứng             việc diễn dịch sang mã phím ASCII là thành công. Khi đó hàm tự động
   dụng trong windows quyền truy cập trực tiếp các thiết bị phần cứng           tạo message WM_CHAR cho phím diễn dịch được. Trong các trường
   của máy tính.                                                                hợp khác, hàm trả về giá trị 0.
   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
Moät soá khaùi nieäm laäp trình trong moâi tröôøng Windows             5    6    Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
Ðiều phối message đến cửa sổ giao diện chính:                              Kiến trúc xử lý chung của ứng dụng trong môi trường windows
    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:                            1.9 RESOURCE CỦA ỨNG DỤNG:
   Khi ứng dụng được thực hiện, windows tạo thêm một tiến trình cho thể       Ðối với một chương trình trong windows, ngoài phần mã lệnh của các
hiện mới của ứng dụng, đồng thời xây dựng một message queue dùng           hàm xử lý, resource là một thành phần không kém phần quan trọng chứa
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ó     các nội dung hỗ trợ cho việc trang trí hoặc phục vụ cho một mục đích đặc
nhiệm vụ thực hiện MessageLoop trên message queue dành cho ứng             biệt của ứng dụng. Các nội dung phổ biến trong resource như sau:
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).        Cursor: Ảnh nhỏ đặc tả vị trí làm việc của thiết bị liên quan như
   Các cách xử lý của tiểu trình chính khi nắm quyền điều khiển ứng           mouse, pen, trackball. Khi người dùng tác động lên những thiết bị này
dụng:                                                                         thì windows sử dụng cursor để phản ánh hiện tượng đó.
   Không thực hiện xử lý nào cả: Ứng dụng kết thúc.                           Bitmap: Tập ảnh điểm (pixels) của một ảnh. Các ảnh điểm này bố trí
   Thực hiện MessageLoop nhưng không tạo cửa sổ giao diện chính:              theo các dòng và phối hợp làm nên hình ảnh của đối tượng.
   Ứng dụng chờ nhận message nhưng người dùng không giao tác được.            Dialog: Thông tin mô tả khung giao diện với các đối tượng nhập liệu
   Khởi tạo một cửa sổ với hàm xử lý message WindowProc và chọn cửa           bên trong, là cơ sở để tạo ra các hộp hội thoại trong ứng dụng.
   sổ này làm cửa sổ giao diện chính: Hàm WindowProc của cửa sổ sẽ            Icon : Ảnh nhỏ được dùng để đặc tả chức năng của một đối tượng,
   tiếp nhận và xử lý message được điều phối từ MessageLoop của tiểu          ứng dụng hay một nội dung dữ liệu.
   trình chính. Người dùng có thể giao tác và kết thúc ứng dụng được.         HTML (Hypertext Markup Language): Ngôn ngữ dùng tạo ra những tài
   Như mục thứ ba, đồng thời tạo ra các tiểu trình phục vụ: Ứng dụng có       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
   khả năng tiếp nhận và thực hiện đồng thời nhiều yêu cầu xử lý.             duyệt tương ứng có thể thể hiện một cách xúc tích.

Moät soá khaùi nieäm laäp trình trong moâi tröôøng Windows             7   8    Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
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.




Moät soá khaùi nieäm laäp trình trong moâi tröôøng Windows             9
CHƯƠNG 2:
                                                                                                     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
                      Thư viện MFC của microsoft                                                     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
                   & ứng dụng cơ bản trong windows                                                   đượ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
2.1 THƯ VIỆN MFC (MICROSOFT FOUNDATION CLASS):                                                       thông qua các thuộc tính và hành vi của nó.
   Thư viện MFC của Microsoft bao gồm các lớp cơ bản, cài đặt bằng                                         DWORD m_nThreadID : Thuộc tính lưu số hiệu của tiểu trình.
ngôn ngữ C++, hỗ trợ việc lập trình trong môi trường windows. Từ các lớp                                   CWnd* m_pMainWnd : Lưu con trỏ đối tượng cửa sổ giao diện
này, MFC xác lập nền tảng hình thành ứng dụng của windows, bao gồm                                         chính của tiểu trình. Khi cửa sổ giao diện chính chấm dứt hoạt
việc định nghĩa bộ khung ứng dụng, các công cụ chuẩn và phổ biến để                                        độ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
bổ sung vào bộ khung nói trên nhằm tạo ra ứng dụng hoàn chỉnh. Với                                         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
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                                      hơn.
phần cần thiết, điều chỉnh và phối hợp chúng hợp lý để có được ứng                                         CWinThread( ); Hành vi tạo lập (constructor) đối tượng tiểu trình.
dụng kết quả mong muốn.                                                                                    virtual BOOL InitInstance( ); Khởi tạo thông số cho đối tượng tiểu
   Lập trình windows với MFC và MicroSoft Visual C++ 6.0 (VC) đạt                                          trình và đảm nhận các xử lý bổ sung khác của ứng dụng. Ðối với
được hiệu quả cao bởi không chỉ khai thác được phiên bản mới nhất của                                      tiểu trình giao diện, hành vi này được dùng để khởi tạo đối tượng
MFC mà còn nhận được nhiều tiện nghi lập trình mà VC cung cấp. Ðây là                                      cửa sổ giao diện và gán địa chỉ của đối tượng cửa sổ cho
con đường ngắn và đơn giản, đặc biệt với người tự học, để viết ứng dụng                                    m_pMainWnd.
windows.                                                                                                   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
2.2 TIẾP CẬN MFC:                                                                                          trả các tài nguyên của hệ thống mà nó đã đăng ký sử dụng.
   MFC là thư viện khổng lồ với khoảng 200 lớp đối tượng mà việc hiểu                                      virtual int Run( ); Hành vi dành riêng cho tiểu trình giao diện, nó
rõ và vận dụng chúng trong một khoảng thời gian ngắn là không thể                                          thực hiện vòng lặp nhận message, chuyển message cho hành vi
đượ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ổ                                       PreTranslateMessage của lớp. Nếu hành vi này trả về giá trị 0 thì
biến nhất của thư viện để xây dựng ứng dụng thông thường. Khi đã có                                        message sẽ tiếp tục được chuyển đến các hàm diễn dịch phím
khả năng nhất định về sử dụng MFC thì với tài liệu MSDN, sẽ chẳng khó                                      TranslateMessage và hàm điều phối message DispatchMessage.
khăn gì trong việc mở rộng khai thác thư viện để ứng dụng trở nên mạnh                                     virtual BOOL PreTranslateMessage(MSG *pMsg); Hành vi cho
mẽ và tinh tế hơn.                                                                                         phép can thiệp trước trên các message nhận được từ message
   Trong những phần trình bày sau, chúng ta sẽ lần lượt tiếp nhận hệ                                       queue của ứng dụng. Thông qua đó, tiểu trình giao diện có thể thực
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à                                   hiện các tiền xử lý message đặc trưng nhằm đáp ứng yêu cầu đặt
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                                        ra cho ứng dụng.
đề.                                                                                                        Khi CWinThread được dùng để quản lý đối tượng tiểu trình chính thì
2.3 TẠO ỨNG DỤNG WINDOWS VỚI MFC NHƯ THẾ NÀO ?:                                                         hàm WinMain (cài sẵn bên trong lớp bởi thư viện MFC) tự động thực
   Theo mô hình kiến trúc ứng dụng windows ở mục (1.8), việc giải quyết                                 hiện các hành vi InitInstance(), Run() và ExitInstance() theo thứ 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.
10   Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Thö vieän MFC cuûa Microsoft & öùng duïng cô baûn trong windows           11
2.5 LỚP QUẢN LÝ TIỂU TRÌNH GIAO DIỆN CHÍNH CWinApp:                                                           MB_OK                                                       OK
    CWinApp, kế thừa từ CWinThread, là lớp đối tượng chuyên dùng quản                                         MB_OKCANCEL                                            OK - Cancel
lý tiểu trình giao diện chính của ứng dụng. Ứng dụng windows chỉ được                                         MB_YESNO                                                 Yes - No
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                                       MB_YESNOCANCEL                                      Yes - No - Cancel
kế thừa public từ CWinThread, CWinApp có các thuộc tính và hành vi bổ                                         MB_ABORTRETRYIGNORE                                Abort - Retry - Ignore
sung sau:                                                                                                     MB_RETRYCANCEL                                       Retry - Cancel
       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.                                            • Các thông số qui định biểu tượng dùng trong nút chọn:
       Tham số dòng lệnh là toàn bộ phần nội dung mà người dùng gõ                                                          Giá trị thông số                    Biểu tượng
       vào ngay sau chuỗi đường dẫn và tên chương trình ứng dụng khi                                         MB_ICONHAND, MB_ICONSTOP,
       họ thực hiện ứng dụng. Ðối với ứng dụng có nhiều chế độ hoạt                                          MB_ICONERROR
       động khác nhau thì việc sử dụng tham số dòng lệnh là một cơ chế                                       MB_ICONQUESTION
       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.                                                                            MB_ICONEXCLAMATION, MB_ICONWARNING
       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.                                                                   MB_ICONASTERISK, MB_ICONINFORMATION
       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                                        • Số hiệu các nút chọn được sử dụng trong hộp thông báo:
       dụng vào bộ nhớ (nếu cursor chưa được nạp). nID là số hiệu của                                            Số hiệu        Nút chọn        Số hiệu       Nút chọn
       cursor. Hàm trả về giá trị handle quản lý cursor. Giá trị này có kiểu                                 IDABORT              Abort     IDOK                 OK
       HCURSOR (handle of cursor) mà windows dùng để quản lý cursor.                                         IDCANCEL            Cancel     IDRETRY             Retry
       HICON LoadIcon ( int nID ); Nạp icon từ resource của ứng dụng                                         IDIGNORE            Ignore     IDYES                Yes
       vào bộ nhớ. nID là số hiệu của icon. Hàm trả về giá trị handle quản                                   IDNO                  No
       lý icon. Giá trị này có kiểu HICON (handle of icon).
                                                                                                           • Hành vi DoMessageBox chờ người sử dụng trả lời bằng cách
       Hành vi hiển thị hộp thông báo và chờ nhận ý kiến người dùng:
                                                                                                              chọn một nút chọn xác định trong hộp thông báo. Hành vi kết
       virtual int DoMessageBox (
                                                                                                              thúc với giá trị trả về là số hiệu của nút được chọn. Kế thừa hành
            LPCTSTR lpszPrompt, // Nội dung thông báo
                                                                                                              vi này để chặn và thực hiện xử lý đặc trưng (sử dụng dạng hộp
            UINT nType,               // Dạng hộp thông báo
                                                                                                              thông báo riêng) cho tất cả các lời gọi AfxMessageBox trong
            UINT hlpIndex = 0         // Số hiệu mục giúp đỡ (WinHelp)
                                                                                                              ứng dụng.
       );
       Hành vi này được kích hoạt với tham số tương ứng mỗi khi trong                                      • Hàm AfxMessageBox sử dụng DoMessageBox để hiển thị hộp
       chương trình sử dụng hàm AfxMessageBox để hiển thị hộp thông                                           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
       báo.                                                                                                   nó.
       int AfxMessageBox (                                                                              Ví dụ: AfxMessageBox( "Chao Ban", MB_ICONSTOP | MB_OK, 0 );
           LPCTSTR lpszPrompt, UINT nType, UINT hlpIndex = 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.
       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

12   Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Thö vieän MFC cuûa Microsoft & öùng duïng cô baûn trong windows                      13
2.6 THỰC HIỆN ỨNG DỤNG ÐƠN GIẢN:                                                                            VC hiển thị hộp hội thoại New Project Information để thông báo
   Trong phần này, chúng ta thực hiện ứng dụng với đối tượng thuộc lớp                                      các thông tin liên quan đến dự án vừa tạo. Chọn OK.
CWinApp quản lý tiểu trình chính. Ðặt tên cho dự án của ứng dụng là                                             Một dự án đã được tạo ra trên đĩa. Với thông tin nhập như trên,
VD0.                                                                                                            dự án mới tạo ra có tên là VD0, toàn bộ phần chương trình
   Các bước thực hiện dự án VD0 như sau:                                                                        nguồn của dự án được lưu trong thư mục VD0 thuộc thư mục
                                                                                                                C:VC6.
      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.                                              Tiếp tục thực hiện các bước sau để hoàn tất dự án theo yêu cầu.
      Thực hiện ứng dụng Microsoft Visual C++ 6.0 (VC).                                                    Ðăng ký sử dụng lớp CWinApp của thư viện MFC: Lớp CWinApp
      Chọn mục File / New từ hệ thống menu của VC.                                                         được khai báo trong afxwin.h của MFC. Bổ sung tập tin stdafx.h
      Trong hộp hội thoại New, chọn trang Projects :                                                       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:




      - 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.                                                               - C/C++ Header File       : Loại nội dung tập tin (.h).
      - An empty project     : Tạo dự án rỗng.                                                                  - Add To Project          : Bổ sung tập tin vào dự án VD0.
      - Finish               : Hoàn tất việc khởi tạo dự án.                                                    - 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:
14   Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Thö vieän MFC cuûa Microsoft & öùng duïng cô baûn trong windows         15
#if !defined( _DU_AN_0_ )                                                                             resource và đối tượng lập trình tương ứng của MFC trong dự án.
          #define _DU_AN_0_                                                                                     Thực hiện như sau:
                                                                                                                - Right-click trên mục tên resource (VD0 Resource):
          // _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 Properties:
      • Chọn mục File / New. Trong hộp hội thoại New, chọn trang
         Files.




                                                                                                                    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:
        - 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                               Chọn phiên bản biên dịch ( chẳng hạn Win32 Debug ). Chọn OK.
16   Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Thö vieän MFC cuûa Microsoft & öùng duïng cô baûn trong windows        17
Ấn định biên dịch với thư viện MFC: Chọn mục Project / Setting.




                                                                                                              - C++ Source File : Loại nội dung tập tin (.cpp).
                                                                                                              - Add To Project : Bổ sung tập tin vào dự án.
      Trong hộp hội thoại Project Settings,
                                                                                                              - File Name          : Tên tập tin (MAIN). Sau đó chọn OK.
      - Setting For: : Chọn phiên bản ấn định (ví dụ: Win32 Debug ),
                                                                                                           • Trong màn hình soạn thảo của main.cpp, nhập nội dung tập tin:
      - General         : Các ấn định chung cho dự án.
         Microsoft Foundation Classes: Cách liên kết thư viện MFC vào                                         #include "stdafx.h" // Tập tin chứa đăng ký thư viện của MFC
         ứng dụng. Có thể tùy chọn một trong hai cách sau:                                                    CWinApp theApp; // Ðối tượng quản lý tiểu trình chính
            Use MFC in Shared DLL: Chương trình sử dụng thư viện                                              Sau khi nhập xong, chọn mục File / Save để lưu tập tin.
            MFC theo cơ chế liên kết động. Tập tin chương trình có kích                                    Biên dịch chương trình: Chọn mục Build / Build <project name>.exe
            thước nhỏ nhưng khi thực hiện cần có các tập tin thư viện                                      hoặc chọn mục trên thanh công cụ.
            (DLL) của MFC trong thư mục hệ thống của windows.                                              Ta đã thực hiện xong một ứng dụng đơn giản trong môi trường
            Use MFC in Static Library: Thư viện MFC được nhúng vào                                         windows. Tập tin chương trình được lưu trong thư mục DEBUG
            chương trình trong lúc biên dịch. Tập tin chương trình có kích                                 (phiên bản biên dịch debug) hoặc RELEASE (phiên bản biên dịch
            thước lớn hơn nhưng ứng dụng có thể hoạt động độc lập.                                         release).
         Sau khi ấn định xong, chọn OK.                                                                    Chạy chương trình: Có thể chạy chương trình trực tiếp trong VC
      Khai báo đối tượng thuộc lớp CWinApp: Dùng bất kỳ tập tin CPP                                        bằng cách nhấn phím F5 hoặc click chọn trên thanh công cụ.
      nào của dự án để thực hiện công việc này. Vì dự án VD0 đang thự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
      hiện ở đây chưa có tập tin CPP, chúng ta tạo mới tập tin CPP cho                                  gì cả bởi nó chỉ là một ứng dụng khung - được xây dựng hoàn toàn từ
      dự án. Giả sử tập tin CPP này có tên là MAIN.CPP. Cách thực hiện                                  lớp CWinApp của MFC mà không có một xử lý bổ sung nào.
      như sau:                                                                                       2.7 THỰC HIỆN ỨNG DỤNG GIAO TÁC ÐƠN GIẢN:
      • Chọn mục File / New. Trong hộp hội thoại New, chọn trang
         Files:
18   Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Thö vieän MFC cuûa Microsoft & öùng duïng cô baûn trong windows     19
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ụ.                                                 Class Type = Generic Class: Chọn loại lớp thông thường vì
      • Chọn trang ClassView:                                                                                       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:
      • Right-click trên mục VD01 Classes, chọn New Class.                                                       VD01.H      : Chứa nội dung khai báo (header) của lớp.
      • Khai báo lớp CEmpApp thông qua hộp hội thoại New Class.                                                  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.
20   Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Thö vieän MFC cuûa Microsoft & öùng duïng cô baûn trong windows       21
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:


      • Ð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();                      Phần bổ sung
                        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"                     Bổ sung
              #include "Emp.h"
                                                                                                              Chọn Add All, sau đó chọn OK.
              BEGIN_MESSAGE_MAP(CEmpApp, CWinApp)
                                                                                                            • Trong hộp hội thoại MFC Class Wizard, Chọn OK để kết thúc.
                 //{{AFX_MSG_MAP(CEmpApp) // Bảng message map,
                                                                                                              Thông tin ClassWizard được lưu trong tập tin có cùng tên với tên
                 //}}AFX_MSG_MAP          // sẽ đề cập đến ở các
                                                                                                              của dự án và phần mở rộng là .CLW.
              END_MESSAGE_MAP()           // phần sau
                                                                                                            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:


22   Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Thö vieän MFC cuûa Microsoft & öùng duïng cô baûn trong windows       23
• Trong màn hình Workspace của dự án, chọn ClassView, right-                                                  UINT stop;                              // Biến kiểm tra đồng ý dừng?
        click trên tiêu đề của lớp CEmpApp:
                                                                                                                    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"
      • Chọn mục Add Virtual Function.                                                                          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.




      • 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()
          {
24   Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Thö vieän MFC cuûa Microsoft & öùng duïng cô baûn trong windows                        25
Chọn mục Insert...                                                                                    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
      Chọn mục Icon, sau đó chọn New:                                                                                       resource.
      Ta nhận được màn hình thiết kế icon. Vẽ icon có nội dung tùy ý.                                       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.
      Ấn định các thông số
                                                                                                     2.10 LỚP CString CỦA MFC:
      thuộc tính của icon (số
                                                                                                        CString là lớp đối tượng của MFC cho phép quản lý một nội dung
      hiệu icon, tên thư mục
                                                                                                     chuỗi trong bộ nhớ với những đặc tính ưu việt sau:
      và tên tập tin chứa
                                                                                                        - Nội dung chuỗi lưu trữ có độ dài lớn với cơ chế sử dụng bộ nhớ tối
      icon) trong dự án: Chọn
                                                                                                           ưu.
      ResourceView        trong
                                                                                                        - Xây dựng dựa trên kiểu TCHAR nên thích nghi với bộ mã
      Workspace của dự án,
                                                                                                           UNICODE.
      rigth-click trên icon mới
                                                                                                        - Các hành vi xử lý sẵn sàng cho các tác vụ chuỗi thông thường.
      thêm.
                                                                                                        Một số hành vi được sử dụng phổ biến của CString như sau:
      Chọn mục Properties.
                                                                                                           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.

26   Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Thö vieän MFC cuûa Microsoft & öùng duïng cô baûn trong windows          27
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;

28    Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
CHƯƠNG 3:                                                                         Cấu trúc quản lý 1 điểm:
                                                                                  typedef struct _POINT {
                  Các lớp GIAO DIỆN đồ họa của MFC                                   int x, y            // Tọa độ ( hoành độ, tung độ ) của điểm
                                                                                  } POINT ;
3.1 CÁC CÔNG CỤ GIAO DIỆN ÐỒ HỌA:                                                 Cấu trúc quản lý 1 vùng hình chữ nhật:
   Ðể hỗ trợ ứng dụng trong việc trang trí giao diện đồ họa (Graphic              typedef struct _RECT {
Device Interface - GDI) như màn hình, máy in., windows cung cấp một                  int top, left;      // Tọa độ góc trái trên hình chữ nhật.
hệ thống các công cụ đồ họa cơ bản như sau:                                          int right, bottom; // Tọa độ góc phải dưới hình chữ nhật.
         Pen : Công cụ vẽ điểm hoặc đường thẳng.                                  } RECT ;
         Brush : Công cụ tô màu.                                                  Cấu trúc quản lý chiều rộng và chiều cao vùng hình chữ nhật:
         Font : Công cụ qui định kiểu ký tự cho nội dung văn bản.                 typedef struct _SIZE {
         Bitmap : Công cụ quản lý vùng ảnh điểm.                                     int cx, cy;         // Chiều rộng, chiều cao vùng hình chữ
         Palette : Công cụ quản lý bộ màu hiển thị.                               nhật.
         Region : Công cụ quản lý vùng hiển thị có dạng bất kỳ.                   } SIZE ;
   Thông qua các công cụ nói trên, ứng dụng trong windows có thể thực       3.4 CÁC LỚP MFC HỖ TRỢ GDI:
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            MCF cung cấp một hệ thống phong phú các lớp với đầy đủ chức năng
đế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ụ   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ỹ
GDI.                                                                        thuật OOP trên các lớp GDI của MFC, người dùng dễ dàng tạo ra ứng
3.2 DEVICE CONTEXT:                                                         dụng mong muốn mà không phải viết quá nhiều mã lệnh trong chương
   Việc khai thác khả năng của các công cụ GDI được thực hiện thông         trình.
qua một cấu trúc chứa thông tin quản lý thiết bị hiển thị: Device Context   3.4.1 Các lớp đối tượng điểm, hình chữ nhật:
(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ị            CPoint : Lớp đối tượng điểm, tương ứng với cấu trúc POINT.
đồ 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                CRect : Lớp đối tượng vùng hình chữ nhật trên giao diện đồ họa,
công cụ GDI mới thì DC phải chấm dứt sử dụng công cụ tương ứng mà                  tương ứng với cấu trúc RECT. CRect có các hành vi đặc trưng sau:
nó đang dùng.                                                                      • CRect( ); Tạo lập đối tượng vùng hình chữ nhật rỗ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              • CRect (int left, int top, int right, int bottom); Tạo lập đối tượng
cụ GDI (trừ bitmap) mặc nhiên cho nó. Ứng dụng có thể tùy nghi thay đổi               vùng hình chữ nhật có thông số xác định.
các công cụ này cho phù hợp với nhu cầu của ứng dụng.                              • int Width( ) const; Trả về độ rộng vùng hình chữ nhật.
3.3. TỌA ÐỘ TRÊN GIAO DIỆN ÐỒ HỌA:                                                 • int Heigth( ) const; Trả về độ cao vùng hình chữ nhật.
   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          • void NormalizeRect( ); Hợp lý hóa các thành phần tọa độ của
độ có gốc (0,0) là góc trái-trên (top-left corner) của giao diện đồ họa,              rect mà không làm thay đổi vị trí và kích thước của nó.
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              VD: Giả sử khởi tạo một rect không hợp lệ như sau:
của trục tung (trục y) hướng từ trên xuống dưới. Trên mặt phẳng giao                     CRect rect( 100, 0, 0, 50 ); // rect.left = 100 > rect.right = 0
diện đồ họa đó:                                                                          rect. NormalizeRect();
      Ðiểm: Biểu diễn bằng cặp tọa độ (x,y).                                          rect trở nên hợp lệ với: rect ( 0, 0, 100, 50 );
      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             CSize : Lớp đối tượng kích thước, tương ứng với cấu trúc SIZE.
      dưới.
                                                                            3.4.2 Lớp CPen:
   Thông tin về điểm, vùng hình chữ nhật và kích thước của các đối
                                                                                CPen là lớp đối tượng quản lý pen, một công cụ GDI quan trọng của
tượng trong mặt phẳng giao diện đồ họa được đặc tả thông qua các cấu
                                                                            DC. Thông qua đối tượng này, DC có thể thay đổi màu sắc, nét vẽ của
trúc sau:

Caùc lôùp giao dieän ñoà hoïa cuûa MFC                                29    30   Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
điểm hay đường thẳng mà DC sẽ trực hiện. CPen có các hành vi đặc            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 sau:                                                                  trưng:
      CPen( ); Tạo lập đối tượng pen rỗng. Chúng ta phải khởi tạo tham             CFont( ); Tạo lập đối tượng font rỗng.
      số cho đối tượng này trước khi sử dụng.                                      CFont(const LOGFONT* lpLogFont ); Tạo lập đối tượng font với
      CPen (                      // Tạo lập đối tượng pen với tham số             thông số đầy đủ. Giá trị thông số được ấn định bởi tham số kiểu
          int nPenStyle,          // Kiểu nét vẽ                                   cấu trúc LOGFONT chứa thông tin. LOGFONT được khai báo như
          int nWidth,             // Ðộ rộng nét vẽ (=1: mặc nhiên)                sau:
          COLORREF crColor // Màu sắc của nét vẽ                                   typedef struct tagLOGFONT {
      );                                                                               LONG lfHeight;        // chiều cao của ký tự
      nPenStyle có thể nhận một trong các giá trị sau:                                 LONG lfWidth;         // chiều rộng trung bình các ký tự
          PS_SOLID :                     PS_DASH :                                     LONG lfEscapement; // góc (1/10) giữa hướng in và trục X
          PS_DOT :                       PS_DASHDOT :                                  LONG lfOrientation;   // góc (1/10) giữa ký tự và trục X (No 9x)
      crColor có thể nhận giá trị từ macro phối màu RGB( ) như sau:                    LONG lfWeight;        // mức độ đậm của font chữ (0 - 1000)
          RGB (int màu_đỏ , int màu_xanh_lá_cây , int màu_xanh_dương                   BYTE lfItalic;        // = TRUE : Chữ nghiêng
          )                                                                            BYTE lfUnderline;     // = TRUE : Chữ gạch dưới
          Mỗi màu được đặc trưng bằng một giá trị trong đoạn 0255 phản                 BYTE lfStrikeOut;     // = TRUE : Chữ gạch ngang thân
          ánh độ sáng của nó. Bộ phối màu theo qui tắc phối màu tự                     BYTE lfCharSet;       // bộ ký tự (=DEFAULT_CHARSET )
          nhiên.                                                                       BYTE lfOutPrecision; // = OUT_DEFAULT_PRECIS
      BOOL CreatePen( int nPenStyle, int nWidth, COLORREF crColor                      BYTE lfClipPrecision; // = CLIP_DEFAULT_PRECIS
      ); Khởi tạo thông số cho đối tượng pen. Ý nghĩa tham số như trên.                BYTE lfQuality;       // = DEFAULT_QUALITY
      operator HPEN() const; Toán tử chuyển kiểu, trả về handle của                    BYTE lfPitchAndFamily; // =DEFAULT_PITCH|FF_DONTCARE
      pen (HPEN) quản lý bởi đối tượng.                                                TCHAR lfFaceName[LF_FACESIZE]; // Chuỗi tên của font
3.4.3 Lớp CBrush:                                                                  } LOGFONT ;
   CBrush là lớp đối tượng quản lý brush, công cụ GDI của DC. Thông                   Win9x chỉ dùng lfEscapement.
qua đối tượng này, DC có thể thay đổi màu sắc, dạng của nét tô trong               int GetLogFont( LOGFONT * pLogFont ); Lấy thông tin của font
một vùng hình chữ nhật mà DC sẽ trực hiện. CBrush có các hành vi đặc               quản lý bởi đối tượng font chữ. Kết quả được điền vào biến kiểu
trưng sau:                                                                         LOGFONT chỉ bởi tham số kiểu con trỏ LOGFONT* : pLogFont.
      CBrush( ); Tạo lập đối tượng brush rỗng.                                     operator HFONT( ); Toán tử chuyển kiểu, trả về handle của font
      CBrush( COLORREF crColor ); Tạo lập đối tượng brush có màu tô                được quản lý bởi đối tượng.
      tương ứng với màu qui định bởi tham số crColor.                              BOOL CreateFontIndirect( LOGFONT *lpLogFont ); Khởi tạo thông
      CBrush( int nIndex, COLORREF crColor ); Tạo lập đối tượng brush              số cho đối tượng font từ thông tin lưu trong cấu trúc chỉ bởi
      có màu tô crColor, và nét tô nIndex.                                         lpLogFont.
      Giá trị nét tô có thể là: HS_VERTICAL (đường kẻ sọc đứng),            3.4.5 Lớp CBitmap:
      HS_HORIZAONTAL (đường kẻ sọc ngang).                                     CBitmap là lớp đối tượng quản lý bitmap, một công cụ GDI quan trọng
      BOOL CreateSolidBrush( COLORREF crColor ); Tạo đặc tính tô            giúp quản lý vùng ảnh điểm (pixels) của DC. Thông qua đối tượng này,
      đặc với màu crColor cho đối tượng brush chưa có thông số.             DC có thể dễ dàng tạo nội dung trang trí trên giao diện đồ họa từ nội
      operator HBRUSH() const; Toán tử chuyển kiểu, trả về handle của       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ử
      brush (HBRUSH) quản lý bởi đối tượng.                                 lý ảnh cơ bản trên nội dung đó. CBitmap cung cấp các hành vi đặc trưng
3.4.4 Lớp CFont:                                                            sau:
   CFont là lớp đối tượng quản lý font, công cụ GDI của DC. Thông qua             CBitmap( ); Tạo lập đối tượng bitmap rỗng.
đố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ý
Caùc lôùp giao dieän ñoà hoïa cuûa MFC                                31    32   Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
BOOL LoadBitmap( UINT nIDResource ); Tạo nội dung cho đối                       Mỗi phần tử của palPalEntry có kiểu PALETTEENTRY phản ánh
        tượng bitmap với thông tin được lấy từ một ảnh trong resource.              giá trị màu dùng hiển thị màu chỉ mục (color index) tương ứng với vị
        nIDResource : số hiệu của ảnh bitmap trong resource của chương              trí thứ tự của nó. Cấu trúc PALETTEENTRY có nội dung như sau:
        trình.
        BOOL CreateCompatibleBitmap (                                               typedef struct tagPALETTEENTRY {
            CDC* pDC, // Con trỏ đối tượng DC tương ứng                                BYTE peRed ;        // Giá trị thành phần màu đỏ
            int nWidth,   // Chiều rộng,                                               BYTE peGreen ;      // Giá trị thành phần màu xanh lá cây
            int nHeight   // chiều cao tính bằng pixel của bitmap được tạo.            BYTE peBlue ;       // Giá trị thành phần màu xanh dương
        ); Tạo nội dung cho đối tượng bitmap với thông tin về màu sắc, độ              BYTE peFlags ;      // Vai trò màu trong hệ thống.
        phân giải tương ứng với DC chỉ bởi con trỏ tham số pDC.                     } PALETTEENTRY;
        int GetBitmap( BITMAP* pBitMap ); Lấy thông tin về bitmap được              operator HPALETTE( ) const; Toán tử chuyển kiểu, trả về handle
        quản lý bởi đối tượng. Kết quả nhận được sẽ được điền vào biến có           của palette quản lý bởi đối tượng.
        kiểu BITMAP chỉ bởi tham số kiểu con trỏ BITMAP* : pBitmap.
                                                                              3.4.7 Lớp CRgn:
        Cấu trúc BITMAP bao gồm các trường có ý nghĩa như sau:
                                                                                 CRgn là lớp đối tượng quản lý region, một công cụ GDI quan trọng
        typedef struct tagBITMAP { /* bm */                                   giúp DC ấn định vùng ảnh xử lý có hình dạng tùy ý trên giao diện đồ họa
           int bmType ;          // Kiểu bitmap,                              của nó.
           int bmWidth ;         // Chiều rộng bitmap tính bằng pixel               CRgn( ); Tạo lập đối tượng vùng ảnh rỗng.
           int bmHeight ;        // Chiều cao bitmap tính bằng pixel                BOOL CreateRectRgn( int x1, int y1, int x2, int y2 ); Khởi tạo thông
           int bmWidthBytes ;    // Kích thước 1 dòng pixel trong bitmap            số cho đối tượng vùng ảnh bằng 1 hình chữ nhật với tọa độ góc trái
           BYTE bmPlanes ;       // Số màu.                                         trên và góc phải dưới lần lượt là (x1, y1) và (x2, y2).
           BYTE bmBitsPixel ;    // Số bit màu của 1 pixel                          BOOL CreateEllipticRgn( int x1, int y1, int x2, int y2 ); Khởi tạo
           LPVOID bmBits ;       // Ðịa chỉ vùng nhớ chứa pixel của                 thông số cho đối tượng vùng ảnh bởi hình ellipse nội tiếp hình chữ
        bitmap                                                                      nhật có góc trái trên (x1, y1) và góc phải dưới (x2, y2).
        } BITMAP;                                                                   BOOL CreatePolygonRgn (
        operator HBITMAP() const; Toán tử chuyển kiểu, trả về handle của                LPPOINT lpPoints, // Mảng chứa tọa độ các điểm ziczac
        bitmap được quản lý bởi đối tượng.                                              int nCount,          // Số phần tử POINT trong mảng trên
                                                                                        int nMode            // = WINDING
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.
                                                                                    Khởi tạo thông số cho đối tượng vùng ảnh bởi một đường ziczac
Thông qua đối tượng này, DC có thể tạo ra các hiệu ứng màu trên giao
                                                                                    khép kín qua các điểm có tọa độ xác định và được lưu trong một
diện đồ họa bằng cách thay đổi các bộ màu một cách phù hợp.
                                                                                    mảng.
      CPalette( ); Tạo lập đối tượng palette rỗng.
                                                                                    int CombineRgn (
      CreatePalette( LPLOGPALETTE lpLogPalette ); Khởi tạo thông số
                                                                                        CRgn* pRgn1, // Con trỏ đối tượng quản lý vùng ảnh thứ nhất
      cho đối tượng palette rỗng. Con trỏ tham số lpLogPalette chỉ đến
                                                                                        CRgn* pRgn2, // Con trỏ đối tượng quản lý vùng ảnh thứ hai
      biến kiểu cấu trúc LOGPALETTE chứa thông tin bộ màu dùng khởi
                                                                                        int nCombineMode         // Cách kết hợp hai vùng ảnh
      tạo.
                                                                                    ); Tạo thông số cho đối tượng vùng ảnh trên cơ sở kết hợp hai vùng
      typedef struct tagLOGPALETTE {
                                                                                    ảnh đã có. Tham số nCombineMode có thể là:
          WORD palVersion;              // Số hiệu palette hệ thống
                                                                                       RGN_AND : Vùng ảnh kết quả là vùng giao nhau giữa hai vùng
          WORD palNumEntries;           // Số màu sử dụng
                                                                                       ảnh.
         PALETTEENTRY palPalEntry[1]; // Chứa các giá trị màu,
                                                                                       RGN_OR : Vùng ảnh kết quả là vùng hợp giữa hai vùng ảnh.
                              // có số phần tử mảng bằng palNumEntries
                                                                                       RGN_DIFF : Vùng ảnh kết quả là vùng bù giữa hai vùng ảnh.
      } LOGPALETTE ;
Caùc lôùp giao dieän ñoà hoïa cuûa MFC                                  33    34   Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
operator HRGN() const; Toán tử chuyển kiểu, trả về handle của              UINT nFormat          // Chứa thông tin canh chỉnh chuỗi hiển
        vùng ảnh quản lý bởi đối tượng.                                        thị.
                                                                               ); In nội dung chuỗi lên giao diện đồ họa của DC với các canh
3.5 LỚP CDC:
                                                                               chỉnh.
   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 đồ
                                                                               lpRect : Chỉ đến biến kiểu RECT chứa thông tin giới hạn vùng hiển
                                                                               thị.
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.
                                                                               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à:
     virtual BOOL CreateCompatibleDC( CDC* pDC ); Khởi tạo thông
                                                                                   DT_CENTER       : Chỉnh giữa theo chiều ngang
     số cho đối tượng DC một cách tương thích với một DC có sẵn được
                                                                                   DT_VCENTER : Chỉnh giữa theo chiều dọc
     chỉ bởi con trỏ tham số pDC.
                                                                                   DT_RIGHT        : Chỉnh phải.
     virtual BOOL DeleteDC( ); Hủy bỏ đối tượng DC.
                                                                               CPoint MoveTo( int x, int y ); Ấn định điểm vẽ hiện hành.
     CPen* SelectObject( CPen* pPen ); Chọn công cụ vẽ mới cho DC.
                                                                               BOOL LineTo( int x, int y ); Vẽ đường thẳng từ điểm vẽ hiện hành
     pPen : con trỏ đến đối tượng pen sẽ được dùng cho DC.
                                                                               đến điểm có tọa độ (x, y).
     Hàm trả về con trỏ chỉ đến đối tượng pen mà DC đang sử dụng.
                                                                               void FillRect (
         Có thể sử dụng hành vi này cho các công cụ trang trí khác của
                                                                                   LPCRECT lpRect, // Con trỏ chỉ đến biến kiểu RECT.
     DC. Kết quả trả về là con trỏ đến đối tượng đang dùng tương ứng.
                                                                                   CBrush* pBrush // Con trỏ đến đối tượng brush dùng tô màu.
     CPent* GetCurrentPen( ); Trả về giá trị con trỏ của đối tượng pen
                                                                               ); Tô màu vùng hình chữ nhật được xác định bởi các giá trị chứa
     đang được sử dụng bởi DC.
                                                                               trong biến kiểu RECT do tham số lpRect chỉ đến.
         Một cách tương tự cho các công cụ trang trí khác.
                                                                               void Draw3dRect (                 // Vẽ hình chữ nhật 3 chiều
     virtual COLORREF SetBkColor( COLORREF crColor ); Ðặt màu
                                                                                   LPCRECT lpRect,               // Con trỏ đến biến RECT
     nền cho DC. crColor là giá trị màu đặt.
                                                                                   COLORREF clrTopLeft,          // Màu vẽ cạnh trái và cạnh trên.
     COLORREF GetBkColor( ); Trả về giá trị màu nền của DC.
                                                                                   COLORREF clrBottomRight // Màu vẽ cạnh phải và cạnh dưới
     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.
                                                                               BOOL DrawEdge (
     COLORREF GetTextColor( ); Trả về giá trị màu hiện dùng để hiển
                                                                                   LPRECT lpRect,      // Con trỏ đến biến kiểu RECT.
     thị các nội dung văn bản trên DC.
                                                                                   UINT nEdge,         // Cách vẽ trên các gờ (trong, ngoài) cạnh.
     int SetBkMode ( int nBkMode ); Ấn định chế độ hiển thị nền ký tự
                                                                                   UINT nFlags         // Các cạnh được vẽ.
     biểu diễn nội dung văn bản. nbkMode chứa thông số ấn định:
                                                                               ); Vẽ khung chữ nhật với hiệu ứng 3 chiều.
         TRANSPARENT : Nền chữ hiển thị trong suốt.
         OPAQUE            : Chữ hiển thị có màu nền.
                                                                               nEdge có thể kết hợp các giá trị sau:
                                                                                   BDR_RAISEDINNER : Vẽ nổi gờ trong
     int GetBkMode( ); Lấy chế độ hiển thị chữ của DC.
                                                                                   BDR_SUNKENINNER : Vẽ chìm gờ trong
     virtual BOOL TextOut (
                                                                                   BDR_RAISEDOUTER : Vẽ nổi gờ ngoài
         int x, y ,            // Tọa độ bắt đầu hiển thị
                                                                                   BDR_SUNKENOUTER              : Vẽ chìm gờ ngoài
         LPCTSTR lpszString,          // Nội dung chuỗi hiển thị.
         int nCount            // Chiều dài chuỗi.
                                                                               nFlags có thể kết hợp các giá trị sau:
                                                                                   BF_RECT                  : Vẽ tất cả các cạnh
     ); Hiển thị nội dung chuỗi văn bản lên giao diện đồ họa của DC.
                                                                                   BF_TOPLEFT               : Vẽ cạnh trái và cạnh trên
     virtual int DrawText (
                                                                                   BF_BOTTOMRIGHT           : Vẽ cạnh phải và cạnh dưới
         LPCTSTR lpszString, // Nội dung chuỗi hiển thị
                                                                               BOOL DrawState (
         int nCount,           // Chiều dài chuỗi
                                                                                   CPoint pt,          // Ðiểm đặt góc trái trên của ảnh trên DC
         LPRECT lpRect,        // Con trỏ đến biến kiểu RECT
                                                                                   CSize size,         // Kích thước vùng hiển thị ảnh
                                                                                   CBitmap* pBitmap, // Con trỏ đối tượng bitmap được vẽ
Caùc lôùp giao dieän ñoà hoïa cuûa MFC                              35   36   Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
UINT nFlags,          // = DST_BITMAP (vẽ bitmap)                            DWORD dwRop                        // Cách chụp pixel từ ảnh nguồn.
            CBrush* pBrush        // Con trỏ đối tượng Brush, sử dụng khi vẽ         ); Tương tự BitBlt nhưng ảnh đích và ảnh nguồn có thể có kích
                                  // Bitmap ẩn: nFlags |= DSS_DISABLED               thước khác nhau nên tạo hiệu ứng co dãn ảnh chép được so với
        ); Vẽ bitmap hoặc icon lên DC.                                               ảnh nguồn.
        BOOL BitBlt (                                                                BOOL DrawIcon (
            int x, int y,             // Tọa độ góc trái trên và                         int x, int y,         // Tọa độ góc trái trên nơi đặt icon trên DC
            int nWidth, int nHeight,        // kích thước vùng nhận ảnh.                 HICON hIcon           // Handle của icon
            CDC* pSrcDC,              // Con trỏ đối tượng quản lý DC nguồn.         ); Vẽ icon hIcon lên vị trí (x, y) của DC quản lý bởi đối tượng.
            int xSrc, int ySrc,       // Góc trái trên phần ảnh nguồn được      3.6 LỚP CImagelist:
        chép.                                                                      CImageList là lớp đối tượng imagelist. Mỗi imagelist cho phép quản lý
            DWORD dwRop               // Cách chụp pixel từ ảnh nguồn.          danh sách ảnh có cùng kích thước và hỗ trợ nhiều tiện ích trên chúng.
        ); Chụp nội dung phần ảnh bắt đầu từ vị trí (xSrc,ySrc) trong DC             CImageList( ); Tạo lập đối tượng imagelist rỗng.
        nguồn sang vùng nhận ảnh bắt đầu từ vị trí (x, y), với kích thước            BOOL Create (
        (nWidth, nHeight) trong DC quản lý bởi đối tượng.                                UINT nBitmapID, // Số hiệu của resource bitmap chứa các
        Giá trị pixel được chuyển vào vùng nhận ảnh tùy thuộc vào giá trị            ảnh
        tham số dwRop. Một số giá trị dùng cho tham số này có thể như                    int cx,               // Ðộ rộng mỗi ảnh trong bitmap nói trên
        sau:                                                                             int nGrow,            // Số ảnh trong bitmap
        • SRCCOPY : Giá trị pixel lấy trực tiếp từ pixel của ảnh nguồn.                  COLORREF crMask // Màu mặt nạ (không hiển thị)
        • SRCPAINT : Là kết quả OR của pixel ảnh nguồn và ảnh nhận.                  ); Khởi tạo nội dung cho đối tượng từ một bitmap trong resource.
        • SRCAND           : Là kết quả AND của pixel ảnh nguồn và ảnh               int GetImageCount( ); Số ảnh của imagelist quản lý bởi đối tượng.
            nhận.                                                                    int Add (
        BOOL MaskBlt (                                                                   CBitmap* pbmImage, // Con trỏ đối tượng bitmap của ảnh
            int x, int y,               // Tọa độ góc trái trên và                   mới.
            int nWidth, int nHeight, // Kích thước vùng nhận ảnh                         CBitmap* pbmMask |          // Ðối tượng bitmap mặt nạ hoặc
            CDC* pSrcDC,                // Con trỏ đối tượng quản lý DC nguồn             [ COLORREF crMask ] // màu mặt nạ của ảnh mới.
            int xSrc, int ySrc,         // Góc trái trên phần ảnh được chép          ); Thêm một ảnh (bitmap) vào imagelist.
            CBitmap& maskBitmap, // Con trỏ đối tượng bitmap mặt nạ                  BOOL BeginDrag( int nImage, CPoint ptHotSpot ); Chuẩn bị
            int xMask, int yMask,       // Góc trái trên vùng ảnh làm mặt nạ         chuyển ảnh thứ nImage trong imagelist với vị trí bắt đầu ptHotSpot.
            DWORD dwRop                 // Cách chụp pixel từ ảnh nguồn.             static BOOL DragEnter( CWnd* pWndLock, CPoint point ); Cấm
        ); Tương tự BitBlt nhưng sử dụng mặt nạ lọc pixel. Ðối tượng                 cửa sổ pWndLock, nơi mà imagelist đang thực hiện chuyển ảnh.
        maskBitmap sử dụng ảnh trắng đen (monochrome bmp) mà mỗi                     static BOOL DragMove(CPoint pt); Chuyển ảnh nImage đến vị trí
        pixel "đen" sẽ ngăn việc chuyển pixel ở vị trí tương ứng từ DC               pt.
        nguồn sang DC quản lý bởi đối tượng, các vị trí khác được chuyển             static BOOL DragLeave( CWnd* pWndLock ); Chấm dứt tình trạng
        bình thường.                                                                 bị cấm của cửa sổ pWndLock.
        BOOL StretchBlt (                                                            static void EndDrag( ); Chấm dứt tác vụ chuyển ảnh.
            int x, int y,                      // Tọa độ góc trái trên và            static BOOL DragShowNolock( BOOL bShow ); Hiển thị hoặc che
            int nWidth, int nHeight,           // Kích thước vùng nhận ảnh.          ảnh trong quá trình chuyển hình.
            CDC* pSrcDC,                       // Con trỏ đối tượng DC nguồn.        BOOL Draw (
            int xSrc, int ySrc,                // Tọa độ góc trái trên và                CDC* pdc,      // Ðối tượng DC dùng vẽ hình
            int nSrcWidth, int nSrcHeight, // Kích thước phần ảnh được                   int nImage,    // Số thứ tự hình được vẽ trong imagelist
        chép.                                                                            POINT pt,      // Tọa độ góc trái trên nơi vẽ hình

Caùc lôùp giao dieän ñoà hoïa cuûa MFC                                    37    38   Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
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(
       );




Caùc lôùp giao dieän ñoà hoïa cuûa MFC                                  39
CHƯƠNG 4:                                                                                                       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.
                  Cửa sổ giao diện và lớp CWnd                                                                  WS_MAXIMIZEBOX : Có hộp phóng to trên caption của cửa
                                                                                                             sổ.
4.1 CỬA SỔ GIAO DIỆN:                                                                                           WS_MINIMIZEBOX : Có hộp thu nhỏ trên caption của cửa sổ.
   Cửa sổ giao diện là thành phần quan trọng của ứng dụng. Nó không                                             WS_THICKFRAME : Viền cho phép thay đổi kích thước cửa
chỉ đóng vai trò trung gian trong trao đổi thông tin giữa ứng dụng với                                       sổ.
người dùng bởi giao diện đồ họa dễ nhìn mà còn là công cụ xử lý                                                 WS_VISIBLE            : Cửa sổ nhìn thấy được (hiển thị).
message hiệu quả và không thể thiếu cho cơ chế điều phối message của                                            Ví dụ: WS_POPUP | WS_CAPTION : Cửa sổ chính có tiêu đề.
ứng dụng windows.                                                                                            lpszClassName là một tên đã đăng ký cho lớp cửa sổ. Ngoài các
   Bên cạnh đó, cửa sổ giao diện còn làm chức năng nhận diện ứng                                             tên mà windows đã đăng ký như STATIC, BUTTON, EDIT, ...
dụng, là thẻ thông hành cho ứng dụng trong hành trình tồn tại, hoạt động                                     (chương 8), ta có thể đăng ký tên lớp cửa sổ riêng của mình một
độ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                                       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
windows.                                                                                                     trong hai cách sau:
4.2 LỚP CWnd:                                                                                                • Ðăng ký trực tiếp:
   CWnd là lớp đối tượng quản lý cửa sổ của windows. Thông qua các                                              LPCTSTR AFXAPI AfxRegisterWndClass (
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                                             UINT nClassStyle,              // Thông số dạng của cửa sổ
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                                                 HCURSOR hCursor = 0,          // Cursor hiển thị trong cửa sổ
cách dễ dàng.                                                                                                      HBRUSH hbrBackground = 0, // Brush dùng tô nền cửa sổ
     HWND m_hWnd : Thuộc tính lưu handle của cửa sổ.                                                               HICON hIcon = 0               // Icon trên tiêu đề của cửa sổ
     CWnd( ); Hành vi tạo lập đối tượng cửa sổ.                                                                 ); Trả về chuỗi tên lớp cửa sổ được đăng ký. Các lần đăng ký
     virtual BOOL Create (                                                                                      tên lớp cửa sổ có tham số giống nhau sẽ nhận được một tên duy
         LPCTSTR lpszClassName, // Tên đăng ký của lớp cửa sổ                                                   nhất.
         LPCTSTR lpszWindowName,              // Tên cửa sổ.                                                    Tham số nClassStyle có thể kết hợp từ các giá trị sau:
         DWORD dwStyle,               // Các thông số về dạng cửa sổ                                               CS_HREDRAW : Cửa sổ được vẽ lại khi chiều rộng thay đổi.
         const RECT& rect,            // Qui định vị trí, kích thước cửa sổ                                        CS_VREDRAW : Cửa sổ được vẽ lại khi chiều cao thay đổi.
         CWnd* pParentWnd,            // Con trỏ đối tượng cửa sổ cha                                              CS_NOCLOSE : Cấm hộp đóng [] trên tiêu đề của cửa sổ.
         UINT nID,                    // Số hiệu cửa sổ                                                         Ví dụ: Ðăng ký lớp cửa sổ có nền màu xanh dương.
         CCreateContext* pContex = NULL                                                                         CString       myClassName;
     ); Khởi tạo thông số cho cửa sổ quản lý bởi đối tượng.                                                     CBRUSH        myBrush;
     Tham số dwStyle qui định đặc điểm và kiểu dáng cửa sổ. Giá trị                                             myBrush.CreateSolidBrush( RGB ( 0, 0, 255 ) );
     dùng cho tham số này có thể kết hợp một số trong các giá trị sau:                                          myClassName = AfxRegisterWndClass (
         WS_POPUP              : Cửa sổ được tạo là cửa sổ chính.                                                                           CS_VREDRAW | CS_HREDRAW,
         WS_CHILD              : Cửa sổ được tạo là cửa sổ con.                                                                             NULL, myBrush, NULL );
         WS_TABSTOP            : Cửa sổ con, chuyển được bằng phím tab.
         WS_OVERLAPPED : Cửa sổ chính.                                                                       • Ðăng ký qua cấu trúc chứa các thông số:
         WS_SYSMENU            : Cửa sổ có hộp menu hệ thống.                                                  BOOL AFXAPI AfxRegisterClass( WNDCLASS* lpWndClass );
         WS_BORDER             : Cửa sổ có viền.                                                               Hàm trả về giá trị TRUE nếu tác vụ đăng ký thành công. Thực
         WS_CAPTION            : Cửa sổ có tiêu đề (caption)                                                   hiện đăng ký theo cách này tránh được sự dùng chung tên lớp
         WS_DISABLED           : Cửa sổ bị cấm.                                                                cửa sổ ở hai ứng dụng khác nhau khi hai ứng dụng này tình cờ
         WS_DLGFRAME           : Cửa sổ có viền đậm kiểu hộp thoại,                                            đăng ký các tên lớp cửa sổ giống nhau về thông số.
40   Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Cöûa soå giao dieän vaø lôùp CWnd                                       41
lpWndClass là con trỏ chỉ đến biến có kiểu cấu trúc                                                     LPVOID lpCreateParams; // Con trỏ vùng chứa thông số cửa
          WNDCLASS.                                                                                          sổ
          typedef struct _WNDCLASS {                                                                             HANDLE hInstance;             // Handle của ứng dụng
             UINT style;                              // Dạng của lớp đăng ký                                    HMENU hMenu;                  // Handle của menu gắn với cửa sổ
             WNDPROC lpfnWndProc;                     // Con trỏ hàm WindowProc của                              HWND hwndParent;              // Handle của cửa sổ cha
                                                      // cửa sổ. Có thể lấy hàm do                               int cy; int cx;               // Chiều rộng và cao của cửa sổ
          MFC                                                                                                    int y; int x;                 // Tọa độ góc trái trên của cửa sổ
                                            // khai báo sẵn: AfxWndProc                                          LONG style;                   // Thông số ấn định dạng cửa sổ
              int cbClsExtra;               // Dành riêng của hệ thống                                           LPCSTR lpszName;              // Tên cửa sổ được tạo
              int cbWndExtra;               // Dành riêng của hệ thống                                           LPCSTR lpszClass;             // Tên lớp cửa sổ dùng cho cửa sổ
              HINSTANCE hInstance;          // Instance handle của ứng                                           DWORD dwExStyle;              // Thông số ấn định dạng mở rộng
          dụng                                                                                               } CREATESTRUCT;
              HICON hIcon;                  // Handle của icon                                                   Trong các lớp kế thừa CWnd, hành vi này được dùng để can
              HCURSOR hCursor;              // Handle của cursor                                                 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
              HBRUSH hbrBackground; // Handle của brush vẽ nền                                                   sổ.
              LPCTSTR lpszMenuName; // Chuỗi tên menu trong                                                  BOOL EnableWindow( BOOL bEnable = TRUE ); Cho phép hoặc
          resource                                                                                           cấm hoạt động của cửa sổ.
              LPCTSTR lpszClassName; // Tên lớp cửa sổ đăng ký                                               BOOL ShowWindow( int nCmdShow ); Ấn định trạng thái hiển thị
          } WNDCLASS;                                                                                        của cửa sổ trên màn hình. Giá trị cho tham số nCmdShow có thể
      BOOL CreateEx (                                                                                        là:
          DWORD dwExStyle,              // Các thông số dạng mở rộng                                             SW_HIDE                     : Dấu cửa sổ
          LPCTSTR lpszClassName, // Tên lớp                                                                      SW_MINIMIZE                 : Thu nhỏ cửa sổ
          LPCTSTR lpszWindowName,               // Tên cửa sổ                                                    SW_RESTORE                  : Ðưa cửa sổ về trạng thái trước đó
          DWORD dwStyle,                // Dạng cửa sổ                                                           SW_SHOW                     : Hiển thị cửa sổ
          int x, int y,                 // Tọa độ góc trái trên của cửa sổ                                       SW_SHOWNA                   : Hiển thị nhưng không kích hoạt cửa
          int nWidth, int nHeight,      // Chiều rộng và cao của cửa sổ                                          sổ
          HWND hwndParent,              // Handle của cửa sổ cha                                                 SW_SHOWMAXIMIZED : Hiển thị và phóng to cửa sổ
          HMENU nIDorHMenu,             // Handle của menu gắn với cửa sổ                                        SW_SHOWMINIMIZED : Hiển thị và thu nhỏ cửa sổ
          LPVOID lpParam = NULL                                                                              BOOL SetWindowPos (
      ); 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.                                          const CWnd* pWndInsertAfter,            // Con trỏ cửa sổ làm mốc
      Tham số dwExStyle qui định dạng mở rộng của cửa sổ có thể kết                                              int x, int y,                     // Tọa độ góc trái trên của cửa sổ
      hợp từ các giá trị sau:                                                                                    int cx, int cy,                   // Kích thước cửa sổ
          WS_EX_TOPMOST              : Cửa sổ không bị che khuất.                                                UINT nFlags                       // Thông số trạng thái
          WS_EX_TOOLWINDOW : Cửa sổ không hiển thị trên taskbar.                                             ); Ấn định vị trí cửa sổ trên màn hình.
          WS_EX_TRANSPARENT : Cửa sổ có nền trong suốt.                                                      Giá trị pWndInsertAfter qui định vị trí đặt cửa sổ theo chiều thứ 3
          WS_EX_CLIENTEDGE : Cửa sổ có gờ quanh vùng client.                                                 (z-order). Giá trị này có thể như sau:
      virtual BOOL PreCreateWindow( CREATESTRUCT& cs ); Hành vi                                                  wndBottom : Cửa sổ được đặt dưới mọi cửa sổ.
      được thực hiện trước khi windows khởi tạo thông số cho cửa sổ.                                             wndTop          : Cửa sổ được đặt trên các cửa sổ thông thường.
      Tham biến cs kiểu CREATESTRUCT chứa thông số khởi tạo.                                                     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ổ:
      typedef struct tagCREATESTRUCT {                                                                           SWP_SHOWWINDOW : Hiển thị cửa sổ.

42   Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Cöûa soå giao dieän vaø lôùp CWnd                                            43
SWP_DRAWFRAME                : Vẽ lại frame của cửa sổ.                                                BOOL bRedraw = TRUE // Vẽ lại cửa sổ sau tác vụ đặt font ?
          SWP_NOREDRAW                 : Không cập nhật lại thông tin cửa sổ.                                ); Ấn định font chữ cho cửa sổ.
      void MoveWindow (                                                                                      CMenu* GetMenu( ); Trả về con trỏ đối tượng menu gắn với cửa
          int x, int y,                  // Tọa độ mới cho góc trái trên                                     sổ.
          int nWidth, int nHeight,       // Chiều rộng và chiều cao của cửa sổ                               BOOL SetMenu( CMenu* pMenu ); Gắn menu cho cửa sổ.
          BOOL bRepaint = TRUE // Yêu cầu windows vẽ lại cửa sổ                                              CWnd* GetParent( ); Trả về con trỏ đến đối tượng cửa sổ cha.
      ); Thay đổi vị trí và kích thước của cửa sổ.                                                           int GetScrollPos( int nBar ); Trả về vị trí hiện hành của nút cuộn
      void GetWindowRect( LPRECT lpRect ); Lấy thông tin tọa độ, kích                                        trên thanh cuộn. nBar chứa số hiệu thanh cuộn quan tâm. nBar có
      thước của cửa sổ, lpRect chỉ đến biến kiểu RECT chứa kết quả.                                          thể là:
      void GetClientRect( LPRECT lpRect ); Lấy thông tin tọa độ, kích                                            SB_HORZ : Thanh cuộn ngang.
      thước vùng client của cửa sổ, lpRect chỉ đến biến RECT chứa kết                                            SB_VERT : Thanh cuộn dọc.
      quả.                                                                                                   int SetScrollPos (
      int GetWindowRgn(HRGN hRgn); Xác định vùng hiển thị của cửa                                                int nBar,                   // Thanh cuộn được chọn
      sổ.                                                                                                        int nPos,                   // Vị trí đặt
      int SetWindowRgn (                                                                                         BOOL bRedraw = TRUE // Vẽ lại thanh cuộn sau tác vụ đặt
          HRGN hRgn,              // Handle của region quản lý vùng ấn định                                  ); Ðặt vị trí nút cuộn cho thanh cuộn tương ứng.
          BOOL bRedraw            // Vẽ lại cửa sổ (TRUE) hay không (FALSE)                                  UINT SetTimer (
      ); Ấn định vùng hiển thị của cửa sổ theo dạng của region.                                                  UINT nIDEvent, // Số hiệu của timer, phân biệt duy nhất
      void GetWindowText( CString rString ); Lấy nội dung chuỗi tiêu đề                                          UINT nElapse, // Chu kỳ timer (tính bằng mili-second)
      của cửa sổ và lưu vào biến đối tượng chuỗi rString.                                                        NULL               // Sử dụng hành vi OnTimer xử lý timer
      int GetWindowTextLength( ); Trả về chiều dài của chuỗi tiêu đề.                                        ); Ðặt biến cố định thời (timer) cho cửa sổ quản lý bởi đối tượng.
      void ClientToScreen( LPPOINT lpPoint / LPRECT lpRect );                                                Mỗi khi hết một chu kỳ của timer, hệ thống gửi WM_TIMER kèm
      Chuyển tọa độ điểm hay vùng hình chữ nhật trong client của cửa                                         theo số hiệu của timer đó đến cho cửa sổ.
      sổ sang hệ trục tọa độ của màn hình.                                                                   BOOL KillTimer( int nIDEvent ); Hủy bỏ timer có số hiệu nIDEvent.
      void ScreenToClient( LPPOINT lpPoint / LPRECT lpRect );                                                afx_msg void OnTimer( UINT nIDEvent ); Hành vi xử lý WM_TIMER
      Chuyển tọa độ điểm hay vùng hình chữ nhật trên màn hình sang                                           của cửa sổ. Tham số nIDEvent chứa số hiệu của timer liên quan.
      hệ trục tọa độ của vùng client trong cửa sổ.                                                           void Invalidate( BOOL bErase = TRUE ); Kích hoạt cơ chế vẽ lại
      HICON GetIcon( BOOL bBigIcon ); Trả về handle của icon mà cửa                                          vùng client của cửa sổ. Nếu bErase = FALSE, windows không thực
      sổ đang sử dụng. Giá trị tham số bBigIcon có ý nghĩa như sau:                                          hiện xóa thông tin trong vùng cần vẽ lại.
          TRUE : Handle của icon hiển thị trên taskbar (big Icon)                                            void InvalidateRect( LPCRECT lpRect, BOOL bErase = TRUE );
          FALSE : Handle của icon hiển thị trên caption (small Icon)                                         Kích hoạt cơ chế vẽ lại một vùng trong client của cửa sổ. Thông tin
      HICON SetIcon (                                                                                        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
          HICON hIcon,        // handle của icon                                                             RECT chỉ bởi lpRect. Tham số bErase có ý nghĩa như Invalidate.
          BOOL bBigIcon // TRUE (đặt bigIcon) , FALSE (đặt smallIcon)                                        int MessageBox (
      ); Ðặt icon mới cho cửa sổ.                                                                                LPCTSTR lpszText,                   // Nội dung thông báo
      static CWnd* PASCAL GetFocus( ); Trả về con trỏ chỉ đến đối                                                LPCTSTR lpszCaption = NULL // Tiêu đề hộp thông báo
      tượng CWnd đang được phép nhận thông tin nhập từ bàn phím.                                                 UINT nType = MB_OK                  // Dạng hộp thông báo
      CWnd* SetFocus( ); Kích hoạt cửa sổ. Hàm trả về con trỏ của đối                                        ); Hiển thị hộp thông báo và trả về số hiệu của nút được chọn.
      tượng CWnd đã được kích hoạt trước đó.                                                                 LRESULT SendMessage (
      CFont* GetFont( ); Trả về đối tượng font chữ của cửa sổ.                                                   UINT message,               // Số hiệu message
      void SetFont (                                                                                             WPARAM wParam = 0, // Tham số kiểu WORD
          CFont* pFont,                    // Con trỏ đến đối tượng font chữ                                     LPARAM lParam = 0           // và kiểu LONG kèm theo message
44   Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Cöûa soå giao dieän vaø lôùp CWnd                                        45
); Gửi message và tham số kèm theo đến hàm WindowProc của                                                  MK_SHIFT          : Phím SHIFT được nhấn kèm theo
      cửa sổ quản lý bởi đối tượng, và chờ đến khi hàm WindowProc xử                                         afx_msg void OnLButtonDown( UINT nFlags, CPoint point ); Hành
      lý xong.                                                                                               vi xử lý WM_LBUTTONDOWN, message do windows gửi đến cửa
      BOOL PostMessage( UINT message,                                                                        sổ khi người dùng ấn nút chuột trái. Các thông tin như trên.
                             WPARAM wParam = 0, LPARAM lParam=0                                              afx_msg void OnLButtonUp( UINT nFlags, CPoint point ); Hành vi
      ); Ðặt message và các tham số kèm theo vào message queue của                                           xử lý WM_LBUTTONUP, message do windows gửi đến cửa sổ khi
      ứng dụng. Hành vi kết thúc mà không chờ message đó được xử lý.                                         người dùng nhả nút chuột trái. Các thông tin như trên.
      afx_msg void OnSize( UINT nType, int cx, int cy ); Hành vi xử lý                                       Một cách tương tự cho các hành vi xử lý message của nút chuột
      WM_SIZE, message do windows gửi đến cửa sổ khi một tác vụ                                              phải.
      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                                    afx_msg void OnMouseMove( UINT nFlags, CPoint point ); Hành
      cửa sổ.                                                                                                vi xử lý WM_MOUSEMOVE, message do windows gửi đến cửa sổ
      afx_msg int OnCreate( LPCREATESTRUCT lpCreateStruct );                                                 khi người dùng di chuyển chuột trong cửa sổ. Các thông tin như
      Hành vi xử lý WM_CREATE, message do windows gửi đến cửa sổ                                             trên.
      khi tác vụ khởi tạo thông số cho cửa sổ được thực hiện xong.                                           int GetDlgCtrlID( ); Trả về số hiệu của đối tượng cửa sổ con.
      afx_msg void OnClose( ); Hành vi xử lý WM_CLOSE, message do                                            afx_msg void OnPaint( ); Hành vi xử lý WM_PAINT, message do
      windows gửi đến cửa sổ khi tác vụ đóng cửa sổ đang xảy ra.                                             windows gửi đến cửa sổ khi hệ thống hoặc ứng dụng có nhu cầu
      afx_msg void OnDestroy( ); Hành vi xử lý WM_DESTROY,                                                   trang trí lại một phần hay toàn bộ giao diện của cửa sổ.
      message do windows gửi đến cửa sổ khi tác vụ hủy bỏ 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
      đang xảy ra.                                                                                           trì trên bề mặt giao diện của cửa sổ. Ðể thực hiện việc này,
      afx_msg void OnKeyDown (                                                                               OnPaint sử dụng một đối tượng CDC và dùng nó cho các thao tác
          UINT nChar,               // Mã phím                                                               đồ họa cần thiết nhằm hoàn thành yêu cầu nói trên.
          UINT nRepCnt,             // Số lần gõ phím                                                        Bố cục xử lý thông thường của hành vi OnPaint như sau:
          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                                                PAINTSTRUCT ps ;                // Biến chứa thông tin trang trí
      cửa sổ khi cửa sổ đang được kích hoạt, đồng thời có phím vừa được                                      CDC* pDC = BeginPaint(&ps);     // Lấy DC của giao diện cửa sổ
      ấn xuống mà không có sự sử dụng phím Alt kèm theo.                                                     .                               // Xử lý trang trí giao diện đồ họa
      afx_msg void OnKeyUp (        // Các tham số tương tự như trên                                         EndPaint(&ps);                  // Chấm dứt.
          UINT nChar, UINT nRepCnt , UINT nFlags                                                             afx_msg void OnHScroll (
      ); Hành vi xử lý WM_KEYUP. Một cách tương tự WM_KEYDOWN.                                                   UINT nSBCode,          // Số hiệu ghi nhận đặc điểm tác động
      afx_msg void OnChar (                                                                                      UINT nPos,             // Vị trí nút cuộn / nút trượt trên mục
          UINT nChar ,              // Mã ASCII                                                                  CScrollBar* pScrollBar // Con trỏ đối tượng quản lý mục
          UINT nRepCnt ,            // Số lần gõ                                                             ); Hành vi xử lý WM_HSCROLL, message do windows gửi đến cửa
          UINT nFlags               // Trạng thái các phím kèm theo                                          sổ khi có một mục là thanh cuộn hay thanh trượt đặt ngang
      ); Hành vi xử lý WM_CHAR, message do windows gửi đến cửa sổ                                            (horizontal scrollbar hoặc horizontal sliderCtrl) trong cửa sổ bị tác
      khi một phím ký tự được gõ.                                                                            động.
      afx_msg void OnLButtonDblClk (                                                                         nSBCode ghi nhận đặc điểm tác động lên nút cuộn / trượt như sau:
          UINT nFlags,              // Chứa giá trị phím được nhấn kèm                                           SB_LEFT                : Giảm nút về vị trí thấp nhất
          CPoint point              // Vị trí double-click chuột                                                 SB_ENDSCROLL           : Chấm dứt tác vụ chuyển nút
      ); Hành vi xử lý WM_LBUTTONDBLCLK, message do windows gửi                                                  SB_LINELEFT            : Giảm nút một vị trí
      đến cửa sổ khi người dùng double-click vào nút chuột trái.                                                 SB_LINERIGHT           : Tăng nút một vị trí
      Tham số nFlag có thể là kết hợp của các giá trị sau:                                                       SB_PAGELEFT            : Giảm nút một đoạn
          MK_CONTROL : Phím CTRL được nhấn kèm theo
46   Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Cöûa soå giao dieän vaø lôùp CWnd                                             47
SB_PAGERIGHT               : Tăng nút một đoạn                                                     • Ðặt điểm chỉ (hotpot) của cursor: Trong màn hình thiết kế
          SB_RIGHT                   : Tăng nút đến vị trí cao nhất                                            cursor:
          SB_THUMBPOSITION : Chuyển nút bằng chuột
          SB_THUMBTRACK : Ðang chuyển nút bằng chuột .                                                           - Click chọn biểu tượng        trên thanh công cụ.
      nPos được sử dụng trong các tác vụ định vị nút tuyệt đối ( ).                                              - Click tại vị trí hotpot của cursor trên màn hình thiết kế.
          Dùng hành vi GetDlgCtrlID của đối tượng chỉ bởi pScrollBar để                                      Dùng đối tượng CWnd làm cửa sổ giao diện chính của ứng dụng:
          xác định số hiệu của mục phát sinh message WM_HSCROLL.                                             Ðược thực hiện bởi hành vi InitInstance (xem 2.4) của đối tượng
          Ðây là cơ sở giúp phân biệt mục này với các mục khác trong                                         CEmpApp quản lý tiểu trình chính. Kế thừa hành vi này từ
          cùng cửa sổ giao diện nhằm lựa chọn xử lý thích hợp cho                                            CWinApp cho lớp CEmpApp (xem 2.7). Nội dung cài đặt của hành
          WM_HSCROLL.                                                                                        vi như sau:
      afx_msg void OnVScroll (                                                                               CWnd* main = new CWnd(); // Con trỏ đối tượng CWnd.
          UINT nSBCode,              // Số hiệu ghi nhận đặc điểm tác động                                   HICON      myIcon;       // Khai báo biến quản lý
          UINT nPos,                 // Vị trí nút cuộn / nút trượt trên mục                                 HCURSOR myCursor;        // handle của cursor và icon
          CScrollBar* pScrollBar // Con trỏ đối tượng quản lý mục                                            CBrush     myBrush;
      ); 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                                                     // Nạp cursor và icon từ resource vào bộ nhớ.
      (vertical scrollbar hoặc vertical sliderCtrl) trong cửa sổ bị tác động.                                myIcon = LoadIcon ( IDR_MAINFRAME );
          Xử lý của hành vi này được cài đặt tương tự hành vi OnHScroll.                                     myCursor = LoadCursor ( IDR_MAINFRAME );
      afx_msg BOOL OnSetCursor (                                                                                         // Tạo brush tô nền cửa sổ với màu RGB(190, 190, 0)
          CWnd* pWnd, // Con trỏ đến đối tượng cửa sổ chứa cursor                                            myBrush. CreateSolidBrush (RGB(190, 190, 0) );
          UINT nHitTest, // Thông tin về vị trí cursor                                                                   // Khởi tạo thông số cho đối tượng cửa sổ main
          UINT message // Chứa các số hiệu message có liên quan đến                                          main->CreateEx( WS_EX_TOPMOST,
                              // trạng thái hiện thời của các nút con chuột                                            AfxRegisterWndClass(
      ); Hành vi xử lý WM_SETCURSOR, message do windows gửi đến                                                        CS_HREDRAW|CS_VREDRAW,
      cửa sổ khi windows cần ấn định lại hình dạng cursor cho phù hợp                                                                         myCursor, myBrush, myIcon),
      với vị trí hiện thời của nó trên cửa sổ.                                                                         "Emp.Example 2",
      nHitTest chứa thông tin vị trí hiện thời của cursor:                                                             WS_SYSMENU | WS_VISIBLE | WS_MINIMIZEBOX,
          HTBORDER : Cursor hiện nằm trên biên cửa sổ                                                                  100, 100, 300, 200, NULL, NULL );
          HTCLIENT         : Cursor hiện nằm trong vùng client                                                           // Dùng main làm cửa sổ giao diện chính
          HTCAPTION : Cursor hiện nằm trên tiêu đề của cửa sổ                                                m_pMainWnd = main;
      virtual LRESULT WindowProc( UINT message,                                                              main->ShowWindow ( SW_SHOW );            // Kích hoạt cửa sổ main
                                     WPARAM wParam, LPARAM lParam );                                    Khi đối tượng cửa sổ main ngừng hoạt động thì ứng dụng cũng kết
      Hành vi xử lý các message gửi đến cửa sổ. Mặc nhiên, hành vi này                               thúc.
      dựa vào bảng MessageMap để chuyển message đến hành vi xử lý                                       Xem VD02: Cửa sổ main với ExStyle là WS_EX_TOPMOST có thể nổi
      message tương ứng của đối tượng quản lý cửa sổ.                                                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
4.3 SỬ DỤNG ÐỐI TƯỢNG CWnd:                                                                          ExStyle là WS_EX_TOOLWINDOW, cửa sổ sẽ không hiển thị trên
4.3.1 Sử dụng CWnd làm giao diện chính của ứng dụng:                                                 taskbar.
   Tạo dự án VD02 như dự án VD01. Thực hiện các bổ sung sau:
                                                                                                     4.3.2 Ứng dụng chỉ chạy một bản (instance) tại mỗi thời điểm:
      Tạo icon có số hiệu là IDC_MAINFRAME. Tham khảo (2.8).
                                                                                                        Ðể ứng dụng chỉ được thực hiện với 1 bản duy nhất, ta cài đặt cơ chế
      Tạo cursor có số hiệu là IDC_MAINFRAME:
                                                                                                     đánh dấu và kiểm tra. Trong chương trình của ứng dụng, ta qui ước đăng
      • Tạo mới cursor: Thực hiện tương tự như tạo mới icon, (2.8).
48   Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Cöûa soå giao dieän vaø lôùp CWnd                                       49
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ổ.




50   Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
CHÖÔNG 5:                                                                                                 UINT nID,                 // Soá hieäu command message
                                                                                                          int nCode,
                               Xử lý message                                                              void* pExtra,
                                                                                                          AFX_CMDHANDLERINFO* pHandlerInfo
5.1 LÔÙP XÖÛ LYÙ MESSAGE CCmdTarget:                                                                  ); Ñieàu phoái command message. Neáu baûn thaân ñoái töôïng laø cöûa soå giao
    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ô              dieän chính thì caùc WM_COMMAND ñöôïc öu tieân gôûi ñeán cho ñoái
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             töôïng. Thoâng qua haønh vi naøy, ñoái töôïng coù theå ñieàu phoái command
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.                message cho caùc ñoái töôïng khaùc (öùng duïng, caùc control, view…). Löu yù
Treân quan ñieåm ñoù, MFC cung caáp lôùp ñoái töôïng CCmdTarget phuïc vuï xöû lyù                     laø ñoái töôïng ñöôïc ñieàu phoái coù theå khoâng coù chöùc naêng xöû lyù command
vaø ñieàu phoái messages trong phaïm vi öùng duïng, giöõa öùng duïng vôùi heä thoáng                  message göûi ñeán, do ñoù caàn kieåm tra keát quaû cuûa haønh vi OnCmdMsg
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:                           treân ñoái töôïng ñöôïc ñieàu phoái. Boá cuïc xöû lyù ñieàu phoái nhö sau:
        void BeginWaitCursor( ); Hieån thò cursor chôø xöû lyù (ñoàng hoà caùt).                      if (Ñoái_töôïng->OnCmdMsg(...) != 0) {
        void EndWaitCursor( ); Chaám döùt hieån thò cursor chôø xöû lyù.                                  return;        // Ñoái töôïng ñöôïc ñieàu phoái ñaõ xöû lyù message
        Ñò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                   …                  // Chuû theå phaûi xöû lyù message
        keá thöøa lôùp CCmdTarget. Caùc macro giuùp caøi ñaët cô cheá naøy nhö sau:             5.2 KHAI BAÙO MUÏC XÖÛ LYÙ MESSAGE TRONG MESSAGE MAP:
        • DECLARE_MESSAGE_MAP( ): AÁn ñònh ñaëc tính xöû lyù message                               Muïc xöû lyù message trong baûng MessageMap cho pheùp aán ñònh moät xöû lyù
            cho lôùp ñoái töôïng xöû lyù message thoâng qua caùc caøi ñaët boå sung sau:        duy nhaát cho moät message. Caùc loaïi message khaùc nhau coù kieåu muïc xöû lyù
            - Thuoäc tính private kieåu caáu truùc maûng chöùa caùc phaàn töû coù kieåu         message khaùc nhau. Caùc kieåu muïc xöû lyù message phoå bieán nhö sau:
                AFX_MSGMAP_ENTRY. Moãi phaàn töû cuûa maûng ñöôïc duøng löu                          Caùc message cuûa heä thoáng, ñöôïc bieåu dieãn bôûi caùc haèng soá baét ñaàu
                tröõ moät muïc xöû lyù message maø lôùp keá thöøa khai baùo boå sung.                baèng WM_ *, muïc xöû lyù message töông öùng coù daïng ON_WM_* ().
            - Thuoäc tính protected kieåu caáu truùc AFX_MSGMAP vôùi teân laø                        Ví duï: WM_PAINT                 ON_WM_PAINT()
                MessageMap chæ ñeán baûng caùc muïc xöû lyù message noùi treân.                                  WM_SIZE              ON_WM_SIZE()
            - Haønh vi protected: virtual AFX_MSGMAP GetMessageMap( );                               Caùc message cuûa ngöôøi duøng: Soá hieäu message ñöôïc choïn tuøy yù trong
                traû veà ñòa chæ cuûa baûng MessageMap chöùa caùc muïc xöû lyù.                      ñoaïn WM_USER ÷ WM_USER+0×7FFF. Muïc xöû lyù message cho caùc
            DECLARE_MESSAGE_MAP ñöôïc ñaët cuoái phaàn khai baùo lôùp:                               message cuûa ngöôøi duøng coù daïng nhö sau:
            class MyClass : public CCmdTarget {                      // Taäp tin .H cuûa lôùp
                                                                                                          ON_MESSAGE( userMessageID , UserFuncName )
                …                      // Caùc noäi dung khai baùo cuûa lôùp
                DECLARE_MESSAGE_MAP()                                                                 Trong ñoù:
            };                                                                                           - userMessageID              : Soá hieäu message do ngöôøi duøng choïn tröôùc
        • BEGIN_MESSAGE_MAP( Teân_lôùp_keá thöøa, Teân_lôùp_cô_sôû ): Baét                               - UserFuncName               : Haøm xöû lyù message, coù khai baùo nhö sau:
            ñaàu noäi dung khai baùo caùc muïc xöû lyù cuûa baûng MessageMap.                         afx_msg LRESULT UserFuncName (
        • END_MESSAGE_MAP( ): Keát thuùc khai baùo baûng MessageMap.                                     WPARAM wParam,  // Tham soá kieåu WORD vaø
            Toaøn boä noäi dung khai baùo cuûa baûng MessageMap ñöôïc ñaët trong                         LPARAM lParam   // Tham soá kieåu LONG keøm theo message
            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 (
Xöû lyù Message                                                                           51    52   Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
Caùc message coù ñaêng kyù cuûa ngöôøi duøng: Ngoaøi caùc message töï ñònh              void [ClassName::]PreFunctionName (CCmdUI* pCmdUI ) {
        nghóa vaø söû duïng theo qui öôùc trong moät öùng duïng, windows cho pheùp                 pCmdUI->Enabled (FALSE ); // Caám ñoái töôïng hoaït ñoäng
        öù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:           Caùc message do ñoái töôïng con (controls) göûi ñeán cöûa soå cha: Tham soá
            UINT RegisterWindowMessage (LPCSTR Chuoãi_teân_message );                           wParam chöùa soá hieäu control, giaù trò WORD cao cuûa tham soá lParam
        Haøm traû veà soá hieäu ñaêng kyù ñöôïc cuûa message. Giaù trò naøy naèm trong          chöùa thoâng tin veà traïng thaùi control ôû thôøi ñieåm göûi message ñeán cöûa soå
        ñoaïn 0×C000÷0×FFFF. Caùc öùng duïng ñang chaïy treân moät heä thoáng coù               cha (ví duï BN_CLICKED laø moät traïng thaùi cuûa button control,…). Muïc
        theå chia xeû message duøng rieâng vôùi ñieàu kieän chuùng phaûi thöïc hieän            xöû lyù message cho message göûi töø control coù daïng nhö sau:
        thao taùc ñaêng kyù cuøng moät chuoãi teân message ñeå laáy soá hieäu message.          ON_CONTROL (Traïng_thaùi_control, Soá_hieäu_Control, Haøm_xöû_lyù )
        Muïc xöû lyù message cho caùc message coù ñaêng kyù cuûa ngöôøi coù daïng:              Ví duï: Ta coù ví duï minh hoïa ñònh höôùng xöû lyù message nhö sau:
        ON_REGISTERED_MESSAGE(UserRegMessageID, UserFuncName)                                   * Khai baùo lôùp (teâp tin .H):
        Sau ñaây laø moät ví duï:                                                               class CMyClass: public CBasedWnd {
                 // Ñaêng kyù message vôùi teân laø “MY_MESS”                                   public: CMyClass();
        const UINT myMess = RegisterWindowMessage(“MY_MESS”);                                      void myProc(void);
                 // Khai baùo muïc xöû lyù cho message ñöôïc ñaêng kyù                             void mySerach();
        BEGIN_MESSAGE_MAP ( CMyWnd, CMyBasedWndClass )                                             void myWork();
          //{{AFX_MSG_MAP ( CMyWnd )                                                               void PremyWork();
          ON_REGISTERED_MESSAGE ( myMess, myFunc )                                                 void OnExit(void);
          // ...                                                                                   DECLARE_MESSAGE_MAP()
          //}}AFX_MSG_MAP                                                                       }
        END_MESSAGE_MAP ( )                                                                     * Phaàn caøi ñaët cuûa lôùp (teâp tin .CPP):
        Message WM_COMMAND: Khi WM_COMMAND ñöôïc göûi ñeán ñoái                                 #define MY_MESSAGE WM_USER + 1
        töôïng xöû lyù message thì tham soá wParam keøm theo chöùa soá hieäu                    static UINT NEAR MY_MESS = RegisterWindowMessage(“MY_MESS”);
                                                                                                BEGIN_MESSAGE_MAP(CMyClass, CDerivedWnd)
        (CommandID) cuûa ñoái töôïng phaùt sinh message. Muïc xöû lyù message
                                                                                                   //{{AFX_MSG_MAP(CMyClass)
        WM_COMMAND aán ñònh xöû lyù töông öùng, vaø coù daïng nhö sau:                             ON_WM_PAINT()                   // WindowsMessage
            ON_COMMAND ( CommandID, FunctionName )                                                 ON_MESSAGE (MY_MESSAGE, myProc)           // UserMessage
                                                                                                   ON_REGISTERED_MESSAGE(MY_MESS,OnSearch)
         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                                             // UserRegMessage
        WM_COMMAND thoâng qua muïc xöû lyù ñieàu khieån message nhö sau:                           ON_COMMAND(ID_DO, myWork)       // CommandMessage
                                                                                                                                   // Command Preprocess
        ON_UPDATE_COMMAND_UI( CommandID, PreFunctionName )                                         ON_UPDATE_COMMAND_UI(ID_DO, PremyWork)
        PreFunctionName laø haønh vi thöïc hieän xöû lyù ñieàu khieån treân ñoái töôïng                                            //Control IDC_EXIT
                                                                                                   ON_CONTROL(BN_CLICKED, IDC_EXIT, OnExit)
        phaùt sinh WM_COMMAND, tham soá nhaän ñöôïc laø giaù trò con troû ñeán
                                                                                                   //}}AFX_MSG_MAP
        ñoái töôïng CCmdUI*. Haønh vi Enable ( BOOL isEnabled ) cuûa ñoái                       END_MESSAGE_MAP()
        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
                                                                                                Caùc muïc xöû lyù message do Classwizard quaûn lyù ñaët giöõa //{{ vaø //}}
        töôïng phaùt sinh WM_COMMAND. Xöû lyù cuûa haønh vi naøy coù theå laø:

Xöû lyù Message                                                                     53    54   Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
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ô                - Choïn WM_CREATE. Sau ñoù choïn Add and Edit.
        sôû keá thöøa töø lôùp CWnd cuûa MFC:                                                        - Haønh vi OnCreate vôùi tham soá thích hôïp ñöôïc boå sung vaøo lôùp
        • Haønh vi OnCreate thöïc hieän caùc aán ñònh caàn thieát cho CEmpWnd                          CEmpWnd, ñoàng thôøi muïc xöû lyù ON_WM_CREATE() ñöôïc ñaët
            tröôùc khi ñi vaøo hoaït ñoäng. Boå sung vaø caøi ñaët haønh vi nhö sau:                   vaøo baûng MessageMap. Caøi ñaët noäi dung cuûa OnCreate nhö sau:
            - Trong maøn hình Workspace cuûa döï aùn, choïn trang ClassView.
                                                                                                         int CEmpWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
            - Right-click treân tieâu ñeà cuûa lôùp CEmpWnd:                                             {
                                                                                                             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:
            - Choïn muïc Add Windows Message Handler... :                                          void CEmpWnd::OnTimer( UINT nIDEvent )
                                                                                                   {
Xöû lyù Message                                                                      55    56   Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
if (nIDEvent == 100) {              // Timer do chuùng ta caøi ñaët                Ta nhaän ñöôïc hoäp hoäi thoaïi Resource Symbols chöùa danh saùch caùc giaù
                      char s[200], ch;                                                               trò ñaõ khai baùo. Coù theå thöïc hieän theâm, xoùa caùc giaù trò khai baùo naøy.
                      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ôû                       Choïn muïc New:
        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:                     Nhaäp teân cuûa giaù trò khai baùo trong hoäp Name, nhaäp giaù trò khai baùo
        Choïn trang ResourceView trong maøn hình Workspace.                                           trong hoäp Value. Sau ñoù choïn OK
        Right-click treân project resources:                                                          Ñ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
        Choïn Resource Symbols...:                                                           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:
Xöû lyù Message                                                                         57   58    Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
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å.




Xöû lyù Message                                                                     59
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).                                     - Choïn Bitmap, Import. Sau ñoù choïn taäp tin chöùa aûnh bitmap thoâng
    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                           qua hoäp hoäi thoaïi File-Folder.
resource cuûa öùng duïng. ÔÛ phaàn xöû lyù, caùc resource naøy ñöôïc taûi vaøo boä nhôù                         - AÁn ñònh caùc thoâng soá cuûa bitmap (soá hieäu laø IDB_MYPICT).
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õ                       Boå sung ñoái töôïng thuoäc tính m_myPict kieåu CBitmap cho CEmpWnd:
ñöôï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.                       - Choïn trang ClassView trong maøn hình Workspace cuûa döï aùn.
6.2 ÖÙNG DUÏNG VÔÙI CÖÛA SOÅ CHÍNH HIEÅN THÒ AÛNH:                                                           - Right-click treân tieâu ñeà cuûa lôùp CEmpWnd:
   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:
                                                                                                             - Choïn Add Member Variable… :
       • 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:




                                                                                                             - 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
          - Choïn Insert:                                                                                    laøm noäi dung cuûa m_myPict. Xöû lyù ñöôïc caøi ñaët nhö sau:
60   Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   ÖÙng duïng coâng cuï GDI                                                          61
int CEmpWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)                                              Ñ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ò
         if (CWnd::OnCreate(lpCreateStruct) == -1)                                                   ñoà hoïa ñöôïc quaûn lyù bôûi chính noù thoâng qua moät soá haønh vi sau:
                return -1;                                                                               - BitBlt          : Sao cheùp vaø giöõ nguyeân tyû leä trong noäi dung aûnh.
           // Khôûi ñoäng bitmap töø bitmap resource IDB_MYPICT                                          - StretchBlt : Sao cheùp vaø thay ñoåi tyû leä trong noäi dung aûnh.
           mypict.LoadBitmap( IDB_MYPICT );                                                          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.
           return 0;
       }                                                                                                 - 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.
       Duøng haønh vi OnPaint cuûa CEmpWnd, veõ aûnh bitmap trong m_myPict                           Vieäc thöïc hieän caàn löu yù caùc böôùc sau:
       thoâng qua haønh vi DrawState cuûa ñoái töôïng CPaintDC dc.                                       - Cöûa soå chính cuûa öùng duïng coù thuoäc tính WS_THICKFRAME.
       void CEmpWnd::OnPaint()                                                                           - 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ò.
          CPaintDC dc(this);
                                                                                                     Caùc böôùc thöïc hieän nhö sau:
          RECT rect;
                                                                                                            Taïo döï aùn VD08 töông töï döï aùn VD07.
          GetClientRect( &rect );              // Kích thöôùc vuøng client
          // draw on client                                                                                 Haønh vi OnPaint cuûa CEmpWnd söû duïng DC trong boä nhôù ñeå loàng aûnh
          dc.DrawState ( CPoint(0,0),          /* Goùc traùi treân cuûa aûnh */                             bitmap, töø ñoù veõ leân vuøng client cuûa cöûa soå. Xöû lyù caøi ñaët nhö sau:
                            CSize (rect.right-rect.left, rect.bottom-rect.top),                             void CEmpWnd::OnPaint()
                            &m_myPict, DST_BITMAP);                                                         {
       }                                                                                                        CPaintDC dc(this);
                                                                                                                RECT           rt;
       Haønh vi OnDestroy cuûa CEmpWnd giaûi phoùng ñoái töôïng m_myPict.
                                                                                                                CDC            memDC;
       void CEmpWnd::OnDestroy()                                                                                CBitmap *oldBmp;
       {                                                                                                        BITMAP bmpInfo;
          CWnd::OnDestroy();
          m_myPict.DeleteObject();                                                                               GetClientRect(&rect);                // Kích thöôùc vuøng client
       }                                                                                                         mypict.GetBitmap(&bmpInfo); // Laáy thoâng tin cuûa aûnh bitmap
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                        memDC.CreateCompatibleDC(&dc);
gaây ra hieän töôïng "chôùp", ta coù theå söû duïng moät soá giaûi phaùp sau:                                    // Loàng bitmap m_myPict vaøo memDC vaø löu laïi bitmap cuõ cuûa noù.
- Khoâng söû duïng ñoái töôïng brush cho cöûa soå lieân quan: Duøng giaù trò NULL                                oldBmp = memDC.SelectObject(&m_myPict);
    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å.                            // Cheùp aûnh töø memDC leân DC quaûn lyù vuøng client cuûa cöûa soå: dc
- 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)                               dc.StretchBlt( 0, 0, rt.right-rt.left, rt.bottom-rt.top, &memDC,
                                                                                                                                    0, 0, bmpInfo.bmWidth, bmpInfo.bmHeight,
- Duøng moät DC trong boä nhôù laøm coâng cuï trang trí trung gian. Thöïc hieän caùc
                                                                                                                                    SRCCOPY);
    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
                                                                                                                 // Phuïc hoài aûnh bitmap cuõ cuûa memDC
    trí caàn thieát thì chuyeån noäi dung DC coâng cuï leân DC cuûa maøn hình.                                   memDC.SelectObject(oldBmp); memDC.DeleteDC();
6.3 SAO CHEÙP AÛNH TÖØ DC VAØO DC, PHOÙNG TO & THU NHOÛ AÛNH:                                                }   // Xem VD08
                                                                                                     6.4 DC TRONG BOÄ NHÔÙ (DC AÛO) - VUØNG VEÕ ÑEÄM LYÙ TÖÔÛNG:
62   Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   ÖÙng duïng coâng cuï GDI                                                               63
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                     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
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                  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õ
moãi noäi dung trang trí, nhö theá seõ caûi thieän ñaùng keå chaát löôïng ñoà hoïa.                   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à
    ÖÙ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                hai haønh vi OnCreate vaø OnDestroy cuûa CEmpWnd moät caùch phuø hôïp.
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                        Baïn haõy thöû aùp duïng ñieàu löu yù naøy cho VD09.
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
                                                                                                      6.5 AÛNH CHUYEÅN ÑOÄNG TRONG VUØNG CLIENT:
xöû lyù cuûa haønh vi OnPaint coù söû duïng ñoái töôïng DC aûo nhö sau:
                                                                                                          Ñöôï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ò
     CClientDC     dc(this);            // Ñoái töôïng DC hieån thò                                   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
     RECT          rect;                                                                              aûnh theo trình töï vôùi khoaûng thôøi gian chôø hôïp lyù.
     CDC           memDrawDC;           // Ñoái töôïng DC aûo ñeå veõ trung gian                      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       memDrawBmp;                                                                                CBitmap: Moãi bitmap quaûn lyù ñöôïc moät aûnh. Ta duøng nhieàu bitmap.
     CBitmap       *memDrawOldBmp;
                                                                                                              AÛnh veõ baèng haønh vi DrawState cuûa ñoái töôïng DC quaûn lyù thieát bò hieån
     GetClientRect ( &rt );
     int           CX = rect.right–rect.left ; int CY = rect.bottom–rect.top;                                 thò. Kích thöôùc aûnh hieån thò khoâng thay ñoåi.
     memDrawBmp.CreateCompatibleBitmap( &dc, CX, CY );                                                        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
     memDrawDC.CreateCompatibleDC( &dc );                                                                     kyø phaàn aûnh caàn veõ naøo sang DC hieån thò. Coù theå thay ñoåi kích thöôùc
     memDrawOldBmp = memDrawDC.SelectObject( &memDrawBmp );                                                   aûnh tuøy yù: StretchBlt.
        ... // Trang trí memDrawDC                                                                            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.
     // Chuyeån noäi dung DC aûo sang dc:
                                                                                                          Trong phaàn naøy ta xaây döïng öùng duïng vôùi hình aûnh chuù böôùm bay trong
     dc.StretchBlt ( 0, 0, CX,CY, &memDrawDC, CX,CY, SRCCOPY );
                                                                                                          vuøng client cuûa cöûa soå. Taäp tin butterfly.bmp trong thö muïc BMP chöùa caùc
     // Huûy boû caùc ñoái töôïng GDI:
     memDrawDC.SelectObject(&memDrawOldBmp);                                                              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ø
     memDrawBmp.DeleteObject();                                                                           veõ leân DC hieån thò. Caùc böôùc thöïc hieän döï aùn nhö sau:
     memDrawDC.DeleteDC();                                                                                    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
     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
                                                                                                              ñöôïc laáy töø taäp tin chöùa caùc aûnh hoaït hình. Ghi nhôù soá aûnh trong bitmap
     chöõ chaïy theo kieåu baûng chöõ ñieän töû trong vuøng client cuûa cöûa soå chính.
                                                                                                              ñoù. Chaúng haïn, choïn taäp tin butterfly.bmp trong thö muïc BMP. Taäp tin
        Taïo döï aùn VD09 töông töï döï aùn VD08.
                                                                                                              naøy coù 4 aûnh, kích thöôùc 32x28.
        Xöû lyù Trang trí memDrawDC trong OnPaint cuûa CEmpWnd nhö sau:
                                                                                                              Boå sung caùc ñoái töôïng thuoäc tính protected cho lôùp CEmpWnd:
  BITMAP      bmpInfo;                                                                                        - m_butterDC :               Ñoái töôïng CDC, quaûn lyù DC loàng aûnh.
  m_myPict.GetBitmap( &bmpInfo );
                                                                                                              - m_butterBmp :              Ñoái töôïng CBitmap, quaûn lyù caùc aûnh hoaït hình.
  memDrawDC.StretchBlt( 0, 0, CX, CY, &memDC,
                        0, 0, bmpInfo.bmWidth, bmpInfo.bmHeight,                                              - m_butterOldBmp : Ñoái töôïng CBitmap*, quaûn lyù con troû chæ ñeán
                        SRCCOPY );                                                                                                         ñoái töôïng bitmap cuõ cuûa m_butterDC.
  memDrawDC.SetTextColor( RGB(255,0,0) ); // text color                                                       - m_pictNo :                 Kieåu int, quaûn lyù soá thöù töï cuûa hình ñang ñöôïc
  memDrawDC.SetBkMode( TRANSPARENT ); // transparent                                                                                       hieån thò trong caùc aûnh hoaït hình noùi treân.
  memDrawDC.TextOut( 30, 100, Chuoãi, I );                                                                    Haønh vi OnCreate cuûa CEmpWnd thöïc hieän caùc chuaån bò:
Xem VD09.                                                                                                     int CEmpWnd::OnCreate( LPCREATESTRUCT lpCreateStruct )
64    Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   ÖÙng duïng coâng cuï GDI                                                                65
{                                                                                                     Haønh vi OnCreate cuûa CEmpWnd thöïc hieän caùc chuaån bò nhö sau:
            if (CWnd::OnCreate(lpCreateStruct) == -1)                                                         int CEmpWnd::OnCreate( LPCREATESTRUCT lpCreateStruct )
                  return -1;                                                                                  {
            // TODO: Add your specialized creation code here                                                      if (CWnd::OnCreate(lpCreateStruct) == -1)
            SetTimer( IDD_TIMER, 250, NULL );                                                                            return -1;
            m_myPict.LoadBitmap( IDB_MYPICT );                                                                    // TODO: Add your specialized creation code here
            // Animation objects by EX10                                                                          SetTimer(IDD_TIMER, 250, NULL);
            m_butterBmp.LoadBitmap( IDB_ANIMATION );                                                              m_mypict.LoadBitmap(IDB_MYPICT);
            m_butterDC.CreateCompatibleDC( NULL );                                                                // animation object by EX10
            m_butterOldBmp = butterDC.SelectObject( &m_butterBmp );                                               m_butterImg.Create(IDB_ANIMATION,32,4,RGB(255,255,255));
            m_pictNo = 0;                                                                                         m_pictNo = 0;
            return 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ù:                       Haønh vi OnPaint söû duïng haønh vi Draw cuûa m_butterImg veõ aûnh:
        memDrawDC.StretchBlt( 20, 50, 32, 28, &m_butterDC,                                                    m_butterImg.Draw( &memDrawDC, m_pictNo, CPoint(30, 170),
                                  m_pictNo*32 , 0 , 32 , 28 , SRCCOPY );                                                           ILD_NORMAL);
        m_pictNo++;               // Choïn aûnh keá tieáp                                                     m_pictNo++;
        if (m_pictNo >= 4) m_pictNo = 0;                                                                      if (m_pictNo >= 4) m_pictNo = 0;
        Haønh vi OnDestroy huûy boû caùc thuoäc tính GDI:                                                     Haønh vi OnDestroy huûy boû ñoái töôïng CImageList:
        m_butterDC.SelectObject(m_butterOldBmp);
                                                                                                              m_butterImg.DeleteImageList();
        m_butterBmp.DeleteObject();
        m_butterDC.DeleteDC();
                                                                                                      6.7 CRgn – CÖÛA SOÅ COÙ HÌNH DAÏNG TUØY YÙ:
        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                       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
        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                 haønh vi SetWindowRgn cuûa ñoái töôïng cöûa soå. Phaàn sau ñaây minh hoïa cho vaán
        ñònh phaàn noäi dung ñöôïc veõ treân aûnh hoaït hình.                                         ñeà treân vaø ñöôïc caøi ñaët trong haønh vi OnCreate cuûa cöûa soå (VD12).
     Haønh vi MaskBlt cuûa CDC cho pheùp duøng monochrome bitmap laøm löôùi
                                                                                                              CRgn newShape;
     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
                                                                                                              newShape.CreateEllipticRgn( 0, 0, 200, 100 );
     (95/98/Me unsupported). Baïn haõy thöû thöïc hieän vôùi VD10 nhö baøi taäp.
                                                                                                              SetWindowRgn( newShape, TRUE );
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                THÖÏC HAØNH:
quaûn lyù bôûi ñoái töôïng CImageList:                                                                1. Vieát öùng duïng vôùi cöûa soå giao dieän chính coù hình tam giaùc.
        Taïo döï aùn VD11 töông töï döï aùn VD10.                                                     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.
        Boå sung ñoái töôïng thuoäc tính m_butterImg kieåu CImageList laøm nhieäm                     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öï
        vuï quaûn lyù caùc aûnh. Xoùa caùc thuoäc tính m_butterBmp, m_butterDC vaø                    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.
        m_butterOldBmp vì khoâng coøn caàn thieát.                                                    4. Vieát öùng duïng hieån thò aûnh cuoän (scroll) töø traùi sang phaûi.

66    Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   ÖÙng duïng coâng cuï GDI                                                             67
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.




68   Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
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:
                                                                                                  - 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:




   - 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).                                         - Prompt: Noäi dung giaûi thích (ñöôïc hieån thò treân StatusBar) vaø noäi
7.2 MENU RESOURCE:                                                                                   dung giaûi thích vaén taét (Tiptext treân thanh coâng cuï). Giöõa hai noäi
   Ñeå tieän vieäc söû duïng vaø chænh söûa menu trong chöông trình, VC cho pheùp                    dung naøy ñöôïc ngaên caùch baèng kyù töï n.
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,           - ID: Soá hieäu cuûa muïc choïn (menu-ID). Neân ñaët teân gôïi nhôù.
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ø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
Caùch taïo menu trong resource:                                                                   Separator trong hoäp Menu Item Properties.
       Taïo môùi menu resource: Thöïc hieän töông töï vieäc taïo môùi icon (2.8).               • 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í
       Löu yù: Choïn Resource Type laø Menu.                                                      cheøn, sau ñoù nhaán phím Insert.
       Ñaët soá hieäu cho menu (ví duï IDR_MAINFRAME vôùi menu chính).                          • Xoùa muïc caøi ñaët: Ñöa veät saùng ñeán vò trí xoùa, goõ phím Delete.
       Thieát keá menu thoâng qua maøn hình thieát keá maø ta vöøa nhaän ñöôïc töø              Taïo môùi döï aùn VD13 nhö VD12, sau ñoù thieát keá menu resource vôùi soá
       böôùc treân. Caùc thao taùc cô baûn nhö sau:                                             hieäu IDR_MAINFRAME. Soá hieäu caùc muïc choïn laàn löôït laø:
       • Caøi ñaët muïc popup: Double-click (hoaëc goõ phím                                        - Start = ID_GAME_START
           Enter) treân vò trí döï ñònh caøi ñaët muïc popup:                                      - Option = ID_GAME_OPTION
           Ta nhaän ñöôïc hoäp hoäi thoaïi Menu Item Properties:                                   - About = ID_GAME_ABOUT
                                                                                                   - Exit       = ID_EXIT
Menu & Phím taét                                                                    69    70   Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
7.3 SÖÛ DUÏNG MENU RESOURCE:                                                               7.4 MUÏC XÖÛ LYÙ COMMAND MESSAGE TÖØ MUÏC CHOÏN CUÛA MENU:
    Menu resource laø cô sôû khôûi taïo heä thoáng menu duøng trong öùng duïng. Heä            Ñ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.
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       Khi ngöôøi duøng choïn moät muïc treân menu, heä thoáng laäp töùc göûi
naøy ñöôïc thöïc hieän thoâng qua caùc böôùc sau:                                          WM_COMMAND ñeán öùng duïng vôùi tham soá wParam chöùa soá hieäu (ID) cuûa
       Naïp menu resource vaøo boä nhôù:                                                   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öû
       HMENU LoadMenu (                                                                    lyù mesage ñeàu coù theå ñaûm nhaän vieäc xöû lyù caùc message naøy.
           HINSTANCE hInstance,             // Handle cuûa öùng duïng                           Tieáp theo, ta xaây döïng öùng duïng vôùi heä thoáng menu nhö VD13. Muïc choïn
           LPCTSTR lpMenuName               // Chuoãi teân resource cuûa menu                   About hieån thò hoäp thoâng baùo giôùi thieäu taùc giaû vaø saûn phaåm.
       ); Haøm traû veà handle cuûa menu trong boä nhôù.
                                                                                                   Taïo döï aùn VD14 nhö VD13.
       - Giaù trò handle cuûa öùng duïng nhaän ñöôïc töø haøm sau:
                                                                                                   Duøng lôùp CEmpWnd caøi ñaët
           HINSTANCE AfxGetInstanceHandle( );
                                                                                                   muïc xöû lyù message:
       - Moãi ñoái töôïng trong resource ñöôïc nhaän dieän baèng moät soá hieäu hoaëc
                                                                                                   - Trong maøn hình Workspace,
           chuoãi teân. Haøm sau ñaây giuùp chuyeån soá hieäu cuûa ñoái töôïng resource
                                                                                                      choïn ClassView. Right-click
           sang chuoãi teân töông öùng:
                                                                                                      treân tieâu ñeà lôùp CEmpWnd:
           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ïn Add Windows Message Handler...
       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;                                                                              - Choïn soá hieäu ID_GAME_ABOUT, click choïn COMMAND. Sau ñoù
       } // Xem VD13 (heä thoáng menu chöa coù xöû lyù)                                              choïn muïc Add and Edit.
Menu & Phím taét                                                                     71    72    Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
- 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.
       - Ñaët teân haønh vi xöû lyù message WM_COMMAND. Choïn OK.                             • Xoùa ñònh nghóa phím taét: Choïn doøng ñònh nghóa phím, goõ phím Del.
       - Noäi dung caøi ñaët cuûa haønh vi naøy nhö sau:                                      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.
         void CEmpWnd::OnGameAbout()                                                          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ôù:
            MessageBox( "The program was written by Mr.EMPn"                                     HACCEL LoadAccelerators (
                         "This product is a not-licensed one.",                                       HINSTANCE hInstance, // Handle cuûa öùng duïng
                         "About",                                                                     LPCTSTR lpTableName // Chuoãi teân resource
                         MB_OK | MB_ICONINFORMATION );                                            ); 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:
       Xem baûng MessageMap cuûa lôùp CEmpWnd, muïc ID_GAME_ABOUT ?                               int TranslateAccelerator (
7.5 PHÍM TAÉT (HOT KEY) CHO MUÏC CHOÏN TREÂN MENU:                                                    HWND hWnd,                // Handle cöûa soå giao dieän duøng phím taét
    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                 HACCEL hAccTable, // Handle cuûa baûng phím taét
treân heä thoáng menu. Caùc phím taét ñöôïc ñònh nghóa trong phaàn resource cuûa                      LPMSG lpMsg               // Con troû bieán chöùa message ñieàu phoái
öùng duïng. Chöông trình seõ duøng leänh ñeå naïp baûng phím taét khi caàn.                       ); Haøm naøy phaûi ñöôïc thöïc hieän treân taát caû caùc message maø öùng
    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,              duïng nhaän ñöôïc. Do ñoù, noù ñöôïc loàng vaøo voøng laëp MessageLoop
    Ctrl+P, Ctrl+A vaø Ctrl+E cho caùc muïc menu: Start, Option, About vaø Exit.                  cuûa öùng duïng. Lôùp CWinThread (xem 2.4) cho pheùp caøi ñaët ñaëc tính
       Taïo döï aùn VD15 töông töï VD14.                                                          naøy thoâng qua haønh vi sau cuûa lôùp:
       Taïo môùi baûng phím taét trong resource (Accelerator resource): Thöïc                         BOOL CWinThread::PreTranslateMessage( MSG *pMsg );
       hieän töông töï vieäc taïo môùi icon (2.8). Resource Type = Accelerator.                   Trong caùc lôùp keá thöøa CWinThread, caøi ñaët naøy coù boá cuïc nhö sau:
       Ñaët soá hieäu cho Accelerator ( giaû söû laø IDR_MAINFRAME ).                             BOOL CEmpApp::PreTranslateMessage (MSG *pMsg)
       Thieát keá baûng phím taét. Caùc thao taùc cô baûn nhö sau:                                { // CEmpApp laø lôùp keá thöøa CWinApp (töø CWinThread)
       • Boå sung ñònh nghóa phím taét: Double-click treân doøng roãng:                             // 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:

Menu & Phím taét                                                                  73    74   Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
- Thuoäc tính m_hAccel kieåu HACCEL löu handle baûng phím taét.                        UINT nCheck                      // Caùch thöùc ñaùnh daáu muïc choïn
           - Haønh vi InitInstance: Boå sung leänh naïp baûng phím taét vaø giöõ giaù         ); Ñaùnh daáu hoaëc huûy boû ñaùnh daáu muïc choïn treân menu.
             trò handle cuûa noù vaøo bieán m_hAccel ñeå söû duïng sau naøy:                  nCheck laø giaù trò keát hôïp cuûa hai noäi dung:
               m_hAccel = LoadAccelerators( AfxGetInstanceHandle(),                           - Caùch ñaùnh daáu muïc: = MF_CHECKED                        : Ñaùnh daáu
                            MAKEINTRESOURCE( IDR_MAINFRAME ) );                                                            = MF_UNCHECKED : Boû ñaùnh daáu
                                                                                              - Caùch chæ ñònh muïc: = MF_BYPOSITION                       : Theo vò trí
           - Haønh vi keá thöøa PreTranslateMessage coù caøi ñaët nhö treân.
                                                                                                                           = MF_BYCOMMAND : Theo soá hieäu muïc
7.6 LÔÙP QUAÛN LYÙ MENU - CMenu:                                                              nIDCheckItem töông öùng chöùa soá hieäu hoaëc vò trí cuûa muïc choïn.
   Ñeå tieän thao taùc treân menu, MFC cung caáp lôùp ñoái töôïng CMenu cho pheùp             UINT EnableMenuItem (
quaûn lyù menu thoâng qua caùc thuoäc tính vaø haønh vi ñaëc tröng sau:                           UINT nIDEnableItem,              // Soá hieäu | vò trí muïc choïn (nhö treân)
       CMenu( ); Haønh vi taïo laäp ñoái töôïng menu.                                             UINT nEnable                     // Caùch thöùc aán ñònh muïc choïn.
       BOOL LoadMenu( UINT nIDResource ); Khôûi taïo thoâng soá cho ñoái                      ); Caám hoaëc cho pheùp muïc choïn hoaït ñoäng.
       töôïng menu töø menu resource.                                                         nIDEnableItem laø giaù trò keát hôïp cuûa hai noäi dung:
       BOOL DestroyMenu( ); Huûy boû ñoái töôïng menu.                                        - Caùch ñònh vò muïc choïn: Nhö treân.
       BOOL DeleteMenu( UINT nPosition, UINT nFlags ); Xoùa moät muïc                         - Traïng thaùi muïc: = MF_ENABLED : Cho pheùp muïc hoaït ñoäng.
       choïn trong menu. Boä giaù trò (nPosition, nFlags) xaùc ñònh muïc choïn.                                       = MF_DISABLED : Caám muïc hoaït ñoäng.
       nFlags = MF_BYCOMMAND : nPosition laø soá hieäu cuûa muïc choïn                                                = MF_GRAYED : Che môø muïc choïn.
                                              (menu-ID).                                      int GetMenuString (
                = MF_BYPOSITION : nPosition laø vò trí thöù töï cuûa muïc                         UINT nIDItem,                        // Soá hieäu muïc choïn
                                              choïn (ñeám töø 0).                                 CString& rString,                    // Tham bieán nhaän keát quaû
       BOOL AppendMenu (                                                                          UINT nFlags                          // Caùch ñònh vò muïc choïn
           UINT nFlags,                               // Ñaëc ñieåm muïc choïn                ); Laáy noäi dung thoâng baùo cuûa moät muïc choïn.
           UINT nIDNewItem = 0,                       // Soá hieäu muïc choïn                 BOOL ModifyMenu (
           LPCTSTR lpszNewItem=NULL                   // Chuoãi thoâng baùo cuûa muïc             UINT nPosition,                      // Soá hieäu | vò trí cuûa muïc choïn
       ); Theâm muïc choïn vaøo cuoái heä thoáng menu.                                            UINT nFlags,                         // Caùch ñònh vò muïc choïn
       nFlags = MF_SEPARATOR : Caùc tham soá khaùc khoâng coù yù nghóa.                           UINT nIDNewItem = 0,                 // Soá hieäu | vi trí môùi cuûa muïc choïn
                = MF_STRING : Caùc thoâng soá ñöôïc hieåu nhö treân.                              LPCTSTR lpszNewItem = NULL // Thoâng baùo môùi cuûa muïc choïn
                = MF_POPUP : nIDNewItem laø handle cuûa menu popup.                           ); Thay ñoåi caùc thoâng soá lieân quan ñeán muïc choïn.
       BOOL InsertMenu (                                                                    Löu yù: Haønh vi GetMenu cuûa CWnd traû veà con troû ñeán ñoái töôïng menu
           UINT nPosition,                        // Vò trí ñöôïc cheøn.                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.
           UINT nFlags,                           // Caùc thoâng tin khaùc
                                                                                           Giaû söû coù yeâu caàu vieát öùng duïng VD16 töông töï VD15; trong ñoù muïc choïn
           UINT nIDNewItem = 0,                   // töông töï AppendMenu().
                                                                                           Start töï ñoäng chuyeån thaønh Stop vaø ngöôïc laïi moãi khi ngöôøi duøng choïn
           LPCTSTR lpszNewItem = NULL
                                                                                           muïc naøy. Coâng vieäc treân ñöôïc thöïc hieän thoâng qua muïc xöû lyù command
       ); Cheøn theâm muïc choïn vaøo tröôùc muïc ñöôïc chæ bôûi nPosition.
                                                                                           message ID_GAME_START. Baïn haõy thöû thöïc hieän öùng duïng naøy (xem
       UINT CheckMenuItem (
                                                                                           VD16).
           UINT nIDCheckItem,             // Soá hieäu | vò trí muïc choïn
                                                                                        7.7 XÖÛ LYÙ ÑIEÀU KHIEÅN MUÏC CHOÏN CUÛA MENU:
Menu & Phím taét                                                                  75    76   Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
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.




Menu & Phím taét                                                                     77
CHÖÔNG 8:                                                                                                        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.
                     Caùc lôùp ñoái Töôïng nhaäp lieäu                                                       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:
    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
                                                                                                                 SS_BITMAP : Coù chöùc naêng hieån thò aûnh bitmap.
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
                                                                                                                 SS_ICON           : Coù chöùc naêng hieån thò aûnh icon hoaëc cursor.
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:
                                                                                                                 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
8.1 CStatic:                                                                                             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
   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                is", muïc thöù hai hieån thò icon cuûa öùng duïng.
dieän. Caùc thuoäc tính vaø haønh vi ñaëc tröng cuûa lôùp naøy nhö sau:                                      Duøng hai ñoái töôïng thuoäc lôùp CStatic ñeå taïo vaø quaûn lyù hai muïc thoâng
       CStatic( ); Taïo laäp ñoái töôïng roãng.                                                              baùo. Ñoái töôïng CEmpWnd laáy chuùng laøm thuoäc tính ñeå tieän quaûn lyù.
       BOOL Create (                                                                                     Döï aùn ñöôïc thöïc hieän qua caùc böôùc sau:
           LPCTSTR lpszText,            // Noäi dung thoâng baùo cuûa muïc                                   Taïo döï aùn VD18 töông töï VD15. Chænh söûa lôùp CEmpWnd nhö sau:
           DWORD dwStyle,               // Thoâng soá daïng muïc thoâng baùo                                 Boå sung hai ñoái töôïng thuoäc tính protected: m_staticIcon vaø
           const RECT& rect,            // Toïa ñoä, kích thöôùc cuûa muïc                                   m_staticText coù kieåu CStatic.
           CWnd* pParentWnd,            // Con troû ñoái töôïng cöûa soå cha                                 Haønh vi OnCreate thöïc hieän khôûi taïo thoâng soá cho hai ñoái töôïng naøy:

78   Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Caùc lôùp ñoái töôïng nhaäp lieäu                                                    79
int CEmpWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)                                                   void SetMargins (
       {                                                                                                          UINT nLeft,               // Leà traùi vaø
           if (CWnd::OnCreate(lpCreateStruct) == -1)                                                              UINT nRight               // leà phaûi tính baèng pixel
               return -1;                                                                                     ); AÁn ñònh bieân traùi vaø bieân phaûi cuûa hoäp nhaäp.
           m_staticText.Create( _T("This is my Icon:"),
                                                                                                              DWORD GetMargins( ); Traû veà giaù trò chöùa thoâng tin bieân traùi (WORD
                                     WS_CHILD|WS_VISIBLE,
                                     CRect(10, 15, 120, 35), this );                                          thaáp) vaø bieân phaûi (WORD cao) cuûa hoäp nhaäp.
           m_staticIcon.Create( _T(""),                                                                       void GetSel (
                                     WS_CHILD | WS_VISIBLE | SS_ICON,                                             int& nStartChar,          // Bieán chöùa vò trí kyù töï ñaàu tieân vaø
                                     CRect( 125,7,157,39 ), this );                                               int& nEndChar             // kyù töï cuoái cuøng cuûa ñoaïn vaên baûn.
           m_staticIcon.SetIcon (                                                                             ); Laáy thoâng tin veà ñoaïn vaên baûn ñang ñöôïc ñaùnh daáu trong hoäp nhaäp.
                               AfxGetApp()->LoadIcon(IDR_MAINFRAME) );                                        void SetSel (
           return 0;                                                                                              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
       Bieân dòch vaø chaïy thöû öùng duïng.                                                                      BOOL bNoScroll = FALSE
8.2 CEdit:                                                                                                    ); Ñaùnh daáu moät ñoaïn vaên baûn trong hoäp nhaäp.
    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                   BOOL SetReadOnly( BOOL bReadOnly = TRUE ); Xaùc laäp traïng thaùi
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å                   chæ xem ñoái vôùi döõ lieäu cuûa hoäp nhaäp.
cha cuûa hoäp nhaäp veà tình hình nhaäp lieäu ñang dieãn ra trong hoäp.                                       void Copy( ); Cheùp noäi dung ñoaïn vaên baûn ñang ñöôïc ñaùnh daáu trong
        CEdit( ); Taïo laäp ñoái töôïng roãng.                                                                hoäp nhaäp vaøo vuøng nhôù heä thoáng (clipboard).
        BOOL Create (                                                                                         void Paste( ); Cheøn noäi dung vaên baûn trong clipboard vaøo hoäp nhaäp baét
            DWORD dwStyle,                // Thoâng soá daïng hoäp nhaäp                                      ñaàu töø vò trí ñang choïn (hoaëc vò trí daáu carret).
            const RECT& rect,             // Toïa ñoä vaø kích thöôùc hoäp nhaäp                              void Clear( ); Xoùa noäi dung ñoaïn vaên baûn ñang ñöôïc ñaùnh daáu.
            CWnd* pParentWnd,             // Con troû ñoái töôïng cöûa soå cha                                void Cut( ); Thöïc hieän caùc thao taùc Copy vaø Clear.
            UINT nID                      // Soá hieäu hoäp nhaäp, phaûi duy nhaát                            void SetPasswordChar (
        ); Khôûi taïo thoâng soá cho ñoái töôïng hoäp nhaäp lieäu.                                                TCHAR ch                  // Kyù töï ñöôïc choïn
        dwStyle: Goàm thoâng soá qui ñònh ñoái vôùi control vaø caùc daïng boå sung:                          ); Ñaët kyù töï ‘che’ cho noäi dung cuûa password trong hoäp nhaäp.
            ES_MULTILINE : Hoäp nhaäp cho pheùp nhieàu doøng.                                                 int GetLineCount( ); Traû veà soá doøng vaên baûn trong hoäp nhaäp.
            ES_PASSWORD : Hoäp nhaäp duøng nhaäp password.                                                    int GetLine (
            ES_READONLY : Hoäp nhaäp chæ xem noäi dung.                                                           int nIndex,               // Chæ soá doøng vaên baûn trong hoäp nhaäp
            ES_xxx                 : Xem thoâng tin trong MSDN.                                                   LPTSTR lpszBuffer, // Vuøng ñeäm chöùa keát quaû
        void GetRect (                                                                                            int nMaxLength            // Chieàu daøi vuøng ñeäm
            LPRECT lpRect             // Con troû ñeán bieán RECT chöùa keát quaû                             ); Laáy noäi dung moät doøng vaên baûn trong hoäp nhaäp.
        ); Laáy thoâng tin veà toïa ñoä, kích thöôùc hoäp nhaäp.                                              int GetFirstVisibleLine( ); Traû veà chæ soá doøng vaên baûn ñöôïc nhìn thaáy
        BOOL GetModify( ); Traû veà TRUE neáu noäi dung hoäp nhaäp thay ñoåi.                                 ñ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
        void SetModify( BOOL bModified = TRUE ); Xaùc laäp hoaëc xoùa côø                                     laø bò che khuaát.
        hieäu ghi nhaän söï thay ñoåi noäi dung trong hoäp nhaäp.

80   Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Caùc lôùp ñoái töôïng nhaäp lieäu                                                     81
int LineFromChar (                                                                                Thöïc haønh 1: Vieát öùng duïng vôùi muïc thoâng baùo "Enter your name:" vaø hoäp
            int nIndex = -1            // Chæ soá kyù töï. –1 laø kyù töï cuoái cuøng.                    nhaäp döõ lieäu beân caïnh treân maøn hình giao dieän chính.
        ); Traû veà chæ soá doøng vaên baûn chöùa kyù töï (Hoäp nhaäp coù nhieàu doøng).                     Taïo döï aùn VD19 töông töï VD18. Chænh söûa CEmpWnd nhö sau:
        int LineIndex (                                                                                      Boå sung hai thuoäc tính protected: m_staticName kieåu CStatic vaø
            int nLine = -1             // Chæ soá doøng vaên baûn, -1 laø doøng cuoái cuøng                  m_editName kieåu CEdit.
        ); Traû veà chæ soá cuûa kyù töï ñaàu tieân trong doøng vaên baûn laøm tham soá.                     Trong haønh vi OnCreate, thöïc hieän khôûi taïo hai ñoái töôïng naøy:
        int LineLength (                                                                                       int CEmpWnd::OnCreate (LPCREATESTRUCT lpCreateStruct)
            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.                                              if (CWnd::OnCreate(lpCreateStruct) == -1)
        CPoint PosFromChar (                                                                                           return -1;
            UINT nChar                 // Chæ soá kyù töï trong hoäp nhaäp                                         m_staticName.Create( _T("Enter your name:" ),
        ); Traû veà toïa ñoä ñieåm ôû goùc traùi treân cuûa kyù töï.                                                                     WS_CHILD | WS_VISIBLE,
        int CharFromPos (                                                                                                                CRect(10, 75, 130, 95), this );
                                                                                                                   m_editName.Create( WS_CHILD | WS_VISIBLE | WS_BORDER,
            CPoint pt                  // Toïa ñoä cuûa ñieåm
                                                                                                                                        CRect(135, 75, 280, 95), this, -1 );
        ); Traû veà chæ soá cuûa kyù töï gaàn ñieåm ñang xeùt nhaát.                                               return 0;
        void LineScroll (                                                                                      }
            int nLines,                // Soá doøng cuoän doïc, < 0 laø cuoän xuoáng.
                                                                                                          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
            int nChars = 0             // Soá kyù töï cuoän ngang, < 0 laø cuoän traùi.
                                                                                                          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.
        ); Cuoän noäi dung vaên baûn ñang hieån thò trong hoäp nhaäp.
                                                                                                          HD: Cöûa soå cha coù haønh vi xöû lyù message thoâng baùo söï thay ñoåi döõ lieäu
     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                  trong hoäp nhaäp thoâng qua muïc xöû lyù message ON_EN_CHANGE.
     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                      Taïo döï aùn VD20 töông töï VD19, Chænh söûa lôùp CEmpWnd nhö sau:
     xöû lyù caùc message thoâng qua muïc xöû lyù message coù daïng nhö sau:                                 Boå sung haønh vi xöû lyù: afx_msg void OnYourNameChange()
         ON_Notification ( ID, memberFxn )
                                                                                                               void CEmpWnd::OnYourNameChange ()
     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:                               CString yourname;
                      afx_msg void memberFxn( void );                                                             m_editName.GetWindowText(yourname);
     ON_Notification coù theå laø moät trong caùc muïc xöû lyù cuï theå sau:                                      SetWindowText(yourname);
          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.                                       Taïo môùi soá hieäu resource: IDC_YOURNAME, duøng giaù trò naøy laøm soá
         ON_EN_HSCROLL                    Ngöôøi duøng click choïn thanh tröôït ngang.                         hieäu cho ñoái töôïng m_editName. Trong haønh vi OnCreate:
         ON_EN_VSCROLL                    Ngöôøi duøng click choïn thanh tröôït doïc.                          int CEmpWnd::OnCreate ( LPCREATESTRUCT lpCreateStruct )
         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.                              if (CWnd::OnCreate(lpCreateStruct) == -1) return -1;
         ON_EN_SETFOCUS                   Edit baét ñaàu hoaït ñoäng.                                              m_staticName.Create ( _T("Enter your name:"),
         ON_EN_UPDATE                     Döõ lieäu nhaäp ñang ñöôïc caäp nhaät cho edit.                                                 WS_CHILD | WS_VISIBLE,
                                                                                                                                          CRect( 10, 75, 130, 95 ), this );
82    Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Caùc lôùp ñoái töôïng nhaäp lieäu                                                   83
m_editName.Create( WS_CHILD | WS_VISIBLE | WS_BORDER,                                        Thöïc haønh 1: Vieát öùng duïng nhö VD19. Boå sung nuùt choïn "Nhap xong",
                       CRect( 135, 75, 280, 95 ), this, IDC_YOURNAME );                                   maø khi choïn, seõ duøng hoäp thoâng baùo ñeå hieån thò noäi dung vöøa nhaäp.
             return 0;                                                                                       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()
        Trong baûng MessageMap, boå sung muïc xöû lyù message:                                                 void CEmpWnd::OnClickNhapxong ()
        BEGIN_MESSAGE_MAP(CEmpWnd, CWnd)                                                                       {
          //{{AFX_MSG_MAP(CEmpWnd)                                                                                CString yourname;
          ON_WM_CREATE()                                                                                          m_editName.GetWindowText( yourname );
          ON_WM_DESTROY()              Muïc boå sung                                                              MessageBox ( yourname, "Hello !",
          ON_WM_PAINT()                                                                                                         MB_OK | MB_ICONEXCLAMATION );
          //}}AFX_MSG_MAP                                                                                      }
          ON_EN_CHANGE( IDC_YOURNAME, OnYourNameChange )                                                       Khai baùo ID resource: IDC_NHAPXONG, boå sung ñoái töôïng thuoäc tính
        END_MESSAGE_MAP()
                                                                                                               protected m_buttonNhapxong kieåu CButton. Trong OnCreate:
8.3 CButton:                                                                                                   int CEmpWnd::OnCreate( LPCREATESTRUCT lpCreateStruct )
   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.                                            if (CWnd::OnCreate(lpCreateStruct) == -1)
      CButton( ); Taïo laäp ñoái töôïng nuùt choïn roãng.                                                              return -1;
      BOOL Create (                                                                                                m_staticName.Create( _T("Enter your name:"),
          LPCTSTR lpszCaption, // Noäi dung thoâng baùo                                                                                    WS_CHILD | WS_VISIBLE,
                                                                                                                                           CRect(10, 75, 130, 95), this );
          DWORD dwStyle,               // Thoâng soá daïng nuùt (BS_PUSHBUTTON)
                                                                                                                   m_editName.Create( WS_CHILD | WS_VISIBLE | WS_BORDER,
          const RECT& rect,            // Toïa ñoä, kích thöôùc nuùt choïn                                                                   CRect( 135, 75, 280, 95 ), this, -1 );
          CWnd* pParentWnd,            // Con troû cöûa soå cha                                                    m_buttonNhapxong.Create (
          UINT nID                     // Soá hieäu nuùt choïn                                                                    _T("Nhap xong"), WS_CHILD | WS_VISIBLE,
      ); Khôûi taïo thoâng soá cho ñoái töôïng nuùt choïn.                                                                        CRect(10, 115, 90, 140), this, IDC_NHAPXONG );
      HBITMAP GetBitmap( ) const ; Handle cuûa aûnh bitmap ñang duøng.                                             return 0;
      HBITMAP SetBitmap(HBITMAP hBitmap); Gaén aûnh bitmap vaøo nuùt.                                          }
      HICON GetIcon( ) const; Handle cuûa icon ñang duøng.                                                     Trong baûng MessageMap cuûa CEmpWnd, boå sung muïc xöû lyù message:
      HICON SetIcon( HICON hIcon ); Gaén icon vaøo nuùt.
      virtual void DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct );                                              ON_BN_CLICKED ( IDC_NHAPXONG , OnClickNhapxong )
      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.                 8.4 CListBox:
     Muïc ON_Notification maø cöûa soå cha duøng xöû lyù message töø nuùt choïn laø:                      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
               Muïc xöû lyù message                YÙ nghóa cuûa message ñöôïc xöû lyù
                                                                                                      pheùp ñaùnh daáu choïn moät hoaëc nhieàu muïc ñoàng thôøi trong listbox.
            ON_BN_CLICKED                         Ngöôøi duøng click treân nuùt.
                                                                                                             CListBox( ); Taïo laäp ñoái töôïng roãng.
            ON_BN_DOUBLECLICKED                   Ngöôøi duøng double-click treân nuùt

84    Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Caùc lôùp ñoái töôïng nhaäp lieäu                                                    85
BOOL Create (                                                                                           virtual void DrawItem (
          DWORD dwStyle,               // Thoâng soá aán ñònh daïng listbox                                       LPDRAWITEMSTRUCT lpDrawItemStruct
          const RECT& rect,            // Toïa ñoä, kích thöôùc cuûa listbox                                  ); Haønh vi keá thöøa nhaèm thöïc hieän trang trí caùc muïc theo caùch rieâng.
          CWnd* pParentWnd,            // Con troû ñoái töôïng cöûa soå cha                                   virtual void MeasureItem (
          UINT nID                     // Soá hieäu cuûa listbox                                                  LPMEASUREITEMSTRUCT lpMeasureItemStruct
      ); Khôûi taïo thoâng soá cho ñoái töôïng ListBox.                                                       ); Laáy thoâng tin laøm cô sôû cho vieäc töï trang trí caùc muïc trong listbox.
      dwStyle: Goàm thoâng soá qui ñònh ñoái vôùi control vaø caùc daïng boå sung:                            virtual void DeleteItem (
          LBS_MULTIPLESEL : Cho pheùp choïn nhieàu muïc ñoàng thôøi                                               LPDELETEITEMSTRUCT lpDeleteItemStruct
          LBS_NOTIFY                   : Thoâng tin cho cöûa soå cha                                          ); Haønh vi keá thöøa ñeå tuøy nghi xöû lyù khi moät muïc bò xoùa khoûi listbox.
          LBS_SORT                     : Caùc muïc ñöôïc xeáp thöù töï                                        virtual int VKeyToItem (
          LBS_MULTICOLUMN : Coù nhieàu coät chöùa caùc muïc                                                       UINT nKey,                   // Maõ phím (virtual key) ñöôïc goõ
          LBS_STANDARD                 : = LBS_NOTIFY | LBS_SORT                                                  UINT nIndex                  // Chæ soá muïc hieän haønh trong listbox
      int GetCount( ); Traû veà soá muïc choïn trong Listbox.                                                 ); Haønh vi keá thöøa cho pheùp tuøy nghi xöû lyù treân phím.
      int GetCurSel( ); Traû veà chæ soá cuûa muïc ñöôïc choïn (single).                                      virtual int CharToItem (
      int SetCurSel (                                                                                             UINT nKey,                   // Maõ phím (character) ñöôïc goõ
          int nSelect                  // Chæ soá muïc ñöôïc choïn                                                UINT nIndex                  // Chæ soá muïc hieän haønh trong listbox
      ); AÁn ñònh muïc choïn trong listbox.                                                                   ); Haønh vi keá thöøa cho pheùp tuøy nghi xöû lyù phím kyù töï.
      int GetSelCount( ); Traû veà soá muïc ñöôïc choïn trong moät listbox. Chæ
                                                                                                         ListbBox vaø cöûa soå cha: ListBox vôùi thoâng soá daïng LBS_NOTIFY coù theå
      duøng cho listbox cho pheùp choïn nhieàu muïc.
                                                                                                         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ù.
      int GetSelItems (
                                                                                                         Muïc ON_Notification maø cöûa soå cha duøng xöû lyù message töø listbox laø:
          int nMaxItems,               // Soá muïc ñöôïc choïn vaø
          LPINT rgIndex                // maûng chöùa caùc chæ soá cuûa chuùng                                   Muïc xöû lyù message              YÙ nghóa cuûa message ñöôïc xöû lyù
      ); Laáy chæ soá cuûa caùc muïc ñöôïc choïn trong listbox.                                                ON_LBN_DBLCLK                     Ngöôøi duøng double-click treân listbox.
      int AddString (                                                                                          ON_LBN_KILLFOCUS                  Keát thuùc hoaït ñoäng nhaäp.
          LPCTSTR lpszItem             // Thoâng baùo cuûa muïc                                                ON_LBN_SELCANCEL                  Huûy boû thao taùc choïn.
      ); Theâm moät muïc vaøo listbox. Neáu listbox khoâng coù ñaëc tính xeáp thöù töï                         ON_LBN_SELCHANGE                  Thay ñoåi muïc choïn trong listbox.
      thì muïc môùi theâm ñöôïc ñaët vaøo cuoái danh saùch caùc muïc.                                          ON_LBN_SETFOCUS                   Baét ñaàu nhaäp lieäu treân listbox.
      int DeleteString (                                                                                       ON_WM_CHARTOITEM                  Duøng cho ownerDraw listbox.
          UINT nIndex                  // Chæ soá cuûa muïc bò xoùa                                            ON_WM_VKEYTOITEM                  Xöû lyù WM_KEYDOWN
      ); Xoùa moät muïc trong listbox.                                                                   Thöïc haønh: Vieát öùng duïng töông töï VD21, theâm listbox coù ba muïc choïn:
      int InsertString (                                                                                 "Ong A", "Ba B" vaø "Co C". Khi ngöôøi duøng click choïn moät muïc trong
          int nIndex,                  // Vò trí cheøn, -1 laø vò trí cuoái listbox                      listbox thì noäi dung cuûa muïc aáy ñöôïc ñieàn vaøo hoäp nhaäp Name.
          LPCTSTR lpszItem             // Thoâng baùo cuûa muïc                                          HD: Duøng ON_LBN_SELCHANGE ñònh höôùng xöû lyù message lieân quan.
      ); Cheøn moät muïc vaøo listbox taïi vò trí xaùc ñònh.
                                                                                                              Taïo öùng duïng VD22 nhö VD21. Chænh söûa lôùp CEmpWnd nhö sau:
      void ResetContent( ); Xoùa taát caû caùc muïc hieän coù trong listbox, laøm
                                                                                                              Boå sung haønh vi protected: afx_msg void OnSelectDanhsach()
      roãng noäi dung listbox quaûn lyù bôûi ñoái töôïng.
                                                                                                              void CEmpWnd::OnSelectDanhsach()
86   Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Caùc lôùp ñoái töôïng nhaäp lieäu                                                           87
{                                                                                                       BOOL Create (
          CString info;                                                                                           DWORD dwStyle,               // Chöùa thoâng soá veà daïng cuûa comboBox
          int iSel = m_listboxDanhsach.GetCurSel();                                                               const RECT& rect,            // Toïa ñoä, kích thöôùc comboBox
          if (iSel == LB_ERR)           // Khoâng coù löïa choïn                                                  CWnd* pParentWnd,            // Con troû ñoái töôïng cöûa soå cha
               iSel = 0;                // Xem nhö choïn muïc ñaàu tieân                                          UINT nID                     // Soá hieäu comboBox
          m_listboxDanhsach.GetText( iSel, info );                                                            ); Khôûi taïo thoâng soá cho ñoái töôïng comboBox.
          m_editName.SetWindowText( info );
                                                                                                              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.
      Khai baùo ID resource: IDC_DANHSACH, thuoäc tính protected                                                  CBS_SIMPLE                       : Simple comboBox.
      m_listboxDanhsach kieåu CLisBox quaûn lyù listbox.                                                          CBS_DROPDOWN                     : Drop-Down comboBox.
      Haønh vi OnCreate thöïc hieän caùc khôûi taïo caàn thieát cho listbox.                                      CBS_SORT                         : Danh saùch caùc muïc xeáp thöù töï.
      int CEmpWnd::OnCreate( LPCREATESTRUCT lpCreateStruct )                                                  int GetCount( ); Traû veà soá muïc choïn trong comboBox.
      {                                                                                                       int GetCurSel( ); Traû veà chæ soá muïc ñöôïc choïn trong comboBox.
          if (CWnd::OnCreate(lpCreateStruct) == -1) return -1;                                                int SetCurSel( int nSelect ); AÁn ñònh muïc choïn trong comboBox.
          ...           // Thöïc hieän töông töï döï aùn VD21,                                                void GetLBText (
                        // Vaø boå sung caùc noäi dung sau:                                                       int nIndex,                  // Chæ soá muïc trong comboBox
          m_listboxDanhsach.Create (                                                                              CString& rString             // Bieán chöùa keát quaû
                    WS_CHILD | WS_VISIBLE | WS_BORDER |                                                       ); Laáy noäi dung thoâng baùo cuûa moät muïc trong comboBox.
                    LBS_NOTIFY | WS_VSCROLL,                                                                  void ShowDropDown (
                    CRect( 195, 7, 280, 65 ), this, IDC_DANHSACH );                                               BOOL bShowIt = TRUE              // TRUE = hieån thò ; FALSE = daáu
          m_listboxDanhsach.AddString( "Ong A" );                                                             ); Hieån thò hoaëc danh saùch chöùa caùc muïc hoã trôï trong comboBox.
          m_listboxDanhsach.AddString( "Ba B" );                                                              int AddString(LPCTSTR lpszString ); Nhö listbox.
          m_listboxDanhsach.AddString( "Co C" );
                                                                                                              int DeleteString( UINT nIndex ); Nhö listbox.
          return 0;
                                                                                                              int InsertString( int nIndex , LPCTSTR lpszString ); Nhö listbox.
      }
                                                                                                              void ResetContent( ); Nhö listbox.
      Trong MessageMap cuûa CEmpWnd, boå sung muïc xöû lyù message:                                           virtual void DrawItem (
      ON_LBN_SELCHANGE( IDC_DANHSACH, OnSelectDanhsach )                                                          LPDRAWITEMSTRUCT lpDrawItemStruct
                                                                                                              ); Nhö listbox.
8.5 CComboBox:                                                                                                virtual void MeasureItem (
    CComboBox laø lôùp ñoái töôïng quaûn lyù hoäp nhaäp vaø phaàn hoã trôï nhaäp vôùi                             LPMEASUREITEMSTRUCT lpMeasureItemStruct
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                         ); Nhö listbox.
saùch hoã trôï taïo thaønh caùc daïng khaùc nhau cuûa comboBox:                                               virtual void DeleteItem (
    - Drop-list         : Giaù trò nhaäp chæ ñöôïc choïn töø danh saùch.                                          LPDELETEITEMSTRUCT lpDeleteItemStruct
    - Simple            : Nhö Drop-list maø danh saùch hieån thò thöôøng tröïc.                               ); Nhö listbox.
    - 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.

88   Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Caùc lôùp ñoái töôïng nhaäp lieäu                                                       89
ComboBox vaø cöûa soå cha: Ñoái töôïng comboBox coù theå göûi message ñeán                                    ...                 // Nhö VD22, boå sung caùc noäi dung sau:
     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                             m_Combobox.Create (
     ON_Notification maø cöûa soå cha duøng xöû lyù message töø comboBox laø:                                                             WS_CHILD | WS_VISIBLE | WS_BORDER |
                                                                                                                                            CBS_DROPDOWNLIST,
            Muïc xöû lyù message                    YÙ nghóa cuûa message ñöôïc xöû lyù                                           CRect( 135, 100, 280, 225 ), this,
         ON_CBN_CLOSEUP                           Danh saùch vöøa ñöôïc ñoùng laïi                                                IDC_COMBOBOX );
         ON_CBN_DBLCLK                            Double-click treân muïc choïn                                    m_Combobox.AddString( "Vo van A" );
         ON_CBN_DROPDOWN                          Danh saùch vöøa ñöôïc môû ra                                     m_Combobox.AddString( "Nguyen thi B" );
         ON_CBN_EDITCHANGE                        Noäi dung hoäp nhaäp ñang thay ñoåi                              m_Combobox.AddString( "Tran thi C" );
                                                                                                                   return 0;
         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                       Trong MessageMap cuûa CEmpWnd, khai baùo muïc xöû lyù message:
         ON_CBN_KILLFOCUS                         Keát thuùc nhaäp lieäu trong comboBox                        ON_CBN_SELCHANGE( IDC_COMBOBOX,OnSelectCombobox )
         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                8.6 CSpinButtonCtrl:
     Thöïc haønh: Vieát öùng duïng töông töï VD22, Boå sung combobox kieåu                               CSpinButtonCTrl laø lôùp ñoái töôïng quaûn lyù nuùt taêng-giaûm treân cöûa soå giao
     dropdown coù ba muïc choïn: "Vo van A", "Nguyen thi B" vaø "Tran thi C".                         dieän. Nuùt taêng-giaûm ñöôïc duøng hoã trôï cho caùc hoäp nhaäp soá nguyeân.
     Khi choïn treân combobox, noäi dung choïn ñöôïc ñieàn vaøo hoäp nhaäp Name.                             CSpinButtonCtrl( ); Taïo laäp ñoái töôïng roãng.
     HD: Duøng ON_CBN_SELCHANGE ñònh höôùng xöû lyù message lieân quan.                                      BOOL Create (
        Taïo döï aùn VD23 töông töï VD22. Chænh söûa lôùp CEmpWnd nhö sau:                                        DWORD dwStyle,               // Chöùa thoâng soá daïng nuùt taêng giaûm
        Boå sung haønh vi protected: afx_msg void OnSelectCombobox ()                                             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
        void CEmpWnd::OnSelectCombobox()                                                                          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.
           CString info;
           int iSel = m_Combobox.GetCurSel( );                                                               dwStyle: Goàm thoâng soá qui ñònh ñoái vôùi control vaø caùc daïng boå sung:
           if (iSel == LB_ERR)                 // no selection                                                    UDS_HORZ                     : Hai nuùt taêng-giaûm naèm ngang
                iSel = 0;                                                                                         UDS_SETBUDDYINT : Duøng cho hoäp nhaäp soá nguyeân.
           m_Combobox.GetLBText( iSel, info );                                                                    UDS_ALIGNRIGHT               : Naèm beân phaûi hoäp nhaäp.
           m_editName.SetWindowText( info );                                                                      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.
        Khai baùo ID resource: IDC_COMBOBOX. Khai baùo ñoái töôïng thuoäc                                    CWnd* SetBuddy (
        tính protected m_Combobox kieåu CComboBox quaûn lyù comboBox.                                             CWnd* pWndBuddy              // Con troû ñoái töôïng ñöôïc hoã trôï.
        Haønh vi OnCreate thöïc hieän caùc khôûi taïo caàn thieát cho comboBox:                              ); 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ù.
        int CEmpWnd::OnCreate (LPCREATESTRUCT lpCreateStruct)
        {                                                                                                    CWnd* GetBuddy( ); Traû veà con troû ñoái töôïng hoäp nhaäp ñöôïc hoã trôï.
            if (CWnd::OnCreate(lpCreateStruct) == -1) return -1;

90    Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Caùc lôùp ñoái töôïng nhaäp lieäu                                                      91
void SetRange (                                                                                        Haønh vi OnClickNhapxong thöïc hieän hieån thò thoâng tin nhaäp:
            int nLower,                   // Giaù trò caän döôùi                                               void CEmpWnd::OnClickNhapxong( )
            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.                                                CString yourname, yourage, mess;
        void GetRange (                                                                                           m_editName.GetWindowText( yourname );
            int &lower,                   // Tham bieán chöùa giaù trò caän döôùi                                 m_editAge.GetWindowText( yourage );
            int& upper                    // Tham bieán chöùa giaù trò caän treân                                 mess.Format ( "%sn is %s years old", yourname, yourage );
        ); Laáy thoâng tin veà giôùi haïn cuûa nuùt taêng-giaûm.                                                  MessageBox( mess,"Hello!", MB_OK | MB_ICONEXCLAMATION );
                                                                                                               }
        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.                             8.7 CProgressCtrl:
     Thöïc haønh: Vieát öùng duïng töông töï VD21; muïc thoâng baùo "Enter your                          CProgressCtrl laø lôùp ñoái töôïng quaûn lyù thanh tieán ñoä xöû lyù treân giao dieän.
     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-                CProgressCtrl( ); Taïo laäp ñoái töôïng roãng.
     250. Nuùt choïn "Nhap xong" cho pheùp hieån thò teân vaø tuoåi vöøa nhaäp.                             BOOL Create (
                                                                                                                DWORD dwStyle,                // Thoâng soá daïng thanh tieán ñoä xöû lyù
        Taïo döï aùn VD24 töông töï VD21. Chænh söûa lôùp CEmpWnd nhö sau:
                                                                                                                const RECT& rect,             // Toaï ñoä, kích thöôùc cuûa thanh
        Khai baùo thuoäc tính m_editAge kieåu CEdit quaûn lyù hoäp nhaäp.
                                                                                                                CWnd* pParentWnd,             // Con troû ñoái töôïng cöûa soå cha
        Haønh vi OnCreate thöïc hieän khôûi taïo thoâng soá cho caùc muïc. Rieâng muïc
                                                                                                                UINT nID                      // Soá hieäu cuûa thanh tieán ñoä
        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
                                                                                                            ); Haønh vi khôûi taïo thoâng soá cho thanh tieán ñoä treân giao dieän.
        quaûn lyù chuùng seõ ñöôïc khai baùo static trong OnCreate:
                                                                                                            dwStyle: Goàm thoâng soá qui ñònh ñoái vôùi control vaø caùc daïng boå sung:
        int CEmpWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)                                                    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.
            if (CWnd::OnCreate(lpCreateStruct) == -1) return -1;
                                                                                                            void SetRange (
            ...             // Töông töï VD21, vaø caùc noäi dung boå sung sau:
                                                                                                                short nLower,             // Giaù trò nhoû nhaát
            m_editAge.Create (
                WS_CHILD | WS_VISIBLE | WS_BORDER | ES_NUMBER,                                                  short nUpper              // Giaù trò lôùn nhaát
                CRect( 135, 45, 190, 65 ), this, -1 );                                                      ); AÁn ñònh giôùi haïn tieán ñoä xöû lyù chæ bôûi thanh tieán ñoä.
                                                                                                            void GetRange(
            static CStatic            m_staticAge;
            static CSpinButtonCtrl m_spinAge;                                                                   int& nLower,              // Bieán chöùa giaù trò nhoû nhaát
            m_staticAge.Create ( _T( "Enter your age:" ),                                                       int& nUpper               // Bieán chöùa giaù trò lôùn nhaát
                                    WS_CHILD | WS_VISIBLE,                                                  ); Laáy thoâng tin veà giôùi haïn tieán ñoä xöû lyù chæ bôûi thanh tieán ñoä.
                                    CRect( 10, 45, 130, 65 ), this );                                       int SetPos( int nPos ); AÁn ñònh vò trí hieän taïi cuûa thanh tieán ñoä.
            m_spinAge.Create ( WS_CHILD | WS_VISIBLE |                                                      int GetPos( ); Traû veà vò trí hieän taïi cuûa thanh tieán ñoä xöû lyù.
               UDS_ARROWKEYS | UDS_SETBUDDYINT | UDS_ALIGNRIGHT,                                            int OffsetPos( int nPos ); AÁn ñònh möùc taêng (giaûm) treân moät ñôn vò cuûa
               CRect(0,0,1,1), this, -1 );
                                                                                                            chæ muïc tieán ñoä trong thanh tieán ñoä baèng nPos, ñoàng thôøi caäp nhaät traïng
            m_spinAge.SetBase( 1 ); m_spinAge.SetRange( 15, 250 );
            m_spinAge.SetBuddy ( &m_editAge );                                                              thaùi hieån thò cuûa thanh tieán ñoä theo giaù trò aán ñònh môùi.
            return 0;                                                                                       int StepIt( ); Thay ñoåi chæ muïc tieán ñoä moät ñôn vò.
        }

92    Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Caùc lôùp ñoái töôïng nhaäp lieäu                                                     93
8.8 CScrollBar:                                                                                                Khai baùo caùc thuoäc tính protected: m_staticScroll kieåu CStatic quaûn lyù
   CScrollBar laø lôùp ñoái töôïng quaûn lyù thanh cuoän treân cöûa soå giao dieän.                            muïc thoâng baùo, m_Scroll kieåu CScrollBar quaûn lyù thanh cuoän.
      CScrollBar( ); Taïo laäp ñoái töôïng roãng.                                                              Haønh vi OnCreate thöïc hieän khôûi taïo thoâng soá cho caùc muïc:
      BOOL Create (                                                                                            int CEmpWnd::OnCreate( LPCREATESTRUCT lpCreateStruct )
          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                                if (CWnd::OnCreate(lpCreateStruct) == -1) return -1;
          CWnd* pParentWnd,               // Con troû ñoái töôïng cöûa soå cha                                     m_staticScroll.Create( _T(""),
          UINT nID                        // Soá hieäu thanh cuoän                                                                           WS_CHILD | WS_VISIBLE,
      ); Khôûi taïo thoâng soá cho ñoái töôïng thanh cuoän treân giao dieän.                                                                 CRect( 10, 15, 120, 35 ), this );
                                                                                                                   m_Scroll.Create( WS_CHILD | WS_VISIBLE | SBS_HORZ,
      dwStyle: Goàm thoâng soá qui ñònh ñoái vôùi control vaø caùc daïng boå sung:
                                                                                                                                 CRect( 10,45,127,65 ), this, IDC_SCROLLBAR );
          SBS_HORZ : Thanh cuoän ñaët ngang (horizontal)                                                           m_Scroll.SetScrollRange( 0,100 );
          SBS_VERT            : Thanh cuoän ñaët ñöùng (vertical)                                                  return 0;
      int GetScrollPos( ); Traû veà vò trí hieän thôøi cuûa moät thanh cuoän.                                  }
      int SetScrollPos (                                                                                       Haønh vi OnHScroll xöû lyù WM_HSCROLL:
          int nPos,                           // Vò trí ñaët nuùt cuoän                                        void CEmpWnd::OnHScroll( UINT nSBCode, UINT nPos,
          BOOL bRedraw = TRUE // Caäp nhaät laïi hình aûnh thanh cuoän                                                                            CScrollBar* pScrollBar )
      ); Ñaët vò trí nuùt cuoän treân thanh cuoän.                                                             { char s[10];
      void SetScrollRange (                                                                                        int     pos = nPos;
          int nMinPos,                        // Giaù trò nhoû nhaát                                               switch (nSBCode) {
          int nMaxPos,                        // Giaù trò lôùn nhaát                                               case SB_LINELEFT:
                                                                                                                       pos = pScrollBar->GetScrollPos() - 1;
          BOOL bRedraw = TRUE // Caäp nhaät laïi thanh cuoän
                                                                                                                       if (pos < 0) pos = 0;
      ); 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.                                  pScrollBar->SetScrollPos( pos );
      void GetScrollRange (                                                                                            sprintf( s, "%d", pos ); m_staticScroll.SetWindowText(s);
          LPINT lpMinPos,                     // Chöùa vò trí ñaàu                                                     break;
          LPINT lpMaxPos                      // Chöùa vò trí cuoái                                                case SB_LINERIGHT:
      ); 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.                             pos = pScrollBar->GetScrollPos() + 1;
      void ShowScrollBar ( BOOL bShow = TRUE ); Baät / Taét thanh cuoän.                                               if (pos > 90) pos = 100;
                                                                                                                       pScrollBar->SetScrollPos(pos);
     ScrollBar vaø cöûa soå cha: Ñoái töôïng scrollbar göûi WM_HSCROLL (ñoái vôùi                                      sprintf(s, "%d", pos); m_staticScroll.SetWindowText(s);
     loaïi scrollbar ngang) hoaëc WM_VSCROLL (ñoái vôùi loaïi scrollbar ñöùng)                                         break;
     ñ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                            case SB_THUMBPOSITION:
     OnVScroll hoaëc OnHScroll cuûa ñoái töôïng CWnd quaûn lyù cöûa soå cha seõ xöû                                    pScrollBar->SetScrollPos(pos);
     lyù caùc message töông öùng noùi treân.                                                                           sprintf(s, "%d", pos); m_staticScroll.SetWindowText(s);
                                                                                                                       break;
     Thöïc hieän öùng duïng nhö VD15. Boå sung thanh cuoän, vaø muïc thoâng baùo ñeå
                                                                                                                   default: CWnd::OnHScroll(nSBCode, nPos, pScrollBar);
     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:                                  }
                                                                                                               Bieân dòch vaø chaïy thöû öùng duïng.
94    Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Caùc lôùp ñoái töôïng nhaäp lieäu                                                 95
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.

96    Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
CHÖÔNG 9:                                                                                              CTLCOLOR_LISTBOX                       : Listbox
                                                                                                       CTLCOLOR_SCROLLBAR : Thanh tröôït
                                 Hoäp hoäi thoaïi                                                      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
9.1 HOÄP HOÄI THOAÏI (DIALOG):
                                                                                                   haønh vi EndDialog ñöôïc duøng ñeå keát thuùc 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
                                                                                                   void EndDialog (
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,
                                                                                                       int nResult              // Giaù trò tham soá cuûa haønh vi.
goïi laø dialog resource. Coù hai kieåu hoaït ñoäng cuûa dialog:
                                                                                                   ); Haønh vi ñöôïc duøng ñeå keát thuùc hoaït ñoäng cuûa dialog kieåu khoùa.
         Dialog khoùa (modal dialog): Taùc vuï thöïc hieän dialog phaûi chôø ñeán khi
                                                                                                   virtual void OnOK( ); Haønh vi keá thöøa ñeå caøi ñaët xöû lyù choïn button coù
         dialog chaám döùt hoaït ñoäng.
                                                                                                   soá hieäu IDOK. Trong CDialog, phaàn caøi ñaët cuûa OnOK chæ laø leänh goïi
         Dialog khoâng khoùa (modeless dialog): Taùc vuï thöïc hieän dialog coù theå
                                                                                                   haønh vi EndDialog vôùi tham soá IDOK.
         tieáp tuïc caùc xöû lyù tieáp theo ngay sau leänh thöïc hieän dialog.
                                                                                                   virtual void OnCancel( ); Haønh vi keá ñeå caøi ñaët xöû lyù choïn button coù soá
9.2 LÔÙP CDialog:                                                                                  hieäu IDCANCEL (phím taét laø ESC). Trong CDialog, caøi ñaët cuûa
   CDialog laø lôùp ñoái töôïng keá thöøa töø lôùp CWnd, ñöôïc söû duïng ñeå quaûn lyù             OnCancel chæ laø leänh goïi haønh vi EndDialog vôùi tham soá IDCANCEL.
dialog. Ngoaøi caùc thuoäc tính vaø haønh vi keá thöøa public töø lôùp CWnd, lôùp                  BOOL Create (
CDialog coù caùc haønh vi boå sung sau ñaây:                                                           UINT nIDTemplate,                           // Soá hieäu dialog resource
      CDialog (                                                                                        CWnd* pParentWnd = NULL                     // Con troû ñoái töôïng cöûa soå cha.
          UINT nIDTemplate,                        // Soá hieäu cuûa dialog resource               ); Haønh vi kích hoaït dialog kieåu khoâng khoùa.
          CWnd* pParentWnd = NULL                  // Con troû ñoái töôïng cöûa soå cha            virtual BOOL DestroyWindow( ); Haønh vi ñöôïc duøng ñeå keát thuùc hoaït
      ); Taïo laäp ñoái töôïng dialog hoaït ñoäng kieåu khoùa.                                     ñoäng cuûa dialog kieåu khoâng khoùa.
      CDialog( ); Taïo laäp ñoái töôïng dialog hoaït ñoäng kieåu khoâng khoùa.                     CWnd* GetDlgItem (
      virtual BOOL OnInitDialog( ); Haønh vi maø ñoái töôïng dialog söû duïng ñeå                      int nID                      // Soá hieäu cuûa control treân dialog
      xöû lyù WM_INITDIALOG, message do windows göûi ñeán dialog tröôùc                            ); Traû veà con troû ñoái töôïng thuoäc lôùp CWnd quaûn lyù control.
      khi kích hoaït dialog. Keá thöøa haønh vi naøy nhaèm thöïc hieän khôûi taïo                  int GetDlgItemText (
      thoâng soá cho dialog vaø caùc controls cuûa noù.                                                int nID,                     // Soá hieäu cuûa control treân dialog
      afx_msg HBRUSH OnCtlColor (                                                                      CString& rString             // Tham bieán kieåu chuoãi chöùa keát quaû
          CDC* pDC,             // Con troû ñoái töôïng DC cuûa control                            ); Laáy noäi dung chuoãi thoâng baùo cuûa control.
          CWnd* pWnd, // Con troû ñoái töôïng cöûa soå quaûn lyù control                           UINT GetDlgItemInt (
          UINT nCtlColor // Thoâng tin veà loaïi control ñöôïc trang trí                               int nID                      // Soá hieäu cuûa control treân dialog
      ); Haønh vi xöû lyù WM_CTLCOLOR, message do windows göûi ñeán                                ); Traû veà giaù trò soá cuûa noäi dung nhaäp trong control.
      dialog khi coù nhu caàu trang trí moät control treân dialog.                                 void SetDlgItemText (
      nCtlColor coù theå laø moät trong caùc giaù trò sau:                                             int nID,                     // Soá hieäu cuûa control treân dialog
          CTLCOLOR_BTN                       : Ñoái töôïng trang trí laø button                        LPCTSTR lpszString // Giaù trò kieåu chuoãi
          CTLCOLOR_DLG                       : Dialog                                              ); Ñaët noäi dung kieåu chuoãi cho control.
          CTLCOLOR_EDIT                      : Hoäp nhaäp lieäu

Hoäp hoäi thoaïi                                                                       97    98   Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
void SetDlgItemInt (                                                                      Thieát keá dialog thoâng qua maøn hình thieát keá maø ta vöøa nhaän ñöôïc töø
             int nID, UINT nValue // Soá hieäu control vaø giaù trò gaùn                           böôùc treân. Caùc thao taùc cô baûn nhö sau:
         ); Gaùn giaù trò soá nValue cho control.                                                  • Baät / Taét thanh coâng cuï hoã trôï thieát keá dialog:
         UINT IsDlgButtonChecked (                                                                    - Choïn muïc menu Tools / Customize...
             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.
                                                                                                       - Ñaùnh daáu hoaëc boû ñaùnh daáu muïc Controls. Choïn Close.
        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                                                                   (Thanh coâng cuï vôùi caùc loaïi control söû duïng ñöôïc treân dialog)
    chæ vieäc khai baùo bieán ñoái                                                                 • AÁn ñònh caùc ñaëc tính cuûa dialog resource: Right-clict treân khung
    töôïng thuoäc lôùp noùi treân vaø söû                                                            dialog resource (vuøng khoâng caøi controls), choïn muïc Properties:
    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 ).                                       - Choïn General ñeå aán ñònh caùc thoâng soá chung.
Hoäp hoäi thoaïi                                                                       99   100 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
ID         : Soá hieäu cuûa dialog resource.                                                Static edge : Khung chìm.
                 Caption : Noäi dung tieâu ñeà cuûa dialog.                                      • Caøi ñoái töôïng hoäp nhaäp leân dialog:
                 Menu : Soá hieäu cuûa menu resource gaén vaøo dialog.                             - Click choïn bieåu töôïng        treân thanh coâng cuï.
                 Font       : AÁn ñònh font duøng cho noäi dung chöõ treân dialog.                 - Thöïc hieän caøi ñaët vaø aán ñònh thoâng soá nhö vôùi muïc thoâng baùo:
             - Choïn Styles ñeå aán ñònh thoâng soá daïng cöûa soå cuûa dialog:                           Multi Line : Hoäp nhaäp cho pheùp nhaäp nhieàu doøng.
                 Style :      Ñaëc tính cuûa dialog. Chaúng haïn choïn Popup cho                          AutoHScroll/AutoVScroll : Töï ñoäng tröôït noäi dung khi thoâng
                               pheùp dialog taïo ra coù thoâng soá daïng WS_POPUP.                        tin nhaäp vöôït quaù kích thöôùc hoäp nhaäp.
                 Border : Kieåu ñöôøng vieàn cuûa dialog.                                                 HorizontalScroll | VerticalScroll : Hieån thò thanh tröôït ngang,
                 Title Bar : Dialog coù tieâu ñeà.                                                        doïc cuûa hoäp nhaäp.
                 System Menu : Dialog coù hoäp System Menu.                                               Want return : Söû duïng phím enter ñeå xuoáng doøng trong hoäp
             - Choïn More Styles ñeå aán ñònh caùc thoâng soá daïng môû roäng:                            nhaäp nhieàu doøng.
                 Visible : Dialog hieån thò. Ñoái vôùi dialog resource duøng cho                          Password : Duøng nhaäp password.
                  modeless dialog thì muïc naøy phaûi luoân ñöôïc choïn.                         • Caøi ñoái töôïng comboBox leân dialog:
           - Choïn Extended Style ñeå aán ñònh caùc thoâng soá daïng môû roäng:                    - Click choïn bieåu töôïng        treân thanh coâng cuï.
                  ToolWindow : Töông öùng WS_EX_TOOLWINDOW.                                        - Thöïc hieän caøi ñaët vaø aán ñònh thoâng soá nhö vôùi muïc thoâng baùo:
                  Static edge : Vuøng client ñöôïc chìm xuoáng (3D).                                      Data : Chöùa caùc muïc choïn. Caùc muïc naøy ñöôïc nhaäp treân caùc
           Goõ phím Enter ñeå keát thuùc.                                                                 doøng khaùc nhau. Löu yù duøng phím Ctrl+Enter ñeå xuoáng doøng.
         • Caøi ñoái töôïng muïc thoâng baùo leân dialog:                                                 Type : Kieåu comboBox.
           - Click choïn bieåu töôïng        treân thanh coâng cuï.                                       Sort : Caùc muïc trong comboBox ñöôïc saép xeáp theo noäi dung.
           - Drag chuoät treân vuøng daønh cho muïc thoâng baùo treân dialog.                    • Caøi ñoái töôïng comboBox leâ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             - Click choïn bieåu töôïng        treân thanh coâng cuï.
              Properties. Thöïc hieän caùc aán ñònh caàn thieát:                                   - Thöïc hieän caøi ñaët vaø aán ñònh thoâng soá nhö vôùi muïc thoâng baùo:
                  ID : Soá hieäu muïc thoâng baùo, maëc nhieân IDC_STATIC. Ñeå                            Selection : Kieåu listbox.
                  dialog nhaän dieän ñöôïc muïc khi xöû lyù message thì giaù trò naøy                     Multi-column : Listbox coù nhieàu coät.
                  phaûi ñöôïc khai baùo töôøng minh vaø duy nhaát.                                        Want Key Input : Lisbox cho pheùp xöû lyù phím.
                  Caption : chuoãi thoâng baùo                                                   • Caøi ñoái töôïng button leân dialog:
              Style :                                                                              - Click choïn bieåu töôïng        treân thanh coâng cuï.
                  Visible : Neáu ñaùnh daáu thì muïc ñöôïc hieån thò.                              - Thöïc hieän caøi ñaët vaø aán ñònh thoâng soá nhö vôùi muïc thoâng baùo:
                  Align Text : Canh chænh noäi dung thoâng baùo trong muïc.                               Default Button: Button öùng vôùi phím taét laø Enter.
                  Center Vertically : Canh chænh giöõa noäi dung thoâng baùo theo                         Multi-lines: Noäi dung thoâng baùo cuûa button coù nhieàu doøng.
                  chieàu doïc trong muïc.                                                                 Notify : Button coù khaû naêng thoâng tin cho cöûa soå cha.
                  Border : Coù khung bao quanh muïc thoâng baùo.                                 • Ñaùnh daáu choïn caùc ñoái töôïng treân dialog: Thöïc hieän thao taùc click.
                  Sunken : Khung chìm.                                                             Phoái hôïp phím Shift hoaëc Ctrl ñeå ñaùnh daáu nhieàu ñoái töôïng.
                  Notify : Muïc thoâng baùo coù khaû naêng thoâng tin cho cöûa soå cha.          • Chænh vò trí cuûa moät ñoái töôïng: Thöïc hieän thao taùc drag ñoái töôïng.
              Extened style :                                                                    • Chænh kích thöôùc cuûa moät ñoái töôïng:
                  Transparent : Neàn muïc trong suoát.                                             - Click choïn ñoái töôïng.

Hoäp hoäi thoaïi                                                                   101    102 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
- Thöïc hieän thao taùc Drag treân bieân cuûa                                            - File name = OptDlg                   : Teân taäp tin,
             ñoái töôïng ñeå ñaït kích thöôùc mong muoán.                                           - Base class = CDialog                 : Lôùp cô sôû
         • Canh chænh vò trí, kích thöôùc moät nhoùm ñoái töôïng:                                   - Dialog ID = IDD_OPTION : Soá hieäu dialog resource.
           - Ñaùnh daáu nhoùm ñoái töôïng                                                           Sau cuøng choïn OK.
           - Choïn coâng cuï phuø hôïp treân thanh coâng cuï:                                       Ñoùng maøn hình thieát keá dialog. Trong maøn hình Workspace, choïn
                 Canh thaúng theo bieân:                                                            ClassView, ta coù lôùp COptionDlg trong danh saùch caùc lôùp cuûa döï aùn.
                 Canh thaúng giöõa dialog:                                                      Treân lôùp COptionDlg, ta coù theå thöïc hieän boå sung thuoäc tính, caøi ñaët caùc
                 Caùc ñeàu nhau:                                                                haønh vi thoâng thöôøng cuõng nhö caùc haønh vi xöû lyù message. Caùc thao taùc
                 Baèng côõ ñoái töôïng choïn cuoái cuøng trong nhoùm:                           hoaøn toaøn töông töï nhö ñaõ thöïc hieän vôùi caùc lôùp CEmpApp vaø CEmpWnd.
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:
    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ø          Khai baùo ñoái töôïng thuoäc lôùp dialog môùi taïo. Duøng chæ thò #include taäp
caùc ñoái töôïng nhaäp lieäu ñöôïc moâ taû trong dialog resource ôû treân.                          tin (.H) chöùa khai baùo lôùp ôû ñaàu chöông trình:
       Trong maøn hình thieát keá dialog, choïn View / ClassWizard (Ctrl+W).                        #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ø
         Choïn OK ñeå taïo lôùp môùi öùng vôùi dialog resource.
                                                                                                    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
         - Name           = COptionDlg        : Nhaäp teân lôùp môùi                                ñoái töôïng cung caáp thoâng tin.
Hoäp hoäi thoaïi                                                                      103    104 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
Ñoái töôïng cung caáp thoâng tin seõ duøng handle cuûa ñoái töôïng nhaän tin ñeå          Haønh vi xöû lyù choïn nuùt OK cuûa lôùp COptionDlg: Thöïc hieän vieäc laáy
         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          thoâng tin töø hoäp nhaäp cuûa noù ñeå gaùn cho ñoái töôïng hoäp nhaäp
         cuûa mình vaøo caùc oâ chöùa tin cuûa ñoái töôïng nhaän tin.                              m_editName treân cöûa soå cha CEmpWnd.
    Thöïc haønh: Taïo öùng duïng VD26 nhö VD25. Thöïc hieän caùc boå sung: Khi                     void COptionDlg::OnOK()
    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                        CString name;
    cöûa soá chính, ngöôïc laïi muïc choïn Cancel seõ khoâng xöû lyù gì caû.                          // Laáy thoâng tin nhaäp trong hoäp nhaäp cuûa dialog
    HD: Muïc nhaäp YourName ñöôïc quaûn lyù bôûi thuoäc tính m_editName cuûa                          GetDlgItemText( IDC_NAME, name );
    ñoái töôïng CEmpWnd, ñaây laø oâ chöùa tin cuûa ñoái töôïng nhaän tin CEmpWnd.                    // 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 );
    Ñoái töôïng COptionDlg laø ñoái töôïng cung caáp tin. Xöû lyù ñieàn thoâng tin chæ
                                                                                                      // Duøng haønh vi lôùp cô sôû ñeå keát thuùc dialog.
    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ø
                                                                                                      CDialog::OnOK();
    ñ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 OnOK cuûa lôùp COptionDlg bò loãi do truy xuaát thuoäc tính kieåu
        Haønh vi thöïc hieän OptionDlg trong CEmpWnd söû duïng duøng con troû chæ                  protected m_editName cuûa lôùp CEmpWnd. Ñeå khaéc phuïc loãi naøy, ta
        ñeán noù laøm tham soá cho haønh vi taïo laäp cuûa ñoái töôïng COptionDlg:                 khai baùo lôùp COptionDlg laø moät lôùp baïn (friend) cuûa lôùp CEmpWnd.
        void CEmpWnd::OnGameOption ()                                                              class CEmpWnd : public CWnd
        {                                                                                          {
            COptionDlg dlg( this );                                                                   friend class COptionDlg;                    // COptionDlg is a friend
            dlg.DoModal();                                                                         public:
        }                                                                                             CEmpWnd();
        Boå sung thuoäc tính protected m_parent kieåu con troû CEmpWnd* cho                           ...                                         // other declarations
        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                    9.5 SÖÛ DUÏNG DIALOG LAØM GIAO DIEÄN CHÍNH CUÛA ÖÙNG DUÏNG:
        ñaàu taäp tin khai baùo (.h) cuûa lôùp COptionDlg.                                      Keá thöøa töø CWnd, lôùp CDialog vaø caùc lôùp keá thöøa töø noù coù theå duøng khai
        Haønh vi taïo laäp cuûa COptionDlg löu giöõ giaù trò con troû cöûa soå cha ñöôïc    baùo caùc ñoái töôïng cöûa soå giao dieän chính cuûa öùng duïng.
        truyeàn cho noù vaøo thuoäc tính m_parent.
                                                                                            9.5.1 Thöïc hieän öùng duïng vôùi giao dieän chính laø dialog:
        COptionDlg::COptionDlg ( CWnd* pParent )
                                                                                                   Taïo döï aùn VD27 töông töï VD03 (döï aùn chæ coù lôùp keá thöøa CWinApp).
                                           : CDialog( COptionDlg::IDD, pParent )
        {                                                                                          Taïo dialog resource coù noäi dung tuøy yù laøm giao dieän chính.
            m_parent = (CEmpWnd*) pParent;                                                         Taïo lôùp quaûn lyù dialog resource. Giaû söû lôùp coù teân laø CMainDlg coù maõ
            //{{AFX_DATA_INIT(COptionDlg)                                                          nguoàn trong caùc taäp tin MainDlg.H vaø MainDlg.CPP.
            // NOTE: the ClassWizard will add member initialization here                           Ñaêng kyù söû duïng lôùp CMainDlg cho phaàn caøi ñaët cuûa lôùp quaûn lyù öùng
            //}}AFX_DATA_INIT                                                                      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.
Hoäp hoäi thoaïi                                                                     105    106 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
BOOL CEmpApp::InitInstance ()                                                               Ñieàn caùc thoâng tin trong hoäp hoäi thoaïi New, Sau ñoù choïn OK.
       {
           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 muïc Dialog Based, sau ñoù choïn Next.
        Choïn menu File / New.




Hoäp hoäi thoaïi                                                                      107   108 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
AÁn ñònh caùc muïc choïn nhö treân. Sau ñoù choïn Next.                                          Ñ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
         Choïn cô cheá lieân keát vôùi thö vieän MFC. Sau ñoù choïn next.                                 Khai baùo bieán m_szNhap kieåu CString, duøng löu giaù trò hoäp nhaäp lieäu.
         Cuoái cuøng, aán ñònh teân taäp tin chöùa khai baùo caùc lôùp. Choïn Finish.                     Caùch thöïc hieän nhö sau:
         Bieân dòch vaø chaïy thöû öùng duïng.                                                            • Môû resource cuûa dialog chính, choïn muïc View/ClassWizard.
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.

Hoäp hoäi thoaïi                                                                           109     110 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
• Choïn trang Member Variables, choïn muïc coù soá hieäu IDC_NHAP.                      void CEmpDlg::OnDat()
           Sau ñoù choïn muïc Add Variable….                                                     {
                                                                                                    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ÔÏ:
            - Meber variable name = m_szNhap : Teân bieán                                     ÖÙng duïng phaùt trieån trong VC coù theå deã daøng khai thaùc caùc tieän ích hoã trôï
            - Category                     = Value        : Loaïi bieán                   bôûi VC (VC Components) hoaëc bôûi caùc öùng duïng khaùc ñöôïc caøi ñaët trong heä
            - Variable type                = CString      : Kieåu cuûa bieán. Choïn OK.   thoáng (ActiveX Controls). Vieäc boå sung vaø khai thaùc caùc tieän ích naøy trong
         Khai baùo bieán m_editNhap kieåu CEdit. Bieán naøy ñöôïc söû duïng ñeå taùc      öùng duïng ñöôïc thöïc hieän thoâng qua caùc böôùc sau:
         ñoäng giaù trò hoäp nhaäp lieäu. Thöïc hieän nhö khai baùo bieán m_szNhap:              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…




         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:               • Choïn nhoùm tieän ích: Double-click muïc nhoùm tieän ích caàn duøng.

Hoäp hoäi thoaïi                                                                   111    112 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
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:




                        (Danh saùch caùc tieän ích cuûa MS Visual C++)                                 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
         • Choïn tieän ích:                                                                            cuûa öùng duïng laø lôùp söû duïng. Hai haønh vi boå sung töï ñoäng cho lôùp:
           Choïn muïc thích hôïp trong danh saùch tieän ích chi tieát. Choïn Insert.                   - 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
            Choïn OK ñeå khaúng ñònh thao taùc.                                                 control naøy leân dialog giao dieän.
         • Khai baùo thoâng tin lôùp ñoái töôïng quaûn lyù tieän ích boå sung (neáu coù).          Duøng MFC Wizard taïo döï aùn XemLich vôùi dialog giao dieän chính.
         • Khai baùo thoâng tin lôùp ñoái töôïng trong öùng duïng söû duïng tieän ích.             Ñaêng kyù 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.                            • Nhoùm tieän ích = Registered ActiveX Controls.
                                                                                                   • Tieän ích = Calendar Control 8.0

Hoäp hoäi thoaïi                                                                       113   114 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
• Khai baùo thoâng tin lôùp ñoái töôïng quaûn lyù tieän ích:                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ø.
           Choïn OK, Choïn Close ñeå ñoùng hoäp hoäi thoaïi tieän ích.
                                                                                     8. Thöïc hieän öùng duïng vôùi giao dieän chính laø dialog. Dialog naøy cho pheùp
         • Lôùp ñoái töôïng CXemLichDlg quaûn lyù dialog giao dieän chính cuûa döï
                                                                                     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ù.
           aùn laøm nhieäm vuï söû duïng control boå sung naøy:
                                                                                     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
           - Môû resource dialog giao dieän, caøi ñaët control sau:
                                                                                     "Mailto: emp@hcmueco.edu.vn". Hình aûnh chuoät ñoåi thaønh                   khi di chuyeån
               - Hoäp xem vaø choïn ngaøy         CCalendar          IDC_DATE
                                                                                     chuoät leân vò trí muïc. Click choïn muïc cho pheùp göûi mail.
           - Taïo bieán ñieàu khieån m_Lich kieåu CCalendar cho control.
                                                                                         HD:
           - Haønh vi OnInitDialog cuûa lôùp ñaët giaù trò cho control:
                                                                                         - Xöû lyù WM_CTLCOLOR ñeå ñaët maøu neàn cuûa dialog vaø maøu chöõ muïc.
                   BOOL CXemLichDlg::OnInitDialog()                                      - 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:
                     CDialog::OnInitDialog();
                                                                                             HINSTANCE ShellExecute (
                     SetIcon(m_hIcon, TRUE);
                     SetIcon(m_hIcon, FALSE);                                                     HWND hWnd,                       // Handle cöûa soå cha.
                                                                                                  LPCTSTR lpOperation,             // Chuoãi noäi dung taùc vuï
                     m_Lich.SetDay( 19 );
                     m_Lich.SetMonth( 11 );                                                       LPCTSTR lpFile,                  // Ñöôøng daãn taäp tin chöông trình
                     m_Lich.SetYear( 2002 );                                                      LPCTSTR lpParameters, // Chuoãi tham soá doøng leänh
                                                                                                  LPCTSTR lpDirectory,             // Ñöôøng daãn thö muïc laøm vieäc
                     return TRUE;
                   }                                                                              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.
                Coù theå söû duïng caùc haønh vi: GetDay, GetMonth, GetYear cuûa     VÍ DUÏÏ: Ñeå göûi mail, ta söû duïng haøm treân nhö sau.
                ñoái töôïng m_List ñeå laáy thoâng tin veà ngaøy ñöôïc choïn.        ShellExecute( NULL, "open", "Mailto:emp@hcmueco.edu.vn","","", SW_SHOW );
         Bieân dòch vaø chaïy thöû öùng duïng.
Hoäp hoäi thoaïi                                                              115    116 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
CHÖÔNG 10:                                                                                            CStatusBar( ); Taïo laäp ñoái töôïng roãng.
                                                                                                      BOOL Create (
             KHUNG CÖÛA SOÅ GIAO DIEÄN CHÍNH                                                              CWnd* pParentWnd,             /* Con troû ñoái töôïng cöûa soå cha */
10.1 KHUNG CÖÛA SOÅ GIAO DIEÄN (FRAME WINDOW):                                                                  /* Thoâng soá daïng cuûa statusbar vaø giaù trò maëc nhieân */
   Frame window laø loaïi cöûa soå chuyeân duøng laøm maøn hình chính cuûa öùng                           DWORD dwStyle WS_CHILD | WS_VISIBLE | CBRS_BOTTOM,
duïng. Frame window coù caùc ñaëc ñieåm nhö sau:                                                                /* 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
        Cho pheùp loàng vaøo frame window thanh traïng thaùi (statusbar), thanh                           ID_INDICATOR_SCRL : Pane traïng thaùi phím scrolllock
        coâng cuï (toolbar), menu vaø caùc phím taét treân menu.                                      void SetWindowText (
        Cho pheùp loàng moät ñoái töôïng view (thuoäc lôùp keá thöøa töø CWnd) vaøo                       LPCTSTR lpszString                // Noäi dung thoâng baùo caäp nhaät
        vuøng client cuûa frame window ñeå hoaït ñoäng phoái hôïp trong vieäc hieån                   ); Caäp nhaät thoâng baùo cho pane coù soá hieäu laø 0.
        thò noäi dung trao ñoåi cuûa öùng duïng. Haønh vi OnSetFocus cuûa frame                       BOOL SetPaneText (
        window thöïc hieän haønh vi OnSetFocus cuûa view ñeå taïo söï ñoàng boä giöõa                     int nIndex,                       // Soá hieäu pane
        frame vaø view khi kích hoaït. Thoâng qua haønh vi OnCmdMsg, frame                                LPCTSTR lpszNewText, // Noäi dung thoâng baùo caäp nhaät
        window coù theå ñieàu phoái command message cho view.                                             BOOL bUpdate=TRUE                 // Veõ laïi thoâng tin caäp nhaät
        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          ); Caäp nhaät noäi dung thoâng baùo trong pane moät pane.
        ñoái töôïng tröïc thuoäc: menu, toolbar, statusbar, view.                                     void SetPaneInfo (
        Cho pheùp cô cheá thöïc hieän WinHelp vaø töï ñoäng keát thuùc WinHelp khi                        int nIndex,                       // Soá thöù töï pane trong statusbar
        frame window chaám döùt hoaït ñoäng.                                                              UINT nID,                         // Soá hieäu gaùn cho pane
10.2 THANH TRAÏNG THAÙI (STATUSBAR) & LÔÙP CStatusBar:                                                    UINT nStyle,                      // Thoâng soá daïng cuûa pane
   StatusBar laø khung bao goàm caùc hoäp (pane) chöùa thoâng baùo. Thoâng qua                            int cxWidth                       // Ñoä roäng pane (tính baèng pixel)
statusbar, öùng duïng coù theå thoâng tin cho ngöôøi duøng veà caùc hoaït ñoäng cuûa öùng             ); AÁn ñònh caùc thoâng soá lieân quan hoaït ñoäng hieån thò cuûa pane.
duïng vaø caùc thoâng soá lieân quan. Statusbar thöôøng ñöôïc ñaët ôû caïnh döôùi cuûa                Giaù trò nStyle coù theå laø:
frame window. Moãi pane treân statusbar coù theå ñöôïc aán ñònh moät kieåu daïng                          SBPS_NOBORDERS : Khoâng vieàn.
theå hieän vaø noäi dung thoâng tin rieâng.                                                               SBPS_POPOUT                 : Vieàn noåi.
   Vieäc quaûn lyù statusbar trong öùng duïng ñöôïc MFC hoã trôï thoâng qua lôùp ñoái                     SBPS_DISABLED               : Caám.
töôïng CStatusBar. Caùc haønh vi ñaëc tröng cuûa lôùp naøy nhö sau:                                       SBPS_STRETCH                : Töï chænh kích thöôùc (cho 1 pane duy nhaát ).

Khung cöûa soå giao dieän chính                                                         117    118Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
SBPS_NORMAL               : Khoâng coù kieåu daùng ñaëc bieät,                       void SetHeight( int cyHeight ); AÁn ñònh chieàu cao cuûa toolbar.
        void SetPaneStyle (                                                                      void EnableDocking (
            int nIndex,                    // Soá thöù töï pane trong statusbar                      DWORD dwStyle            // Caùch keát toolbar vaøo frame window
            UINT nStyle                    // Thoâng soá daïng cuûa pane                                                      // xem EnableDocking() cuûa CFrameWnd
        ); AÁn ñònh thoâng soá daïng cuûa pane.                                                  ); 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
10.3 THANH COÂNG CUÏ (TOOLBAR) & LÔÙP CToolBar:
                                                                                                 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
    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
                                                                                                 phuø hôïp treân töøng nuùt choïn.
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            Thöïc hieän toolbar trong öùng duïng: Ta tieán haønh caùc böôùc sau ñaây.
do MFC cung caáp nhaèm hoã trôï vieäc quaûn lyù toolbar trong öùng duïng.                 10.3.1 Thieát keá toolbar resource:
       CToolBar( ); Taïo laäp ñoái töôïng roãng.                                              Toolbar resource chöùa thoâng tin veà hình aûnh, soá hieäu, noäi dung thoâng baùo
       BOOL Create (                                                                      vaø caùc höôùng daãn cho töøng muïc choïn treân thanh toolbar.
           CWnd* pParentWnd,                /* Con troû ñoái töôïng cöûa soå cha */               Môû döï aùn caàn boå sung toolbar resource trong VC.
                  /* Thoâng soá daïng cuûa toolbar vôùi giaù trò maëc nhieân */                   Taïo môùi toolbar resource: Thöïc hieän töông töï taïo môùi icon (2.8).
           DWORD dwStyle = WS_CHILD | WS_VISIBLE | CBRS_TOP,                                      Löu yù: Choïn Resource Type = ToolBar.
                  /* Soá hieäu cuûa toolbar, giaù trò maëc nhieân cho toolbar chính */            Ñaët soá hieäu cho toolbar (ví duï IDR_MAINFRAME cho toolbar chính).
           UINT nID = AFX_IDW_TOOLBAR                                                             Thieát keá toolbar thoâng qua maøn hình thieát keá maø ta vöøa nhaän ñöôïc töø
       ); Khôûi taïo thoâng soá cho ñoái töôïng toolbar.                                          böôùc treân. Caùc thao taùc cô baûn nhö sau:
       dwStyle coù theå nhaän caùc thoâng soá sau:                                                • Khai baùo thoâng soá cho nuùt choïn:
           CBRS_GRIPPER                   : Toolbar di chuyeån ñöôïc                                 - Double-click treân nuùt:
           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                                          - AÁn ñònh caùc thoâng soá cho nuùt:
           CRect rcBorders = CRect ( 0, 0, 0, 0 ),                                                        ID : Soá hieäu cuûa nuùt choïn, coù theå laø soá hieäu cuûa muïc menu.
           UINT nID = AFX_IDW_TOOLBAR                                                                     Width, Height : Chieàu roäng vaø chieàu cao cuûa nuùt.
       ); Khôûi taïo ñoái töôïng toolbar vôùi thoâng soá daïng môû roäng.                                 Prompt : Töông töï nhö Prompt cuûa muïc choïn treân menu.
       dwCtrlStyle coù theå laø TBSTYLE_TRANSPARENT (trong suoát).
       BOOL LoadToolBar (                                                                        • Theâm moät nuùt môùi: Double-click treân           . Sau ñoù thöïc hieän khai
           UINT nIDResource             // Soá hieäu cuûa toolbar resource                         baùo thoâng soá cho nuùt nhö treân.
       ); Taïo daïng cho toolbar töø toolbar resource.                                           • Chuyeån vò trí cuûa nuùt: Drag nuùt ñeán vò trí thích hôïp.

Khung cöûa soå giao dieän chính                                                    119    120Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
• Taùch nhoùm nuùt: Drag nuùt ra xa vò trí nuùt keá caän.                                   DWORD dwStyle = WS_OVERLAPPEDWINDOW,
        • Xoùa nuùt: Drag nuùt ra khoûi thanh toolbar.                                                                                  /* Toïa ñoä, kích thöôùc cuûa frame
        • Trang trí nuùt: Thöïc hieän nhö trang trí icon.                                                                                   rectDefault: Giaù trò maëc nhieân */
        Khi thieát keá xong, choïn muïc Save vaø ñoùng maøn hình thieát keá toolbar.                const RECT& rect = rectDefault,
10.3.2 Duøng toolbar resource cho ñoái töôïng CToolBar cuûa FrameWnd:                                                                   // Con troû ñoái töôïng cöûa soå cha
      Khai baùo ñoái töôïng thuoäc tính kieåu CToolBar trong lôùp CFrameWnd                         CWnd* pParentWnd = NULL,
      cuûa öùng duïng:                                                                                                                  // Chuoãi teân menu resource
      CToolBar m_toolbar; // Ñaët trong khai baùo lôùp CFrameWnd                                    LPCTSTR lpszMenuName = NULL,
                                                                                                    DWORD dwExStyle                     // Thoâng soá daïng frame môû roäng
      Haønh vi OnCreate cuûa FrameWnd khôûi taïo thoâng soá cho ñoái töôïng
                                                                                                  ); Khôûi taïo thoâng soá cho frame window.
      toolbar . Sau ñoù keát ñoái töôïng toolbar vaøo frame window.
                                                                                                afx_msg int OnCreate( LPCREATESTRUCT lpCreateStruct ); Haønh vi
        int CEmpFrame::OnCreate( LPCREATESTRUCT lpCreateStruct )                                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 (
            if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
                                                                                                    UINT nIDResource, // Soá hieäu caùc resource lieân quan: icon,
                return -1;
                                                                                                                               // cursor, baûng phím taét, menu (baét buoäc).
            // Create the main toolbar for frame window
                                                                                                    DWORD dwDefaultStyle                // Thoâng soá daïng frame window
            m_toolbar.CreateEx(this, TBSTYLE_FLAT,
                     WS_CHILD | WS_VISIBLE | CBRS_TOP                                                      = WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE,
                     | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY);                                  CWnd* pParentWnd                    // Con troû ñoái töôïng cöûa soå cha
            // Initiate toolbar’s appearance by toolbar resource                                ); Khôûi taïo thoâng soá cho frame window.
            m_toolbar.LoadToolBar(IDR_MAINFRAME);                                               BOOL LoadAccelTable (
            m_toolbar.EnableDocking(CBRS_ALIGN_ANY);                                                LPCTSTR Baûng_phím_taét             // Teân baûng phím taét trong resource
            // attach the toolbar to frame window                                               ); Naïp baûng phím taét, chæ duøng khi frame ñöôïc khôûi taïo bôûi Create.
            this->EnableDocking(CBRS_ALIGN_ANY);                                                virtual void ActivateFrame (
            this->DockControlBar(&m_toolbar, AFX_IDW_DOCKBAR_TOP);
                                                                                                    int nCmdShow = -1                   // Thoâng soá veà traïng thaùi kích hoaït
            return 0;
        }                                                                                       ); 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 (
10.4 LÔÙP CFrameWnd:                                                                                DWORD dwDockStyle                   // Thoâng soá aán ñònh
    CFrameWnd laø lôùp ñoái töôïng keá thöøa töø CWnd cho pheùp quaûn lyù frame                 ); Qui ñònh caùch keát thanh coâng cuï vaøo frame window.
window trong öùng duïng. Ngoaøi caùc thuoäc tính vaø haønh vi keá thöøa public töø              dwDockStyle coù theå nhaän moät trong caùc giaù trò sau:
CWnd, CFrameWnd coù caùc thuoäc tính vaø haønh vi ñaëc tröng giuùp vieäc aán ñònh                   CBRS_ALIGN_TOP                   : Keát ôû caïnh treân vuøng client.
vaø ñieàu khieån frame window ñöôïc deã daøng vaø hieäu quaû.                                       CBRS_ALIGN_BOTTOM : Keát ôû caïnh döôùi
       CFrameWnd( ); Haønh vi taïo laäp.                                                            CBRS_ALIGN_LEFT                  : Keát ôû caïnh traùi
       BOOL Create (                                                                                CBRS_ALIGN_RIGHT                 : Keát ôû caïnh phaûi
           LPCTSTR lpszClassName,          // Teân lôùp ñaõ ñaêng kyù cuûa frame                    CBRS_ALIGN_ANY                   : Keát ôû moïi vò trí noùi treân.
           LPCTSTR lpszWindowName, // Teân, tieâu ñeà cuûa frame window
                                           /* thoâng soá daïng cuûa frame */

Khung cöûa soå giao dieän chính                                                    121   122Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
void DockControlBar (                                                                   Thöïc haønh 2: Thöïc hieän öùng duïng töông töï VD28, caøi heä thoáng menu
            CControlBar * pBar,                // Con troû ñoái töôïng toolbar                  töông töï ví duï chöông 7 cho ñoái töôïng frame window.
            UINT nDockBarID                    // Thoâng soá aán ñònh                              Taïo môùi döï aùn VD29 töông töï döï aùn VD28.
        ); Keát ñoái töôïng toolbar vaøo frame window, söû duïng khi tröôùc ñoù ñònh               Taïo môùi menu resource vôùi soá hieäu IDR_MAINFRAME, thieát keá menu
        caùch keát toolbar cho frame window laø CBRS_ALIGN_ANY. Thoâng soá                         naøy nhö moâ taû ôû chöông 7.
        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:         Taïo môùi baûng phím taét vôùi soá hieäu IDR_MAINFRAME. Khai baùo noäi
            AFX_IDW_DOCKBAR_TOP                         : Keát ôû caïnh treân                      dung baûng phím taét nhö muïc (7.5).
            AFX_IDW_DOCKBAR_BOTTOM : Keát ôû caïnh döôùi                                           Haønh vi InitInstance cuûa CEmpApp thöïc hieän khai baùo con troû ñoái
            AFX_IDW_DOCKBAR_LEFT                        : Keát ôû caïnh traùi                      töôïng CFrameWnd*. Duøng haønh vi LoadFrame cuûa ñoái töôïng naøy ñeå
            AFX_IDW_DOCKBAR_RIGHT                       : Keát ôû caïnh phaûi                      khôûi ñoäng thoâng soá cho noù töø caùc resource lieân quan:
        virtual BOOL OnCreateClient (                                                              BOOL CEmpApp::InitInstance()
            LPCREATESTRUCT lpcs,                    // Con troû ñeán caáu truùc chöùa              {
            CCreateContext* pContext                // Caùc thoâng soá lieân keát.                     CFrameWnd *main = new CFrameWnd;
        ); Haønh vi ñöôïc thöïc hieän khi caùc view ñaõ ñöôïc taïo xong. Keá thöøa haønh               m_pMainWnd = main;
                                                                                                       main->LoadFrame(IDR_MAINFRAME);
        vi naøy ñeå aán ñònh caùc thoâng soá rieâng cuûa öùng duïng.
                                                                                                       main->ShowWindow(SW_SHOW); // Show the frame window
        virtual CWnd* GetMessageBar( ); Traû veà con troû troû ñeán ñoái töôïng                        return TRUE;
        statusbar tröïc thuoäc.                                                                    }
10.5 SÖÛ DUÏNG FRAME WINDOW LAØM GIAO DIEÄN CHÍNH:                                           10.5.2 String Table vaø CFrameWnd:
    Keá thöøa töø CWnd, CFrameWnd vaø caùc lôùp keá thöøa töø noù coù theå duøng khai            StringTable, moät thaønh phaàn trong resource cuûa öùng duïng, duøng chöùa caùc
baùo caùc ñoái töôïng cöûa soå giao dieän chính cuûa öùng duïng.                             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
10.5.1 Thöïc hieän öùng duïng vôùi giao dieän chính laø CFrameWnd:                           haèng chuoãi trong resource cöûa öùng duïng ñöôïc thöïc hieän nhö sau:
    Thöïc haønh 1: Thöïc hieän öùng duïng vôùi cöûa soå chính laø frame window.                      Taïo môùi resource (nhö 2.8). Löu yù choïn resource type laø String Table.
       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                      Double-click hoaëc goõ Enter treân doøng troáng cuûa StringTable:
           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;
       }

Khung cöûa soå giao dieän chính                                                       123    124Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
- ID = Soá hieäu haèng chuoãi.                                                              int CEmpFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
        - 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.                                     if (CFrameWnd::OnCreate( lpCreateStruct ) == -1)
                                                                                                               return -1;
    Φ Söû duïng haèng chuoãi trong StringTable: Coù theå söû duïng haèng chuoãi trong                   // The IDs of all statusbar’panes
    StringTable laøm giaù trò cho bieán chuoãi trong chöông trình. Ñoái vôùi bieán                      UINT ID_array[3] = { 1, 1, ID_SEPARATOR };
    chuoãi ñöôïc quaûn lyù bôûi ñoái töôïng chuoãi CString, xöû lyù naøy ñöôïc thöïc hieän
                                                                                                        m_status.Create( this );               // Thanh statusbar chính
    thoâng qua haønh vi sau:                                                                            m_status.SetIndicators( ID_array, 3 );
       BOOL CString::LoadString (                                                                       m_status.SetPaneText( 0, "Mr.Emp" );
           UINT nID                  // Soá hieäu haèng chuoãi trong resource                           m_status.SetPaneText( 1, "Hello world!" );
       );                                                                                               // Set the size of each pane on statusbar
       Sau ñaây laø moät ví duï khôûi taïo giaù trò chuoãi myString töø string resource:                m_status.SetPaneInfo( 0, 1000, 0, 40 );
       CString myString;                                                                                m_status.SetPaneInfo( 1, 1001, 0, 70 );
       myString.LoadString (ID_GAME_OPTION );                                                           m_status.SetPaneInfo( 2, ID_SEPARATOR, 0, 300 );
                                                                                                        return 0;
    Φ 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õ              Thöïc haønh 4: Vieát öùng duïng nhö VD30 vôùi thanh coâng cuï coù 4 nuùt choïn
    ñöôïc söû duïng laøm tieâu ñeà cuûa frame window naøy.                                      töông öùng 4 muïc choïn trong heä thoáng menu.
       Môû döï aùn VD29.                                                                           Taïo döï aùn VD31 nhö VD30.
       Taïo môùi haèng chuoãi “Emp.Example 29” trong StringTable vôùi soá hieäu                    Taïo môùi toolbar resource coù soá hieäu IDR_MAINFRAME vôùi caùc nuùt
       laø IDR_MAINFRAME.                                                                          choïn töông öùng caùc muïc menu.
       Thöïc hieän chaïy thöû öùng duïng vaø quan saùt tieâu ñeà cöûa frame window.                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
    Thöïc haønh 3: Thöïc hieän öùng duïng nhö VD29; thanh statusbar vôùi ba muïc
                                                                                                   thoâng soá cho caùc ñoái töôïng m_status vaø m_toolbar, sau ñoù keát ñoái töôïng
    (pane): muïc thöù nhaát chöùa noäi dung "Mr.Emp", muïc thöù hai chöùa noäi dung
                                                                                                   m_toolbar vaøo frame window
    "Hello world!", muïc thöù ba hieån thò thoâng tin hoaït ñoäng cuûa öùng duïng.
                                                                                                   int CEmpFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
    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
                                                                                                       ...                          // Caùc caøi ñaët nhö VD30
    CEmpFrame thöïc hieän khôûi taïo thoâng soá cho ñoái töôïng statusbar. Duøng                       m_toolbar.CreateEx ( this,
    CEmpFrame khai baùo ñoái töôïng cöûa soá chính cuûa öùng duïng.                                            TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
       Taïo döï aùn VD30 nhö VD29.                                                                             | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY );
       Boå sung lôùp CEmpFrame keá thöøa CFrameWnd. Xem (5.4.1).                                        m_toolbar.LoadToolBar ( IDR_MAINFRAME );
       Boå sung ñoái töôïng thuoäc tính protected m_status thuoäc lôùp CStatusBar                       m_toolbar.EnableDocking ( CBRS_ALIGN_ANY );
       cho lôùp CEmpFrame:                                                                              this->EnableDocking ( CBRS_ALIGN_ANY );
                                                                                                        this->DockControlBar( &m_toolbar, AFX_IDW_DOCKBAR_TOP );
       CStatusBar m_status;                                                                             return 0;
       Boå sung haønh vi OnCreate (xöû lyù WM_CREATE) cho CEmpFrame vaø                             }
       thöïc hieän caøi ñaët nhö sau:

Khung cöûa soå giao dieän chính                                                       125    126Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
Haønh vi InitInstance cuûa CEmpApp söû duïng lôùp CEmpFrame khai baùo           - Haønh vi OnPaint thöïc hieän veõ chöõ chaïy:
        ñoái töôïng cöûa soå chính cuûa öùng duïng:                                         void CEmpView::OnPaint()
        BOOL CEmpApp::InitInstance()                                                        {
        {                                                                                      static char mess[] = "Chao cac ban !                                   ";
            CEmpFrame *main = new CEmpFrame;                                                   char ch;
            m_pMainWnd = main;                                                                 UINT i;
            main->LoadFrame(IDR_MAINFRAME);                                                    CPaintDC dc(this); // device context for painting
            main->ShowWindow(SW_SHOW);                                                         ch = mess[0];
            return TRUE;                                                                       for (i=0; i < strlen(mess)-1; i++)
        }                                                                                          mess[i] = mess[i+1];
                                                                                               mess[i] = ch;
    Thöïc haønh 5: Thöïc hieän öùng duïng töông töï VD31. Trong frame window,
                                                                                               dc.TextOut(10, 10, mess, 15);
    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            Duøng lôùp CEmpView khai baùo ñoái töôïng view trong CEmpFrame:
        hieån thò noäi dung chöõ chaïy. Caùc caøi ñaët caàn thieát nhö sau:             - Boå sung thuoäc tính protected m_view thuoäc lôùp CEmpView vaøo lôùp
        - Haønh vi OnCreate thöïc hieän caøi ñaët timer:                                   CEmpFrame.
                                                                                        - Haønh vi OnCreate cuûa CEmpFrame thöïc hieän khôûi taïo thoâng soá phuø
            int CEmpView::OnCreate(LPCREATESTRUCT lpCreateStruct)
            {                                                                              hôïp cho ñoái töôïng m_view; duøng soá hieäu cho m_view laø
                if (CWnd::OnCreate( lpCreateStruct) == -1 )                                AFX_IDW_PANE_FIRST (view maëc nhieân cuûa frame)
                    return -1;                                                              int CEmpFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
                SetTimer( ID_TIMER, 300, NULL );       // Interval = 300ms                  {
                return 0;                                                                       ... // Nhö caøi ñaët cuûa VD31
            }                                                                                   m_view.Create ( NULL, NULL, AFX_WS_DEFAULT_VIEW,
        - Haønh vi OnDestroy huûy boû timer:                                                                CRect(0,0,0,0), this, AFX_IDW_PANE_FIRST);
          void CEmpView::OnDestroy()                                                            return 0;
          {                                                                                 }
             KillTimer( ID_TIMER );                                                     - Haønh vi PreCreateWindow thöïc hieän huûy thoâng soá aán ñònh daïng
             CWnd::OnDestroy();                                                           "chìm xuoáng" cho vuøng client (chöùa view – to get a nice look):
          }                                                                                 BOOL CEmpFrame::PreCreateWindow(CREATESTRUCT& cs)
        - Haønh vi OnTimer kích hoaït OnPaint:                                              {
          void CEmpView::OnTimer(UINT nIDEvent)                                               if (!CFrameWnd::PreCreateWindow(cs))
          {                                                                                        return FALSE;
             if (nIDEvent == ID_TIMER) {                                                      cs.dwExStyle &= ~WS_EX_CLIENTEDGE;
                 Invalidate();               // Generates a WM_PAINT                          return TRUE;
             }                                                                              }
             CWnd::OnTimer(nIDEvent);                                                   Duøng CEmpFrame laøm cöûa soå chính cuûa öùng duïng (nhö VD31).
          }
Khung cöûa soå giao dieän chính                                           127    128Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
Thöïc haønh 6: Thöïc hieän öùng duïng nhö VD32. Khi choïn muïc Start cuûa                BOOL CEmpFrame::OnCmdMsg (
    menu thì maøn hình view thöïc hieän chöõ chaïy, ñoàng thôøi noäi dung muïc                                   UINT nID, int nCode, void *pExtra,
    chuyeån thaønh Stop. Neáu ngöôøi duøng choïn laïi muïc naøy (Stop), hoaït ñoäng                              AFX_CMDHANDLERINFO *pHandlerInfo )
    chaïy chöõ döøng laïi vaø noäi dung muïc choïn chuyeån thaønh Start.                     {
                                                                                               // Dispatch command messages to m_view
       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                        if (m_view.OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
       seõ laøm côø hieäu cho chöõ chaïy. Moät soá chænh söûa sau cuûa CEmpView:                     return TRUE; // message was processed by m_view
       - Khôûi ñaàu aán ñònh khoâng chaïy chöõ:                                                  return CFrameWnd::OnCmdMsg ( nID, nCode, pExtra,
          int CEmpView::OnCreate(LPCREATESTRUCT lpCreateStruct)                                                               pHandlerInfo );
          {                                                                                  }
              if (CWnd::OnCreate(lpCreateStruct) == -1)
                                                                                      10.5.3 Duøng MFC wizard taïo öùng duïng vôùi giao dieän chính framewindow:
                  return -1;
              isRun = FALSE;                 // no animation                              Ñ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
              SetTimer( ID_TIMER, 300, NULL );                                        hieän caùc coâng vieäc nhö treân, MFC wizard cung caáp chöùc naêng hoã trôï taïo
              return 0;                                                               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:
        - Haønh vi OnTimer() döïa treân m_isRun ñeå haønh ñoäng:                              Choïn menu File / New.
            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                    Ñieàn caùc thoâng tin trong hoäp hoäi thoaïi New, Sau ñoù choïn OK.
        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.
Khung cöûa soå giao dieän chính                                                129    130Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
AÁn ñònh nhö treân. Choïn Next.                Choïn Next.




        AÁn ñònh nhö treân. Choïn Next.                Choïn StatusBar vaø ToolBar. Sau ñoù choïn Next
Khung cöûa soå giao dieän chính           131   132Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
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.

Khung cöûa soå giao dieän chính                                                        133
CHÖÔNG 11:                                                                                                 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.
              Caùc KIEÁN TRUÙC Document & View                                                             virtual BOOL OnOpenDocument (
                                                                                                               LPCTSTR lpszPathFileName                   // Ñöôøng daãn vaø teân taäp tin
    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                      ); Haønh vi ñöôïc thöïc hieän khi ñoái töôïng CDocument chuaån bò nhaän noäi
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                      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.
baûn – rich text format vaø löu döôùi daïng maõ nhò phaân – compound file), daïng                          virtual BOOL OnSaveDocument (
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.                        LPCTSTR lpszPathName                       // Ñöôøng daãn vaø teân taäp tin
    ÖÙng duïng söû duïng döõ lieäu coù theå deã daøng phaùt trieån treân VC nhôø MFC                       ); Haønh vi ñöôïc thöïc hieän khi noäi dung cuûa document saép ñöôïc löu vaøo
cung caáp boä khung chuaån cho caùc döï aùn thao taùc döõ lieäu. Boä khung naøy bao                        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
goàm ba thaønh phaàn: Document-View-Frame (DVF). Trong ñoù:                                                caùch rieâng cuûa öùng duïng.
       Document:               Quaûn lyù toaøn boä noäi dung döõ lieäu cuûa öùng duïng ñöôïc               BOOL IsModified( ); Traû veà tình traïng caäp nhaät döõ lieäu trong document
                               löu tröõ trong boä nhôù.                                                    ; =TRUE (coù chænh söûa) hoaëc =FALSE (khoâng coù chænh söûa).
       View:                   Thöïc hieän chöùc naêng hieån thò vaø quaûn lyù moät phaàn           11.2 CView:
                               döõ lieäu cuûa document.                                                CView, lôùp keá thöøa töø lôùp CWnd, giuùp quaûn lyù thaønh phaàn view cuûa öùng
       Frame Window: Chöùa view, ñieàu phoái command message töø ngöôøi                             duïng. Trong boä ba DVF, view laø thaønh phaàn giao dieän quan troïng cho pheùp
                               duøng ñeán caùc view moät caùch thích hôï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û.
    Boä khung naøy ñöôïc thöïc hieän thoâng qua caùc lôùp lieân quan sau ñaây.                             CView( ); Taïo laäp ñoái töôïng view.
11.1 CDocument:                                                                                            virtual void OnInitialUpdate( ); Haønh vi ñöôïc thöïc hieän khi ñoái töôïng
   CDocument laø lôùp ñoái tuôïng quaûn lyù moät noäi dung döõ lieäu (Document).                           view ñöôïc keát vaøo danh saùch caùc ñoái töôïng view cuûa document. Vieäc
      CDocument( ); Taïo laäp ñoái töôïng roãng.                                                           keá thöøa nhaèm caøi ñaët caùc aán ñònh khôûi taïo thoâng soá cho view.
      void AddView (                                                                                       virtual void OnActivateView (
          CView* pView                   // Con troû ñoái töôïng view                                          BOOL bActivate,                  // =TRUE: kích hoaït ; vaø ngöôïc laïi
      ); Boå sung view vaøo danh saùch caùc view cuûa document.                                                CView* pActivateView, // Ñoái töôïng view ñöôïc kích hoaït
      void RemoveView (                                                                                        CView* pDeactiveView // Ñoái töôïng view bò ngöøng hoaït ñoäng
          CView* pView                   // Con troû ñoái töôïng view                                      ); Haønh vi ñöôïc thöïc hieän moãi khi ñoái töôïng view ñöôïc kích hoaït hoaëc
      ); Loaïi boû moät view ra khoûi danh saùch caùc view cuûa document.                                  thoâi kích hoaït.
      void UpdateAllViews (                                                                                virtual void OnActivateFrame (
          CView* pSender,                // Ñoái töôïng view mieãn caäp nhaät                                  UINT nState,                     // Traïng thaùi kích hoaït
          LPARAM lHint = 0L,             // Soá hieäu caäp nhaät                                               CFrameWnd* pFrameWnd // Con troû ñoái töôïng frame chöùa view
          CObject* pHint = NULL // Caáu truùc chöùa thoâng tin caäp nhaät                                  ); Haønh vi ñöôïc thöïc hieän moãi khi ñoái töôïng frame chöùa view ñöôïc kích
      ); Thoâng baùo caùc view trong danh saùch view cuûa document caäp nhaät laïi                         hoaït.
      noäi dung hieån thò.                                                                                 Traïng thaùi kích hoaït cuûa frame chöùa view coù theå laø:
      const CString& GetTitle( ); Traû veà noäi dung tieâu ñeà cuûa döõ lieäu.                                 WA_INACTIVE : Frame chöùa view ngöøng hoaït ñoäng.
      virtual void DeleteContents( ); Xoùa roãng noäi dung document.                                           WA_ACTIVE             : Frame chöùa view ñöôïc kích hoaït.


134 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Caùc kieán truùc Document & View                                                     135
CDocument* GetDocument( ); Traû veà con troû ñoái töôïng CDocument                                  virtual BOOL GetDocString (
       ñang söû duïng view.                                                                                    CString& rString,                    // Bieán chuoãi chöùa keát quaû
       virtual void OnUpdate (                                                                                 enum DocStringIndex index // Chæ soá muïc thoâng tin caàn laáy.
           CView* pSender,           // Ñoái töôïng view laøm thay ñoåi döõ lieäu                          );
           LPARAM lHint,             // Töông töï UpdateAllViews()                                         Chæ soá muïc thoâng tin caàn laáy coù theå laø:
           CObject* pHint            // cuûa CDocument                                                     - CDocTemplate::windowTitle :                Tieâu ñeà
       ); Haønh vi ñöôïc thöïc hieän khi noäi dung döõ lieäu trong document lieân                          - CDocTemplate::docName :                    Teân document.
       quan ñeán view ñöôïc caäp nhaät.                                                                    - CDocTemplate::fileNewName : Teân maëc nhieân duøng cho taäp tin
       BOOL DoPreparePrinting( CPrintInfo* pInfo ); Môû hoäp in aán.                                                                                    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
11.3 CFrameWnd:
                                                                                                       ñoái töôïng löu tröõ döõ lieäu thoâng qua haønh vi keá thöøa ñöôïc: Serialize.
    CFrameWnd laø lôùp ñoái töôïng quaûn lyù khung cöûa soå giao dieän chính cuûa
                                                                                                           virtual void Serialize( CArchive& ar );
öùng duïng (chöông 10). Tham gia vaøo boä ba DVF cuûa öùng duïng söû duïng döõ
                                                                                                           throw( CMemoryException ); // Duøng khi ar lieân quan boä nhôù trong.
lieäu, lôùp ñoái töôïng CFrameWnd coù caùc hoaït ñoäng xöû lyù boå sung nhö sau:
                                                                                                           throw( CArchiveException );            // Duøng khi ar laø Archive treân ñóa.
        Khi frame ñöôïc kích hoaït, noù goïi haønh vi OnActivateView cuûa view.
                                                                                                           throw( CFileException );               // Duøng khi ar laø File.
        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             11.5 HOÃ TRÔÏ TÖØ PHÍA ÑOÁI TÖÔÏNG QUAÛN LYÙ ÖÙNG DUÏNG:
        ñöa leân tieâu ñeà cuûa frame.                                                                  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öõ
        Frame thöïc hieän ñieàu phoái command message cho view.                                     lieäu vaø thao taùc döõ lieäu döïa treân boä khung DVF nhö sau:
                                                                                                           void AddDocTemplate (
11.4 CDocTemplate:
                                                                                                                CDocTemplate* pTemplate // Con troû ñoái töôïng quaûn lyù boä DVF
   CDocTemplate laø lôùp ñoái töôïng quaûn lyù boä ba DVF cuûa MFC. Boä ba naøy
                                                                                                           ); Ñöa moät boä ba DVF vaøo danh saùch döõ lieäu quaûn lyù bôûi öùng duïng.
bao goàm CDocument – CView – CFrameWnd.
                                                                                                           BOOL ProcessShellCommand ( CCommandLineInfo& rCmdInfo );
      CDocTemplate (
                                                                                                                Thöïc hieän taùc vuï xöû lyù döõ lieäu theo yeâu caàu cuûa system shell. ÖÙng
          UINT nIDResource,                      // Soá hieäu caùc resource lieân quan:
                                                                                                           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
          CRuntimeClass* pDocClass,              // menu, icon, phím taét, stringTable
                                                                                                           caùc boä DVF trong danh saùch döõ lieäu quaûn lyù bôûi öùng duïng.
          CRuntimeClass* pFrameClass,
                                                                                                                rCmdInfo : Chöùa caùc thoâng soá doøng leänh (neáu coù) bao goàm teân döõ
          CRuntimeClass* pViewClass
                                                                                                           lieäu, leänh thao taùc (edit, open, ...) treân döõ lieäu do shell chuyeån ñeán.
      ); Taïo laäp vaø khôûi taïo thoâng soá cho ñoái töôïng CDocTemplate.
                                                                                                           void ParseCommandLine ( CCommandLineInfo& rCmdInfo );
      - pDocClass: Con troû ñoái töôïng CRuntimeClass quaûn lyù thoâng tin cuûa
                                                                                                                Chuaån bò thoâng soá caàn thieát trong rCmdInfo ñeå chuyeån cho haønh vi
          lôùp document taïi thôøi ñieåm thöïc thi chöông trình.
                                                                                                           ProcessShellCommand. Caùc thoâng soá naøy töông öùng vôùi noäi dung tham
      - pFrameClass: Con troû ñoái töôïng CRuntimeClass quaûn lyù thoâng tin
                                                                                                           soá doøng leänh cuûa öùng duïng.
          cuûa lôùp frame window taïi thôøi ñieåm thöïc thi chöông trình.
                                                                                                           afx_msg void OnFileNew(); Haønh vi traû lôøi cho WM_COMMAND
      - pViewClass: Con troû ñoái töôïng CRuntimeClass quaûn lyù thoâng tin
                                                                                                           ñöôïc phaùt ra bôûi muïc menu coù soá hieäu ID_FILE_NEW.
          cuûa lôùp view taïi thôøi ñieåm thöïc thi chöông trình.
                                                                                                           afx_msg void OnFileOpen(); Haønh vi traû lôøi cho WM_COMMAND
      Con troû chöùa thoâng tin thi haønh cuûa moät lôùp nhaän ñöôïc töø macro sau:
                                                                                                           ñöôïc phaùt ra bôûi muïc menu coù soá hieäu ID_FILE_OPEN.
          CRuntimeClass* RUNTIME_CLASS ( Teân_Lôùp )

136 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Caùc kieán truùc Document & View                                                     137
afx_msg void OnFilePrintSetup(); Haønh vi xöû lyù WM_COMMAND                                        Ñoái töôïng view:
       ñöôï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:




                                                                                                       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:



       Ñoái töôïng Frame window:




                                                                                                           AÁn ñònh nhö treân. Choïn OK.

138 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Caùc kieán truùc Document & View                                                   139
AÁn ñònh nhö treân. Choïn Next.                                                                     Choïn None (döõ lieäu chæ chöùa vaên baûn). Choïn Next.




       Choïn None (khoâng söû duïng cô sôû döõ lieäu). Choïn Next.                                         AÁn ñònh caùc muïc caàn caàn thieát:
140 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Caùc kieán truùc Document & View                                 141
- Printing and print preview: Cho pheùp chöùc naêng in aán.                                         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.
       - MAPI: Söû duïng dòch vuï mail cho döõ lieäu cuûa öùng duïng.                                      Löu yù: Choïn lôùp CTxtDVFView, khai baùo lôùp cô sôû laø CEditView ñeå
       Choïn Next.                                                                                         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.




       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.




                                                                                                           AÁn ñònh nhö treân. Choïn Next.




142 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Caùc kieán truùc Document & View                                                        143
Choïn None (khoâng söû duïng cô sôû döõ lieäu). Choïn Next.                                         Choïn caùc muïc caàn thieát (11.7). Choïn Next.




       ÖÙng duïng söû duïng OLE (Container) töø öùng duïng khaùc. Choïn Next.                              Choïn caùc muïc caàn thieát (11.7). Choïn Next.
144 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Caùc kieán truùc Document & View                         145
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.
                                                                                                           Choïn None (khoâng söû duïng cô sôû döõ lieäu). Choïn Next.
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.                                                                     Choïn None. Choïn Next.
146 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Caùc kieán truùc Document & View                                     147
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
       AÁn ñònh caùc muïc caàn thieát; choïn chöùc naêng in aán. Choïn Next.                               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.
       Choïn caùc muïc caàn thieát (11.7). Choïn Next.
148 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Caùc kieán truùc Document & View                                            149
CImageList* SetImageList (                                                                              CImageList* pImagelist, // Con troû ñoái töôïng imagelist
           CImageList* pImagelist, // Ñoái töôïng imagelist                                                    int imgStyle                     // Thoâng soá qui ñònh caùch söû duïng
           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.
       ); 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ø:
       Caùch söû duïng coù theå laø:                                                                           TVSIL_NORMAL : AÛnh duøng cho caùc muïc bình thöôøng.
           LVSIL_NORMAL : AÛnh bình thöôøng.                                                                   TVSIL_STATE :             AÛnh duøng cho caùc muïc ñaëc tröng do ngöôøi
           LVSIL_SMALL               : AÛnh nhoû.                                                                                        duøng ñònh nghóa.
       int InsertItem (                                                                                    UINT GetCount( ); Traû veà soá muïc cuûa treeview.
           int nItem,                // Chæ soá muïc ñöôïc theâm                                           HTREEITEM GetRootItem( ); Traû veà handle cuûa phaàn töû ñaàu goác.
           LPCTSTR lpszItem, // Noäi dung thoâng baùo cuûa muïc                                            HTREEITEM GetFirstVisibleItem( ); Traû veà handle cuûa phaàn töû hieån
           int nImage                // Chæ soá aûnh trong Imagelist maø muïc söû duïng                    thò ñaàu tieân trong vuøng nhìn thaáy cuûa treeview (NULL: Khoâng coù).
       ); Theâm moät muïc vaøo listview.                                                                   HTREEITEM GetSelectedItem(); Traû veà handle cuûa phaàn töû ñang ñöôïc
       BOOL DeleteItem (                                                                                   choïn.
           int nItem                 // Soá hieäu cuûa muïc                                                HTREEITEM GetNextVisibleItem( HTREEITEM hItem ); Traû veà
       ); Xoùa moät muïc trong listview.                                                                   handle cuûa phaàn töû hieån thò keá sau phaàn töû coù handle laø hItem.
       BOOL DeleteAllItems( ); Xoùa roãng listview.                                                        HTREEITEM GetPrevVisibleItem( HTREEITEM hItem ); Traû veà
       BOOL GetItem (                                                                                      handle cuûa phaàn töû hieån thò keá tröôùc phaàn töû coù handle laø hItem.
           LVITEM* pItem             // Con troû ñeán caáu truùc nhaän thoâng tin                          HTREEITEM InsertItem (
       ); Laáy thoâng tin lieân quan ñeán muïc coù soá thöù töï nItem.                                         LPCTSTR lpszItem,                // Noäi dung thoâng baùo cuûa muïc
       BOOL SetItem (                                                                                          int nImage,                      // Chæ soá aûnh duøng cho muïc ôû traïng thaùi
           LVITEM* pItem             // Con troû ñeán caáu truùc chöùa thoâng soá                              int nImageSelected,              // bình thöôøng vaø khi muïc ñöôïc choïn.
       ); Ñaët thoâng soá cho muïc coù chæ soá laø pItem ->iItem.                                              HTREEITEM parent = TVI_ROOT,                      // Con troû muïc cha
       BOOL EnsureVisible (                                                                                    HTREEITEM hInsertAfter = TVI_LAST // Con troû muïc ñöùng tröôùc
           int nItem,                // Chæ soá phaàn töû caàn nhìn thaáy.                                 ); Theâm moät muïc vaøo treeview, traû veà handle cuûa phaàn töû môùi theâm.
           BOOL bPartialIsOK // =FALSE: Toaøn boä, =TRUE: Moät phaàn                                       BOOL DeleteItem (
       ); Cuoän danh saùch ñeå nhìn thaáy phaàn töû nItem neáu phaàn töû naøy khoâng                           HTREEITEM hItem /* handle cuûa muïc*/ ); Xoùa muïc cuûa treeview.
       ñöôïc nhìn thaáy trong vuøng hieån thò cho pheùp cuûa view.                                         BOOL DeleteAllItems( ); Xoùa roãng noäi dung treeview.
11.10.2 CTreeView:                                                                                         BOOL GetItem (
   CTreeView laø lôùp ñoái töôïng quaûn lyù maøn hình view coù caáu truùc caây.                                TVITEM* pItem                // Con troû ñeán caáu truùc nhaän thoâng tin
      CTreeView( ); Taïo laäp ñoái töôïng treeview.                                                        ); Laáy thoâng tin cuûa phaàn töû pItem->iItem.
      CTreeCtrl& GetTreeCtrl( ); Traû veà ñoái töôïng CTreeCtrl laøm cô sôû cho                            BOOL SetItem (
      caùc taùc vuï lieân quan TreeView.                                                                       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.
       Caùc haønh vi ñaëc tröng cuûa CTreeCtrl:
                                                                                                           BOOL SetItemImage (
       BOOL SetBkColor( COLOREF cr ); Ñaët maøu neàn cho treeview.
                                                                                                               HTREEITEM hItem,             // handle cuûa phaàn töû
       COLORREF GetBkColor( ); Traû veà giaù trò maøu neàn cuûa treeview.
                                                                                                               int nImage,                  // Chæ soá aûnh duøng cho muïc ôû traïng thaùi
       CImageList* SetImageList (
150 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Caùc kieán truùc Document & View                                                      151
int nSelectedImage          // bình thöôøng vaø khi muïc ñöôïc choïn.                           BOOL Create (
       ); AÁn ñònh chæ soá aûnh trong imagelist duøng cho muïc.                                                CWnd* pParentWnd,                    // Con troû ñoái töôïng cöûa soå cha
       BOOL SetItemText (                                                                                      int nMaxRows,                        // Soá haøng toái ña cuûa caùc pane
           HTREEITEM hItem,            // handle cuûa muïc                                                     int nMaxCols,                        // Soá coät toái ña cuûa caùc pane
           LPCTSTR lpszItem            // Noäi dung thoâng baùo                                                SIZE sizeMin,                        // Kích thöôùc toái thieåu cuûa moãi pane
       ); AÁn ñònh laïi noäi dung thoâng baùo cuûa muïc trong treeview.                                        CCreateContext* pContext, // Thoâng soá lieân keát, laáy töø frame
                                                                                                               DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_HSCROLL |
11.10.3 CSplitterWnd:
                                                                                                                                         WS_VSCROLL | SPLS_DYNAMIC_SPLIT,
   Vuøng client trong frame window cho pheùp caøi ñaët moät cöûa soå view duy
                                                                                                               UINT nID = AFX_IDW_PANE_FIRST
nhaát. Ñeå loàng ñöôïc nhieàu view vaøo frame ta phaûi phaân chia vuøng client cuûa
                                                                                                           ); Khôûi taïo thoâng soá spliiter window vôùi soá haøng, coät thay ñoåi ñöôïc.
frame. Vieäc phaân chia naøy ñöôïc hoã trôï bôûi coâng cuï splitter window.
                                                                                                           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
    Moãi splitter window cho pheùp taùch vuøng client cuûa frame window thaønh
                                                                                                           lôùp view töông öùng taïi thôøi ñieåm thöïc thi chöông trình. Xem (11.4).
nhieàu haøng vaø coät. Sau ñoù, moãi oâ (pane) nhaän ñöôïc töø splitter naøy coù theå laïi
                                                                                                           void SetColumnInfo (
ñöôï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:
                                                                                                               int col,                             // Chæ soá coät trong splitter
       - Splitter thöù nhaát taùch frame window thaønh hai doøng vaø 1 coät.
                                                                                                               int cxIdeal,                         // Ñoä roäng mong muoán vaø
       - Splitter thöù hai taùch pane thöù nhaát cuûa splitter thöù nhaát thaønh 2 coät
                                                                                                               int cxMin                            // ñoä roäng toái thieåu (tính baèng pixel)
           vaø 1 doøng.
                                                                                                           ); AÁn ñònh thoâng soá veà ñoä roäng cho coät trong splitter window.
    Moãi pane nhaän ñöôïc töø caùc splitter window cho pheùp gaén moät maøn hình
                                                                                                           void GetColumnInfo (
view. Nhö vaäy, thoâng qua caùc splitter window, frame window coù theå chöùa
                                                                                                               int col,                             // Chæ soá coät
nhieàu maøn hình view ñoàng thôøi.
                                                                                                               int& cxCur,                          // Tham bieán chöùa ñoä roäng hieän thôøi
    Nhaèm tieän vieäc thao taùc vôùi coâng cuï splitter window, MFC cung caáp lôùp
                                                                                                               int& cxMin                           // Tham bieán chöùa ñoä roäng toái thieåu
ñoái töôïng CSplitterWnd cho pheùp quaûn lyù caùc spliiter window trong öùng duïng.
                                                                                                           ); Laáy thoâng tin veà ñoä roäng cuûa coät.
Caùc haønh vi ñaëc tröng cuûa lôùp CSplitterWnd nhö sau:
                                                                                                           void SetRowInfo (
       CSplitterWnd( ); Taïo laäp ñoái töôïng splitter window.
152 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Caùc kieán truùc Document & View                                                       153
int row,                            // Chæ soá haøng                                        Thöïc haønh 1: Vieát öùng duïng nhö VD30. Taïo splitter trong CEmpFrame vôùi
           int cyIdeal,                        // Ñoä cao mong muoán                                   hai view: beân traùi laø treeview (duøng lôùp view keá thöøa töø CTreeView), beân
           int cyMin                           // Ñoä cao toái thieåu                                  phaûi laø list (duøng lôùp view keá thöøa töø ListView).
       ); AÁn ñònh thoâng soá veà ñoä cao cho haøng trong splitter window.                                 Taïo döï aùn VD35 töông töï VD30.
       void GetRowInfo (                                                                                   Ñaêng kyù söû duïng CTreeView vaø CListView:
           int row,                            // Chæ soá haøng                                            Trong taäp tin stdafh.h cuûa döï aùn, boå sung chæ thò:
           int& cyCur,                         // Tham bieán chöùa ñoä cao hieän thôøi                         #include <afxcview.h>
           int& cyMin                          // Tham bieán chöùa ñoä cao toái thieåu                     Boå sung vaøo döï aùn hai lôùp môùi:
       ); Laáy thoâng tin veà ñoä cao cuûa haøng.                                                              CEmpTree keá thöøa töø CTreeView
       void RecalcLayout( ); Caäp nhaät thoâng soá aán ñònh môùi cuûa splitter.                                CEmpList keá thöøa töø CListView.
       CWnd* GetPane (                                                                                     Caùch thöïc hieän töông töï nhö ñaõ laøm vôùi CEmpWnd, muïc (5.4.1).
           int row, int col                    // Chæ soá haøng vaø coät cuûa pane                         Khai baùo ñoái töôïng thuoäc tính protected m_splitter kieåu CSplitterWnd.
       ); Traû veà con troû ñoái töôïng view caøi trong pane.                                              Haønh vi OnCreateClient cuûa CEmpFrame thöïc hieän khôûi taïo vaø caøi ñaët
11.10.4 SÖÛ DUÏNG SPLITTERWND TRONG FRAME WINDOW:                                                          caùc pane, view caàn thieát:
      Khai baùo ñoái töôïng thuoäc lôùp SplitterWnd nhö laø thuoäc tính cuûa frame.                        BOOL CEmpFrame::OnCreateClient( LPCREATESTRUCT lpcs,
                                                                                                                                              CCreateContext* pContext )
       CSplitterWnd m_splitter;                                                                            {
                                                                                                             if (!CFrameWnd::OnCreateClient(lpcs, pContext))
       Duøng haønh vi OnCreateClient cuûa frame ñeå taïo caùc pane vaø caøi view:                                   return FALSE;
       BOOL CEmpFrame::OnCreateClient (
                                          LPCREATESTRUCT lpcs,                                                 m_splitter.CreateStatic(this, 1, 2);
                                          CCreateContext* pContext )                                           m_splitter.CreateView( 0, 0, RUNTIME_CLASS(CEmpTree),
       {                                                                                                                                     CSize(120,0), NULL );
         if (!CFrameWnd::OnCreateClient(lpcs, pContext))                                                       m_splitter.CreateView(0,1, RUNTIME_CLASS(CEmpList),
              return FALSE;                                                                                                                  CSize(0,0), NULL );
                                                                                                               return TRUE;
           // 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:                                     Thöïc haønh 2: Thöïc hieän öùng duïng töông töï VD35. Töï ñoäng thöïc hieän boå
           m_splitter.CreateView ( 0, 0, RUNTIME_CLASS(viewClass1),                                    sung ba phaàn töû trong treeview, moãi phaàn töû coù hai phaàn töû con. Caùc phaàn
                                      CSize(120,0), NULL);                                             töû ñeàu coù hình minh hoïa cho traïng thaùi ñöôïc choïn vaø khoâng ñöôïc choïn.
           m_splitter.CreateView(0,1, RUNTIME_CLASS(viewClass2),                                           Taïo döï aùn VD36 töông töï VD35.
                                      CSize(0,0), NULL);                                                   Boå sung bitmap resource chöùa hai aûnh cuøng kích thöôùc:       . Ñaët soá
           ...                            // Thöïc hieän caùc caøi ñaët khaùc                              hieäu cho bitmap resource laø IDB_IMGTREE.
           return TRUE;                                                                                    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:
11.10.5 CAÙC VÍ DUÏ THÖÏC HAØNH:                                                                           int CEmpTree::OnCreate(LPCREATESTRUCT lpCreateStruct)

154 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Caùc kieán truùc Document & View                                                 155
{                                                                                            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
           if (CTreeView::OnCreate(lpCreateStruct) == -1)                                           password baûo veä döõ lieäu. Chæ môû ñöôïc döõ lieäu neáu coù password hôïp leä.
                  return -1;                                                                        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);
           static CImageList img;   // use only in this function
                                                                                                    Backward, Forward, hoäp combobox nhaäp vaø ghi nhôù caùc URL ñaõ nhaäp.
           img.Create(IDB_IMGTREE, 16, 2, RGB(255,255,255));
                                                                                                    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
           CTreeCtrl& myCtrl = GetTreeCtrl();   // Based control                                    treân maùy nhö windows explorer.
           myCtrl.SetImageList(&img, TVSIL_NORMAL);                                                     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
           HTREEITEM hihi;                              // Add needed items                         vaø caäp nhaät döõ lieäu cho caùc baûng trong cô sôû döõ lieäu.
           hihi = myCtrl.InsertItem("Muc 1", 0, 1);                                                 6. Vieát öùng duïng RTF View. Trong maøn hình view, khi di chuyeån chuoät leân
                  myCtrl.InsertItem("Muc 11", 0, 1, hihi);                                          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
                  myCtrl.InsertItem("Muc 12", 0, 1, hihi);
                                                                                                    thaønh , ngöôïc laïi chænh daïng chuoät veà daïng maëc nhieân cuûa heä thoáng.
           hihi = myCtrl.InsertItem("Muc 2", 0, 1);
                  myCtrl.InsertItem("Muc 21", 0, 1, hihi);                                          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
                  myCtrl.InsertItem("Muc 22", 0, 1, hihi);                                          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
           hihi = myCtrl.InsertItem("Muc 3", 0, 1);                                                 ñ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.
                  myCtrl.InsertItem("Muc 31", 0, 1, hihi);                                          8. Quan saùt chöông trình tra cöùu töø ñieån. Vieát öùng duïng RTF view söû duïng
                  myCtrl.InsertItem("Muc 321", 0, 1,                                                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
                                     myCtrl.InsertItem("Muc 32", 0, 1, hihi));                      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.
           return 0;                                                                                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
       Haønh vi keá thöøa PreCreateWindow aán ñònh thoâng soá daïng treeview:                       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,
       BOOL CEmpTree::PreCreateWindow(CREATESTRUCT& cs) {                                           Khi click vaøo cöûa soå view, noäi dung chænh söûa ñöôïc caäp nhaät vaøo view.
         cs.style |= TVS_HASLINES|TVS_LINESATROOT|                                                  10. Quan saùt Yahoo Messenger!. Thöïc hieän öùng duïng giao dieän rtf nhö sau:
                     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:


156 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Caùc kieán truùc Document & View                                                      157
CHÖÔNG 12:                                                                                                 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:
                     Moät soá vaán ñeà trong windows                                                       free((void*)m_pszProfileName);                   // Huûy boû vuøng nhôù caáp phaùt
                                                                                                           m_pszProfileName=_tcsdup(_T(“ÑöôøngDaãn-TeânTaäpTin_INI”));
12.1 TAÄP TIN INI:                                                                                         BOOL WriteProfileString (
    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                         LPCTSTR lpszSection,                     // Teân thaønh phaàn
cuûa öùng duïng trong moâi tröôøng windows phieân baûn 3.x vaø 9x. Caùc noäi dung                              LPCTSTR lpszEntry,                       // Teân muïc
naøy ñöôïc chia thaønh caùc thaønh phaàn (section) phaân bieät theo chöùc naêng hoaëc                          LPCTSTR lpszValue                        // Giaù trò cuûa muïc (kieåu chuoãi)
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                      ); Löu giaù trò kieåu chuoãi cuûa moät muïc trong thaønh phaàn 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                        BOOL WriteProfileInt (
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                     LPCTSTR lpszSection,                     // Teân thaønh phaàn
ngaên caùch vôùi teân muïc baèng daáu "=".                                                                     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.
   Xeùt ví duï laø taäp tin WIN.INI noùi treân:                                                            UINT GetProfileInt (
      - windows            : Teân thaønh phaàn (section).                                                      LPCTSTR lpszSection,                     // Teân thaønh phaàn
      - NullPort           : Teân muïc (entry).                                                                LPCTSTR lpszEntry,                       // Teân muïc. Neáu muïc ñoïc khoâng
      - None               : Giaù trò cuûa muïc NullPort.                                                      int nDefault                             // coù thì söû duïng giaù trò naøy.
   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                    ); Traû veà giaù trò kieåu soá nguyeân cuûa moät muïc trong thaønh töông öùng.
töôïng quaûn lyù öùng duïng CWinApp thoâng qua caùc thuoäc tính, haønh vi sau:                             BOOL GetProfileBinary (
       const char* m_pszAppName : Löu chuoãi teân cuûa öùng duïng. Giaù trò                                    LPCTSTR lpszSection,                     // Teân thaønh phaàn
       thuoäc tính naøy coù theå ñöôïc thay ñoåi ñöôïc nhö sau:                                                LPCTSTR lpszEntry,                       // Teân muïc
                                                                                                               LPBYTE *pData,                           // Ñòa chæ con troû vuøng ñeäm
       free( (void*) m_pszAppName );              // Giaûi phoùng vuøng nhôù
                                                                                                               UINT *nBytes                             // Ñòa chæ bieán nhaän kích thöôùc.
       m_pszAppName =_tcsdup( _T(“Teân_môùi_cuûa_öùng_duïng”) );
                                                                                                           ); Ñoïc khoái maõ nhò phaân cuûa moät muïc vaøo vuøng ñeäm.

158 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Moät soá vaán ñeà trong Windows                                                      159
Haønh vi traû veà giaù trò TRUE neáu taùc vuï ñoïc thaønh coâng.                                - Moãi muïc trong caáu truùc caây (tree) goïi laø khoùa (key).
       Vôùi: pData : Ñòa chæ bieán con troû quaûn lyù vuøng ñeäm nhaän thoâng tin.                     - Khoùa laù (khoâng coù con) laø thaønh phaàn chöùa caùc muïc.
             nBytes : Ñòa chæ bieán chöùa kích thöôùc thoâng tin ñoïc ñöôïc.                           - Moãi muïc coù moät teân ñeå nhaän bieát vaø coù moät giaù trò xaùc ñònh.
         ÖÙng duïng caàn giaûi phoùng vuøng ñeäm pData khi chaám döùt söû duïng.                       Haønh vi SetRegistryKey cuûa lôùp ñoái töôïng CWinApp cho pheùp ñònh höôùng
          Ñoaïn chöông trình sau thöïc hieän ghi xuoáng thaønh phaàn MY_TEST                           vieäc ñoïc/ghi giaù trò caùc muïc leân system registry thay vì söû duïng taäp tin INI
       cuûa taäp tin INI cuûa öùng duïng: MyName = Mr.Emp vaø MyVer = 11.                              nhö (12.1). Haønh vi loaïi protected naøy coù cuù phaùp nhö sau:
       CWinApp* pApp = AfxGetApp();              // Ñoái töôïng quaûn lyù öùng duïng                       void SetRegistryKey ( UINT lpszRegistryKey );
       pApp->WriteProfileString ("MY_TEST", "MyName", "Mr.Emp");                                           lpszRegistryKey : Thoâng thöôøng laø chuoãi chöùa teân haõng phaàn meàm; ví
       pApp->WriteProfileInt ("MY_TEST", "MyVer", 11);                                                     duï Netscape. Giaù trò naøy trôû thaønh khoùa con cuûa khoùa Software thuoäc
           Ñoaïn chöông trình sau thöïc hieän ñoïc töø thaønh phaàn MY_TEST cuûa                           khoùa goác HKEY_CURRENT_USER trong system registry.
       taäp tin INI giaù trò hai muïc noùi treân.                                                      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
       CWinApp* pApp = AfxGetApp();                // Ñoái töôïng quaûn lyù öùng duïng                 m_pszAppName cuûa ñoái töôïng öùng duïng) trôû thaønh khoùa con cuûa khoùa xaùc
       CString myName = pApp->GetProfileString (                                                       ñònh bôûi lpszRegistryKey, vaø caùc thaønh phaàn chöùa caùc muïc trôû thaønh khoùa
                                             "MY_TEST", "MyName", "Mr.Emp" );                          con cuûa khoùa m_pszAppName. Moät thöù töï ñöôïc thieát laäp nhö sau:
       UINT myVer = pApp->GetProfileInt ("MY_TEST", "MyVer", 11);                                         HKEY_CURRENT_USERSoftware<Teân_haõng_phaàn_meàm>
12.2 SYSTEM REGISTRY:                                                                                                         <Teân_öùng_duïng><Teân_thaønh_phaàn><Caùc_muïc>.
    System Registry laø cô sôû döõ lieäu do windows quaûn lyù, ñöôïc söû duïng ñeå löu                 Thöïc hieän öùng duïng IniReg. ÖÙng duïng ñaêng kyù söû duïng system registry
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.                     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ö
System registry coù caáu truùc nhö sau (chöông trình RegEdit.exe).                                     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:
            (System registry ôû moät maùy söû duïng phieân baûn Windows-Me )                               - Môû dialog resource, caøi ñaët caùc control sau:

160 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Moät soá vaán ñeà trong Windows                                                      161
- Hoäp nhaäp giaù trò muïc MyName Edit    IDC_WRITE_NAME                                      Taskbar laø thanh coâng cuï ñaëc bieät cuûa öùng duïng desktop trong windows.
         - Hoäp nhaäp giaù trò muïc MyVer   Edit   IDC_WRITE_VERSION                                Noäi dung cuûa taskbar ñöôïc chia thaønh 4 thaønh phaàn chính:
         - Hoäp hieån thò muïc MyName       Static IDC_READ_NAME                                       - Start menu:               Muïc kích hoaït heä thoáng menu caùc öùng duïng.
         - Hoäp hieån thò muïc MyVer        Static IDC_READ_VERSION                                    - Quick Launch Bar: Danh muïc caùc öùng duïng thöôøng duøng.
         - Nuùt choïn thöïc hieän ghi       Button IDC_WRITE                                           - Taskbar Buttons:          Danh saùch caùc öùng duïng ñang chaïy.
         - Nuùt choïn thöïc hieän ñoïc      Button IDC_READ                                            - Status Area:              Chöùa icon giao dieän cuûa caùc öùng duïng ñang chaïy.
       - Haønh vi OnWrite öùng vôùi nuùt IDC_WRITE löu giaù trò caùc muïc:                                                         ÖÙng duïng coù theå nhaän ñöôïc tín hieäu nhaäp cuûa
           void CIniRegDlg::OnWrite()                                                                                              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.
              CWinApp* pApp = AfxGetApp();                                                             Vieäc caøi ñaët hoaëc huûy boû icon giao dieän cuûa öùng duïng treân status area
              CString myName;                                                                       ñuôïc thöïc hieän thoâng quan haøm sau:
              UINT      myVer;                                                                         BOOL Shell_NotifyIcon (
              GetDlgItemText(IDC_WRITE_NAME, myName);                                                      DWORD dwMessage,                        // Taùc vuï thöïc hieän
              myVer = GetDlgItemInt(IDC_WRITE_VERSION);                                                    PNOTIFYICONDATA lpdata                  // Caáu truùc chöùa thoâng soá lieân quan
              pApp->WriteProfileString("MY_TEST", "MyName", myName);                                   ); Traû veà giaù trò TRUE neáu taùc vuï thöïc hieän thaønh coâng.
              pApp->WriteProfileInt("MY_TEST", "MyVer", myVer);                                        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.
       - Haønh vi OnRead öùng vôùi nuùt IDC_READ ñoïc giaù trò caùc muïc:                                  NIM_MODIFY : Thay ñoåi thoâng soá lieân quan icon giao dieän.
          void CIniRegDlg::OnRead()                                                                        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á.
              CWinApp* pApp = AfxGetApp();
              CString myName;                                                                          Caùc tröôøng trong caáu truùc NOTIFYICONDATA coù yù nghóa nhö sau:
              UINT         myVer;                                                                      typedef struct _NOTIFYICONDATA {
              myName = pApp->GetProfileString( "MY_TEST",                                                 DWORD cbSize;                 // Kích thuôùc caáu truùc
                                                 "MyName", "NoName" );                                    HWND hWnd;                    // Handle cuûa cöûa soå xöû lyù message töø icon
              myVer = pApp->GetProfileInt( "MY_TEST", "MyVer", 0 );                                       UINT uID;                     // Soá hieäu cuûa icon treân status area
              SetDlgItemText( IDC_READ_NAME, myName );                                                    UINT uFlags;                  // Qui ñònh caùc thoâng soá coù yù nghóa
              SetDlgItemInt( IDC_READ_VERSION, myVer );                                                   UINT uCallbackMessage; // Soá hieäu message cuûa icon göûi cöûa soå.
          }                                                                                               HICON hIcon;                  // Handle cuûa icon ñöôïc söû duïng
       Bieân dòch vaø chaïy öùng duïng.                                                                   TCHAR szTip[64];              // Noäi dung chuù thích cuûa icon giao dieän.
12.3 VUØNG STATUS AREA TREÂN TASKBAR:                                                                  } 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.

162 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Moät soá vaán ñeà trong Windows                                                     163
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               Caùc böôùc thöïc hieän döï aùn cuûa öùng duïng:
       moät message ñeán cöûa soå xöû lyù lieân quan icon vôùi noäi dung nhö sau:                         Duøng MFC Wizard taïo öùng duïng TaskbarIcon coù giao dieän laø dialog.
       - message         : Soá hieäu message cuûa icon (trong uCallbackMessage).                          Thöïc hieän caùc boå sung sau ñaây cho lôùp dialog CTaskbarIconDlg:
       - wParam          : Soá hieäu cuûa icon.                                                           - Môû dialog resource, caøi ñaët caùc control sau:
       - lParam          : Chöùa caùc traïng thaùi cuûa chuoät hoaëc phím maø ngöôøi                         - Hoäp thoâng baùo traïng thaùi icon Static           IDC_ICON_INFO
                           duøng ñaõ söû duïng ñeå taùc ñoäng leân icon giao dieän.                          - Nuùt thöïc hieän ñaët icon              Button IDC_ICON_SET
       Haønh vi WindowProc cuûa cöûa soå xöû lyù lieân quan seõ tuøy nghi xöû lyù:                           - Nuùt thöïc hieän xoùa icon              Button IDC_ICON_REMOVE
       LRESULT CTaskbarIconDlg::WindowProc ( UINT message,                                                - Khai baùo thuoäc tính protected m_isIconShow kieåu luaän lyù, ñeå ghi
                                        WPARAM wParam, LPARAM lParam )                                       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.
          if ( message == Icon_uCallbackMessage ) {                                                       - Haønh vi OnInitDialog chuaån bò caùc thoâng soá:
               switch ( lParam ) {
                                                                                                             BOOL CTaskbarIconDlg::OnInitDialog()
               …                // Xöû lyù bieán coá phím / chuoät trong lParam                              {
               }                                                                                                 CDialog::OnInitDialog();
               return 0 ;
                                                                                                                 m_isIconShow = FALSE;                 // Baét ñaàu, icon chöa ñöôïc ñaët.
          }
                                                                                                                 return TRUE;
          return CDialog::WindowProc(message, wParam, lParam);
                                                                                                             }
       }
                                                                                                           - Haønh vi OnIconSet öùng vôùi nuùt choïn IDC_ICON_SET thöïc hieän caøi
   Giaû söû caàn thöïc hieän öùng duïng nhö sau:                                                             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
   - 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.                                             - Haønh vi OnIconRemove öùng vôùi nuùt choïn IDC_ICON_REMOVE
   - Hoäp thoâng baùo cho bieát caùc bieán coá nhaäp taùc ñoäng leân icon.                                   thöïc hieän xoùa icon giao dieän khoûi status area:

164 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Moät soá vaán ñeà trong Windows                                                   165
void CTaskbarIconDlg::OnIconRemove()                                                      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ôû
              if ( !m_isIconShow ) return;                                                          roäng .SCR. Ñeå söû duïng öùng duïng ScreenSaver, ta cheùp taäp tin chöông trình
              NOTIFYICONDATA dt;                                                                    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
              memset(&dt, 0, sizeof(NOTIFYICONDATA));
                                                                                                    Control Panel (Desktop Properties) caøi ñaët öùng duïng ScreenSaver cho heä
              dt.cbSize = sizeof(NOTIFYICONDATA);
              dt.uID           = 100;                                                               thoáng thoâng qua trang Screen Saver:
              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;
                   }                                                                                   Teân taäp tin chöông trình cuûa öùng duïng ScreenSaver ñöôïc duøng laøm teân
                   return 0;
                                                                                                       ScreenSaver trong danh saùch löïa choïn caùc ScreenSaver. Neáu ta khai baùo
              }
              return CDialog::WindowProc(message, wParam, lParam);                                     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
       Bieân dòch vaø chaïy öùng duïng.                                                                laøm teân ScreenSaver trong danh saùch noùi treân.

166 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Moät soá vaán ñeà trong Windows                                                 167
Khi khoaûng thôøi gian maø ngöôøi duøng ngöøng töông taùc vôùi heä thoáng vöôït                     (a) Chaïy minh hoïa tröïc tieáp ScreenSaver: Vuøng chaïy maãu laø cöûa soå con
   quaù giaù trò aán ñònh Wait thì heä thoáng töï ñoäng thöïc hieän öùng duïng                             trong hoäp hoäi thoaïi Display Properties. Handle cuûa cöûa soå naøy laø moät
   ScreenSaver.                                                                                            giaù trò trong tham soá doøng leänh coù noäi dung nhö sau:
12.4.1 Ñaëc ñieåm:                                                                                               "/p xxxx"
   Khaùc vôùi caùc öùng duïng thoâng thöôøng khaùc, öùng duïng ScreenSaver phaûi coù                         Trong ñoù:
khaû naêng öùng xöû khaùc nhau trong caùc tình huoáng khaùc nhau maø öùng duïng                              - /p (hoaëc /P): Giaù trò phaûn aùnh tình huoáng thöïc hieän.
ñöôï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                   - xxxx : Caùc chöõ soá phaûn aùnh giaù trò handle cuûa cöûa soå con.
ScreenSaver laø:                                                                                             Caùch laáy giaù trò handle naøy töø tham soá doøng leänh nhö sau:
   (a) Chaïy minh hoïa tröïc tieáp ScreenSaver trong maøn hình con cuûa hoäp hoäi                                HWND parent;                         // Bieán chöùa handle
         thoaïi: Khi ngöôøi duøng click choïn öùng duïng ScreenSaver trong danh                                  sscanf(m_lpCmdLine+3, "%d", &parent);
         saùch caùc ScreenSaver cuûa hoäp hoäi thoaïi Display Properties / Screen                            ÔÛ cheá ñoä naøy, ScreenSaver ñöôïc thieát keá theo kieåu öùng duïng coù
         Saver.                                                                                              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
   (b) Thöïc hieän chöùc naêng aán ñònh thoâng soá cuûa ScreenSaver: Khi ngöôøi                              thöïc. Cöûa soå naøy ñöôïc loàng vaøo vò trí cuûa cöûa soå con noùi treân.
         duøng click choïn muïc Setting... sau khi ñaõ choïn öùng duïng ScreenSaver                    (b) Thöïc hieän chöùc naêng aán ñònh thoâng soá: Noäi dung tham soá doøng leänh
         trong danh saùch caùc ScreenSaver.                                                                nhö sau:
   (c) Thöïc hieän chöùc naêng ñaët Password cuûa ScreenSaver: Khi ngöôøi duøng                                  "/c xxxx"
         click choïn muïc Password Setting... sau khi ñaõ choïn öùng duïng                                   Trong ñoù:
         ScreenSaver trong danh saùch caùc ScreenSaver. Chæ söû duïng cho caùc                               - /c (hoaëc /C) : Giaù trò phaûn aùnh tình huoáng thöïc hieän.
         phieân baûn Win9x trôû veà tröôùc.                                                                  - xxxx : Handle cuûa hoäp hoäi thoaïi (dialog).
   (d) Chaïy minh hoïa ScreenSaver trong maøn hình thöïc: Khi ngöôøi duøng                                   ÔÛ cheá ñoä naøy, ScreenSaver ñöôïc thieát keá theo kieåu öùng duïng coù
         click choïn muïc Preview sau khi ñaõ choïn öùng duïng ScreenSaver trong                             maøn hình giao dieän chính laø dialog vôùi caùc muïc nhaäp cho pheùp ñieàu
         danh saùch caùc ScreenSaver. Cheá ñoä chaïy naøy töông töï cheá ñoä chaïy                           chænh thoâng soá lieân quan ñeán caùch thöùc hoaït ñoäng cuûa ScreenSaver
         thöïc nhaèm giuùp ngöôøi duøng hình dung ñöôïc hoaït ñoäng thöïc cuûa                               ôû cheá ñoä thöïc. Dialog giao dieän laø dialog khoùa (modal dialog) vaø ñoái
         ScreenSaver.                                                                                        töôïng cöûa soå cha cuûa noù laø hoäp hoäi thoaïi noùi treân.
   (e) Chaïy ScreenSaver: Khi khoaûng thôøi gian maø heä thoáng ngöøng töông                           (c) Thöïc hieän chöùc naêng ñaët Password: Noäi dung tham soá doøng leänh nhö
         taùc vôùi ngöôøi duøng lôùn hôn khoaûng thôøi gian chôø cho pheùp. Ñaây laø                       sau:
         cheá ñoä chaïy thöïc cuûa ScreenSaver.                                                                  "/a xxxx"
                                                                                                             Trong ñoù:
12.4.2 Tham soá doøng leänh (Command Line Parameters):
                                                                                                             - /a (hoaëc /A): Giaù trò nhaän dieän tình huoáng thöïc hieän.
   Moãi khi thöïc hieän öùng duïng ScreenSaver, heä thoáng cung caáp thoâng tin veà
                                                                                                             - xxxx : Handle cuûa cöûa soå hoäi thoaïi.
tình huoáng cuï theå maø öùng duïng ñöôïc thöïc hieän thoâng qua noäi dung tham soá
                                                                                                             ÔÛ cheá ñoä naøy, ScreenSaver ñöôïc thieát keá theo kieåu öùng duïng coù
doøng leänh göûi ñeán cho chöông trình cuûa öùng duïng. ÖÙng duïng ScreenSaver
                                                                                                             maøn hình giao dieän chính laø dialog. Dialog giao dieän coù theå laø dialog
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.
                                                                                                             duøng ñaët password cuûa heä thoáng (thö vieän MPR.DLL) hoaëc dialog
   Thuoäc tính m_lpCmdLine cuûa ñoái töôïng quaûn lyù tieåu trình chính trong öùng
                                                                                                             cuûa ngöôøi duø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
                                                                                                       (d) Chaïy minh hoïa ScreenSaver: Noäi dung tham soá doøng leänh nhö sau:
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
                                                                                                                 "/s"
öùng caùc tröôøng hôïp (12.4.1), noäi dung tham soá doøng leänh coù theå laø:
168 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Moät soá vaán ñeà trong Windows                                                   169
Trong ñoù:                                                                                    Giaû söû caàn thöïc hieän öùng duïng ScreenSaver vôùi noäi dung hoaït ñoäng laø
         - /s (hoaëc /S): Giaù trò nhaän dieän tình huoáng thöïc hieän.                             hieån thò caâu chaøo "Hello !". Caùc böôùc thöïc hieän nhö sau:
         ÔÛ cheá ñoä naøy, ScreenSaver thöïc hieän xöû lyù nhö chaïy thöïc.                                Taïo döï aùn ScreenSaver töông töï döï aùn VD01.
   (e) Chaïy ScreenSaver: ÔÛ cheá ñoä naøy, ScreenSaver ñöôïc thieát keá theo                              Boå sung lôùp CEmpScreenSaverWnd keá thöøa töø lôùp CWnd cho döï aùn.
       kieåu öùng duïng coù maøn hình giao dieän chính laø cöûa soå vôùi noäi dung                         Thöïc hieän caøi ñaët cho lôùp CEmpScreenSaverWnd nhö sau:
       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å                   - Haønh vi OnPaint hieån thò thoâng baùo "Hello !" ôû chính giöõa vuøng
       desktop cuûa heä thoáng.                                                                                client cuûa cöûa soå.
       Phaàn löïa choïn trình huoáng xöû lyù cuûa öùng duïng ScreenSaver ñöôïc caøi                            void CEmpScreenSaverWnd::OnPaint()
       ñaët trong haønh vi InitInstance cuûa ñoái töôïng quaûn lyù öùng duïng.                                 {
                                                                                                                  CPaintDC dc(this);          // device context ñeå veõ
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                                // Do ScreenSaver's works here :
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).                             LOGFONT lf;
Do ñoù, chöông trình ScreenSaver phaûi xöû lyù caùc message lieân quan vieäc nhaäp                                 CFont       font, *oldFont;
lieäu:
    - Caùc message do taùc ñoäng leân baøn phím:                                                                   memset(&lf, 0, sizeof(LOGFONT));
           WM_KEYDOWN, WM_KEYUP                                                                                    strcpy(lf.lfFaceName, "Arial");
    - Caùc message do taùc ñoäng leân chuoät:                                                                      lf.lfHeight = 50; lf.lfWidth = 14;
           WM_MOUSEMOVE,                                                                                           font.CreateFontIndirect(&lf);      // Taïo font chöõ ñeå söû duïng
           WM_LBUTTONDOWN, WM_LBUTTONUP,                                                                           oldFont = dc.SelectObject(&font); // vaø löu font chöõ cuõ.
           WM_RBUTTONDOWN, WM_RBUTTONUP,
                                                                                                                   RECT rect;
           WM_MBUTTONUP, WM_MBUTTONDOWN
                                                                                                                   dc.GetClipBox(&rect);            // Xoùa neàn DC
           Thoâng thöôøng, khi nhaän ñöôïc moät trong caùc message naøy thì öùng                                   dc.FillRect(&rect, &CBrush(RGB(0, 128,128)));
       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                                  dc.SetBkMode(TRANSPARENT);
Ctrl+Alt+Del ñeå ‘qua maët’ öùng duïng. Vieäc ngaên caám naøy thöïc hieän nhö sau:                                 rect.top += 3; rect.left+= 3;
                                                                                                                   dc.SetTextColor(RGB(0, 0, 128));
   UINT oldval;                     // Duøng baûo löu traïng thaùi
                                                                                                                   dc.DrawText("Hello !", 7, &rect,
   // Baét ñaàu, caám phím:                                                                                                 DT_CENTER | DT_VCENTER | DT_SINGLELINE);
   SystemParametersInfo ( SPI_SETSCREENSAVERRUNNING,                                                               rect.top      -= 3; rect.left    -= 3;
                                    1 , &oldval, 0 );                                                              rect.bottom -= 3; rect.right -= 3;
   ... // Phaàn thöïc hieän cuûa ScreenSaver                                                                       dc.SetTextColor(RGB(255, 255, 0));
   // Cuoái cuøng, thoâi caám phím:                                                                                dc.DrawText("Hello !", 7, &rect,
   SystemParametersInfo ( SPI_SETSCREENSAVERRUNNING,                                                                        DT_CENTER | DT_VCENTER | DT_SINGLELINE);
                                  0, &oldval, 0);                                                                  dc.SelectObject(oldFont);           // Khoâi phuïc laïi font chöõ cuõ
                                                                                                               }
12.4.4 Thöïc hieän öùng duïng ScreenSaver ñôn giaûn:


170 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Moät soá vaán ñeà trong Windows                                                  171
- Caùc haønh vi xöû lyù message cuûa chuoät vaø baøn phím: OnKeyDown,                                       case 'a':
         OnLButtonDown, OnMouseMove, OnRButtonDown thöïc hieän göûi                                                case 'A':
         message ñoùng cöûa soå:                                                                                       // Ñaët Password (khoâng duøng cho WinNT-Win2000)
               PostMessage( WM_CLOSE, 0, 0 );                                                                          // Söû duïng hoäp Password cuûa heä thoáng cho töông thích.
                                                                                                                       typedef VOID (WINAPI *PWDCHANGEPASSWORD) (
       Taïo môùi dialog resource vaø lôùp CEmpScreenSaverDlg keá thöøa töø                                                                   LPCSTR lpcRegkeyname,
       CDialog söû duïng dialog resource naøy. Dialog CEmpScreenSaverDlg                                                                     HWND hwnd,UINT uiReserved1,
       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                                                         UINT uiReserved2 );
       cuûa öùng duïng ScreenSaver. Coù theå löu caùc thoâng soá aán ñònh bôûi ngöôøi                                  PWDCHANGEPASSWORD PwdChangePassword;
       duøng vaøo system registry (12.2).                                                                              HINSTANCE hmpr;
       Boå sung vaø chænh söûa lôùp quaûn lyù öùng duïng CEmpApp nhö sau:                                              hmpr = ::LoadLibrary("MPR.DLL");
       - Boå sung caùc thuoäc tính protected quaûn lyù hoaït ñoäng ScreenSaver:                                        if (hmpr == NULL) return FALSE;
           BOOL m_bFullDemo;                                                                                           PwdChangePassword = (PWDCHANGEPASSWORD)
                                                                                                                           ::GetProcAddress(hmpr, "PwdChangePasswordA");
           UINT Ctrl_Alt_Del_State;
                                                                                                                       if (PwdChangePassword != NULL)
       - Haønh vi InitInstance löïa choïn xöû lyù ñeå thöïc hieän moät caùch phuø hôïp                                     PwdChangePassword("SCRSAVE",parent,0,0);
           vôùi caùc tình huoáng hoaït ñoäng cuûa öùng duïng:                                                          FreeLibrary(hmpr);
           BOOL CEmpApp::InitInstance()                                                                                return FALSE;
           {                                                                                                       case 'p':
               m_bFullDemo = FALSE;                     // Löu cheá ñoä minh hoïa                                  case 'P':
               HWND parent;                             // Handle cöûa soå cha                                         // Xem minh hoïa trong maøn hình con
               RECT         rect;                       // Vò trí cöûa soå öùng duïng                                  style = WS_CHILD | WS_VISIBLE | WS_DISABLED ;
               DWORD exstyle = 0, style;                // Daïng cöûa soå öùng duïng                                   break;
                                                                                                                   default:
               sscanf(m_lpCmdLine + 3, "%d", &parent);
                                                                                                                       // Cheá ñoä chaïy thöïc cuûa ScreenSaver
               switch (m_lpCmdLine[1]) {                                                                               m_bFullDemo = TRUE;
               case 'c':                                                                                               parent = GetDesktopWindow();
               case 'C':                                                                                               exstyle = WS_EX_TOOLWINDOW | WS_EX_TOPMOST;
                   // Chöùc naêng aán ñònh thoâng soá                                                                  style = WS_POPUP | WS_VISIBLE;
                   CEmpScreenSaverDlg* main;                                                                       }
                   CWnd* pr;                                                                                       // Xaùc ñònh cheá ñoä chaïy cuï theå
                   pr = new CWnd();                                                                                CEmpScreenSaverWnd* main;
                   pr->Attach(parent);                                                                             main = new CEmpScreenSaverWnd;
                   main = new CEmpScreenSaverDlg(pr);                                                              m_pMainWnd = main;
                   m_pMainWnd = main;
                   main->DoModal();                                                                                POINT p1, p2;                       // Goùc traùi treân, phaûi döôùi
                   pr->Detach();                                                                                   GetWindowRect (parent, &rect); // Xaùc ñònh vò trí cöûa soå cha
                   delete main;                                                                                    p1.x = rect.left; p1.y = rect.top;
                   delete pr;                                                                                      p2.x = rect.right; p2.y = rect.bottom;
                   return FALSE;
172 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Moät soá vaán ñeà trong Windows                                                  173
if (!m_bFullDemo) {                                                                  12.5 ÖÙNG DUÏNG SÖÛ DUÏNG NHIEÀU TIEÅU TRÌNH:
                    // Chaïy trong cöûa soå con :                                                       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
                    // Xaùc ñònh toïa ñoä cöûa soå con trong hoäp Display Properties                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
                    ScreenToClient ( parent, &p1 );                                                 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
                    ScreenToClient ( parent, &p2 );                                                 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).
               // Cöûa soå giao dieän chính coù toïa ñoä vaø kích thöôùc thích hôïp                 12.5.1 Tieåu trình xöû lyù noäi:
               main->CreateEx(exstyle, _T("STATIC"),"Emp.ScreenSaver",                                  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
                             style, p1.x, p1.y, p2.x, p2.y, parent, NULL);                          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
               // Daáu con chuoät vaø khoùa phím neáu chaïy ScreenSaver thöïc                       trình ñöôïc thöïc hieän thoâng qua caùc noäi dung sau ñaây:
               if (m_bFullDemo) {
                                                                                                            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
                   ShowCursor(FALSE);
                   main->SetCapture();                                                                      tieåu trình (Thread Procedure). Haøm naøy coù khai baùo nhö sau:
                   SystemParametersInfo (                                                                       UINT MyThreadProc ( LPVOID pParam );
                                     SPI_SETSCREENSAVERRUNNING,                                                     pParam : Tham soá duy nhaát maø haøm ñieàu khieån nhaän ñöôïc khi
                                     1,&Ctrl_Alt_Del_State, 0                                                                     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
               main->UpdateWindow();
                                                                                                            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.
               return TRUE;
           }                                                                                                Thöïc hieän khôûi ñoäng tieåu trình xöû lyù noäi thoâng qua haøm sau:
                                                                                                            CWinThread* AfxBeginThread (
       - Haønh vi ExitInstance thöïc hieän gôõ boû caùc caøi ñaët:                                              AFX_THREADPROC pfnThreadProc,                       // Haøm ñieàu khieån
           int CEmpApp::ExitInstance()                                                                          LPVOID pParam,                                      // Tham soá cuûa haøm.
           {                                                                                                    int nPriority = THREAD_PRIORITY_NORMAL,
               if (m_bFullDemo) {                                                                               UINT nStackSize = 0,
                   ReleaseCapture();                                                                            DWORD dwCreateFlags = 0,
                   ShowCursor(TRUE);                                                                            LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL
                   SystemParametersInfo (
                                                                                                            );
                                SPI_SETSCREENSAVERRUNNING,
                                0, &Ctrl_Alt_Del_State, 0                                                  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
               return CWinApp::ExitInstance();                                                                  … // Thöïc hieän caùc xöû lyù caàn thieát.
           }                                                                                                  return ( coù_loãi ) ? 1 : 0;
       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ä                         …                           // Chuaån bò khôûi ñoäng tieåu trình
       thoáng vaø ñoåi teân taäp tin vôùi phaàn môû roäng laø .SCR.                                        pInfo = new MyInfo ; // Chæ ñeán vuøng chöùa caùc giaù trò thoâng soá
       Söû duïng Control Panel / Display / ScreenSaver kieåm tra keát quaû.                                AfxBeginThread( MyThreadProc, pInfo );

174 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Moät soá vaán ñeà trong Windows                                                        175
Giaû söû caàn thöïc hieän öùng duïng sau:                                                               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
   - 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                               m_isTextScrolled = TRUE;
      doøng chöõ trong hoäp thoâng baùo cho ñeán khi coù tín hieäu ngöøng.                                            // Khôûi ñoäng tieåu trình vôùi tham soá laø dialog giao dieän
   - Tieåu trình giao dieän quaûn lyù dialog nhaän yeâu caàu ngöôøi duøng:                                            AfxBeginThread( TextScrolling, this );
          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.                                                                   TextScrolling laø haøm xöû lyù cuûa tieåu trình chaïy chöõ. Haøm nhaän tham soá
          Muïc Close chaám döùt öùng duïng.                                                                void* laø con troû chæ ñeán ñoái töôïng dialog giao dieän. Coù theå khai baùo
   Döï aùn cuûa öùng duïng ñöôïc thöïc hieän nhö sau:                                                      haøm trong phaàn caøi ñaët cuûa lôùp CWorkerThreadDlg ñeå tieän söû duïng.
      Taïo döï aùn WorkerThread vôùi giao dieän chính laø dialog.                                          UINT TextScrolling(void* pParam) {
      Thöïc hieän caùc caøi ñaët sau cho lôùp CWorkerThreadDlg laøm giao dieän:                              // Con troû pParam thöïc chaát laø con troû ñoái töôïng dialog giao dieän
      - Môû dialog resource, caøi ñaët caùc control sau:                                                     CWorkerThreadDlg* pDlg = (CWorkerThreadDlg*)pParam;
          - Hoäp chöùa doøng chöõ chaïy                 Static    IDC_INFO                                   static CString info = " Welcome to multi-thread programming";
          - Nuùt leänh cho pheùp chöõ chaïy | ngöøng Button IDOK                                             while (pDlg->m_isTextScrolled) {
      - Thuoäc tính public m_isTextScrolled kieåu BOOL ghi nhaän thoâng tin                                      // Giaù trò thoâng baùo cho pheùp tieåu trình tieáp tuïc thöïc hieän:
          veà hoaït ñoäng chaïy chöõ.                                                                            info = info.Mid(1) + info.Left(1);
      - Haønh vi OnInitDialog khôûi ñoäng caùc thoâng soá:                                                       pDlg->SetDlgItemText(IDC_INFO, info);
                                                                                                                 Sleep(100);                         // Taïm nghæ
           BOOL CWorkerThreadDlg::OnInitDialog()                                                             }
           {
                                                                                                             return 0;                               // Keát thuùc tieåu trình xöû lyù noäi
             CDialog::OnInitDialog();
                                                                                                           }
             SetIcon(m_hIcon, TRUE); // Set big icon
             SetIcon(m_hIcon, FALSE); // Set small icon                                                    Bieân dòch vaø chaïy thöû öùng duïng.
               m_isTextScrolled = FALSE; // Chöa thöïc hieän chaïy chöõ                             12.5.2 Tieåu trình giao dieän:
               return TRUE;                                                                             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)
       - Haønh vi OnOK öùng vôùi nuùt leänh IDOK thöïc hieän khôûi ñoäng hoaëc                      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
         thoâng baùo ngöøng tieåu trình xöû lyù chaïy chöõ:                                         hieän thoâng qua caùc noäi dung sau ñaây:

176 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Moät soá vaán ñeà trong Windows                                                        177
Chuaån bò giao dieän (cöûa soå hoaëc dialog) cuûa tieåu trình giao dieän.                           BOOL CSubUserThread::InitInstance()
       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.                       CSubUserDlg dlg;
       Thöïc hieän khôûi ñoäng tieåu trình giao dieän thoâng qua haøm sau:                                   m_pMainWnd = &dlg;
                                                                                                             dlg.DoModal();
       CWinThread* AfxBeginThread (
                                                                                                             return TRUE;
           CRuntimeClass* pThreadClass,                                                                    }
           int nPriority = THREAD_PRIORITY_NORMAL,
           UINT nStackSize = 0,                                                                            Thöïc hieän caùc caøi ñaët sau cho lôùp dialog CUserIntThreadDlg:
           DWORD dwCreateFlags = 0,                                                                        - Môû dialog resource, caøi ñaët caùc control sau:
           LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL                                                       - 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
       pThreadClass : Con troû ñeán caáu truùc quaûn lyù thoâng tin thi haønh cuûa lôùp                    - Haønh vi OnOK cho nuùt choïn IDOK kích hoaït tieåu trình giao dieän:
       ñoái töôïng quaûn lyù tieåu trình giao dieän ñöôïc kích hoaït. Xem (11.4).                             void CUserIntThreadDlg::OnOK()
                                                                                                              {
      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
                                                                                                                  AfxBeginThread( RUNTIME_CLASS(CSubUserThread) );
   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
                                                                                                           Bieân dòch vaø chaïy thöû öùng duïng.
   dieän cuûa tieåu trình giao dieän chính.
                                                                                                    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
   Caùc böôùc thöïc hieän nhö sau:
                                                                                                          töôïng CWinThread quaûn lyù tieåu trình.
      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,                    12.6 LAÄP TRÌNH MULTIMEDIA VÔÙI MCI:
      caøi nuùt thoaùt vôùi soá hieäu IDCANCEL.                                                         MCI (Media Control Interface) cung caáp boä leänh cô baûn coù tính thích nghi
      Boå sung lôùp CSubUserDlg keá thöøa töø CDialog söû duïng resource treân.                     cao vôùi nhieàu thieát bò media trong vieäc thöïc hieän caùc noäi dung multimedia.
      Boå sung lôùp ñoái töôïng CSubUserThread keá thöøa töø CWinThread cho                             Moãi thieát bò media söû duïng cho vieäc thöïc hieän noäi dung multimedia ñöôïc
      pheùp quaûn lyù caùc tieåu trình giao dieän con. Ñoái töôïng CSubUserThread                   MCI quaûn lyù thoâng qua cöûa soå giao dieän MCI thuoäc lôùp MCIWnd. Ñaây laø lôùp
      nhaän ñoái töôïng CSubUserDlg laøm cöûa soå giao dieän chính thoâng qua                       cöûa soå do MCI ñaêng kyù tröôùc nhaèm phuïc vuï cho muïc ñích naøy.
      haønh vi InitInstance cuûa noù.                                                                   Cöûa soå giao dieän MCI nhö sau:

178 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Moät soá vaán ñeà trong Windows                                                      179
- 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ù
   Sau ñaây laø caùc haøm MCI söû duïng phoå bieán (Vfw.h):                                                  thieát bò media ñöôïc söû duïng.
      HWND MCIWndCreate (                                                                                  - Haønh OnInitDialog khôûi ñoäng thieát bò media:
          HWND hwndParent,                 // Handle cöûa soå cha cuûa cöûa soå MCI
                                                                                                               BOOL CMCIDlg::OnInitDialog()
          HINSTANCE hInstance, // Handle cuûa öùng duïng                                                       {
          DWORD dwStyle,                   // Daïng cöûa soå giao dieän MCI                                      CDialog::OnInitDialog();
          LPSTR szFile                     // Ñöôøng daãn, teân taäp tin media.                                  SetDlgItemText(IDC_FILE, "HappyNewYear.rmi");
      ); Môû thieát bò media vaø söû duïng noäi dung multimedia trong taäp tin töông                             m_mciWnd = MCIWndCreate ( this->GetSafeHwnd(),
      öùng. Haøm traû veà con troû cöûa soå MCI quaûn lyù thieát bò ñöôïc môû.                                                                AfxGetInstanceHandle(),
      Thoâng soá dwStyle cuûa cöûa soå MCI ñöôïc keát hôïp töø caùc giaù trò sau:                                         /*invisible*/       ~WS_VISIBLE, NULL );
          MCIWNDF_SHOWALL                      : Hieån thò caùc muïc cuûa cöûa soå.                              return TRUE;
          MCIWNDF_NOMENU                       : Khoâng hieån thò nuùt choïn menu.                             }
          MCIWNDF_NOPLAYBAR : Khoâng hieån thò progressbar.
                                                                                                           - Haønh vi OnPlay öùng vôùi nuùt IDC_PLAY thöïc hieän noäi dung media:
      LONG MCIWndOpen (                        // Traû veà giaù trò 0 neáu thaønh coâng.
                                                                                                              void CMCIDlg::OnPlay()
          HWND hwnd,                           // Handle cöûa soå MCI                                         {
          LPSTR szFile                         // Ñöôøng daãn, teân taäp tin media.                               char fName[1024];              // Laáy teân taäp tin multimedia
          DWORD dwStyle = 0                                                                                       GetDlgItemText(IDC_FILE, fName, 1023);
      ); Môû noäi dung multimedia môùi cho thieát bò media quaûn lyù bôûi hwnd.                                   if ( MCIWndOpen( m_mciWnd, fName, 0 ) == 0 ) {
      LONG MCIWndClose( HWND hwnd ); Ñoùng noäi dung multimedia.                                                       MCIWndPlay( m_mciWnd );
      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.                                                          - Haønh vi OnStop ngöøng thöïc hieän:
      LONG MCIWndResume( HWND hwnd ); Tieáp tuïc.                                                             void CMCIDlg::OnStop()
      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                            MCIWndStop( m_mciWnd );
   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:                                                                         Bieân dòch vaø chaïy thöû öùng duïng.
      Duøng MFC Wizard taïo döï aùn MCI vôùi giao dieän chính laø dialog.                           12.7 AÁN ÑÒNH MOÄT SOÁ TÍNH NAÊNG CUÛA WINDOWS:
      Khai baùo söû duïng thö vieän MCI trong taäp tin STDAFX.H:                                       Moâi tröôøng windows cho pheùp ngöôøi duøng aán ñònh moät soá tính naêng tieän
       #include <Vfw.h>                                                                             í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å
       #pragma comment (lib, "Vfw32.lib")                 // MCI library                            ñöôï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:
       Trong lôùp dialog giao dieän chính: CMCIDlg
180 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Moät soá vaán ñeà trong Windows                                                   181
BOOL SystemParametersInfo (                                                                      12.8.1 Caùc kieåu hook (Hook Type):
       UINT uiAction,            // Soá hieäu cuûa chöùc naêng caàn thöïc hieän                        Hook ñöôïc phaân chia thaønh caùc kieåu khaùc nhau tuøy thuoäc vaøo kieåu
       UINT uiParam,             // AÁn ñònh tuøy thuoäc uiAction                                   message ñöôïc hook. Moät soá kieåu hook phoå bieán nhö sau:
       PVOID pvParam,            // Con troû vuøng ñeäm, tuøy thuoäc uiAction                          WH_KEYBOARD :                    Hook caùc message lieân quan baøn phím.
       UINT fWinIni              // Ñeà nghò caäp nhaät user profile. = 0: khoâng.                     WH_MOUSE :                       Hook caùc message lieân quan con chuoät.
   ); Laáy hoaëc ñaët thoâng soá qui ñònh tính naêng töông öùng cuûa heä thoáng.                       WH_CBT :                         Hook caùc thao taùc treân cöûa soå giao dieän.
   Giaù trò uiAction coù theå laø:                                                                     WH_CALLWNDPROCRET : Hook giaù trò traû veà töø haøm xöû lyù message
       SPI_GETLOWPOWERTIMEOUT : Laáy thoâng soá low power timeout                                                                       WindowProc coù kieåu CWPRETSTRUCT.
       SPI_GETPOWEROFFTIMEOUT                       : Laáy thoâng soá power timeout                    WH_CALLWNDPROC :                 Hook caùc message tröôùc khi message ñöôïc
       SPI_GETSCREENSAVETIMEOUT : Laáy thoâng soá S.saver timeout                                                                       chuyeån ñeán thuû tuïc WindowProc.
       SPI_SETLOWPOWERTIMEOUT : Ñaët thoâng soá low power timeout                                   12.8.2 Danh saùch hook (Hook Chain):
       SPI_SETPOWEROFFTIMEOUT                       : Ñaët thoâng soá power timeout                    Danh saùch hook laø danh saùch caùc con troû chæ ñeán caùc thuû tuïc hook. Moãi
       SPI_SETSCREENSAVETIMEOUT : Ñaët thoâng soá S.saver timeout.                                  kieåu hook coù moät danh saùch hook rieâng. Khi moät message phaùt sinh, noù ñöôïc
         Khi uiAction laø giaù trò coù yù nghóa laáy thoâng soá:                                    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
           uiParam : Coù giaù trò baèng 0                                                           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:
           pvParam : Chæ ñeán vuøng ñeäm nhaän giaù trò thoâng soá hieän haønh.                     ghi nhaän message, chænh söûa message, hoaëc ngaên caám message khoâng ñeå noù
         Khi uiAction laø giaù trò coù yù nghóa ñaët thoâng soá:                                    ñeán ñöôïc thuû tuïc hook keá tieáp.
           uiParam : Giaù trò thoâng soá aán ñònh.
                                                                                                    12.8.3 Thuû tuïc hook (Hook Procedure):
           pvParam : = NULL
                                                                                                        Thuû tuïc hook laø chöông trình con chuyeân duïng cho vieäc hook loaïi message
       Ñoaïn chöông trình sau thöïc hieän caám tính naêng screen saver:                             lieân quan. Chöông trình con xöû lyù hook coù khai baùo nhö sau:
       UINT oldStatus;                                                                                  LRESULT CALLBACK HookProc ( int nCode, WPARAM wParam,
       // Laáy thoâng soá qui ñònh tính naêng ScreenSaver, löu vaøo oldStatus                                                                    LPARAM lParam );
       SystemParametersInfo( SPI_GETSCREENSAVETIMEOUT,                                                  Caùc tham soá göûi cho chöông trình con naøy khaùc nhau theo töøng kieåu hook:
                                      0, &oldStatus, 0 );                                                  WH_KEYBOARD – xöû lyù message baøn phím - KeyboardProc:
       // Caám tính naêng ScreenSaver                                                                      code :      - HC_ACTION:           Message cuûa phím ñöôïc thöïc hieän.
       SystemParametersInfo( SPI_SETSCREENSAVETIMEOUT,                                                                 - HC_NOREMOVE: Message cuûa phím chöa ñöôïc laáy khoûi
                                      0, NULL, 0 );
                                                                                                                                              message queue.
       … // Caùc xöû lyù trong ñieàu kieän ScreenSaver bò caám                                             wParam: Maõ phím lieân quan.
       // Traû laïi aán ñònh tröôùc ñoù cho tính naêng ScreenSaver : oldStatus                             lParam : - Caùc bit 0÷15 :         Giaù trò cho bieát soá laàn goõ phím
       SystemParametersInfo( SPI_SETSCREENSAVETIMEOUT,                                                                 - Caùc bit 16÷23 :     Maõ scan code cuûa phím.
                                        oldStatus, NULL, 0 );                                                          - 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:
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
                                                                                                             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
coù theå can thieäp ñeå caøi ñaët thuû tuïc xöû lyù message (hook procedure) tröôùc khi
                                                                                                                                              message queue.
message ñoù ñeán ñöôïc ñoái töôïng xöû lyù message maø heä thoáng ñieàu phoái.
                                                                                                             wParam : Soá hieäu message cuûa con chuoät
182 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Moät soá vaán ñeà trong Windows                                                    183
lParam        : Con troû ñeán caáu truùc MOUSEHOOKSTRUCT.                                         hMod :           Handle cuûa öùng duïng hoaëc DLL chöùa thuû tuïc hook.
       typedef struct tagMOUSEHOOKSTRUCT {                                                                LRESULT CallNextHookEx (
          POINT pt;                // Vò trí chæ ñieåm cuûa con chuoät                                        HHOOK hhk,                 // Handle cuûa thuû tuïc hook chieám quyeàn
          HWND hwnd;               // Handle cöûa soå lieân quan.                                             int nCode,                 // Chuyeån giao giaù trò caùc tham soá
          UINT wHitTestCode;       // Xem (4.2): WM_SETCURSOR                                                 WPARAM wParam, // maø thuû tuïc hook chieám quyeàn
          ULONG_PTR dwExtraInfo; // Caùc thoâng tin boå sung khaùc.                                           LPARAM lParam              // nhaän ñöôïc töø heä thoáng
       } MOUSEHOOKSTRUCT, *PMOUSEHOOKSTRUCT;                                                              ); Thöïc hieän thuû tuïc hook bò chieám quyeàn, giuùp oån ñònh cho windows.
                                                                                                          BOOL UnhookWindowsHookEx (
       WH_CBT – Xöû lyù thao taùc treân cöûa soå - CBTProc:                                                   HHOOK hhk                  // Handle cuûa thuû tuïc hook huûy boû.
       Quan heä giöõa caùc thoâng soá nhö sau:                                                            ); Huûy boû thuû tuïc hook trong danh saùch hook.
        Code                              wParam                       lParam                          Neáu thuû tuïc hook ñöôïc caøi trong DLL thì caàn söû duïng caùc haøm sau:
        HCBT_ACTIVATE                     Handle cuûa cöûa soå         Con troû caáu truùc                HMODULE LoadLibrary (
        ( Kích hoaït cöûa soå )                                        chöùa thoâng tin.                      LPCTSTR lpFileName                 // Ñöôøng daãn, teân taäp tin DLL
        HCBT_CREATEWND                    Handle cuûa cöûa soå.        Con troû caáu truùc                ); Traû veà giaù trò handle cuûa DLL.
        ( Taïo môùi cöûa soå )                                         chöùa thoâng tin.                  FARPROC GetProcAddress (
                                                                                                              HMODULE hModule,                  // Handle cuûa DLL chöùa thuû tuïc
        HCBT_DESTROYWND Handle cuûa cöûa soå.                          =NULL                                  LPCSTR lpProcName                  // Teân thuû tuïc
        ( Huûy boû cöûa soå )                                                                             ); Traû veà con troû cuûa thuû tuïc töông öùng.
        HCBT_MINMAX              Handle cuûa cöûa soå.                 Word thaáp chöùa             12.8.5 ÖÙng duïng hook messages cuûa keyboard:
        ( Phoùng to hay Thu nhoû                                       thoâng soá hieån thò            Trong phaàn naøy, ta thöïc hieän öùng duïng hook message cuûa baøn phím. Xöû lyù
        cöûa soå )                                                     cöûa soå ( SW_xxx ).         hook cuûa öùng duïng baät tieáng beep ñeå thoâng baùo coù goõ phím vaø chuyeån
        HCBT_MOVESIZE               Handle cuûa cöûa soå.              Con troû caáu truùc          message nhaän ñöôïc cho thuû tuïc xöû lyù hook ñaõ bò xöû lyù naøy chieám quyeàn.
        ( Di chuyeån hoaëc thay                                        RECT quaûn lyù toïa             Caùc böôùc thöïc hieän nhö sau:
        ñoåi kích thöôùc cöûa soå )                                    ñoä, kích thöôùc môùi.             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:
12.8.4 Caùc dòch vuï lieân quan hook:                                                                     - Trong phaàn caøi ñaët, boå sung bieán löu vaø haøm xöû lyù hook:
      HHOOK SetWindowsHookEx (
                                                                                                              HHOOK oldHook; // Chöùa ñòa chæ thuû tuïc hook bò chieám quyeàn
         int idHook,                   // Kieåu hook
         HOOKPROC lpfn,                // Ñòa chæ thuû tuïc hook                                             LRESULT CALLBACK myHook ( int code, WPARAM wParam,
         HINSTANCE hMod,               // Handle cuûa ñôn theå chöùa hook                                                                              LPARAM lParam) {
         DWORD dwThreadId // Soá hieäu tieåu trình söû duïng hook                                               MessageBeep( -1 ); // Thöïc hieän beep ñeå thoâng tin
      ); Caøi ñaët thuû tuïc hook vaøo danh saùch hook töông öùng. Haøm traû veà                                // Thöïc hieän thuû tuïc bò chieám quyeàn.
      handle cuûa thuû tuïc hook ñöôïc caøi ñaët tröôùc thuû tuïc bò chieám quyeàn.                             return CallNextHookEx(oldHook, code, wParam, lParam);
      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                - Haønh vi OnInitDialog xöû lyù caøi ñaët thuû tuïc hook:
                       ñaët noù trong moät taäp tin DLL.                                                     BOOL CHookDlg::OnInitDialog()
                                                                                                             {
184 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Moät soá vaán ñeà trong Windows                                                 185
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:
   SOFTWAREMicrosoftWindowsCurrentVersionRun 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:Gamemci.exe" caøi trong thaønh phaàn :
 HKEY_CURRENT_USERSOFTWAREMicrosoftWindowsCurrentVersionRun
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_USERSOFTWAREMicrosoftInternet ExplorerTypedURLs
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ø.




186 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
CHÖÔNG 13:                                                                                          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
                              MFC vôùi Internet                                                     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
13.1 GIAO THÖÙC TRUYEÀN THOÂNG TCP/IP:
                                                                                                    laäp ñoù cuõng giuùp TCP/IP nhanh choùng thích nghi vôùi caùc coâng ngheä
13.1.1 Giôùi thieäu:
                                                                                                    maïng môùi nhö ATM (Asynchronous Transfer Mode).
    TCP/IP (Transmission Control Protocol/Internet Protocol) bao goàm giao
                                                                                                    Taàng Internet (Internet Layer):
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
                                                                                                    Taàng internet ñaûm nhaän chöùc naêng ñònh vò, ñoùng goùi thoâng tin vaø
(host) treân heä thoáng maïng ñònh vò ñòa chæ IP (IP Host Address Internetwork).
                                                                                                    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,
    TCP/IP ra ñôøi töø naêm 1969 bôûi cô quan nghieân cöùu caùc döï aùn cao caáp
                                                                                                    ARP, ICMP, vaø IGMP.
thuoäc boä quoác phoøng Hoa Kyø (Department of Defence Advanced Research
                                                                                                    - Giao thöùc IP (Internet Protocol): Giao thöùc truyeàn thoâng ñònh tuyeán;
Projects Agency - DARPA) nhaèm muïc tieâu xaây döïng moät giao thöùc truyeàn
                                                                                                        coù nhieäm vuï ñònh vò ñòa chæ IP, taùch vaø keát caùc packet.
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ô
                                                                                                    - Giao thöùc ARP (Address Resolution Protocol): Coù nhieäm vuï thöï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öø
                                                                                                        hieän hoaùn chuyeån caùc giaù trò ñòa chæ moät caùch töông öùng giöõa taàng
thaønh quaû phaùt trieån maïng ARPANET, tieàn thaân cuûa Internet ngaøy nay.
                                                                                                        internet (logic address) vaø taàng giao tieáp maïng (physic address).
13.1.2 Kieán truùc cuûa giao thöùc TCP/IP treân moâ hình DARPA:                                     - Giao thöùc ICMP (Internet Control Message Protocol): Coù nhieäm vuï
   Moâ hình DARPA vôùi giao thöùc truyeàn thoâng TCP/IP laø moät kieán truùc bao                        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
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:                            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
       Taàng giao tieáp maïng (Network Interface Layer):                                                nhaän qua ñöôøng truyeàn naøy. Giao thöùc naøy ñaûm baûo thoâng tin ñöôïc
       Taàng giao tieáp maïng (taàng truy xuaát maïng) ñaûm nhaän nhieäm vuï nhaän                      chuyeån ñeán host nhaän chính xaùc vaø an toaø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ò          Taàng öùng duïng (Application Layer):

MFC vôùi Internet                                                                     187    188 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
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          Treân 4 bytes ñòa chæ IP, ta coù theå choïn moät soá bytes tuøy yù chöùa ñòa chæ
       taàng khaùc, ñoàng thôøi ñònh nghóa caùc giao thöùc truyeàn thoâng maø öùng             maïng, soá bytes coøn laïi duøng chöùa ñòa chæ host. Moãi caùch choïn khaùc nhau
       duïng cuûa ngöôøi duøng coù theå söû duïng ñeå truyeàn döõ lieäu qua heä thoáng         taïo thaønh moät lôùp ñòa chæ IP. Coù 3 lôùp ñòa chæ IP phoå bieán:
       maïng. Caùc giao thöùc truyeàn thoâng phoå bieán nhö sau:                                   - Lôùp A : 1 byte cho ñòa chæ maïng, 3 bytes cho ñòa chæ host
       - Giao thöùc HTTP (HyperText Transfer Protocol): Duøng chuyeån taûi                         - Lôùp B : 2 bytes cho ñòa chæ maïng, 2 bytes cho ñòa chæ host
           caùc taäp tin tham gia vaøo noäi dung trang WEB (World Wide Web).                       - Lôùp C : 3 bytes cho ñòa chæ maïng, 1 byte cho ñòa chæ host
       - Giao thöùc FTP (File Transfer Protocol): Duøng chuyeån taûi caùc taäp tin                 Löu yù:
           thoâng thöôøng.                                                                         - Giaù trò ñòa chæ host vôùi taát caû caùc bits baèng 1 laø ñòa chæ chæ cho moïi
       - Giao thöùc SMTP (Simple Mail Transfer Protocol): Duøng chuyeån taûi                          host treân heä thoáng maïng (host broadcast address) chöùa host. Khoâng
           noäi dung thö tín bao goàm thoâng ñieäp vaø caùc döõ lieäu keøm theo.                      moät host naøo ñöôïc söû duïng ñòa chæ naøy.
       - Giao thöùc Telnet: Duøng cho hoaït ñoäng thaâm nhaäp host töø xa thoâng                   - Moät ñòa chæ IP coù phaàn ñòa chæ host vôùi taát caû caùc bits baèng 0 chính
           qua caùc thieát bò ñaàu cuoái (Terminal).                                                  laø ñòa chæ cuûa heä thoáng maïng. Khoâng duøng ñòa chæ naøy cho host.
           Beân caïnh caùc giao thöùc truyeàn thoâng noùi treân, taàng öùng duïng coøn                   Address       Class First Host ID        Last Host ID
       cung caáp caùc dòch vuï sau:                                                                     Class A       w.0.0.1                   w.255.255.254
       - Dòch vuï chuyeån ñoåi domain name thaønh ñòa chæ IP töông öùng.                                Class B       w.x.0.1                   w.x.255.254
       - Dòch vuï cung caáp thoâng tin ñònh vò ñòa chæ IP.                                              Class C       w.x.y.1                   w.x.y.254
       - Dòch vuï quaûn lyù caùc thieát bò maïng (boä ñònh tuyeán, caàu noái, hub
                                                                                            13.1.4 Subnet:
           thoâng minh) nhaèm thu thaäp vaø trao ñoåi thoâng tin quaûn lyù maïng.
                                                                                                Vôùi soá bits duøng cho ñòa chæ host trong caùc lôùp ñòa chæ, soá löôïng host cuûa
13.1.3 Ñòa chæ IP:                                                                          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ù,
    Ñòa chæ IP laø giaù trò giuùp xaùc ñònh moät host duy nhaát treân heä thoáng maïng.     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
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æ     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
cuûa host treân maïng ñoù.                                                                  nöõa, 16 trieäu giaù trò ñòa chæ cho moät heä thoáng maïng laø quaù dö thöøa.
    - Ñòa chæ maïng (Network address - Network ID): Soá hieäu duøng cho moät                    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
        heä thoáng maïng caùc host cuøng chung moät ñaëc ñieåm ñònh tuyeán. Caùc heä        nhoùm nhoû hôn goïi laø maïng con (SubNet). Moãi subnet töông öùng vôùi moät ñòa
        thoáng maïng keát vaøo internet phaûi coù ñòa chæ maïng phaân bieät.                chæ maïng subnet vaø giôùi haïn ñòa chæ IP caùc host tröïc thuoäc. Ñòa chæ subnet laø
    - Ñòa chæ host (host address - host ID): Soá hieäu duøng cho moät host                  giaù trò hình thaønh töø moät phaàn bits trong ñòa chæ host cuûa ñòa chæ IP thuoäc heä
        (workstation, server, router, TCP/IP host). Caùc host trong cuøng moät heä          maïng ban ñaàu. Coù theå xem Subnet laø taäp con cuûa heä maïng.
        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                                      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
        Hay:          192.168.3.24                                                             laø 139.12.0.0. Heä maïng naøy cho pheùp xaùc laäp 65535 ñòa chæ host. Thöïc


MFC vôùi Internet                                                                    189    190 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
hieän chia heä maïng treân thaønh 256 subnet döïa treân byte thöù ba, ta ñöôïc caùc             Xaùc ñònh ñòa chæ maïng: Ñeå taùch ñòa chæ maïng töø moät ñòa chæ IP baát kyø
   subnet 8-bit ñòa chæ lôùp B:                                                             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:
       Caùc subnet ñöôïc taïo thaønh laø: 139.12.1.0, 139.12.2.0 vaø 139.12.3.0.              Stt           Ñòa chæ Subnet theo heä nhò phaân               Giôùi haïn ñòa chæ IP
13.1.5 Subnet Mask:                                                                            1     11000000.10101000.00000000.00000001-                192.168.0.1 -
    Subnet mask laø moät giaù trò 32 bits giuùp taùch giaù trò ñòa chæ maïng (hoaëc ñòa              11000000.10101000.00011111.11111110                 192.168.31.254
chæ subnet) vaø ñòa chæ host töø moät ñòa chæ IP baát kyø (trong moät lôùp ñòa chæ baát        2     11000000.10101000.00100000.00000001-                192.168.32.1 -
kyø, caùch phaân chia subnet baát kyø). Giaù trò naøy ñöôïc xaây döïng nhö sau:                      11000000.10101000.00111111.11111110                 192.168.63.254
    - Caùc giaù trò bit töông öùng vôùi ñòa chæ maïng coù giaù trò laø 1.                      3     11000000.10101000.01000000.00000001-                192.168.64.1 -
    - Caùc giaù trò bit töông öùng vôùi ñòa chæ host coù giaù trò laø 0.                             11000000.10101000.01011111.11111110                 192.168.95.254
   Giaù trò subnet mask cuõng ñöôïc bieåu dieãn döôùi daïng num-dot.                           4     11000000.10101000.01100000.00000001-                192.168.96.1 -
   Ta coù subnet mask maëc nhieân cho caùc lôùp ñòa chæ nhö sau:                                     11000000.10101000.01111111.11111110                 192.168.127.254
     Class                  Bits for Subnet Mask                  Subnet Mask                  5     11000000.10101000.10000000.00000001-                192.168.128.1 -
    Class A 11111111 00000000 00000000 00000000                  255.0.0.0                           11000000.10101000.10011111.11111110                 192.168.159.254
    Class B 11111111 11111111 00000000 00000000                  255.255.0.0                   6     11000000.10101000.10100000.00000001-                192.168.160.1 -
    Class C 11111111 11111111 11111111 00000000                  255.255.255.0                       11000000.10101000.10111111.11111110                 192.168.191.254
                                                                                               7     11000000.10101000.11000000.00000001-                192.168.192.1 -
    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æ
                                                                                                     11000000.10101000.11011111.11111110                 192.168.223.254
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ò
                                                                                               8     11000000.10101000.11100000.00000001-                192.168.224.1 -
mask treân ñòa chæ subnet.
                                                                                                     11000000.10101000.11111111.11111110                 192.168.255.254
    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            13.1.6 Host domain name:
    mask söû duïng toång coäng 24 bits (255.255.255.0) ñeå ñònh nghóa ñòa chæ                   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
    maïng subnet. Ñòa chæ maïng subnet vaø giaù trò subnet mask töông öùng ñöôïc            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
    bieåu dieãn theo daïng num-dot nhö sau:                                                 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á,
                          138.96.58.0, 255.255.255.0                                        caùc kyù töï ‘-‘ vaø ‘.’ vaø coù yù nghóa töông ñöông vôùi ñòa chæ IP trong vieäc quaûn lyù
        Hay:              138.96.58.0/24                     (24-bit mask)                  ñò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:

MFC vôùi Internet                                                                    191    192 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
- Nick name: Moät nhaõn ñöôïc duøng cho moät ñòa chæ IP duy nhaát.                          thoâng tin yeâu caàu khoâng xaùc ñònh ñöôïc thì noù seõ chuyeån ñeán DNS server
   - Domain name: Teân ñöôïc hình thaønh töø caáu truùc phaân lôùp. Caáu truùc                 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
     phaân lôùp naøy ñöôïc qui ñònh phoå bieán thaønh luaät vaø ñöôïc goïi laø heä             ñöôïc traû veà theo loä trình ngöôïc laïi.
     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                                       13.1.7 IP Routing:
    EDU                    Caùc cô quan giaùo duïc, nghieân cöùu                                IP routing laø tieán trình xöû lyù göûi packet ñeán host nhaän döïa treân ñòa chæ IP
    GOV                    Toå chöùc chính phuû                                             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ø
    MIL                    Cô quan quaân söï                                                ôû thieát bò ñònh tuyeán (router device) nhaèm thöïc hieän quyeát ñònh löïa choïn vò trí
    NET                    cô quan quaûn lyù maïng chính                                    maø packet seõ ñöôïc chuyeån ñeán.
    ORG                    Caùc toå chöùc khaùc                                                 Ñeå thöïc hieän quyeát ñònh treân, taàng IP tham khaûo baûng ñònh tuyeán ñöôïc löu
    INT                    Caùc toå chöùc quoác teá                                         tröõ trong boä nhôù. Noäi dung baûng ñònh tuyeán ñöôïc khôûi taïo maëc nhieân khi
    <country code>         Caùc nhaùnh cho caùc quoác gia tröø Hoa Kyø                      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
   Moät teân mieàn ñaày ñuû (Fully Qualified Domain Name – FQDN) chöùa
                                                                                            töï ñoäng trong quaù trình lieân laïc vôùi caùc boä ñònh tuyeán.
   ñöôø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.
                                                                                                Coù hai daïng phoå bieán khi göûi packet; göûi tröïc tieáp vaø göûi giaùn tieáp.
   Ví duï: ftpsrv.wcoast.slate.com
                                                                                                     Göûi tröïc tieáp (Direct delivery): Xaûy ra khi host nhaän vaø host göûi ñöôïc
   Vieäc chuyeån ñoåi giöõa ñòa chæ IP vaø Domain name ñöôïc thöïc hieän döïa treân                  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
   baûng chuyeån ñoåi IP-DomainName do DNS server, moät host chuyeân duïng                           ñònh cuûa taàng giao tieáp maïng vaø ñöôïc göûi ñi.
   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            Göûi giaùn tieáp (Indirect delivery): Xaûy ra khi host nhaän vaø host göûi ñöôïc
   baûng thoâng tin naøy thoâng qua caùc dòch vuï cung caáp bôûi windows socket.                     keát noái thoâng qua moät trung gian (boä ñònh tuyeán). Khi ñoù seõ coù moät quaù
   Windows socket truyeàn yeâu caàu cuûa öùng duïng ñeán boä phaän phaân giaûi                       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
   domain name cuûa giao thöùc truyeàn thoâng TCP/IP. Boä phaän naøy chuyeån                         ñeán host nhaän (hoaëc giaùn tieáp ñeán moät boä ñònh tuyeán khaùc).
   yeâu caàu ñeán DNS server. DNS server nhaän yeâu caàu vaø thöïc hieän; neáu
MFC vôùi Internet                                                                    193    194 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
- 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                         Metric        Purpose
                                                                                                     Address                                         Interface
                   A göûi tröïc tieáp ñeán B                                                    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
                   A göûi giaùn tieáp packet ñeán router1 , router 1 göûi giaùn tieáp ñeán                                                                                     DirectyAttached
                   router 2, router 2 göûi tröïc tieáp ñeán C.                                  157.55.16.0       255.255.240.0     157.55.27.90   157.55.27.90   1
                                                                                                                                                                               Network
       Baûng ñònh tuyeán:                                                                       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
           Baûng ñònh tuyeán ñöôïc xaùc laäp treân taát caû caùc host (node, router) vaø
                                                                                                224.0.0.0         224.0.0.0         157.55.27.90   157.55.27.90   1            Multicast Address
       ñöôïc ñaët bôûi caùc giaù trò maëc nhieân trong quaù trình khôûi ñoäng cuûa giao         255.255.255.255   255.255.255.255   157.55.27.90   157.55.27.90   1            Limited Broadcast
       thöùc TCP/IP. Noäi dung cuûa baûng chöùa thoâng tin veà heä thoáng caùc ñòa chæ                  ( Moät baûng ñònh tuyeán cuûa Windows NT )
       IP treân maïng, caùch keát noái vôùi caùc ñòa chæ aáy.
                                                                                                    Xöû lyù ñònh tuyeán:
           Moãi khi moät goùi thoâng tin ñöôïc göûi ñi, baûng ñònh tuyeán seõ ñöôïc söû
                                                                                                        Xöû lyù ñònh tuyeán laø xöû lyù thöïc hieän löïa choïn muïc ñònh tuyeán trong
       duïng ñeå xaùc ñònh:
                                                                                                    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
           - Ñò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
                                                                                                    ñöôïc thöïc hieän thoâng qua caùc böôùc sau:
               chæ cuûa host nhaän packet, ngöôïc laïi, laø ñòa chæ cuûa boä ñònh tuyeán.
                                                                                                        - Treân moãi muïc ñònh tuyeán, thöïc hieän pheùp toaùn AND giöõa ñòa chæ
           - Giao dieän söû duïng ñeå göûi: Bao goàm thoâng tin veà caáu truùc vaät lyù
                                                                                                            host nhaän vaø giaù trò subnet mask. Kieåm tra keát quaû naøy vôùi
               vaø logic cuûa thieát bò keát noái maïng ôû nôi göûi vaø nôi nhaän.
                                                                                                            Network ID ñeå ñaùnh giaù ñoä phuø hôïp (ñoä töông töï).
       Caáu truùc noäi dung cuûa moät muïc trong baûng ñònh tuyeán:
                                                                                                        - Choïn ra caùc muïc ñònh tuyeán coù möùc ñoä phuø hôïp cao nhaát. Trong
           [ Network ID, Subnet Mask, Next Hop, Interface, Metric ]
                                                                                                            caùc muïc ñònh tuyeán naøy, choïn ra caùc muïc coù chi phí tuyeán truyeàn
       Trong ñoù:
                                                                                                            nhoû nhaát. Cuoái cuøng, töø caùc muïc ñònh tuyeán choïn ñöôïc, muïc ñònh
           - Network ID: Ñòa chæ maïng töông öùng vôùi tuyeán truyeàn tin.
                                                                                                            tuyeán ñöôïc söû duïng laø muïc coøn roãi.
           - Subnet Mask: Giaù trò duøng taùch ñòa chæ maïng töø ñòa chæ IP.
                                                                                                       Xöû lyù ñònh tuyeán khaùc nhau treân caùc loaïi host khaùc nhau:
           - Next Hop:            Ñòa chæ IP cuûa host trung gian keá tieáp.
MFC vôùi Internet                                                                     195    196 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
Host göûi: Packet ñöôïc göûi töø giao thöùc ôû taàng caáp cao hôn cuûa IP (TCP,             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
       UDP, ...). Khi ñoù vai troø IP ôû host göûi nhö sau:                                    packet qua ñöôøng truyeàn maïng. Moãi socket coù moät kieåu xaùc ñònh vaø gaén lieàn
       - Ñaët giaù trò cho tröôøng TTL (Times-To-Live) theo giaù trò qui ñònh cuûa             vôùi moät tieán trình xöû lyù truyeàn thoâng. Coù hai loaïi socket:
         öùng duïng taàng caáp cao hoaëc laáy giaù trò maëc nhieân cuûa heä thoáng.                   Stream Socket:            Cô cheá truyeàn döõ lieäu theo doøng.
       - Xaùc ñònh tuyeán toái öu cho packet truyeàn ñi.                                              Datagram Socket: Cô cheá truyeàn döõ lieäu theo packet.
       - Neáu khoâng xaùc ñònh ñöôïc tuyeán truyeàn thì thoâng baùo loãi ñeán taàng                  Ñòa chæ socket laø moät giaù trò bao goàm ñòa chæ cuûa host vaø soá hieäu port
         truyeàn thoâng ôû caáp cao hôn. Ngöôïc laïi, thöïc hieän truyeàn theo tuyeán.             maø tieán trình xöû lyù truyeàn thoâng lieân quan socket ñaõ ñaêng kyù söû duïng.
       Host ñònh tuyeán: Vai troø cuûa IP nhö sau:                                             13.2.3 Moät soá caáu truùc döõ lieäu cuûa Winsock API:
       - Kieåm tra checksum cuûa packet. Neáu sai thì huûy packet.                                   Ñòa chæ num-dot cuûa host:
       - Kieåm tra ñòa chæ IP cuûa host nhaän treân packet. Neáu ñòa chæ naøy laø ñòa                    Ñöôïc bieåu dieãn bôûi moät giaù trò chuoãi coù noäi dung laø boán giaù trò soá coù
         chæ moät boä ñònh tuyeán thì noäi dung packet (tröø phaàn noäi dung IP                      ñoä lôùn baèng byte vaø ñöôïc ngaên caùch baèng daáu ‘.’
         header) ñöôïc chuyeån cho giao thöùc taàng caáp cao töông öùng. Ngöôïc                      Ví duï: "127.0.0.1"
         laïi, giaûm giaù trò tröôøng TTL ñi 1; neáu giaù trò tröôøng naøy baèng 0 thì               Caáu truùc khôûi ñoäng winsock :
         huûy boû packet vaø göûi thoâng ñieäp "ICMP Time Expired-TTL                                 typedef struct WSAData {
         Expired" cho host göûi, ngöôïc laïi xaùc ñònh tuyeán göûi vaø göûi packet.                      WORD           wVersion;
       Host nhaän: Vai troø cuûa IP nhö sau:                                                             WORD           wHighVersion;
       - Kieåm tra checksum cuûa packet. Neáu sai thì huûy packet.                                       char           szDescription[WSADESCRIPTION_LEN+1];
                                                                                                         char           szSystemStatus[WSASYS_STATUS_LEN+1];
       - Neáu ñòa chæ host nhaän ghi treân packet khoâng phaûi laø ñòa chæ cuûa host
                                                                                                         unsigned short iMaxSockets;
         ñang xöû lyù thì huûy packet.                                                                   unsigned short iMaxUdpDg;
       - Göûi noäi dung packet (tröø IP header) leân giao thöùc taàng cao hôn.                           char FAR *     lpVendorInfo;
13.2 LAÄP TRÌNH TCP/IP VÔÙI WINSOCK:                                                                  } WSADATA, *LPWSADATA;
    Winsock (Windows Socket) coù xuaát xöù töø BSD (Berkeley Software                                 szDescription: Thoâng tin veà phieân baûn winsock ñang söû duïng.
Distribution - UNIX), töông thích vôùi windows qua phieân baûn WinSock1.1.                            szSystemStatus: Thoâng tin veà phieân baûn heä ñieàu haønh windows.
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                    Caáu truùc chöùa thoâng tin cuûa host :
thoâng TCP vaø UDP. Thoâng qua winsock, öùng duïng coù theå trieån khai deã daøng
                                                                                                      struct hostent {
caùc taùc vuï truyeàn thoâng treân taàng truyeàn thoâng cuûa moâ hình maïng.
                                                                                                          char FAR * h_name;               // Domain name
13.2.1 Port:                                                                                              char FAR * FAR * h_aliases; // Teân duøng thay domain name
   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              short h_addrtype; // Kieåu ñòa chæ, vôùi TCP/IP laø AF_INET
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                      short h_length;         // Kích thöôùc ñòa chæ, 4 bytes cho AF_INET
öù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                   char FAR * FAR * h_addr_list;         // Danh saùch ñòa chæ. Phaàn töû
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.                                                               // ñaàu danh saùch h_addr_list[0]
                                                                                                                                                // (hay h_addr) laø ñòa chæ host.
13.2.2 Socket:                                                                                        } HOSTENT, *PHOSTENT;
                                                                                                      Ñòa chæ socket treân moät host:
                                                                                                      struct sockaddr {
MFC vôùi Internet                                                                       197    198 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
unsigned short sa_family; // Hoï ñòa chæ cuûa host.                                            - Low-order byte = winsock major version number.
          char sa_data[14];         // Ñòa chæ (cho pheùp nhieàu loaïi ñòa chæ)                          - Ví duï: MAKEWORD (1, 1 ) Winsock version 1.1.
       } SOCKADDR ;                                                                                  int gethostname (             // Haøm traû veà SOCKET_ERROR neáu coù loãi
       Caáu truùc naøy ñöôïc töông thích bôûi SOCKADDR_IN cuûa MicroSoft:                                char FAR *name,           // Vuøng ñeäm chöùa thoâng tin
                                                                                                         int namelen               // Kích thöôùc vuøng ñeäm
       struct sockaddr_in {
                                                                                                     ); Laáy thoâng tin veà teân cuûa host.
          short sin_family;                 // Coù giaù trò laø AF_INET
                                                                                                     PHOSTENT gethostbyname (
          unsigned short sin_port;          // Soá hieäu port
                                                                                                         const char FAR *name             // Tham soá chöùa teân host
          struct in_addr sin_addr;          // Ñòa chæ IP 4 bytes cuûa host
                                                                                                     ); Haøm traû veà con troû ñeán caáu truùc HOSTENT chöùa thoâng tin cuûa host.
          char sin_zero[8];                 // Chæ ñeå töông thích vôùi SOCKADDR
                                                                                                     int WSACleanup( ); Chaám döùt söû duïng dòch vuï winsock.
       } SOCKADDR_IN ;
       sin_addr : Ñòa chæ IP 4 bytes cuûa host, coù caùc caùch dieãn taû nhö sau:             13.3 MFC VÔÙI LAÄP TRÌNH WINSOCK:
       struct in_addr {                                                                          Thö vieän söû duïng: AfxSock.h
            union {                                                                           13.3.1 Khôûi ñoäng Winsock:
               struct {                                                                              BOOL AfxSocketInit ( WSADATA* lpwsaData = NULL );
                   unsigned char s_b1, s_b2, s_b3, s_b4;                                             AfxSocketInit ñaûm nhaän vieäc thöïc hieän WSAStartup khi baét ñaàu öùng
               } S_un_b;                  // Ñòa chæ IP baèng 4 bytes                            duïng vaø WSACleanup khi öùng duïng keát thuùc. Lôøi goïi AfxSocketInit ñöôïc
               struct {                                                                          thöïc hieän trong haønh vi InitInstance cuûa ñoái töôïng quaûn lyù tieåu trình chính
                   unsigned short s_w1, s_w2;                                                    cuûa öùng duïng. Tham soá truyeàn cho haøm coù yù nghóa nhö vôùi WSAStartup.
               } S_un_w;                  // Ñòa chæ IP baèng 2 words                         13.3.2 Lôùp CAsyncSocket:
               unsigned long S_addr;      // Ñòa chæ IP baèng 1 long                              CAsyncSocket laø lôùp ñoái töôïng quaûn lyù socket. Baèng söï bao haøm caùc dòch
            } S_un;                                                                           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
13.2.4 Moät soá dòch vuï cuûa Winsock API:                                                    hoaït ñoäng truyeàn thoâng treân taàng truyeàn taûi cuûa giao thöùc TCP/IP.
      char FAR * inet_ntoa (                                                                      Caùc haønh vi ñaëc tröng lôùp CAsyncSocket nhö sau:
          struct in_addr in                // Ñòa chæ IP 4 bytes                                      CAsyncSocket( ); Khôûi taïo ñoái töôïng socket roãng.
      ); Traû veà chuoãi ñòa chæ num-dot töông öùng.                                                  BOOL Create (
      unsigned long inet_addr (                                                                           UINT            nSocketPort = 0,
          const char FAR *cp               // Ñòa chæ IP num-dot                                          int             nSocketType = SOCK_STREAM,
      ); Haøm traû veà giaù trò kieåu long cuûa ñòa chæ IP 4 bytes töông öùng.                            long            lEvent = FD_READ | FD_WRITE | FD_OOB |
      int WSAStartup (                      // Haøm traû veà giaù trò 0 neáu thaønh coâng                                 FD_ACCEPT | FD_CONNECT | FD_CLOSE,
          WORD version,                    // Phieân baûn winsock                                         LPCTSTR         lpszSocketAddress = NULL
          LPWSADATA pMyInfo // Con troû caáu truùc nhaän thoâng tin.                                  ); 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ù).
      ); Khôûi ñoäng, chuaån bò cho vieäc khai thaùc caùc dòch vuï cuûa winsock.                      Trong ñoù:
      version: Chöùa soá hieäu phieân baûn winsock caàn duøng                                         - nSocketPort : Soá hieäu port cuûa socket. Giaù trò naøy coù theå xaùc ñònh
          - High-order byte = winsock minor version number.                                                                 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.
MFC vôùi Internet                                                                       199   200 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
- n SocketType : AÁn ñònh giao thöùc söû duïng; SOCK_STREAM cho                                int nLevel                          = SOL_SOCKET
                            TCP hoaëc SOCK_DGRAM cho UDP.                                         BOOL Listen (
       - lEvent :           Bao goàm caùc thoâng soá lieân quan ñeán caùc bieán coá                   int nConnectionBacklog = 5 // Chieàu daøi doøng chôø keát noái
                            truyeàn thoâng maø öùng duïng muoán winsock phaûn hoài                ); Chôø nhaän keát noái töø host ñoái taùc (server chôø caùc clients).
                            ngay treân socket quaûn lyù bôûi ñoái töôïng socket.                  BOOL Connect (
                            FD_READ               : Nhaän ñöôïc thoâng tin.                           LPCTSTR lpszHostAddress, // Ñòa chæ num.dot cuûa host ñoái taùc
                            FD_WRITE              : Göûi ñöôïc thoâng tin.                            UINT nHostPort                      // Soá hieäu port treân host ñoái taùc
                            FD_ACCEPT : Ñoàng yù keát noái.                                       ); Xin keát noái vôùi host ñoái taùc (clients keát noái vôùi server).
                            FD_CONNECT : Ñeà nghò keát noái.                                      BOOL Connect (
                            FD_CLOSE              : Chaám döùt keát noái.                             const SOCKADDR* lpSockAddr, // Ñòa chæ socket host ñoái taùc
                            FD_OOB                : Thoâng tin ngoaøi tuyeán.                         int nSockAddrLen                            // Kích thöôùc lpSockAddr
       - lpszSocketAddress : Chuoãi chöùa ñòa chæ num-dot cuûa host ñoái taùc maø                 ); Xin keát noái vôùi host ñoái taùc (clients keát noái vôùi server).
                            socket ñöôïc keát (bind). INADDR_ANY laø ñòa chæ                      virtual BOOL Accept (
                            duøng keát vôùi taát caû caùc host trong heä thoáng maïng.                CAsyncSocket& rConnectedSocket,
       BOOL Bind (                                                                                    SOCKADDR* lpSockAddr = NULL,
           UINT nSocketPort,                              // Soá hieäu port                           int* lpSockAddrLen = NULL
           LPCTSTR lpszSocketAddress = NULL // Ñòa chæ num-dot cuûa host                          ); 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).
       ); Keát socket vôùi moät host xaùc ñònh.                                                   Trong ñoù:
       BOOL Bind (                                                                                - rConnectedSocket : Bieán chöùa ñoái töôïng socket ñöôïc taïo môùi vôùi
           const SOCKADDR* lpSockAddr,                  // Ñòa chæ socket host ñoái taùc                                       caùc ñaëc tính gioáng nhö ñoái töôïng chuû theå vaø
           int nSockAddrLen                             // Kích thöôùc lpSockAddr                                              duøng ñeå quaûn lyù lieân keát vöøa thieát laäp.
       ); Keát socket vôùi moät host xaùc ñònh.                                                   - lpSockAddr :               Ñòa chæ bieán kieåu SOCKADDR ñöôïc duøng ñeå
       BOOL SetSockOpt (                                                                                                       nhaän ñòa chæ host ñoái taùc.
           int nOptionName,                     // Thuoäc tính caàn aán ñònh                      - lpSockAddrLen : Ñòa chæ bieán ñöôïc duøng ñeå nhaän kích thöôùc cuûa
           const void* lpOptionValue,           // Ñòa chæ bieán chöùa giaù trò aán ñònh                                       ñòa chæ traû veà trong lpSockAddr.
           int nOptionLen,                      // Kích thöôùc bieán chöùa giaù trò               virtual int Send (                // Söû duïng cho Stream Socket
           int nLevel = SOL_SOCKET // Möùc ñaët thoâng soá cho socket                                 const void* lpBuf,            // Ñòa chæ vuøng ñeäm chöùa döõ lieäu truyeàn
       ); AÁn ñònh ñaëc tính hoaït ñoäng cuûa socket.                                                 int nBufLen,                  // Kích thöôùc vuøng ñeäm
       nOptionName cho pheùp löïa choïn thuoäc tính aán ñònh cuûa socket :                            int nFlags = 0                // Thoâng soá aán ñònh ñaëc tính göûi
       - SO_BROADCAST : BOOL → Göûi message ñeán moïi host.                                       ); Göûi döõ lieäu thoâng qua moät socket ñöôïc keát noái.
       - SO_DONTROUTE : BOOL → Göûi tröïc tieáp khoâng qua router.                                Thoâng soá duøng cho ñaëc tính göûi:
       Ví duï: Neáu aán ñònh ñaëc tính cuûa socket laø cho pheùp göûi message ñeán                - MSG_DONTROUTE                   = Göûi thaúng khoâng qua router.
       moïi host thì haønh vi treân ñöôïc thöïc hieän vôùi tham soá nhö sau:                      - MSG_OOB                         = Göûi ngoaïi tuyeán (khaån caáp)
           int nOptionName,                  = SO_BROADCAST                                       int SendTo (                                        // Söû duïng cho Datagram
           const void* lpOptionValue, = Ñòa chæ bieán luaän lyù baèng TRUE                            const void* lpBuf,                              // Vuøng ñeäm döõ lieäu
           int nOptionLen,                   = sizeof (BOOL)                                          int nBufLen,                                    // Kích thöôùc vuøng ñeäm

MFC vôùi Internet                                                                   201    202 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
UINT nHostPort,                                // Soá hieäu port ñoái taùc              virtual void OnConnect (
           LPCTSTR lpszHostAddress = NULL, // Ñòa chæ num-dot ñoái taùc                                int nErrorCode            // Maõ loãi
           int nFlags = 0                                 // Ñaëc tính göûi.                       ); Nhaän ñöôïc yeâu caàu xin keát noái cuûa host ñoái taùc.
       ); Göûi packet ñeán host ñoái taùc. Haøm traû veà soá bytes döõ lieäu göûi ñöôïc.           virtual void OnAccept (
       Ñeå göûi packet ñeán taát caû caùc host, ñaët lpszHostAddress = NULL.                           int nErrorCode            // Maõ loãi, = 0 is OK
       int SendTo (                                       // Söû duïng cho Datagram                ); Nhaän ñöôïc söï ñoàng yù keát noái cuûa host ñoái taùc.
           const void* lpBuf,                             // Nhö treân …                           virtual void OnSend (
           int nBufLen,                                                                                int nErrorCode
           const SOCKADDR* lpSockAddr,                    // Ñòa chæ socket ñoái taùc              ); Socket ñaõ saün saøng cho vieäc göûi döõ lieäu.
           int nSockAddrLen,                              // Kích thöôùc ñòa chæ                   virtual void OnReceive (
           int nFlags = 0                                                                              int nErrorCode
       ); Göûi packet ñeán host ñoái taùc. Haøm traû veà soá bytes döõ lieäu ñöôïc göûi.           ); Döõ lieäu ñaõ saün saøng chôø nhaän thoâng qua socket.
       Ñeå göûi packet ñeán taát caû caùc host, giaù trò ñòa chæ ñoái taùc ñaët nhö sau:           virtual void OnOutOfBandData (
           lpSockAddr->sin_addr.s_addr = htonl ( INADDR_BROADCAST );                                   int nErrorCode
       virtual int Receive (                    // Söû duïng cho Stream Socket                     ); Coù döõ lieäu khaån caáp saün saøng chôø nhaän thoâng qua socket.
           void* lpBuf,                         // Ñòa chæ vuøng ñeäm nhaän döõ lieäu              virtual void OnClose (
           int nBufLen,                         // Kích thöôùc vuøng ñeäm                              int nErrorCode
           int nFlags = 0                       // Ñaëc tính nhaän döõ lieäu.                      ); Socket chuaån bò chaám döùt hoaït ñoäng.
       ); Nhaän döõ lieäu thoâng qua moät socket ñöôïc keát noái.                                  BOOL ShutDown (
       int ReceiveFrom (                        // Söû duïng cho Datagram                              int nHow                  // 0 = receive, 1 = send ; 2 = both
           void* lpBuf,                         // Ñòa chæ vuøng ñeäm chöùa döõ lieäu              ); Chaám döùt taùc vuï truyeàn thoâng töông öùng treân socket.
           int nBufLen,                         // Kích thöôùc vuøng ñeäm                          virtual void Close( ); Huûy boû socket.
           CString& rSocketAddress,             // Ñòa chæ num-dot ñoái taùc
                                                                                            13.4 LAÄP TRÌNH WINSOCK CHO GIAO THÖÙC UDP:
           UINT& rSocketPort,                   // Soá hieäu port ñoái taùc
                                                                                                Trong phaàn naøy ta söû duïng giao thöùc UDP ñeå thöïc hieän truyeàn thoâng ñieäp
           int nFlags = 0                       // Ñaëc tính göûi
                                                                                            giöõa hai hay nhieàu host. ÖÙng duïng thieát keá cho pheùp ngöôøi duøng soaïn thaûo
       ); Nhaän döõ lieäu töø host ñoái taùc.
                                                                                            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.
       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.
                                                                                               Caùch thöïc hieän nhö sau:
       BOOL AsyncSelect ( long lEvent = FD_READ | FD_WRITE |
                                                                                                  Duøng MFC Wizard taïo döï aùn Udp vôùi cöûa soå giao dieän chính laø dialog.
                  FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE );
                                                                                                  ÔÛ böôùc ‘Step 2 of 4’: Choïn hoã trôï Windows Sockets:
           Ñaêng kyù bieán coá truyeàn thoâng mong muoán (xem Create ).

MFC vôùi Internet                                                                     203   204 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
}
                                                                                                   - 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);
                                                                                                        }
       Choïn Finish hoaøn ñeå hoaøn taát vieäc khôûi taïo döï aùn.                                      else
       Tieáp tuïc thöïc hieän caùc boå sung sau :                                                         SendTo(m_Buffer, BUF_LEN, RECEIV_PORT, peerAddr);
       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:                                                            - Haønh vi keá thöøa OnReceive nhaän thoâng tin göûi ñeán vaø hieån thò trong
       - Khai baùo caùc haèng, soá hieäu port söû duïng trong öùng duïng:                            hoäp thoâng baùo coù soá hieäu laø IDC_READ cuûa dialog lieân quan:
           const BUF_LEN                  = 512;          // Chieàu daøi vuøng ñeäm                  void CEmpUdp::OnReceive(int nErrorCode)
           const SENT_PORT                = 2051;         // port göûi thoâng tin                    {
           const RECEIV_PORT = 2050;                      // port nhaän thoâng tin                      CString peerAddr;                    // Ñòa chæ host ñoái taùc vaø
       - Caùc ñoái töôïng thuoäc tính söû duïng trong lôùp:                                             UINT       port;                     // soá hieäu port söû duïng
           char           *m_Buffer;        // Vuøng ñeäm chöùa thoâng tin nhaän-göûi                   ReceiveFrom(m_Buffer, BUF_LEN, peerAddr, port);
           CDialog        *m_Parent; // Con troû ñoái töôïng dialog lieân quan                          sprintf (m_Buffer, "%sn(from %s)", m_Buffer, peerAddr );
       - Haønh vi khôûi taïo cuûa lôùp nhaän tham soá laø con troû ñoái töôïng dialog                   m_Parent->SetDlgItemText ( IDC_READ, m_Buffer );
           giao dieän lieân quan; thöïc hieän löu giaù trò con troû vaøo thuoäc tính cuûa                 AsyncSelect(FD_READ);               // Duy trì vieäc nhaän thoâng tin
           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ôû 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ò
               m_Parent = parent;
                                                                                                   thoâng tin nhaän, vaø hoäp nhaäp IP vôùi bieán m_IP duøng nhaäp ñòa chæ IP.
               m_Buffer = new char[BUF_LEN + 1];
MFC vôùi Internet                                                                    205    206 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
Thöïc hieän caùc boå sung cho lôùp CUDPDlg quaûn lyù dialog giao dieän:                    CSocket sockSrvr;                          CSocket sockClient;
       - Khai baùo caùc ñoái töôïng thuoäc tính quaûn lyù socket nhaän vaø göûi thoâng            // Taïo socket 1,2                         // Taïo socket 2
          tin cuûa öùng duïng:                                                                    sockSrvr.Create(nPort);                    sockClient.Create( );
          CEmpUdp *m_sentUDP;                // Quaûn lyù socket göûi thoâng tin                  // Chôø nhaän keát noái
          CEmpUdp *m_receivUDP; // Quaûn lyù socket nhaän thoâng tin                              sockSrvr.Listen( );
       - Haønh vi OnInitDialog: Caáp phaùt vaø khôûi taïo thoâng soá cho caùc ñoái                                                           // Xin pheùp keát noái 3,4
          töôïng CEmpUdp:                                                                                                                    sockClient.Connect(strAddr,nPort);
          m_sentUDP = new CEmpUdp(this);                                                          // Chuaån bò socket keát noái
          m_receivUDP = new CEmpUdp(this);                                                        CSocket sockRecv;
          m_sentUDP->Create(SENT_PORT, SOCK_DGRAM, 0);                                            // Ñoàng yù keát noái 5
          m_receivUDP->Create(RECEIV_PORT,SOCK_DGRAM,FD_READ);                                    sockSrvr.Accept( sockRecv );
       - Haønh vi OnOK (töông öùng nuùt choïn OK) thöïc hieän göûi thoâng ñieäp:                  // Truyeàn döõ lieäu 6 .                   // Truyeàn döõ lieäu 6 .
          void CUDPDlg::OnOK()                                                                    ...                                        ...
          {                                                                                       // Keát thuùc keát noái 7 .
                                                                                                                                             sockClient.Close()
              m_sentUDP->AsyncSelect(FD_WRITE); // Ñaêng kyù göûi                                 sockSrvr.Close();
          }
                                                                                                 Caùch thöïc hieän:
       Bieân dòch vaø chaïy thöû öùng duïng.
                                                                                                    Taïo taäp döï aùn roãng (Blank Workspace):
13.5 LAÄP TRÌNH WINSOCK CHO GIAO THÖÙC TCP:                                                         - Choïn muïc File / New
    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öï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
   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ø          server coù nhieäm vuï chôø keát noái vaø cung caáp döõ lieäu cho caùc client.
   host client nhö sau:                                                                              - Trong maøn hình Worksapce, right-click treân muïc Workspace.

    Server                                  Client

    // Khai baùo socket                     // Khai baùo socket
MFC vôùi Internet                                                                      207    208 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
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
     - Choïn Add New Project to Workspace.                                                                 // IDC_FILE : Soá hieäu hoäp nhaäp teân taäp tin treân dialog
     - Duøng Wizard taïo döï aùn TcpServer vôùi giao dieän chính laø dialog, vaø                           m_Parent->GetDlgItemText(IDC_FILE, fileName);
         coù söû duïng windows socket. Caùch thöïc hieän töông töï (13.4).                                 fileOK = file.Open(fileName, CFile::modeRead);
   Thöïc hieän caùc coâng vieäc sau cho döï aùn TcpServer :                                                total = 0;                    // Chöùa kích thöôùc thoâng tin göûi
     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                      if (!fileOK ||
     ñöôïc keát noái (OnSend), vaø chaám döùt keát noái khi ñaõ truyeàn xong                               ( buf.length = file.Read( buf.info, BUFFER_LEN ) )
     (Close). Caøi ñaët cuûa lôùp CEmpTcpWriter nhö sau:                                                             < BUFFER_LEN )
     - Khai baùo kieåu caáu truùc cho vuøng ñeäm chöùa döõ lieäu göûi:                                     fileReady = FALSE;            // Khoâng coù file hoaëc ñaõ göûi heát
         const BUFFER_LEN = 1024; // Kích thöôùc vuøng chöùa döõ lieäu                                Send( &buf, BUFFER_LEN + sizeof(int) );
         typedef struct _tagBuf {                                                                     total += buf.length;
             int     length;                       // Kích thöôùc döõ lieäu thöïc                     if (fileReady) {
             char info[BUFFER_LEN]; // Vuøng chöùa döõ lieäu                                               Sleep( 300 );                     // Thôøi gian nghæ cho client
         } BUFFER;                                                                                         AsyncSelect( FD_WRITE ); // Göûi tieáp
                                                                                                      }
     - Caùc thuoäc tính protected:
                                                                                                      else {
             BOOL           m_isBusy; // Traïng thaùi phuïc vuï.                                           if ( fileOK ) file.Close();
             CDialog* m_Parent; // Ñoái töôïng dialog lieân quan                                           Close();
     - Haønh vi taïo laäp nhaän tham soá laø con troû ñoái töôïng dialog lieân quan,                       m_isBusy = FALSE;             // Saün saøng nhaän döõ lieäu
         vaø xaùc ñònh traïng thaùi saün saøng:                                                            CString result;
         CEmpTcpWriter::CEmpTcpWriter( CDialog* parent )                                                   result.Format( "nReady to connect to clients !n"
         {                                                                                                                     "%d (bytes) transfered completed", total );
             m_Parent = parent;              // Ñoái töôïng dialog lieân quan                              m_Parent->SetDlgItemText( IDC_INFO, result );
                                                                                                      }
             m_isBusy = FALSE;               // Saün saøng nhaän döõ lieäu
                                                                                                  }
         }
                                                                                              Boå sung lôùp CEmpTcpServer keá thöøa CAsyncSocket ñaûm nhaän caùc
     - Haønh vi OnSend thöïc hieän göûi döõ lieäu cho client lieân keát:
                                                                                              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:
         void CEmpTcpWriter::OnSend( int nErrorCode )
         {                                                                                    - Caùc thuoäc tính protected cuûa lôùp CEmpTcpServer:
             static       BOOL fileOK = TRUE;                                                        CEmpTcpWriter* m_pDoSendObject; // Ñoái töôïng göûi döõ lieäu
MFC vôùi Internet                                                               209    210 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
CDialog*               m_Parent;                  // Dialog lieân quan                      // Xaùc ñònh ñòa chæ IP cuûa server host
       - Haønh vi taïo laäp nhaän tham soá laø con troû ñoái töôïng dialog lieân quan:                    char name[1024];
           CEmpTcpServer::CEmpTcpServer( CDialog* parent )                                                gethostname( name, 1024 );
           {                                                                                              PHOSTENT phost = gethostbyname( name );
                                                                                                          SetDlgItemText( IDC_HOSTIP,
              m_Parent = parent;               // Con troû ñoái töôïng dialog lieân quan
                                                                                                                               inet_ntoa(*(in_addr*)phost->h_addr) );
              m_pDoSendObject = new CEmpTcpWriter( m_Parent );
                                                                                                          m_Tcp = new CEmpTcpServer( this );
           }
                                                                                                          m_Tcp->Create( PORT_NO );                // Khôûi taïo thoâng soá
       - Haønh vi huûy boû giaûi phoùng ñoái töôïng m_pDoSendObject:
                                                                                                          m_Tcp->Listen();                         // Chôø keát noái
           CEmpTcpServer::~CEmpTcpServer( )                                                               return TRUE;
           {                                                                                         }
              delete m_pDoSendObject;
           }                                                                                      - Haønh vi OnDestroy thöïc hieän giaûi phoùng ñoái töôïng truyeàn thoâng
                                                                                                     void CTcpServerDlg::OnDestroy()
       - Haønh vi OnAccept chaáp nhaän keát noái neáu ñang roãi:
                                                                                                     {
           void CEmpTcpServer::OnAccept( int nErrorCode )                                               CDialog::OnDestroy();
           {                                                                                            delete m_Tcp;
              if ( m_pDoSendObject->m_isBusy )                                                       }
                   return ;                                     // Ñang baän phuïc vuï
                                                                                                  Taïo döï aùn TcpClient. Thao taùc töông töï döï aùn TcpServer.
              SOCKADDR_IN Addr;
              int                      Len = sizeof(SOCKADDR_IN);                             Thöïc hieän caùc coâng vieäc sau ñaây vôùi döï aùn TcpClient :
              if (Accept(*m_pDoSendObject, (SOCKADDR*) &Addr, &Len))                              Boå sung lôùp CEmpTcpReader keá thöøa CAsyncSocket ñaûm nhaän chöùc
                   // Khôûi ñoäng hoaït ñoäng göûi döõ lieäu treân m_pDoSendObject                naêng xin keát noái (Connect), vaø nhaän döõ lieäu (OnReceive) töø server:
                   m_pDoSendObject->AsyncSelect(FD_WRITE);                                        - Thuoäc tính public chöùa traïng thaùi truyeàn thoâng:
           }                                                                                             BOOL m_isBusy; // = TRUE : Ñang baän
       Thöïc hieän caùc caøi ñaët boå sung cho lôùp ñoái töôïng dialog CTcpServerDlg              - Thuoäc tính protected chöùa con troû ñoái töôïng dialog lieân quan:
       laøm giao dieän chính cuûa öùng duïng server:                                                     CDialog* m_Parent;
       - Môû dialog resource, caøi ñaët caùc control sau:                                         - Haønh vi taïo laäp nhaän tham soá laø ñoái töôïng dialog lieân quan:
           - Hoäp nhaäp teân taäp tin                     : Edit     Soá hieäu IDC_FILE               CEmpTcpReader::CEmpTcpReader(CDialog* parent)
           - 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                                 m_isBusy = FALSE; // Saün saøng laøm vieäc
       - Ñoái töôïng thuoäc tính protected laøm nhieäm vuï truyeàn thoâng:                               m_Parent = parent;
              CEmpTcpServer*             m_Tcp;                                                       }
       - Haønh vi OnInitDialog cuûa dialog khôûi taïo thoâng soá cho dialog vaø caùc              - Haønh vi OnReceive nhaän döõ lieäu vaø löu xuoáng taäp tin:
           thoâng soá caàn thieát cho hoaït ñoäng truyeàn thoâng vôùi m_Tcp:                          void CEmpTcpReader::OnReceive(int nErrorCode)
           BOOL CTcpServerDlg::OnInitDialog()                                                         {
           {                                                                                             static         BOOL fileOK = TRUE;
              CDialog::OnInitDialog(); SetIcon( m_hIcon, TRUE );                                         static         BOOL fileReady = FALSE;
              SetDlgItemText( IDC_FILE, "C:/AUTOEXEC.BAT" );                                             static         CFile    file;
                                                                                                         static         long     total;
MFC vôùi Internet                                                                   211    212 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
BUFFER buf;                                                                              - Nuùt leänh download taäp tin töø server       : Button      IDOK
               Receive(&buf, BUFFER_LEN + sizeof(int));                                             - Taïo thuoäc tính bieán m_serverIP cho hoäp nhaäp IDC_HOSTIP.
               if ( fileOK && (!fileReady) ) {                                                      - Ñoái töôïng thuoäc tính protected laøm nhieäm vuï truyeàn thoâng:
                    m_Parent->SetDlgItemText(IDC_INFO, "nDownloading...");                                 CEmpTcpReader *m_readTcp;
                    fileReady = TRUE;                                                               - Haønh vi OnInitDialog cuûa dialog khôûi taïo thoâng soá cho dialog vaø
                    CString fileName;               // Teân taäp tin chöùa döõ lieäu nhaän              caùc thoâng soá caàn thieát cho hoaït ñoäng truyeàn thoâng vôùi m_readTcp:
                    // IDC_FILE : Soá hieäu hoäp nhaäp teân taäp tin treân dialog                       BOOL CTcpClientDlg::OnInitDialog()
                    m_Parent->GetDlgItemText( IDC_FILE, fileName );                                     {
                    fileOK = file.Open ( fileName,                                                          CDialog::OnInitDialog();
                                          CFile::modeWrite | CFile::modeCreate );                           SetIcon(m_hIcon, TRUE);                  // Set big icon
                    total = 0;        // Kích thöôùc döõ lieäu nhaän ñöôïc                                  SetIcon(m_hIcon, FALSE);                 // Set small icon
               }                                                                                            m_serverIP.SetWindowText( "127.0.0.1" );                  // local host
               if ( fileOK && buf.length > 0 ) {                                                            SetDlgItemText( IDC_FILE, "C:/Autoexec.000" );
                    file.Write( buf.info, buf.length );                                                     m_readTcp = new CEmpTcpReader( this );
                    total += buf.length;                                                                    return TRUE;
                    if ( buf.length < BUFFER_LEN )                                                      }
                         fileReady = FALSE;         // Ñaõ nhaän ñuû döõ lieäu töø server           - Haønh vi OnDestroy giaûi phoùng ñoái töôïng truyeàn thoâng:
               }
                                                                                                        void CTcpClientDlg::OnDestroy()
               else
                                                                                                        {
                    fileReady = FALSE;
                                                                                                            CDialog::OnDestroy();
               if (fileReady)                                                                               delete m_readTcp;
                    CAsyncSocket::OnReceive(nErrorCode); // Nhaän tieáp                                 }
               else {                                                                               - Haønh vi OnOK öùng vôùi nuùt choïn download baét ñaàu nhaän döõ lieäu:
                    m_isBusy = FALSE;               // Trôû laïi traïng thaùi saün saøng @              void CTcpClientDlg::OnOK()
                    Close();                                                                            {
                    if (fileOK) file.Close();                                                               CString s;
                    CString result;                                                                         m_serverIP.GetWindowText(s);
                    result.Format( "nReady to connect to server !n"                                       if ( m_readTcp->m_isBusy || s == "0.0.0.0" ) return;
                                        "%d (bytes) download completed.", total );                          m_readTcp->m_isBusy = TRUE; // Traïng thaùi baän @
                    m_Parent->SetDlgItemText(IDC_INFO, result);                                             m_readTcp->Create();
               }                                                                                            m_readTcp->Connect(s, PORT_NO);
           }                                                                                            }
       Thöïc hieän caùc caøi ñaët boå sung cho lôùp ñoái töôïng dialog CTcpClientDlg                Bieân dòch caùc döï aùn vaø thöû nghieäm treân moät hoaëc nhieàu maùy.
       laøm giao dieän chính cuûa öùng duïng client:                                                Choïn muïc : Project / Set Active Project ñeå aán ñònh döï aùn laøm vieäc
       - Môû dialog resource, caøi ñaët caùc control sau:                                            trong taäp döï aùn (Workspace) nhö tröôøng hôïp noùi treân.
           - Hoäp nhaäp teân taäp tin                    : Edit       IDC_FILE                      Söû duïng CSocket vaø CSocketFile cho taùc vuï truyeàn taäp tin noùi treân.
           - 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
MFC vôùi Internet                                                                     213    214 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
Lôùp CSocket:                                                                                     Sau khi nhaän ñöôïc tín hieäu traû lôøi nhö treân töø öùng duïng nhaän mail,
            CSocket laø lôùp keá thöøa CAsyncSocket maø caùc haønh vi göûi vaø nhaän                  öù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öï.
       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            ‘Trình dieän’ vôùi öùng duïng nhaän mail:
       taát. Nhö vaäy, seõ khoâng gaëp loãi taùc vuï ngheõn (WSAEWOULDBLOCK)                             Göûi: HELO <SP> <domain> <CRLF>
       khi thöïc hieän truyeàn döõ lieäu vôùi CSocket. Ñieàu naøy raát quan troïng vôùi                  Trong ñoù:       SP           : Kyù töï khoaûng traéng
       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).                                 CRLF         : rn             // return & newline in C
            Trong phaàn noäi dung tieáp theo, CSocket seõ ñöôïc söû duïng ñeå thay theá                  Nhaän: OK             : 250 BBN-UNIX.ARPA
       cho CAsyncSocket trong caùc ví duï minh hoïa.                                                              ERROR : Soá hieäu loãi (keát noái bò töø choái).
13.6 TCP VÔÙI SMTP (SIMPLE MAIL TRANSFER PROTOCOL):                                                   Neáu nhaän ñöôïc traû lôøi “250 <Server Name>” töø öùng duïng nhaän mail,
    SMTP laø giao thöùc ñôn giaûn vaø hieäu quaû cho vieäc truyeàn taûi e-mail töø host               öùng duïng göûi mail coù theå tieáp tuïc caùc coâng vieäc keá tieáp.
göûi ñeán host nhaän mail; ví duï töø moät mail client ñeán moät mail server. Quaù                    Ñaêng kyù ñòa chæ ngöôøi göûi mail:
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              Göûi: MAIL <SP> FROM:<ñòa_chæ_nôi_göûi> <CRLF>
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.              Nhaän: OK              : 250 OK
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                        ERROR : Ñaêng kyù khoâng ñöôïc chaáp nhaän keát thuù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:                  Ñ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
       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                            ERROR : 550 Failure
       nhaän ñeå xin keát noái.                                                                       Truyeàn noäi dung cuûa mail: Coù theå laëp nhieàu laàn thao taùc sau ñaây tuøy
       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                 theo soá ñoaïn vaên baûn trong noäi dung cuûa mail.
       tuïc chuyeån phaàn noäi dung keá tieáp cuûa mail.                                                  Göûi: Noäi dung ñoaïn vaên baûn thöù (i) 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               Nhaän: Khoâng coù traû lôøi cuûa host nhaän.
       dung töø choái töø phía host nhaän.                                                            Chaám döùt truyeàn noäi dung cuûa mail:
13.6.1 Qui öôùc giao taùc giöõa öùng duïng göûi mail vaø öùng duïng nhaän mail:                           Göûi: <CRLF> . <CRLF>
      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                  Nhaän: 250 OK
      giao thöùc TCP keát noái vôùi öùng duïng nhaän mail treân host nhaän thoâng qua                 Keát thuùc keát noái vôùi host nhaän:
      ñòa chæ IP cuûa host nhaän vaø soá hieäu port cuûa öùng duïng nhaän mail.                           Göûi: QUIT <CRLF>
         Göûi: Môû socket vaø lieân laïc vôùi öùng duïng nhaän mail (port = 25).                          Nhaän: 221 Terminated Info
         Nhaän: 220 <Domain> <ServerName> ready                                                   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:
MFC vôùi Internet                                                                       215    216 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
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                     void CSMTPDlg::OnOK()
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.                                                    char         s[1025];
        Duøng MFC Wizard taïo döï aùn vôùi cöûa soå giao dieän chính laø dialog, coù söû                     UINT         port;
                                                                                                             CSocket m_sock;
        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):                                GetDlgItemText(IDC_SERVER_IP, s, 1024);
                                                                                                             port = GetDlgItemInt(IDC_SERVER_PORT);
        - Môû dialog resource, caøi ñaët caùc control sau:
            - Hoäp nhaäp ñòa chæ mail server           : Edit       IDC_SERVER_IP                            m_sock.Create();
            - Hoäp nhaäp soá hieäu port                : Edit       IDC_SERVER_PORT                          if (!m_sock.Connect(s, port)) return;
            - Hoäp nhaäp ñòa chæ ngöôøi nhaän          : Edit       IDC_MAIL_TO                              if (!m_sock.Receive(s, 1024) || GetErrorCode(s) != 220)
            - Hoäp nhaäp tieâu ñeà cuûa mail           : Edit       IDC_MAIL_SUBJECT                              return;
            - Hoäp soaïn thaûo noäi dung mail          : Edit       IDC_MAIL                                 strcpy(s, "HELO Mr.Emprn");
            - Nuùt leänh thöïc hieän göûi mail         : Button IDOK                                         m_sock.Send(&s, strlen(s));
                                                                                                             if (!m_sock.Receive(s, 1024) || GetErrorCode(s) != 250)
        - Haønh vi OnInitDialog thöïc hieän caùc khôûi taïo caàn thieát:
                                                                                                                  return;
            BOOL CSMTPDlg::OnInitDialog()
                                                                                                             // Ñòa chæ ngöôøi göûi
            {
                                                                                                             strcpy(s, "MAIL FROM:Mr.Emprn");
                CDialog::OnInitDialog();
                                                                                                             m_sock.Send(&s, strlen(s));
                SetIcon(m_hIcon, TRUE);                                                                      if (!m_sock.Receive(s, 1024) || GetErrorCode(s) != 250)
                SetIcon(m_hIcon, FALSE);                                                                          return;
                SetDlgItemText(IDC_SERVER_IP, "omail.hcmueco.edu.vn");                                        // Ñòa chæ ngöôøi nhaän
                SetDlgItemText(IDC_SERVER_PORT, "25");                                                        strcpy(s, "RCPT TO:");
                SetDlgItemText(IDC_MAIL_TO, "emp@hcmueco.edu.vn");                                            GetDlgItemText(IDC_MAIL_TO, s + strlen(s), 1024);
                SetDlgItemText(IDC_MAIL_SUBJECT,                                                              strcpy(s + strlen(s), "rn");
                                                       "A Lesson of Mr.Emp");                                 m_sock.Send(&s, strlen(s));
                SetDlgItemText(IDC_MAIL, "Hello Mr.Emp!rnrn"                                              if (!m_sock.Receive(s, 1024) || GetErrorCode(s) == 550)
                                                       "It's nice to meet You.rnrn"                            return;
                                                       "Thanks for your lessons.");
                return TRUE;                                                                                  // Chuaån bò truyeàn noäi dung mail
            }                                                                                                 strcpy(s, "DATArn");
                                                                                                              m_sock.Send(&s, strlen(s));
        - Haønh vi kieåm tra loãi treân giaù trò nhaän ñöôïc töø öùng duïng nhaän mail:
                                                                                                              if (!m_sock.Receive(s, 1024) || GetErrorCode(s) != 354)
            Caøi ñaët haønh vi protected: GetErrorCode cho lôùp CSMTPDlg:                                          return;
            UINT CSMTPDlg::GetErrorCode(char *sReply)
            {                                                                                                 // Chuû ñeà mail
                UINT rs = 0;                                                                                  strcpy(s, "Subject:");
                sscanf(sReply, "%d", &rs);                                                                    GetDlgItemText(IDC_MAIL_SUBJECT, s + strlen(s), 1024);
                return rs;        // Traû veà soá hieäu loãi ghi trong döõ lieäu nhaän ñöôïc                  strcpy(s + strlen(s), "rn");
           }                                                                                                  m_sock.Send(&s, strlen(s));
       - Haønh vi OnOK öùng vôùi nuùt choïn IDOK thöïc hieän göûi mail:                                       // Noäi dung mail
MFC vôùi Internet                                                                       217    218 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
GetDlgItemText(IDC_MAIL, s, 1024);                                                                  -ERR error_message            keát thuùc.
               sprintf(s, "%s%s", s, "rn");                                                    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:
               m_sock.Send(&s, strlen(s));                                                           Laáy thoâng tin veà hoäp mail:
               // Keát thuùc                                                                            Göûi: STAT <CRLF>
               strcpy(s, "rn.rn");                                                                  Nhaän: +OK <SP> <number_of_mail> <SP> <mail_total_size>
               m_sock.Send(&s, strlen(s));                                                                       -ERR error_message
               strcpy(s, "QUITrn");                                                                Laáy thoâng tin chi tieát cuûa caùc mail trong hoäp mail:
               m_sock.Send(&s, strlen(s));                                                              Göûi: LIST <CRLF>
               m_sock.Close();                                                                          Nhaän: +OK <SP> Mailbox scan listing follows
               MessageBox("The Mail was sent OK !", "Send mail");                                                -ERR error_message
           }                                                                                         Ñoïc mail:
13.7 TCP VÔÙI POP3 (Post Office Protocol - Version 3):                                                  Göûi: RETR <SP> <soá_hieäu_mail_ñöôïc_ñoïc> <CRLF>
    POP3 laø giao thöùc cho pheùp mail client host keát noái vôùi mail server host ñeå                  Nhaän: +OK kích_thöôùc_message octets
laáy thoâng tin veà hoäp mail cuûa ngöôøi duøng treân mail server. Hoaït ñoäng truy                                … message do mail server göûi veà, keát thuùc bôûi daáu ‘.’
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                             -ERR error_message
hoäp mail cuûa hoï treân mail server. Töông töï SMTP, quaù trình taûi mail töø server                Xoùa mail:
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             Göûi: DELE <SP> <soá_hieäu_mail_xoùa> <CRLF>
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.              Nhaän: +OK message <n> deleted
Mail server tieáp nhaän yeâu caàu cuûa client vaø traû lôøi hoaëc göûi döõ lieäu.                                -ERR error_message
                                                                                                     Chaám döùt lieân keát vôùi mail server:
13.7.1 Qui öôùc giao taùc giöõa hai öùng duïng mail client vaø mail server:
                                                                                                        Göûi: QUIT <CRLF>
      Thieát laäp lieân keát: Ñaàu tieân, öùng duïng mail client söû duïng giao thöùc
                                                                                                        Nhaän: + OK goodbye_message
      TCP keát noái vôùi öùng duïng mail server thoâng qua ñòa chæ IP cuûa mail
                                                                                                                 - ERR error_message
      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).              13.7.2 Thieát keá öùng duïng nhaän mail:
         Nhaän: +OK ok_message                                                                    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
                   -ERR error_message                                                         vaø laáy mail töø moät POP mail server. Thoâng soá lieân quan mail server vaø thoâng
         Sau khi nhaän ñöôïc tín hieäu traû lôøi ‘OK’ töø öùng duïng mail server, öù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 mail client tieáp tuïc thöïc hieän caùc taùc vuï sau theo thöù töï.                    Duøng MFC Wizard taïo döï aùn vôùi cöûa soå giao dieän chính laø dialog, coù söû
   Ñaêng kyù taøi khoaûn truy caäp mail server:                                                       duïng winsock (xem muïc 13.4). Ñaët teân cho döï aùn laø POP3.
       Khai baùo user name:                                                                           Thöïc hieän caùc caøi ñaët sau cho dialog giao dieän chính (CPOP3Dlg):
         Göûi: USER <SP> <teân_ngöôøi_söû_duïng> <CRLF>                                               - Môû dialog resource, caøi ñaët caùc control sau:
         Nhaän: +OK ok_message                                                                           - Hoäp nhaäp ñòa chæ mail server : Edit         IDC_SERVER_IP
                  -ERR error_message keát thuùc.                                                         - Hoäp nhaäp soá hieäu port           : Edit    IDC_SERVER_PORT
       Khai baùo password:                                                                               - Hoäp nhaäp teân ngöôøi truy caäp : Edit       IDC_USER_NAME
         Göûi: PASS <SP> <noäi_dung_password> <CRLF>                                                     - Hoäp nhaäp password truy caäp : Edit          IDC_USER_PASSWORD
         Nhaän: +OK ok_message
MFC vôùi Internet                                                                      219    220 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
- Hoäp nhaäp soá hieäu mail nhaän veà          :                      Edit           - Haønh vi protected : isOK kieåm tra traû lôøi cuûa mail server treân döõ
                                               IDC_MAIL_NO                                      lieäu nhaän ñöôïc sau moãi taùc vuï lieân laïc:
         - Hoäp hieån thò noäi dung mail       : Edit   IDC_MAIL                                BOOL CPOP3Dlg::isOK(char *result)
         - 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                                 return ( result[0] == '+' &&
       - Haønh vi OnOK öùng vôùi nuùt OK thöïc hieän laáy thoâng tin veà hoäp mail:                           result[1] == 'O' &&
         void CPOP3Dlg::OnOK()                                                                                result[2] == 'K' );               // +OK : Thaønh coâng
         {                                                                                      }
            char           s[1025];                                                           - Haønh vi OnReadMail (nuùt choïn IDC_READ_MAIL) taûi mail veà:
            UINT           port;                                                                void CPOP3Dlg::OnReadMail()
            CSocket m_sock;                                                                     { char          s[10241];
            GetDlgItemText (IDC_SERVER_IP, s, 1024);                                                UINT        port;
            port = GetDlgItemInt(IDC_SERVER_PORT);                                                  CSocket m_sock;
            m_sock.Create();                                                                        GetDlgItemText(IDC_SERVER_IP, s, 1024);
            if (!m_sock.Connect(s, port)) return;                                                   port = GetDlgItemInt(IDC_SERVER_PORT);
            if ( !m_sock.Receive(s, 1024) || !isOK(s) ) return;                                     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);                                    strcpy(s, "USER ");                  // Ñaêng nhaäp
               strcat(s, "rn");                                                                     GetDlgItemText(IDC_USER_NAME, s + strlen(s), 1024);
               m_sock.Send(&s, strlen(s));                                                            strcat(s, "rn");
               if ( !m_sock.Receive(s, 1024) || !isOK(s) ) return;                                    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);                                  strcpy(s, "PASS ");                  // Hôïp leä ?
               strcat(s, "rn");                                                                     GetDlgItemText(IDC_USER_PASSWORD, s+strlen(s), 1024);
               m_sock.Send(&s, strlen(s));                                                            strcat(s, "rn");
               if ( !m_sock.Receive(s, 1024) || !isOK(s) ) return;                                    m_sock.Send(&s, strlen(s));
                                                                                                      if ( !m_sock.Receive(s, 1024) || !isOK(s) ) return;
               strcpy(s, "LISTrn");             // Laáy thoâng tin hoäp mail
               m_sock.Send(&s, strlen(s));                                                            strcpy(s, "RETR ");                // Taûi mail veà
               if ( (port = m_sock.Receive(s, 1024)) < 1 || !isOK(s) )                                GetDlgItemText (IDC_MAIL_NO, s + strlen(s), 1024);
                    return;                                                                           strcat(s, "rn");
                                                                                                      m_sock.Send(&s, strlen(s));
               s[port] = '0';
                                                                                                      if ( (port = m_sock.Receive(s, 10240)) == 0 || !isOK(s) )
               SetDlgItemText(IDC_MAIL, s+4); // Boû qua +OK<SP>                                           return;
               // Keát thuùc...                                                                       s[port] = '0'; SetDlgItemText(IDC_MAIL, strstr(s, "From"));
               strcpy(s, "QUITrn");
               m_sock.Send(&s, strlen(s));                                                            strcpy(s, "QUITrn");           // Keát thuùc
                                                                                                      m_sock.Send(&s, strlen(s)); m_sock.Close();
               m_sock.Close();                                                                    }
           }
MFC vôùi Internet                                                                221   222 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
13.8 TCP VÔÙI HTTP & FTP:                                                                            pstrProxyName :            Proxy. Söû duïng cho truy xuaát thoâng qua proxy.
    HTTP vaø FTP laø caùc giao thöùc taàng öùng duïng ñöôïc xaây döïng döïa treân giao               pstrProxyBypass :          Danh saùch ñòa chæ caùc server ñöôïc truy xuaát tröïc
thöùc TCP ôû taàng truyeàn taûi (moâ hình DARPA).                                                                               tieáp (duøng cho aán ñònh truy xuaát qua proxy).
       HTTP: Giao thöùc phuïc vuï moâ hình öùng duïng Client/Server, duøng phoå                      dwFlags :                  Thoâng soá veà cheá ñoä toái öu trong truy xuaát server.
                 bieán trong vieäc truyeàn taûi caùc noäi dung HTML (www) giöõa                                                 INTERNET_FLAG_DONT_CACHE :
                 client vaø server. Trong ñoù öùng duïng client keát noái vôùi öùng duïng                                               Khoâng söû duïng cache ôû taát caû caùc host lieân
                 server thoâng qua coång TCP xaùc ñònh, thoâng thöôøng laø 80.                                                          quan ñeán caùc taùc vuï taäp tin cuûa giao taùc.
       FTP: Giao thöùc truyeàn taûi taäp tin. ÖÙng duïng client keát noái vôùi öùng                                             INTERNET_FLAG_OFFLINE :
                 duïng server thoâng qua hai coång TCP; moät duøng ñieàu khieån                                                         Söû duïng cache cho caùc taùc vuï taäp tin.
                 truyeàn, moät duøng truyeàn döõ lieäu; thoâng thöôøng laø 20 vaø 21.                CFtpConnection* GetFtpConnection (
       MFC hoã trôï raát maïnh cho vieäc khai thaùc caùc giao thöùc noùi treân thoâng                    LPCTSTR pstrServer,                               // Ñòa chæ FTP server
       qua caùc lôùp ñoái töôïng trong thö vieän AfxInet.h.                                              LPCTSTR pstrUserName = NULL,                      // Teân ñaêng nhaäp
13.8.1 CInternetSession:                                                                                 LPCTSTR pstrPassword = NULL,                      // password hôïp leä
    CInternetSession laø lôùp ñoái töôïng quaûn lyù moät giao taùc xaùc ñònh vôùi maïng                  INTERNET_PORT nPort =                             /* soá hieäu port keát noái */
internet, keå caû vieäc thöïc hieän keát noái vôùi proxy server.                                                           INTERNET_INVALID_PORT_NUMBER,
    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                 BOOL bPassive = FALSE                             // Cô cheá keát noái
treân caùc internet server thoâng qua caùc dòch vuï ñaëc bieät nhö FTP, HTTP.                        ); Traû veà con troû ñoái töôïng quaûn lyù lieân keát vôùi FTP server.
       CInternetSession (                                                                            bPassive : Qui ñònh cô cheá choïn port cho keát noái.
            LPCTSTR pstrAgent = NULL,                                                                        - TRUE : Do ngöôøi duøng choïn.
            DWORD dwContext = 1,                                                                             - FALSE: Do FTP Server choïn (laø cô cheá maëc nhieân).
            DWORD dwAccessType =                                                                     CHttpConnection* GetHttpConnection (
                                      INTERNET_OPEN_TYPE_PRECONFIG,                                      LPCTSTR pstrServer,                               // Ñòa chæ HTTP server
            LPCTSTR pstrProxyName = NULL,                                                                INTERNET_PORT nPort =                             /* soá hieäu port */
            LPCTSTR pstrProxyBypass = NULL,                                                                                INTERNET_INVALID_PORT_NUMBER,
            DWORD dwFlags = 0                                                                            LPCTSTR pstrUserName = NULL,                      // Teân ñaêng nhaäp
       ); Haønh vi taïo laäp vaø khôûi taïo thoâng soá cho ñoái töôïng giao taùc internet.               LPCTSTR pstrPassword = NULL                       // password hôïp leä
       pstrAgent :                Teân öùng duïng. Moät soá öùng duïng duøng teân laøm giaù          ); Traû veà con troû ñoái töôïng quaûn lyù lieân keát vôùi HTTP server.
                                  trò nhaän dieän ñoái vôùi server.                           13.8.2 CInternetFile:
       dwContext :                Soá hieäu nhaän dieän dieãn tieán cuûa taùc vuï.               CInternetFile laø lôùp ñoái töôïng quaûn lyù moät taäp tin treân maïng internet.
       dwAccessType :             Kieåu truy xuaát.                                                 CInternetFile( ); Taïo laäp ñoái töôïng quaûn lyù taäp tin.
                                  INTERNET_OPEN_TYPE_PRECONFIG :                                    virtual LONG Seek (
                                          Theo aán ñònh maëc nhieân cuûa heä thoáng.                    LONG lOffset,             // Cöï ly dôøi töông ñoái
                                  INTERNET_OPEN_TYPE_DIRECT :                                           UINT nFrom                // Vò trí laøm moác.
                                          Tröïc tieáp khoâng thoâng qua proxy.                      ); AÁn ñònh vò trí con troû (ñaàu ñoïc/ghi döõ lieäu) trong taäp tin.
                                  INTERNET_OPEN_TYPE_PROXY :                                        Caùc giaù trò duøng cho nFrom coù theå laø:
                                          Thoâng qua proxy.                                         - CFile::current          : Tính töø vò trí hieän haønh cuûa con troû taäp tin.

MFC vôùi Internet                                                                      223    224 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
- CFile::begin              : Tính töø ñaàu taäp tin.                                           LPCTSTR pstrNew                    // Teân môùi cuûa thö muïc
       - CFile::end                : Tính töø cuoái taäp tin.                                      ); Ñoåi teân thö muïc treân FTP server.
       virtual UINT Read (                                                                         BOOL Remove (
           void* lpBuf,                // Ñòa chæ vuøng ñeäm chöùa döõ lieäu ñoïc                      LPCTSTR pstrFileName // Ñöôøng daãn vaø teân taäp tin
           UINT nCount                 // Kích thöôùc döõ lieäu ñoïc vaøo                          ); Xoùa taäp tin treân FTP server.
       ); Ñoïc döõ lieäu töø taäp tin.                                                             CInternetFile* OpenFile (
       virtual void Write (                                                                            LPCTSTR pstrFileName, // Ñöôøng daãn vaø teân taäp tin ñöôïc môû
           const void* lpBuf,          // Ñòa chæ vuøng ñeäm chöùa döõ lieäu ghi ra                    DWORD dwAccess = GENERIC_READ,
           UINT nCount                 // Kích thöôùc döõ lieäu ñöôïc ghi                              DWORD dwFlags = FTP_TRANSFER_TYPE_BINARY,
       ); Ghi döõ lieäu ra taäp tin.                                                                   DWORD dwContext = 1
       virtual BOOL ReadString (                                                                   ); Môû taäp tin treân FTP server. Traû veà con troû ñoái töôïng CInternetFile
           CString& rString            // Bieán chöùa chuoãi ñoïc vaøo                             quaûn lyù taäp tin ñöôïc môû.
       ); Ñoïc moät chuoãi töø taäp tin.                                                           dwAccess : Cheá ñoä môû taäp tin, choïn moät trong caùc cheá ñoä môû sau:
       virtual void WriteString (                                                                                  GENERIC_WRITE : Môû ñeå ghi.
           LPCTSTR pstr                // Bieán chöùa chuoãi ñöôïc ghi ra                                          GENERIC_READ : Môû ñeå ñoïc.
       ); Ghi moät chuoãi ra taäp tin.                                                             dwFlags : Kieåu noäi dung taäp tin.
       virtual void Close( ); Ñoùng taäp tin, chaám döùt moïi taùc vuï lieân quan.                                 FTP_TRANSFER_TYPE_ASCII                        : Maõ ASCII
13.8.3 CFtpConnection:                                                                                             FTP_TRANSFER_TYPE_BINARY : Maõ nhò phaân
    CFtpConnection laø lôùp ñoái töôïng quaûn lyù moät lieân keát vôùi FTP server. Ñoái            BOOL PutFile (
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               LPCTSTR pstrLocalFile,               // Ñöôøng daãn vaø teân taäp tin ôû client
thoâng qua haønh vi GetFtpConnection vôùi thoâng soá thích hôïp (13.8.1). Caùc                         LPCTSTR pstrRemoteFile, // Ñöôøng daãn vaø teân taäp tin ôû server
haønh vi ñaëc tröng cuûa lôùp ñoái töôïng CFtpConnection nhö sau:                                      DWORD dwFlags =                      /* Kieåu noäi dung taäp tin */
       BOOL SetCurrentDirectory (                                                                                         FTP_TRANSFER_TYPE_BINARY,
           LPCTSTR pstrDirName             // Ñöôøng daãn cuûa thö muïc.                               DWORD dwContext = 1                  // Soá hieäu nhaän dieän taùc vuï
       ); AÁn ñònh thö muïc laøm vieäc maëc nhieân treân FTP server.                               ); Taûi moät taäp tin töø host laøm vieäc leân FTP server (upload).
       BOOL GetCurrentDirectory (                                                                  BOOL GetFile (
           CString& strDirName             // Bieán chöùa keát quaû                                    LPCTSTR pstrRemoteFile,                // Ñöôøng daãn teân taäp tin treân server
       ); Laáy ñöôøng daãn cuûa thö muïc laøm vieäc treân FTP server.                                  LPCTSTR pstrLocalFile,                 // Ñöôøng daãn teân taäp tin treân client
       BOOL RemoveDirectory (                                                                          BOOL bFailIfExists = TRUE, // Cheá ñoä xöû lyù truøng teân taäp tin.
           LPCTSTR pstrDirName             // Ñöôøng daãn thö muïc                                     DWORD dwAttributes = FILE_ATTRIBUTE_NORMAL,
       ); Xoùa thö muïc treân FTP server.                                                              DWORD dwFlags =                        /* Kieåu noäi dung taäp tin */
       BOOL CreateDirectory (                                                                                             FTP_TRANSFER_TYPE_BINARY,
           LPCTSTR pstrDirName             // Ñöôøng daãn vaø teân thö muïc                            DWORD dwContext = 1
       ); Taïo môùi thö muïc treân FTP server.                                                     ); Taûi moät taäp tin töø FTP server veà host laøm vieäc.
       BOOL Rename (                                                                               bFailIfExists : Qui ñònh caùch thöïc hieän khi teân duøng cho taäp tin ghi
           LPCTSTR pstrExisting,           // Ñöôøng daãn vaø teân cuõ cuûa thö muïc               truøng vôùi teân moät taäp tin ñaõ coù treân host laøm vieäc.

MFC vôùi Internet                                                                     225   226 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
TRUE        Thoâng baùo loãi.                                                               BOOL TimThay = TimFile.FindFile(_T("*.TXT"));
           FALSE       Töï ñoäng ghi choàng leân noäi dung ñaõ coù.                                    while (TimThay) {
       dwAttributes : Thuoäc tính taäp tin. Coù theå keát hôïp caùc giaù trò sau:                        TimThay = TimFile.FindNextFile();
           FILE_ATTRIBUTE_ARCHIVE                    : Taäp tin ñöôïc caäp nhaät.                        … // Xöû lyù taäp tin tìm thaáy
           FILE_ATTRIBUTE_DIRECTORY : Thö muïc.                                                        }
                                                                                                   }
           FILE_ATTRIBUTE_NORMAL                     : Taäp tin bình thöôøng.
                                                                                                   catch (CInternetException* pEx) {
           FILE_ATTRIBUTE_HIDDEN                     : Taäp tin aån maët.
                                                                                                       … // Coù loãi
           FILE_ATTRIBUTE_READONLY : Taäp tin chæ ñoïc.                                            }
           FILE_ATTRIBUTE_SYSTEM                     : Taäp tin heä thoáng.                        if (pConnect != NULL) pConnect->Close();
           FILE_ATTRIBUTE_TEMPORARY : Taäp tin söû duïng taïm thôøi.                               delete pConnect;
       virtual void Close( ); Keát thuùc lieân keát vôùi FTP server.
                                                                                            13.8.5 CHttpConnection:
13.8.4 CFtpFindFile:                                                                           CHttpConnection laø lôùp ñoái töôïng quaûn lyù moät lieân keát vôùi HTTP server.
   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      Ñ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
FTP server. Caùc haønh vi ñaëc tröng cuûa lôùp nhö sau:                                     internet thoâng qua haønh vi GetHttpConnection vôùi thoâng soá thích hôïp (13.8.1).
      CFtpFileFind( CFtpConnection* pConnection ); Taïo laäp vaø khôûi taïo                 Lôùp CHttpConnection coù haønh vi ñaëc tröng sau:
      thoâng soá cho ñoái töôïng tìm kieám taäp tin.                                               CHttpFile* OpenRequest (
      virtual BOOL FindFile (                                                                          int nVerb,
          LPCTSTR pstrName = NULL,                        // Daïng teân taäp tin caàn tìm              LPCTSTR pstrObjectName,
          DWORD dwFlags = INTERNET_FLAG_RELOAD                                                         LPCTSTR pstrReferer = NULL,
      ); Khôûi ñoäng quaù trình tìm kieám taäp tin. Traû veà giaù trò TRUE neáu khôûi                  DWORD dwContext = 1,
      ñieåm tìm kieám thaønh coâng.                                                                    LPCTSTR* pstrAcceptTypes = NULL,
      Coù theå söû duïng ? , * ñeå aán ñònh daïng teân cuûa taäp tin caàn tìm.                         LPCTSTR pstrVersion = NULL,
      dwFlags = INTERNET_FLAG_DONT_CACHE khoâng söû duïng cache.                                       DWORD dwFlags = INTERNET_FLAG_EXISTING_CONNECT
      virtual BOOL FindNextFile( ); Tìm taäp tin keá tieáp thoûa ñieàu kieän. Traû                 ); Traû veà con troû ñoái töôïng CHttpFile quaûn lyù taäp tin döõ lieäu caàn truy
      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             xuaát treân HTTP server.
      nhö ñaõ tìm heát caùc taäp tin thoûa ñieàu kieän tìm kieám.                                  nVerb: AÁn ñònh loaïi taùc vuï truy xuaát ñoái vôùi taäp tin döõ lieäu.
      CString GetFileURL( ); Traû veà chuoãi ñöôøng daãn cuûa taäp tin vöøa tìm                        CHttpConnection::HTTP_VERB_POST                      : Ghi döõ lieäu
      ñöôïc theo yeâu caàu.                                                                            CHttpConnection::HTTP_VERB_GET                       : Ñoïc döõ lieä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                   CHttpConnection::HTTP_VERB_DELETE : Xoùa taäp tin döõ lieäu.
      môû roäng laø ‘txt’ treân FTP server:                                                        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.
       CInternetSession sess(_T("FTP - Example")); // Quaûn lyù giao taùc                          dwContext :           Soá hieäu nhaän dieän taùc vuï truy xuaát.
       CFtpConnection* pConnect = NULL;            // Lieân keát vôùi server                       pstrAcceptTypes : Chöùa caùc kieåu döõ lieäu maø client mong muoán khai
       try {                                                                                                             thaùc trong noäi dung cuûa taäp tin döõ lieäu ñöôïc truy
           pConnect = sess.GetFtpConnection(“ftp.hcmueco.edu.vn”);                                                       xuaát. Ví duï: "text/*" = Chæ laáy noäi dung text, khoâng
           CFtpFileFind TimFile ( pConnect );      // Ñoái töôïng tìm kieám                                              nhaän döõ lieäu laø hình aûnh, maõ,…
MFC vôùi Internet                                                                    227    228 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
pstrVersion:   Giao thöùc söû duïng, maëc nhieân laø "HTTP/1.0"                                  HTTP_ADDREQ_FLAG_REPLACE :                            Thay theá noäi dung tröôùc
       dwFlags :      Toái öu trong truy xuaát                                                                                                                bôûi noäi dugn sau coù cuøng
           INTERNET_FLAG_RELOAD                   : Khoâng ñoïc töø cache.                                                                                    loaïi yeâu caàu.
           INTERNET_FLAG_DONT_CACHE               : Khoâng ñeå laïi cache.                                "Accept: text/*" vaø "Accept: audio/*"              "Accept: audio/*"
13.8.6 CHttpFile:                                                                                       HTTP_ADDREQ_FLAG_ADD :                                Nhö _REPLACE vaø töï
   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                                                                      ñoäng boå sung neáu loaïi
truy xuaát treân HTTP server.                                                                                                                                 yeâu caàu môùi laø chöa coù.
      BOOL QueryInfo (                                                                              BOOL SendRequest (
           DWORD dwInfoLevel,                           // Thoâng soá truy vaán                         CString& strHeaders,                      // Noäi dung yeâu caàu.
           LPVOID lpvBuffer,                            // Vuøng ñeäm nhaän keát quaû                   LPVOID lpOptional = NULL,                 // Caùc dieãn giaûi cuûa client (khoâng
           LPDWORD lpdwBufferLength,                    // Chieàu daøi vuøng ñeäm                       DWORD dwOptionalLen = 0                   // baét buoäc )
           LPDWORD lpdwIndex = NULL                                                                 ); Göûi yeâu caàu lieân quan taäp tin döõ lieäu leân HTTP server. Neáu khoâng
      ); Truy vaán thoâng tin lieân quan ñeán taäp tin döõ lieäu. Traû veà giaù trò TRUE            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
      neáu taùc vuï truy vaán thaønh coâng. Thoâng soá truy vaán coù theå laø:                      vi AddRequestHeaders.
           HTTP_QUERY_FLAG_REQUEST_HEADERS : Thoâng tin header.                                     BOOL SendRequestEx (
           HTTP_QUERY_LAST_MODIFIED : Ngaøy caäp nhaät cuoái cuøng.                                     LPINTERNET_BUFFERS lpBuffIn,                      // Kích thöôùc döõ lieäu
      BOOL AddRequestHeaders (                                                                          LPINTERNET_BUFFERS lpBuffOut, // Vuøng ñeäm chöùa döõ lieäu
           CString& str,            // Noäi dung thoâng soá yeâu caàu                                   DWORD dwFlags = HSR_INITIATE,
           DWORD dwFlags = HTTP_ADDREQ_FLAG_ADD_IF_NEW                                                  DWORD dwContext = 1
      ); 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           ); Ghi thoâng tin leân taäp tin döõ lieäu treân HTTP server.
      döõ lieäu. Caùc yeâu caàu naøy seõ ñöôïc göûi leân HTTP server thöïc hieän.                   BOOL EndRequest (
      Noäi dung moãi yeâu caàu phaûi keát thuùc baèng <CRLF>. Xem (RFC2616):                            DWORD dwFlags = 0,
      - Accept              : Ñeà nghò kieåu döõ lieäu truy xuaát trong taäp tin.                       LPINTERNET_BUFFERS lpBuffIn = NULL,
           Cuù phaùp: "Accept: (media-range [ accept-params ][,])* "                                    DWORD dwContext = 1
           Ví duï:       "Accept: audio/*" , "Accept: text/plain"                                   ); Ngöøng taùc vuï ghi treân taäp tin döõ lieäu cuûa HTTP server.
      - User-Agent          : Teân, duøng nhaän dieän öùng duïng yeâu caàu.                         virtual CString GetFileURL( ); Traû veà ñöôøng daãn vaø teân cuûa taäp tin döõ
           Cuù phaùp : "User-Agent" ":" Name( product | comment )*"                                 lieäu treân HTTP server.
           Ví duï :      "User-Agent: Mr.EMP"                                                       virtual void Close( ); Keát thuùc truy xuaát taäp tin döõ lieäu.
      - Content-Type : Kieåu noäi dung 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ø
           Cuù phaùp : "Content-Type: media-type*"                                              hieån thò noäi dung cuûa taäp tin /index.html treân server naøy.
           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/*"


MFC vôùi Internet                                                                     229    230 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
CInternetSession session("HTTP - Example");                                         Sau ñaây laø caùc böôùc thöïc hieän döï aùn cuûa öùng duïng noùi treân:
       CHttpFile* file=NULL;                                                                 Duøng MFC Wizard, taïo döï aùn Ftp vôùi giao dieän chính laø dialog.
       CString strServer = "www.hcmueco.edu.vn";                                             Boå sung chæ thò: #include <afxinet.h> cho taäp tin stdafx.h cuûa döï aùn.
       CString strObject("/index.html");                                                     Thöïc hieän caùc caøi ñaët sau cho lôùp dialog CFtpDlg cuûa döï aùn:
       INTERNET_PORT port = INTERNET_DEFAULT_HTTP_PORT;
                                                                                             - Môû dialog resource, caøi ñaët caùc control sau:
       CString strHeaders (
                "Accept: text/*rn”                                                             - Hoäp nhaäp ñòa chæ FTP server                 : Edit       IDC_URL
                “User-Agent: Mr.Emprn"                                                         - Hoäp hieån thò danh saùch caùc taäp tin       : ListBox IDC_FILE_LIST
                "Content-Type: application/x-www-form-urlencodedrn");                          - Nuùt leänh thöïc hieän tìm kieám taäp tin : Button IDOK
       CHttpConnection* server = NULL;                                                       - Taïo bieán m_fileList cho control IDC_FILE_LIST.
       try {                                                                                 - 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
            server=session.GetHttpConnection(strServer, port);                                   tin trong thö muïc goác cuûa FTP server vaø ñöa vaøo danh saùch:
            file=server->OpenRequest (
                                                                                                 Caøi ñaët töông töï ví duï muïc (13.8.4)
                   CHttpConnection::HTTP_VERB_POST,strObject );
       }                                                                                         Phaàn caøi ñaët cuûa Xöû lyù taäp tin tìm thaáy nhö sau:
       catch (CInternetException* pEx) {                                                         m_fileList.ResetContent();
                                                                                                 while (TimThay) {
            … // Coù loãi
                                                                                                     bWorking = TimFile.FindNextFile();
       }
                                                                                                     m_fileList.AddString(TimFile.GetFileURL());
       if (server==NULL) return;
                                                                                                 }
       if (file!=NULL) {
            file->AddRequestHeaders(strHeaders);                                             Bieân dòch vaø chaïy öùng duïng.
            file->SendRequest();                  // Xaùc laäp yeâu caàu truy xuaát     13.8.8 Thöïc hieän öùng duïng HTTP client ñôn giaûn:
            CString line;                         // Söû duïng cho ñoïc chuoãi             Trình töï tieán haønh caùc xöû lyù cuûa öùng duïng nhö sau:
            while (file->ReadString(line)) {                                               - Thieát laäp giao taùc internet, taïo lieân keát HTTP töø giao taùc naøy.
                … // Xöû lyù noäi dung ñoïc ñöôïc                                          - 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
            file->Close();                                                                    AddRequestHeaders vaø SendRequest treân noäi dung taäp tin.
            delete file;
                                                                                           - Truy xuaát döõ lieäu: Read, ReadString hoaëc Write, WriteString.
       }
       server->Close();                                                                    Sau ñaây laø caùc böôùc thöïc hieän döï aùn cuûa öùng duïng noùi treân:
       delete server;                                                                        Duøng MFC Wizard, taïo döï aùn Http vôùi giao dieän chính laø dialog.
13.8.7 Thöïc hieän öùng duïng FTP client ñôn giaûn:                                          Boå sung chæ thò: #include <afxinet.h> cho taäp tin stdafx.h cuûa döï aùn.
   Trình töï tieán haønh caùc xöû lyù cuûa öùng duïng nhö sau:                               Thöïc hieän caùc caøi ñaët sau cho lôùp dialog CHttpDlg cuûa döï aùn:
   - Thieát laäp giao taùc internet, taïo lieân keát FTP töø giao taùc naøy.                 - Môû dialog resource, caøi ñaët caùc control sau:
   - Taïo ñoái töôïng CFtpFileFind töø lieân keát FTP, tìm taäp tin treân ftp server.            - Hoäp nhaäp ñòa chæ HTTP server                : Edit       IDC_URL
   - Taïo ñoái töôïng CInternetFile töø taäp tin tìm ñöôïc. Thöïc hieän caùc taùc vuï            - Hoäp hieån thò noäi dung taäp tin             : Edit       IDC_SOURCE
      ñoïc ghi moät caùch thích hôïp.                                                            - Nuùt leänh thöïc hieän taûi taäp tin veà      : Button IDOK
   - Ñoùng caùc ñoái töôïng.


MFC vôùi Internet                                                                 231   232 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
- 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 + "rn";
          }
          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.




MFC vôùi Internet                                                                      233
PHUÏ LUÏC A:                                                                                            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
                                Moät soá vaán ñeà                                                   quan. Haønh vi theå hieän maët hoaït ñoäng cuûa ñoái töôïng.
                                                                                                    Ví duï:
                         laäp trình höôùng ñoái töôïng                                                  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.
A.1 LAÄP TRÌNH HÖÔÙNG ÑOÁI TÖÔÏNG (OOP):                                                                Ta coù moâ hình cuûa ñoái töôïng nhö sau:
    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                                        Ñoái töôïng = Thuoäc tính + Haønh vi
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.
                                                                                                    A.2.5 Chöông trình (Program):
    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
                                                                                                        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
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
                                                                                                    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
ñ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
                                                                                                    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.
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                                   Chöông trình = Taäp hôïp caùc ñoái töôïng + Kòch baûn
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.3 ÑAËC ÑIEÅM LAÄP TRÌNH HÖÔÙNG ÑOÁI TÖÔÏNG:
A.2 CAÙC KHAÙI NIEÄM:                                                                                  - Tính khaùch quan (Objective):
A.2.1 Lôùp (Class):                                                                                      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
   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               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ù.
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.                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
   Ví duï:                                                                                               caùch hôïp lyù ñeå ñaït ñöôïc muïc ñích cuûa chöông trình.
   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,                 - Tính ñoùng goùi (Encapsulation):
   maùu laïnh vaø coù caùc haønh vi: soáng döôùi nöôùc, thôû baèng mang, ñeû tröùng.                     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.
A.2.2 Ñoái töôïng (Object):                                                                            - Tính keá thöøa (Inheritance):
    Ñ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õ            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
coù nhöõng thuoäc tính, haønh vi cuûa lôùp ñoù.                                                          laø söï keá thöøa. Caùc lôùp ñaõ coù goïi laø lôùp cô sôû (based class), lôùp ñöôïc
    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ôû                ñònh nghóa goïi laø lôùp keá thöøa (derived class). Beân caïnh vieäc keá thöøa,
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.                               lôùp keá thöøa coù theå ñöôïc boå sung nhöõng haønh vi vaø thuoäc tính caàn thieát
A.2.3 Thuoäc tính (Attribute):                                                                           ñeå phuïc vuï cho nhu caàu môùi phaùt sinh. Cô cheá ñoù ñaõ taïo söï phaùt trieån
    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              cho öùng duïng maø ñoái töôïng tham gia.
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.                - Tính ña hình (Polymorphism):
A.2.4 Haønh vi (Method):
234 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Phuï luïc A: Moät soá vaán ñeà laäp trình höôùng ñoái töôïng                          235
Cô cheá trieån khai nhieàu caùch theå hieän khaùc nhau cho moät haønh vi theo                            class Teân_lôùp {
       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                        public:
       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                          [ Khai baùo caùc thuoäc tính, haønh vi kieåu public ]
       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                    protected:
       phuø hôïp ñeå coù caùch theå hieän haønh vi caàn trieån khai theo yù muoán. Cô                              [ Khai baùo caùc thuoäc tính, haønh vi kieåu private ]
       cheá naøy taïo khaû naêng öùng xöû phong phuù cuûa ñoái töôïng.                                          privated:
A.4 PHAÂN LOAÏI THUOÄC TÍNH VAØ HAØNH VI:                                                                          [ Khai baùo caùc thuoäc tính, haønh vi kieåu private ]
   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.                    // Phaàn caøi ñaët cuûa lôùp:
   - Protected: Caùc thuoäc tính, haønh vi aån chöùa beân trong ñoái töôïng, hoã trôï                           kieåu Teân_lôùp::Teân_haønh_vi_1( [ Danh_saùch_tham_soá ] ) {
                    caùc hoaït ñoäng cuûa ñoái töôïng vaø coù theå truyeàn laïi cho caùc                           … // Caùc xöû lyù trong haønh vi
                    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                          kieåu Teân_lôùp::Teân_haønh_vi_n( [ Danh_saùch_tham_soá ] ) {
                    caùc lôùp ñoái töôïng keá thöøa.                                                               … // Caùc xöû lyù trong haønh vi
                                                                                                                }
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                          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
                             thaønh. Haønh vi naøy duøng ñeå caøi ñaët caùc xöû lyù khôûi                   khai baùo (.h) vaø caøi ñaët (.cpp). Trong ñoù:
                             taïo caùc giaù trò thuoäc tính cuûa ñoái töôïng.                                  - Taäp tin .H :      Chöùa toaøn boä phaàn khai baùo cuûa lôùp vaø caùc chæ thò
                                 Moät lôùp ñoái töôïng coù theå coù moät hoaëc nhieàu haønh                                         ñònh höôùng bieân dòch (neáu caàn).
                             vi taïo laäp. Teân haønh vi taïo laäp truøng vôùi teân lôùp. Caùc                 - Taäp tin .CPP : Chöùa toaøn boä phaàn caøi ñaët cuûa lôùp. ÔÛ ñaàu taäp tin
                             haønh vi taïo laäp ñöôïc phaân bieät laãn nhau bôûi caáu truùc                                         naøy khai baùo chæ thò söû duïng taäp tin .H:
                             caùc tham soá cuûa chuùng.                                                                             #include "Teân_taäp_tin_h_lieân_quan"
   - 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
                                                                                                            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
                             söï toàn taïi cuûa noù.
                                                                                                            giaù trò kieåu chuoãi cuûa C caàn quaûn lyù vaø truy xuaát.
                                 Moät lôùp ñoái töôïng coù moät haønh vi huûy boû duy
                                                                                                                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
                             nhaát. Teân haønh vi huûy boû truøng vôùi teân cuûa lôùp
                                                                                                                thuoäc tính vaø haønh vi nhö sau:
                             nhöng ñöôïc baét ñaàu baèng daáu ‘~’. Haønh vi huûy boû
                                                                                                                - Thuoäc tính: char* info ñöôïc söû duïng ñeå xin caáp phaùt vuøng nhôù
                             khoâng coù tham soá.
                                                                                                                                   chöùa noäi dung chuoãi.
   Caû haønh vi taïo laäp vaø huûy boû ñeàu khoâng coù kieåu traû veà.
                                                                                                                - Haønh vi:        - Haønh vi taïo laäp vôùi moät tham soá laø giaù trò chuoãi
A.6 KHAI BAÙO LÔÙP, ÑOÁI TÖÔÏNG TRONG C++:                                                                                           laøm noäi dung khôûi ñaàu cho ñoái töôïng chuoãi.
A.6.1 Khai baùo lôùp:                                                                                                              - Haønh vi huûy boû giaûi phoùng vuøng nhôù info.
   Lôùp ñoái töôïng ñöôïc khai baùo trong C++ nhö sau:                                                                             - Haønh vi laáy ñòa chæ vuøng chöùa noäi dung chuoãi.
      // Phaàn khai baùo cuûa lôùp:                                                                         Lôùp chuoãi ñöôïc khai baùo trong C++ nhö sau:

236 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Phuï luïc A: Moät soá vaán ñeà laäp trình höôùng ñoái töôïng                         237
// Taäp tin String1.h                                                                       C++ cho pheùp ñònh nghóa lôùp keá thöøa töø moät hoaëc nhieàu lôùp cô sôû. Cuù
           class CString1 {                                                                         phaùp thöïc hieän khai baùo naøy nhö sau:
           public:
                                                                                                        class Teân_lôùp_keá_thöøa: [ public | private ] Teân_lôùp_cô_sôû1
               CString1 ( char* s );  // Haønh vi taïo laäp
                                                                                                                                   [, [public | private ] Teân_lôùp_cô_sôû2 [ , … ]
               ~CString1 ( void );    // Haønh vi huûy boû                                              {
               char* GetInfo( void );
                                                                                                             …       // Caùc khai baùo boå sung cuûa lôùp keá thöøa
           protected:
                                                                                                        };
               char* info;
           };                                                                                           Ñ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:
           // Taäp tin String1.cpp
           CString1::CString1( char* s ) {
                                                                                                             Thuoäc tính lôùp cô sôû             Thuoäc tính nhaän ñöôïc cho lôùp keá thöøa
               info = new char[ strlen( s ) + 1 ];
               strcpy( info, s );                                                                                    public                          public                     private
           }
           CString1::~CString1( ) {                                                                                protected                       protected                    private
               delete info;
           }                                                                                                        private                Khoâng truy xuaát ñöôïc      Khoâng truy xuaát ñöôïc
           char* CString1::GetInfo( void ) {
                                                                                                              Ñaëc ñieåm keá thöøa                   public                     Private
               return info;
           }                                                                                            Ví duï: Khai baùo lôùp CString1B keá thöøa hoaøn toaøn töø lôùp CString1.
A.6.2 Khai baùo ñoái töôïng:
                                                                                                              class CString1B : public CString1 { };
   Ñ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ù.                                A.7.1 Keá thöøa haønh vi taïo laäp:
   Cuù phaùp khai baùo bieán ñoái töôïng trong C++ nhö sau:                                             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
   Teân_lôùp Teân_bieán_ñoái_töôïng( [Danh saùch giaù trò laøm tham soá ] );                        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:

A.6.3 Söû duïng ñoái töôïng trong chöông trình:                                                         Haønh_vi_taïo_laäp_cuûa_lôùp_keá_thöøa( [ Danh saùch thamm soá ] ) :
   Thöïc hieän haønh vi cuûa bieán ñoái töôïng (caùc haønh vi public) nhö sau:                                    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á ] )
   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” );                                                                      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
         printf( "Gia tri chuoi luu la: %s ", a.GetInfo() );                                        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:
A.7 KEÁ THÖØA TRONG C++:                                                                                                        Haønh_vi_taïo_laäp_cuûa_lôùp_sô_sôû_1

238 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Phuï luïc A: Moät soá vaán ñeà laäp trình höôùng ñoái töôïng                              239
class CString2 : public CString1 {
                          Haønh_vi_taïo_laäp_cuûa_lôùp_sô_sôû_2                                             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() ) { }
                                                                                                            };
                          Haønh_vi_taïo_laäp_cuûa_lôùp_sô_sôû_n                                             // Chöông trình Main2.cpp söû duïng lôùp CString2 khai baùo ôû treân.
                                                                                                            #include "String2.h"
                          Haønh_vi_taïo_laäp_cuûa_lôùp_keá_thöøa                                            void main( void ) {
                                                                                                                CString2 a( “Vo Van B” );
A.7.2 Keá thöøa haønh vi huûy boû:                                                                              CString2 b( &a );
   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á                        printf( "Gia tri chuoi luu la: %s ", b.GetInfo() );
thöøa haønh vi huûy boû cuûa lôùp cô sôû maø khoâng caàn phaûi khai baùo.                                       // Keát quaû nhaän ñöôïc: Gia tri chuoi luu la: Vo Van B
                                                                                                            }
   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        A.8 KHAI BAÙO HAØNH VI TOAÙN TÖÛ SOÁ HOÏC:
cô sôû seõ ñöôïc thöïc hieän theo thöù töï nhö sau:                                                     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).
                          Haønh_vi_huûy_boû_cuûa_lôùp_keá_thöøa
                                                                                                        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.
                         Haønh_vi_huûy_boû_cuûa_lôùp_sô_sôû_(n)
                                                                                                           Khai baùo:
                       Haønh_vi_huûy_boû_cuûa_lôùp_sô_sôû_(n-1)                                             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:
                          Haønh_vi_taïo_laäp_cuûa_lôùp_sô_sôû_1                                             Teân lôùp::operator Kyù_hieäu_haønh_vi ( void );
A.7.3 Thöïc hieän haønh vi lôùp cô sôû:                                                                     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öû
    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ô                     gaùn ( = ), coäng ( + ), vaø chuyeån kieåu lôùp ñoái töôïng chuoãi veà kieåu chuoãi
sôû cuûa noù. Caùch thöïc hieän haønh vi cuûa lôùp cô sôû nhö sau:                                          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
       Teân_lôùp_cô_sôû::Teân_haønh_vi( [ Danh_saùch_giaù_trò_tham_soá ] );
                                                                                                                caùc haønh vi toaùn töû sau ñaây:
                                                                                                                - Toaùn töû chuyeån kieåu: char *
       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
                                                                                                                - Toaùn töû gaùn ( = ) vôùi tham soá laø moät giaù trò kieåu chuoãi cuûa C.
       töôïng CString2 keá thöøa töø CString1 vaø boå sung haønh vi taïo laäp nhaän
                                                                                                                - Toaùn töû coäng ( + ) vôùi tham soá laø moät giaù trò kieåu chuoãi cuûa C vaø
       tham soá laø moät ñoái töôïng CString1.
                                                                                                                    traû veà con troû ñeán ñoái töôïng chuoãi môùi.
       Lôùp CString2 ñöôïc khai baùo trong C++ nhö sau:
                                                                                                            Lôùp CString3 ñöôïc khai baùo trong C++ nhö sau:
       // Taäp tin String2.h
       #include “String1.h”                                                                                 // Taäp tin String3.h
240 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Phuï luïc A: Moät soá vaán ñeà laäp trình höôùng ñoái töôïng                          241
#include “String1.h”                                                                             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
       class CString3 : public CString1 {                                                           ñaët cuûa noù. Haønh vi toaùn töû = cuûa lôùp CString3 coù theå vieát nhö sau:
       public:
                                                                                                            void CString3::operator = ( char* s ) {
          CString3( char* s ) : CString1( s ) { }
                                                                                                               delete this->info;
          // Toaùn töû chuyeån kieåu                                                                           this->info = new char[ strlen( s ) + 1 ];
          operator char* ( void ) {                                                                            strcpy( this->info, s );
              return info;                                                                                  }
          }
          void operator = ( char* s );                                                              A.10 HAØNH VI virtual:
          CString3* operator + ( char* s );                                                             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.
       // Taäp tin String3.cpp                                                                          Trong ví duï sau, lôùp A ñöôïc caøi ñaët vôùi haønh vi khung Action. Trong caùc
       #include "String3.h"                                                                         lôùp B vaø C keá thöøa töø A, haønh vi naøy ñöôïc theå hieän khaùc nhau nhö sau:
       void CString3::operator = ( char* s ) {                                                          - Lôùp B : Baät tieáng beep cuûa PC speaker.
           delete info;                                                                                 - Lôùp C : Baät hoaëc taét kyù töï x.
           info = new char[ strlen( s ) + 1 ];
           strcpy( info, s );                                                                           class A {
       }                                                                                                public:
       CString3* CString3::operator + ( char* s ) {                                                        void Action( void ) { } // Haønh vi khung cô sôû
           char* ketqua;                                                                                }
           ketqua = new char[ strlen(info) + strlen( s ) + 1 ];                                         class B : public A {
           sprintf( ketqua, "%s%s", info, s );                                                          public:
           CString3* kq = new CString3( ketqua );                                                          void Action( void ) {
           delete ketqua;                                                                                     // Caùch theå hieän Action cuûa lôùp B
           return kq;                                                                                         putch( 7 );
       }                                                                                                   }
                                                                                                        }
      // Chöông trình Main3.cpp söû duïng lôùp CString3 khai baùo ôû treân.
      #include "String3.h"                                                                              class C : public A {
      void main( void ) {                                                                               public:
          CString3 s1( "Chao Cac " );                                                                      void Action( void ) {
          CString3 s2( "Ban" );                                                                               // Caùch theå hieän Action cuûa lôùp C ; baät, taét chöõ x
          CString3 *s = (s1 + s2);                                                                            static char ch = ‘x’;
          printf( "Cong hai chuoi la: %s", *s );                                                              putch(x);
          delete s;                                                                                           ch = ( ch == ‘x’ )? ‘ ‘ : ‘x’ ;
          // Keát quaû nhaän ñöôïc: Cong hai chuoi la: Chao Cac Ban                                        }
      }                                                                                                 }
A.9. CON TROÛ this:                                                                                     void main ( void ) {

242 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Phuï luïc A: Moät soá vaán ñeà laäp trình höôùng ñoái töôïng                       243
A* a[5];                           // 5 phaàn töû kieåu lôùp A                                   class Duongtron {
       for ( int i = 0; i<5; i++ ) {                                                                       protected:
          if ( i % 2 )                                                                                        float R;
               a[ i ] = new B();          // Khôûi taïo ngaãu nhieân theo kieåu lôùp B                        static float pi;
          else                                                                                             public:
               a[ i ] = new C();          // hoaëc lôùp C                                                     Duongtron( float bankinh ) {
       }                                                                                                          R = bankinh;
       while ( !kbhit() ) {                                                                                   }
          for ( i = 0; i < 5 ; i++ )                                                                          float Chuvi( void )
               a[ i ]->Action( );         // Haønh ñoäng theo caùch cuûa lôùp B hoaëc C                       {
          delay( 100 );                   // Taïm döøng                                                           return R * R * pi;
       }                                                                                                      }
       for ( i = 0; i < 5 ; i++ )                                                                             static float Chuvi( float bankinh )
          delete a[ i ];                                                                                      {
   }                                                                                                              return R * R * pi;
                                                                                                              }
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                   float Duongtron::pi =3.14159;
ñöôï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:                                                                     // Chöông trình minh hoïa söû duïng lôùp Duongtron
                                                                                                        void main( void ) {
   static Kieåuthuoäctính Thuoäctính;
                                                                                                            // Duøng haønh vi tónh Chuvi( . ) cuûa Duongtron ñeå tính chu vi
   static Kieåutraûveà    Haønhvi ( [ Danh_saùch_tham_soá ] );
                                                                                                            // cuûa moät ñöôøng troøn baát kyø
   Trong phaàn caøi ñaët cuûa lôùp:                                                                         printf( “Chu vi duong tron ban kinh R = 10 la : %0.2f” ,
                                                                                                                    Duongtron::Chuvi( 10 ) );
   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á ] ) {                                      // Duøng haønh vi Chuvi() ñeå tính chu vi cuûa ñoái töôïng Duongtron
                                                                                                            Duongtron a( 20 );
       …               // Noäi dung caøi ñaët cuûa haønh vi
                                                                                                            printf( “Chu vi duong tron ban kinh R = 20 la : %0.2f”, a.Chuvi() );
   }                                                                                                    }
   Löu yù: Haønh vi static chæ ñöôïc pheùp söû duïng caùc thuoäc tính static vaø haønh
                                                                                                            Neáu thuoäc tính pi cuûa Duongtron khoâng phaûi laø thuoäc tính static thì
   vi static cuûa lôùp.
                                                                                                            haønh vi Chuvi( float Bankinh ) cuûa Duongtron seõ khoâng hôïp leä vì haønh
   Trong ví duï sau, ta caøi ñaët lôùp Duongtron vôùi thuoäc tính baùn kính, thuoäc                         vi naøy ñaõ söû duïng moät thuoäc tính khoâng phaûi static.
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:

244 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com   Phuï luïc A: Moät soá vaán ñeà laäp trình höôùng ñoái töôïng                   245

More Related Content

PDF
11 vidu baitap_c
PDF
12 vidu baitap_c
PDF
[Share] tổng hợp các bài tập c căn bản
PDF
Cognos v10.1
PDF
2024 Trend Updates: What Really Works In SEO & Content Marketing
PDF
Storytelling For The Web: Integrate Storytelling in your Design Process
PDF
Artificial Intelligence, Data and Competition – SCHREPEL – June 2024 OECD dis...
PDF
How to Leverage AI to Boost Employee Wellness - Lydia Di Francesco - SocialHR...
11 vidu baitap_c
12 vidu baitap_c
[Share] tổng hợp các bài tập c căn bản
Cognos v10.1
2024 Trend Updates: What Really Works In SEO & Content Marketing
Storytelling For The Web: Integrate Storytelling in your Design Process
Artificial Intelligence, Data and Competition – SCHREPEL – June 2024 OECD dis...
How to Leverage AI to Boost Employee Wellness - Lydia Di Francesco - SocialHR...

Recently uploaded (20)

DOCX
Chủ nghĩa xã hội khoa học - Đề Cương Cuối Kỳ.docx
DOCX
LUẬN VĂN GROUP ĐỀ BÀI ĐÁNH GIÁ GIAO TIẾP SƯ PHẠM
DOCX
Ôn tập văn học phương đông thi giữa kì ..
PDF
bai giang an toan thong tin ke toan nam 2020
PPTX
Triet hoc con nguoi va triet hoc thac si
PDF
GIẢI PHÁP NÂNG CAO CÔNG TÁC CHỦ NHIỆM QUA CÁC TIẾT SINH HOẠT THEO CHỦ ĐỀ NHẰ...
PPT
Slide Nguyên lý bảo hiểm đại học knh tế quốc dân
PDF
SÁNG KIẾN “NGHIÊN CỨU VÀ ĐỀ XUẤT GIẢI PHÁP TỰ RÈN LUYỆN KỸ NĂNG MỀM CHO HỌC S...
PDF
Bản phân loại thực vật môn thực vật dược
PDF
Cơ bản về matlab simulink cho người mới bắt đầu
PPTX
VNR202 LỊCH SỬ ĐẢNG, MÔN HỌC CẦN THIẾT C
PPTX
Ứng dụng AI trong hệ thống cơ điện của nhóm 3.pptx
PDF
CHUYÊN ĐỀ DẠY THÊM HÓA HỌC LỚP 10 CẢ NĂM THEO FORM THI MỚI BGD - CÓ ÔN TẬP + ...
PPTX
slide chương 2 excel cơ bản...........,,
DOCX
Cao Thuy Linh-San pham cuoi khoa.- bồi dưỡng thường xuyêndocx
PPTX
Bai 44 Thuyet dong hoc phan tu chat khi Cau tao chat .pptx
PDF
CHUYÊN ĐỀ DẠY THÊM HÓA HỌC LỚP 12 CẢ NĂM THEO FORM THI MỚI BGD - CÓ ÔN TẬP + ...
PDF
TeétOrganicChemistryFromVietNamVeryHardd
PDF
CHUYÊN ĐỀ DẠY THÊM HÓA HỌC LỚP 12 CẢ NĂM THEO FORM THI MỚI BGD - CÓ ÔN TẬP + ...
PPTX
Bai 28 Cau tao chat Thuyet dong hoc phan tu chat khi.pptx
Chủ nghĩa xã hội khoa học - Đề Cương Cuối Kỳ.docx
LUẬN VĂN GROUP ĐỀ BÀI ĐÁNH GIÁ GIAO TIẾP SƯ PHẠM
Ôn tập văn học phương đông thi giữa kì ..
bai giang an toan thong tin ke toan nam 2020
Triet hoc con nguoi va triet hoc thac si
GIẢI PHÁP NÂNG CAO CÔNG TÁC CHỦ NHIỆM QUA CÁC TIẾT SINH HOẠT THEO CHỦ ĐỀ NHẰ...
Slide Nguyên lý bảo hiểm đại học knh tế quốc dân
SÁNG KIẾN “NGHIÊN CỨU VÀ ĐỀ XUẤT GIẢI PHÁP TỰ RÈN LUYỆN KỸ NĂNG MỀM CHO HỌC S...
Bản phân loại thực vật môn thực vật dược
Cơ bản về matlab simulink cho người mới bắt đầu
VNR202 LỊCH SỬ ĐẢNG, MÔN HỌC CẦN THIẾT C
Ứng dụng AI trong hệ thống cơ điện của nhóm 3.pptx
CHUYÊN ĐỀ DẠY THÊM HÓA HỌC LỚP 10 CẢ NĂM THEO FORM THI MỚI BGD - CÓ ÔN TẬP + ...
slide chương 2 excel cơ bản...........,,
Cao Thuy Linh-San pham cuoi khoa.- bồi dưỡng thường xuyêndocx
Bai 44 Thuyet dong hoc phan tu chat khi Cau tao chat .pptx
CHUYÊN ĐỀ DẠY THÊM HÓA HỌC LỚP 12 CẢ NĂM THEO FORM THI MỚI BGD - CÓ ÔN TẬP + ...
TeétOrganicChemistryFromVietNamVeryHardd
CHUYÊN ĐỀ DẠY THÊM HÓA HỌC LỚP 12 CẢ NĂM THEO FORM THI MỚI BGD - CÓ ÔN TẬP + ...
Bai 28 Cau tao chat Thuyet dong hoc phan tu chat khi.pptx
Ad
Ad

Visual.c

  • 1. LEÂ NGOÏC THAÏNH lntmail@yahoo.com LAÄP TRÌNH WINDOWS VÔÙI MFC Microsoft Visual C++ 6.0 NHAØ XUAÁT BAÛN THOÁNG KEÂ
  • 2. MUÏC LUÏC 3.4.2 Lôùp Cpen 31 3.4.3 Lôùp CBrush 31 CHÖÔNG 1 : MOÄT SOÁ KHAÙI NIEÄM LAÄP TRÌNH Trang 3.4.4 Lôùp CFont 32 TRONG MOÂI TRÖÔØNG WINDOWS 1 3.4.5 Lôùp CBitmap 32 1.1 Chöông trình ( Program ) 1 3.4.6 Lôùp CPalette 33 1.2 ÖÙng duïng ( Application ) 1 3.4.7 Lôùp CRgn 34 1.3 Tieán trình ( Process ) 1 3.5 Lôùp CDC 35 1.4 Tieåu trình (Thread ) 1 3.6 Lôùp CImageList 38 1.5 Thoâng ñieäp ( Message ) 2 1.5.1 Nguoàn goác cuûa message 2 CHÖÔNG 4 : CÖÛA SOÅ GIAO DIEÄN LÔÙP VAØ LÔÙP CWnd 40 1.5.2 Caùc loaïi message 2 4.1 Cöûa soå giao dieän 40 1.5.3 Soá hieäu message (Message Indentifier – MessageID) 3 4.2 Lôùp CWnd 40 1.5.4 Ñaëc taû message 3 4.3 Söû duïng ñoái töôïng CWnd 49 1.6 Cöûa soå giao dieän (window) cuûa öùng duïng 3 4.3.1 Söû duïng CWnd laøm giao dieän chính cuûa öùng duïng 49 1.7 Message queue 5 4.3.2 ÖÙng duïng chæ chaïy moät baûn (instance) taïi moãi thôøi ñieåm 50 1.8 Kieán truùc xöû lyù cuûa öùng duïng trong Windows 7 1.9 Resource cuûa öùng duïng 8 CHÖÔNG 5 : XÖÛ LYÙ MESSAGES 51 5.1 Lôùp xöû lyù message CCmdTarget: 51 CHÖÔNG 2 : THÖ VIEÄN MFC CUÛA MICROSOFT 5.2 Khai baùo muïc xöû lyù message trong MessageMap 52 & ÖÙNG DUÏNG CÔ BAÛN TRONG WINDOWS 10 5.3 Caùc lôùp keá thöøa CCmdTarget 55 2.1 Thö vieän MFC (Microsoft Foundation Class) 10 5.4 MessageMap cuûa lôùp keá thöøa CWnd trong öùng duïng 55 2.2 Tieáp an MFC 10 5.4.1 Cöûa soå cuûa öùng duïng coù chöùc naêng hoaït ñoäng 55 2.3 Taïo öùng duïng windows vôùi MFC nhö theá naøo ? 10 5.4.2 WM_PAINT vaø haønh vi OnPaint cuûa CWnd 58 2.4 Lôùp quaûn lyù tieåu trình CwinThread 11 2.5 Lôùp quaûn lyù tieåu trình giao dieän chính CwinApp 12 CHÖÔNG 6 : ÖÙNG DUÏNG COÂNG CUÏ GDI 60 2.6 Thöïc hieän öùng duïng ñôn giaûn 14 6.1 DC vaø BITMAP 60 2.7 Thöïc hieän öùng duïng giao taùc ñôn giaûn 20 6.2 ÖÙng duïng vôùi cöûa soå chính hieån thò aûnh 60 2.8 Taïo môùi Icon Resource cho öùng duïng 25 6.3 Sao cheùp aûnh töøø DC ñeán DC, phoùng to & thu nhoû aûnh 63 2.9 Löu tröõ chöông trình nguoàn 27 6.4 DC trong boä nhôù ( DC aûo) – vuøng veõ ñeäm lyù töôûng 64 2.10 Lôùp Cstring cuûa MFC 27 6.5 AÛnh chuyeån ñoäng trong vuøng client 65 6.6 CImageList – coâng cuï quaûn lyù boä aûnh cuøng côõ 66 CHÖÔNG 3 : CAÙC LÔÙP GIAO DIEÄN ÑOÀ HOÏA CUÛA MFC 29 6.7 CRgn – Cöûa soå coù hình daïng tuøy yù 67 3.1 Caùc coâng cuï giao dieän ñoà hoïa 29 3.2 Device Context 29 CHÖÔNG 7 : MENU – PHÍM TAÉT 69 3.3 Toïa ñoä treân giao dieän ñoà hoïa 29 7.1 Ñònh nghóa 69 3.4 Caùc lôùp MFC hoã trôï GDI 30 7.2 Menu resoure 69 3.4.1 Caùc lôùp ñoái töôïng ñieåm, hình chöõ nhaät 30
  • 3. 7.3 Söû duïng menu resource 71 10.3.1 Thieát keá ToolBar resource 120 7.4 Muïc xöû lyù command message töø muïc choïn cuûa menu 72 10.3.2 Duøng toolbar resource cho CToolBar cuûa FrameWnd 121 7.5 Phím taét (hot key ) cho muïc choïn treân menu 73 10.4 Lôùp CFrameWnd 121 7.6 Lôùp quaûn lyù menu – CMenu 75 10.5 Söû duïng frame window laøm giao dieän chính 123 7.7 Xöû lyù ñieàu khieån muïc choïn cuûa menu 77 10.5.1 Thöïc hieän öùng duïng vôùi giao dieän frame window 123 10.5.2 String Table vaø CFrameWnd 124 CHÖÔNG 8 : CAÙC LÔÙP ÑOÁI TÖÔÏNG NHAÄP LIEÄU 10.5.3 Duøng MFC wizard taïo öùng duïng giao dieän framewindow 130 ( WINDOWS CONTROLS ) 78 8.1 CStatic 78 CHÖÔNG 11 : CAÙC KIEÁN TRUÙC DOCUMENT – VIEW 134 8.2 CEdit 80 11.1 CDocument 134 8.3 CButton 84 11.2 CView 135 8.4 ClistBox 85 11.3 CFrameWnd 136 8.5 CComboBox 88 11.4 CDoctemplate 136 8.6 CSpinButtonCtrl 91 11.5 Hoã trôï töø phía ñoái töôïng quaûn lyù öùng duïng 137 8.7 CProgressCtrl 93 11.6 Trình töï taïo laäp caùc ñoái töôïng tham gia boä DVF 138 8.8 CscrollBar 94 11.7 Text Document Appication 139 8.9 CSliderBar 96 11.8 Rich Text Format (rtf) Document Appication 143 11.9 HTML Document View Appication 146 CHÖÔNG 9 : HOÄP HOÄI THOAÏI 97 11.10 Moät soá lôùp view ñaëc bieät 149 9.1 Hoäp hoäi thoaïi (Dialog) 97 11.10.1 CListView 149 9.2 Lôùp CDialog 97 11.10.2 CTreeView 150 9.3 Taïo vaø söû duïng dialog trong chöông trình 99 11.10.3 CSplitterWnd 152 9.3.1 Taïo dialog resource 99 11.10.4 Söû duïng splitterwnd trong frame window 154 9.3.2 Khai baùo lôùp keá thöøa CDialog söû duïng dialog resource 103 11.10.5 Caùc ví duï thöïc haønh 155 9.3.3 Söû duïng dialog trong chöông trình 104 9.4 Lieân keát giöõa dialog vaø caùc thaønh phaàn khaùc 104 CHÖÔNG 12 : MOÄT SOÁ VAÁN ÑEÀ TRONG WINDOWS 158 9.5 Söû duïng dialog laøm giao dieän chính cuûa öùng duïng 106 12.1 Taäp tin INI 158 9.5.1 Thöïc hieän öùng duïng vôùi giao dieän chính laø dialog 106 12.2 System Registry 160 9.5.2 Duøng MFC wizard taïo öùng duïng vôùi giao dieän dialog 107 12.3 Vuøng Status Area treân Taskbar 162 9.6 Khai baùo bieán cho control treân dialog 109 12.4 ÖÙng duïng ScreenSaver 167 9.7 Khai thaùc caùc tieän ích hoã trôï 112 12.4.1 Ñaëc ñieåm 168 12.4.2 Tham soá doøng leänh 168 CHÖÔNG 10 : KHUNG CÖÛA SOÅ GIAO DIEÄN CHÍNH 117 12.4.3 Ñaëc ñieåm giao taùc vôùi ngöôøi duøng 170 10.1 Khung cöûa soå giao dieän (Frame Window) 117 12.4.4 Thöïc hieän öùng duïng ScreenSaver ñôn giaûn 171 10.2 Thanh traïng thaùi (statusbar) & lôùp CStatusbar 117 12.5 ÖÙng duïng söû duïng nhieàu tieåu trình 175 10.3 Thanh coâng cuï (toolbar) & lôùp CToolBar 119 12.5.1 Tieåu trình xöû lyù noäi 175
  • 4. 12.5.2 Tieåu trình giao dieän 177 13.7.2 Thieát keá öùng duïng nhaän mail 220 12.5.3 Caùc haøm hoã trôï 179 13.8 TCP vôùi HTTP vaø FTP 223 12.6 Laäp trình Multimedia vôùi MCI 179 13.8.1 Lôùp CInternetSession 223 12.7 AÁn ñònh moät soá tính naêng cuûa Windows 181 13.8.2 Lôùp CInternetFile 224 12.8 Baãy (hook) message (Windows Hook) 182 13.8.3 Lôùp CFtpConnection 225 12.8.1 Caùc kieåu hook (Hook Type) 183 13.8.4 Lôùp CFtpFindFile 227 12.8.2 Danh saùch hook (Hook Chain) 183 13.8.5 Lôùp CHttpConnection 228 12.8.3 Thuû tuïc hook (Hook Procedure) 183 13.8.6 Lôùp CHttpFile 229 12.8.4 Caùc dòch vuï lieân quan hook 184 13.8.7 Thöïc hieän öùng duïng FTP client ñôn giaûn 231 12.8.5 ÖÙng duïng hook messages cuûa keyboard 185 13.8.8 Thöïc hieän öùng duïng HTTP client ñôn giaûn 232 12.9 Caøi ñaët cheá ñoä thöïc hieän öùng duïng töï ñoäng 186 Phuï luïc A: MOÄT SOÁ VAÁN ÑEÀ CHÖÔNG 13 : MFC VÔÙI INTERNET 187 LAÄP TRÌNH HÖÔÙNG ÑOÁI TÖÔÏNG 234 13.1 Giao thöùc truyeàn thoâng TCP/IP 187 A.1 Laäp trình höôùng ñoái töôïng (OOP) 234 13.1.1 Giôùi thieäu 187 A.2 Caùc khaùi nieäm 234 13.1.2 Kieán truùc cuûa giao thöùc TCP/IP treân moâ hình DARPA 187 A.2.1 Lôùp (Class) 234 13.1.3 Ñòa chæ IP 189 A.2.2 Ñoái töôïng (Object) 234 13.1.4 Subnet 190 A.2.3 Thuoäc tính (Attribute) 234 13.1.5 Subnet Mask 191 A.2.4 Haønh vi (Method) 235 13.1.6 Host domain name 192 A.2.5 Chöông trình (Program) 235 13.1.7 IP Routing 194 A.3 Ñaëc ñieåm laäp trình höôùng ñoái töôïng 235 13.2 Laäp trình TCP/IP vôùi Winsock 197 A.4 Phaân loaïi thuoäc tính vaø haønh vi 236 13.2.1 Port 197 A.5 Caùc haønh vi ñaëc bieät 236 13.2.2 Socket 198 A.6 Khai baùo lôùp, ñoái töôïng trong C++ 236 13.2.3 Moät soá caáu truùc döõ lieäu cuûa Winsock API 198 A.6.1 Khai baùo lôùp 236 13.2.4 Moät soá dòch vuï cuûa Winsock API 199 A.6.2 Khai baùo ñoái töôïng 238 13.3 MFC vôùi laäp trình Winsock 200 A.6.3 Söû duïng ñoái töôïng trong chöông trình 238 13.3.1 Khôûi ñoäng Winsock 200 A.7 Keá thöøa trong C++ 239 13.3.2 Lôùp CAsyncSocket 200 A.7.1 Keá thöøa haønh vi taïo laäp 239 13.4 Laäp trình Winsock cho giao thöùc UDP 204 A.7.2 Keá thöøa haønh vi huûy boû 240 13.5 Laäp trình Winsock cho giao thöùc TCP 207 A.7.3 Thöïc hieän haønh vi lôùp cô sôû 240 13.6 TCP vôùi SMTP (Simple Mail Transfer Protocol) 215 A.8 Khai baùo haønh vi toaùn töû soá hoïc 241 13.6.1 Qui öôùc giöõa öùng duïng göûi mail vaø nhaän mail 215 A.9 Con troû this 243 13.6.2 Thieát keá öùng duïng göûi mail 217 A.10 Haønh vi virtual 243 13.7 TCP vôùi Pop3 (Post Office Protocol – Version 3) 219 A.11 Thuoäc tính vaø haønh vi tónh 244 13.7.1 Qui öôùc giöõa öùng duïng mail client vaø mail server 219
  • 5. LÔØI MÔÛ ÑAÀU TAØI LIEÄU THAM KHAÛO [1] Richard Simon, Windows 95 - Win32 Programming API-BIBLE, Ngoân ngöõ laäp trình C++ ñöôïc bieát ñeán nhö laø moät trong nhöõng ngoân ngöõ Waite Group Press 1996. 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 [2] Jeff Prosise, Programming Windows 95 with MFC, Microsoft Press. ôû 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 [3] M. Tracy, Professional Visual C++ ISAPI Programming, Wrox Press. 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 [4] Dr. GUI, Microsoft Developer Network - MSDN, 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ôû Microsoft Corporation Software. 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 [5] Dino Esposito,Visual C++ Windows Shell Programming, Wrox Press. 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 PHAÀN MEÀM CAÀN CAØI ÑAËT: 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 - Microsoft Visual C++ 6.0 hoaëc Microsoft Visual C++ .NET. höôùng söû duïng heä ñieàu haønh Microsoft Windows nhö hieän nay, chuùng ta - MSDN ( Microsoft Developer Network ), baûn thaùng 10/2003. 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 MAÕ NGUOÀN: vaø khai thaùc noù sao cho öùng duïng hoaït ñoäng hieäu quaû nhaát. Source Code cuûa caùc ví duï minh hoïa trong cuoán saùch naøy vaø cuûa moät soá Microsoft Visual C++, saûn phaåm cuûa Microsoft, vôùi khaû naêng bieân dòch öu chöông trình troø chôi maø chuùng toâi mong muoán chia xeû cuøng baïn ñoïc 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 löu trong ñóa meàm ñính keøm, vaø coù theå download töø ñòa chæ: 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 http://thanh.andisw.com/?id=16&id2=85 Windows haàu phuïc vuï cho öùng duïng cuûa mình. WEB SITE: 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 Source Code ñaëc saéc cuûa nhieàu taùc giaû treân theá giôùi coù theå download: 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 - http://msdn.microsoft.com höôùng ñoái töôïng vôùi C++, nhaèm khai thaùc hieäu quaû thö vieän MFC vaø töøng - http://www.codeguru.com 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 - http://www.codeproject.com xeáp theo caùc caáp ñoä tieán trieån phuø hôïp. - http://www.softechsoftware.it - http://www.flipcode.com 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 - http://nps.vnet.ee 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 LIEÂN HEÄ: 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 - Taùc giaû: Leâ Ngoïc Thaïnh 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 - Cô quan: Khoa Tin Hoïc Quaûn Lyù, Tröôøng ÑHKT TP.HCM 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 Ñòa chæ: 279 Nguyeãn Tri Phöông Q10, TP.HCM. söûa cuoán saùch kòp thôøi. - Ñòa chæ e-mail: lntmail@yahoo.com Thaønh phoá Hoà Chí Minh, ngaøy 19.11.2002 emp@ueh.edu.vn Taùc giaû
  • 6. CHƯƠNG 1: 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ọ. Một số khái niệm Lập trình 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. Trong môi trường Windows 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.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 1.5 THÔNG ÐIỆP (MESSAGE): máy, được bố trí theo một trình tự logic nhằm phối hợp thực hiện một Thông điệp (message) là giá trị phản ánh một nội dung giao tiếp hay công việc xác định. Các chỉ thị được thể hiện dưới dạng mã nguồn yêu cầu xử lý giữa hệ thống (windows) và ứng dụng, giữa các ứng dụng (source code) hay mã máy (machine code). Chương trình mã máy có thể với nhau hoặc giữa các thành phần trong cùng một ứng dụng. thực hiện được trên máy có bộ lệnh tương thích, với chương trình mã 1.5.1 Nguồn gốc message: nguồn thì phải sử dụng một ứng dụng chuyên dụng để chuyển sang mã Cả windows và ứng dụng đều có thể phát sinh message. máy trước khi thực hiện. Windows phát sinh message khi cần thông tin cho ứng dụng các Việc chuyển các chỉ thị dạng mã nguồn sang chỉ thị mã máy để thực hoạt động nhập-xuất (hoạt động gõ phím, di chuyển hay click chuột, hiện được tiến hành bằng một trong hai cơ chế sau: . của người dùng), các thay đổi của hệ thống (font chữ, chế độ phân Thông dịch: Mỗi chỉ thị mã nguồn được chuyển sang chỉ thị mã máy giải màn hình, màu sắc,...) hoặc những biến đổi khác liên quan đến tương ứng và được thực hiện ngay, sau đó tiếp tục với chỉ thị kế tiếp. ứng dụng. Biên dịch: Tất cả các chỉ thị mã nguồn được chuyển sang các chỉ thị Ứng dụng phát sinh message khi xử lý điều khiển các thành phần mã máy tướng ứng. Tập hợp các chỉ thị mã máy này gọi là chương 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 trình mã máy. Chương trình mã máy được lưu lại trong tập tin chương dùng, hoặc khi ứng dụng thực hiện giao tiếp với windows hay với các 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. ứng dụng khác đang thực hiện trong cùng hệ thống. 1.2 ỨNG DỤNG (APPLICATION): 1.5.2 Các loại message: Khi một chương trình được cài đặt trên máy tính để sử dụng, ta gọi đó Message được định nghĩa bởi hệ thống: Là các message do hệ điều là ứng dụng, ví dụ như ứng dụng NotePad, ứng dụng Microsoft Word,.... hành windows tạo ra nhằm phục vụ hoạt động điều khiển toàn bộ hệ Trong môi trường windows, mỗi ứng dụng có thể được thi hành nhiều thống, xử lý thông tin vào-ra hoặc các thông tin khác cho ứng dụng. 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 Khi có nhu cầu, ứng dụng có thể sử dụng những message này để dụng gọi là thể hiện (instance) của ứng dụng đó. 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 1.3 TIẾN TRÌNH (PROCESS): viết ứng dụng định nghĩa nhằm tạo kênh liên lạc đặc thù giữa các Tiến trình là khái niệm chỉ một instance đang hoạt động của ứng thành phần trong ứng dụng, giữa ứng dụng với windows hoặc với dụng. Khi ta double-click trên biểu tượng NotePad để chạy ứng dụng các ứng dụng khác đang thực hiện trong cùng hệ thố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: Moät soá khaùi nieäm laäp trình trong moâi tröôøng Windows 1 2 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 7. 1.5.3 Số hiệu message (Message Indentifier - MessageID): 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 Có rất nhiều message khác nhau được sử dụng trong môi trường người dùng. windows. Ứng với mỗi message xác định, windows sử dụng một giá trị Dạng thông thường của một cửa sổ giao diện trong windows: 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 { System Menu Box: Chứa biểu tượng của ứng dụng, là nút mở hộp HWND hwnd; // Giá trị có kích thước 4 bytes (long) menu hệ thống với các mục di chuyển, thay đổi kích thước hoặc đóng UINT message; // Số hiệu của message cửa sổ. WPARAM wParam; // Giá trị không âm có kích thước 2 bytes Caption bar: Thanh tiêu đề của ứng dụng. LPARAM lParam; // Giá trị không âm có kích thước 4 bytes Menu bar: Hệ thống menu với các mục lựa chọn xử lý. DWORD time; // Thời điểm sinh ra messsge Minimize / Maximize Box : Nút điều khiển thu nhỏ / phóng to cửa sổ. POINT pt; // Tọa độ cursor khi message được gửi. Restore Box : Nút khôi phục kích thước trước đó của cửa số. } MSG; Border: Ðường viền bao quanh cửa sổ. Trường hwnd (window handle) của cấu trúc chứa thẻ (handle) quản lý Client area: Vùng làm việc của cửa sổ, dùng để hiển thị thông tin. cửa sổ giao diện liên quan đến message. wParam và lParam là hai tham Scroll bar: Thanh cuộn nội dung vùng làm việc của cửa sổ. số gửi kèm theo message làm nhiệm vụ chứa thông tin bổ sung. Hai Window Procedure: Ngoài giao diện đồ họa, cửa sổ của windows có tham số này được dùng khi message có nhiều ý nghĩa thực tế khác nhau. khả năng tiếp nhận và xử lý message. Khả năng này được thực hiện Windows sử dụng giá trị có kích thước 4 bytes để quản lý các đối thông qua hàm xử lý message mà ta đã gắn cho cửa sổ. Hàm xử lý tượng của nó. Giá trị này gọi là thẻ quản lý đối tượng (object handle). này có khai báo như sau: Ứng với mỗi loại đối tượng cụ thể, windows sử dụng một kiểu handle LRESULT CALLBACK WindowProc ( riêng. HWND là kiểu handle dùng quản lý đối tượng cửa sổ giao diện HWND hwnd, // Tham số chứa Handle của cửa sổ liên trong windows. quan UINT uMsg, // Tham số chứa số hiệu message 1.6 CỬA SỔ GIAO DIỆN (WINDOW) CỦA ỨNG DỤNG: WPARAM wParam, // Tham số bổ sung thứ nhất kiểu WORD Cửa sổ giao diện là thành phần quan trọng trong việc tạo ra môi LPARAM lParam // Tham số bổ sung thứ hai kiểu LONG trường giao diện đồ họa của các ứng dụng trong windows. Cùng với sự ) ; Hàm trả về một giá trị có kích thước là 32 bits. phát triển của hệ điều hành windows, hình ảnh cửa sổ giao diện cũng Khi một yêu cầu xử lý được chuyển đến cửa sổ dưới dạng message, thay đổi theo với chiều hướng sinh động hơn về hình thức và phong phú hàm WindowProc gắn với cửa sổ sẽ căn cứ trên số hiệu message hơn về chức năng. Ðiều đó không chỉ góp phần tăng tính thẩm mỹ mà (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 Moät soá khaùi nieäm laäp trình trong moâi tröôøng Windows 3 4 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 8. khả năng xử lý của cửa sổ) hàm phải chuyển message cho windows con trỏ tham số plMSG. Khi đã lấy được một message, hàm kết thúc xử lý thông qua lời gọi hàm xử lý message mặc nhiên của windows. và trả về một giá trị nguyên. Nếu message nhận được là message kết Hàm xử lý này có tên gọi là DefWindowProc với khai báo như sau: thúc ứng dụng (số hiệu WM_QUIT) thì hàm trả về giá trị 0. Ngược lại, LRESULT DefWindowProc( // Default Window Procedure hàm trả về giá trị khác 0. HWND hWnd, // Với các tham số có ý nghĩa như trên Kiểm tra và lấy một message trong message queue của ứng dụng: UINT Msg, BOOL PeekMessage( WPARAM wParam, LPMSG lpMsg; // . Như GetMessage LPARAM lParam HWND hWnd; ); UINT wMsgFilterMin; Khi đó, kết quả trả về của DefWindowProc được dùng làm kết quả UINT wMsgFilterMax; của hàm WindowProc. Qui tắc nói trên cần phải được đảm bảo, nếu UINT wRemoveMsg; // Có thực hiện xóa message không ? không, ứng dụng có thể làm rối loạn hoạt động của hệ điều hành // PM_NOREMOVE: không xóa windows. ); Hàm trả về giá trị 0 nếu message queue rỗng. Ngược lại, hàm trả về 1.7 MESSAGE QUEUE: một giá trị khác không và thông tin về message được điền vào biến Message queue là danh sách thứ tự các message do windows tạo ra kiểu MSG được chỉ bởi tham số kiểu con trỏ lpMSG. 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 Diễn dịch message của bàn phím sang mã phím ASCII: trước). Có hai loại message queue trong windows: BOOL TranslateMessage( Message queue của hệ thống (system queue): Ðược windows dùng CONST MSG *lpMsg; // con trỏ đến biến chứa message 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 Tham số lpMsg là con trỏ chỉ đến biến kiểu MSG chứa nội dung đặc dùng. tả message được lấy từ message queue và cần diễn dịch. Message queue của ứng dụng (application queue): Ðược windows tạo Hàm trả về giá trị khác 0 nếu message nhận được tương ứng với một ra và cấp cho các thể hiện của ứng dụng. Windows tự động điều phối thao tác trên bàn phím (nhấn phím: WM_KEYDOWN, các message từ system queue sang application queue một cách phù WM_SYSKEYDOWN; thôi nhấn phím: WM_KEYUP, 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 WM_SYSKEYUP) hoặc một message có ý nghĩa tương đương mà xử lý của người dùng thông qua hệ thống. Cơ chế này ngăn các ứng việc diễn dịch sang mã phím ASCII là thành công. Khi đó hàm tự động dụng trong windows quyền truy cập trực tiếp các thiết bị phần cứng tạo message WM_CHAR cho phím diễn dịch được. Trong các trường của máy tính. hợp khác, hàm trả về giá trị 0. 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 Moät soá khaùi nieäm laäp trình trong moâi tröôøng Windows 5 6 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 9. Ðiều phối message đến cửa sổ giao diện chính: Kiến trúc xử lý chung của ứng dụng trong môi trường windows 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: 1.9 RESOURCE CỦA ỨNG DỤNG: Khi ứng dụng được thực hiện, windows tạo thêm một tiến trình cho thể Ðối với một chương trình trong windows, ngoài phần mã lệnh của các hiện mới của ứng dụng, đồng thời xây dựng một message queue dùng hàm xử lý, resource là một thành phần không kém phần quan trọng chứa 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ó các nội dung hỗ trợ cho việc trang trí hoặc phục vụ cho một mục đích đặc nhiệm vụ thực hiện MessageLoop trên message queue dành cho ứng biệt của ứng dụng. Các nội dung phổ biến trong resource như sau: 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). Cursor: Ảnh nhỏ đặc tả vị trí làm việc của thiết bị liên quan như Các cách xử lý của tiểu trình chính khi nắm quyền điều khiển ứng mouse, pen, trackball. Khi người dùng tác động lên những thiết bị này dụng: thì windows sử dụng cursor để phản ánh hiện tượng đó. Không thực hiện xử lý nào cả: Ứng dụng kết thúc. Bitmap: Tập ảnh điểm (pixels) của một ảnh. Các ảnh điểm này bố trí Thực hiện MessageLoop nhưng không tạo cửa sổ giao diện chính: theo các dòng và phối hợp làm nên hình ảnh của đối tượng. Ứng dụng chờ nhận message nhưng người dùng không giao tác được. Dialog: Thông tin mô tả khung giao diện với các đối tượng nhập liệu Khởi tạo một cửa sổ với hàm xử lý message WindowProc và chọn cửa bên trong, là cơ sở để tạo ra các hộp hội thoại trong ứng dụng. sổ này làm cửa sổ giao diện chính: Hàm WindowProc của cửa sổ sẽ Icon : Ảnh nhỏ được dùng để đặc tả chức năng của một đối tượng, tiếp nhận và xử lý message được điều phối từ MessageLoop của tiểu ứng dụng hay một nội dung dữ liệu. trình chính. Người dùng có thể giao tác và kết thúc ứng dụng được. HTML (Hypertext Markup Language): Ngôn ngữ dùng tạo ra những tài Như mục thứ ba, đồng thời tạo ra các tiểu trình phục vụ: Ứng dụng có 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 khả năng tiếp nhận và thực hiện đồng thời nhiều yêu cầu xử lý. duyệt tương ứng có thể thể hiện một cách xúc tích. Moät soá khaùi nieäm laäp trình trong moâi tröôøng Windows 7 8 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 10. 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. Moät soá khaùi nieäm laäp trình trong moâi tröôøng Windows 9
  • 11. CHƯƠNG 2: 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 Thư viện MFC của microsoft 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 & ứng dụng cơ bản trong windows đượ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 2.1 THƯ VIỆN MFC (MICROSOFT FOUNDATION CLASS): thông qua các thuộc tính và hành vi của nó. Thư viện MFC của Microsoft bao gồm các lớp cơ bản, cài đặt bằng DWORD m_nThreadID : Thuộc tính lưu số hiệu của tiểu trình. ngôn ngữ C++, hỗ trợ việc lập trình trong môi trường windows. Từ các lớp CWnd* m_pMainWnd : Lưu con trỏ đối tượng cửa sổ giao diện này, MFC xác lập nền tảng hình thành ứng dụng của windows, bao gồm chính của tiểu trình. Khi cửa sổ giao diện chính chấm dứt hoạt việc định nghĩa bộ khung ứng dụng, các công cụ chuẩn và phổ biến để độ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 bổ sung vào bộ khung nói trên nhằm tạo ra ứng dụng hoàn chỉnh. Với 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 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 hơn. phần cần thiết, điều chỉnh và phối hợp chúng hợp lý để có được ứng CWinThread( ); Hành vi tạo lập (constructor) đối tượng tiểu trình. dụng kết quả mong muốn. virtual BOOL InitInstance( ); Khởi tạo thông số cho đối tượng tiểu Lập trình windows với MFC và MicroSoft Visual C++ 6.0 (VC) đạt trình và đảm nhận các xử lý bổ sung khác của ứng dụng. Ðối với được hiệu quả cao bởi không chỉ khai thác được phiên bản mới nhất của tiểu trình giao diện, hành vi này được dùng để khởi tạo đối tượng MFC mà còn nhận được nhiều tiện nghi lập trình mà VC cung cấp. Ðây là cửa sổ giao diện và gán địa chỉ của đối tượng cửa sổ cho con đường ngắn và đơn giản, đặc biệt với người tự học, để viết ứng dụng m_pMainWnd. windows. 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 2.2 TIẾP CẬN MFC: trả các tài nguyên của hệ thống mà nó đã đăng ký sử dụng. MFC là thư viện khổng lồ với khoảng 200 lớp đối tượng mà việc hiểu virtual int Run( ); Hành vi dành riêng cho tiểu trình giao diện, nó rõ và vận dụng chúng trong một khoảng thời gian ngắn là không thể thực hiện vòng lặp nhận message, chuyển message cho hành vi đượ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ổ PreTranslateMessage của lớp. Nếu hành vi này trả về giá trị 0 thì biến nhất của thư viện để xây dựng ứng dụng thông thường. Khi đã có message sẽ tiếp tục được chuyển đến các hàm diễn dịch phím khả năng nhất định về sử dụng MFC thì với tài liệu MSDN, sẽ chẳng khó TranslateMessage và hàm điều phối message DispatchMessage. khăn gì trong việc mở rộng khai thác thư viện để ứng dụng trở nên mạnh virtual BOOL PreTranslateMessage(MSG *pMsg); Hành vi cho mẽ và tinh tế hơn. phép can thiệp trước trên các message nhận được từ message Trong những phần trình bày sau, chúng ta sẽ lần lượt tiếp nhận hệ queue của ứng dụng. Thông qua đó, tiểu trình giao diện có thể thực 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à hiện các tiền xử lý message đặc trưng nhằm đáp ứng yêu cầu đặt 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 ra cho ứng dụng. đề. Khi CWinThread được dùng để quản lý đối tượng tiểu trình chính thì 2.3 TẠO ỨNG DỤNG WINDOWS VỚI MFC NHƯ THẾ NÀO ?: hàm WinMain (cài sẵn bên trong lớp bởi thư viện MFC) tự động thực Theo mô hình kiến trúc ứng dụng windows ở mục (1.8), việc giải quyết hiện các hành vi InitInstance(), Run() và ExitInstance() theo thứ 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. 10 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Thö vieän MFC cuûa Microsoft & öùng duïng cô baûn trong windows 11
  • 12. 2.5 LỚP QUẢN LÝ TIỂU TRÌNH GIAO DIỆN CHÍNH CWinApp: MB_OK OK CWinApp, kế thừa từ CWinThread, là lớp đối tượng chuyên dùng quản MB_OKCANCEL OK - Cancel lý tiểu trình giao diện chính của ứng dụng. Ứng dụng windows chỉ được MB_YESNO Yes - No 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 MB_YESNOCANCEL Yes - No - Cancel kế thừa public từ CWinThread, CWinApp có các thuộc tính và hành vi bổ MB_ABORTRETRYIGNORE Abort - Retry - Ignore sung sau: MB_RETRYCANCEL Retry - Cancel 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. • Các thông số qui định biểu tượng dùng trong nút chọn: Tham số dòng lệnh là toàn bộ phần nội dung mà người dùng gõ Giá trị thông số Biểu tượng vào ngay sau chuỗi đường dẫn và tên chương trình ứng dụng khi MB_ICONHAND, MB_ICONSTOP, họ thực hiện ứng dụng. Ðối với ứng dụng có nhiều chế độ hoạt MB_ICONERROR động khác nhau thì việc sử dụng tham số dòng lệnh là một cơ chế MB_ICONQUESTION 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. MB_ICONEXCLAMATION, MB_ICONWARNING 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. MB_ICONASTERISK, MB_ICONINFORMATION 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 • Số hiệu các nút chọn được sử dụng trong hộp thông báo: dụng vào bộ nhớ (nếu cursor chưa được nạp). nID là số hiệu của Số hiệu Nút chọn Số hiệu Nút chọn cursor. Hàm trả về giá trị handle quản lý cursor. Giá trị này có kiểu IDABORT Abort IDOK OK HCURSOR (handle of cursor) mà windows dùng để quản lý cursor. IDCANCEL Cancel IDRETRY Retry HICON LoadIcon ( int nID ); Nạp icon từ resource của ứng dụng IDIGNORE Ignore IDYES Yes vào bộ nhớ. nID là số hiệu của icon. Hàm trả về giá trị handle quản IDNO No lý icon. Giá trị này có kiểu HICON (handle of icon). • Hành vi DoMessageBox chờ người sử dụng trả lời bằng cách Hành vi hiển thị hộp thông báo và chờ nhận ý kiến người dùng: chọn một nút chọn xác định trong hộp thông báo. Hành vi kết virtual int DoMessageBox ( thúc với giá trị trả về là số hiệu của nút được chọn. Kế thừa hành LPCTSTR lpszPrompt, // Nội dung thông báo vi này để chặn và thực hiện xử lý đặc trưng (sử dụng dạng hộp UINT nType, // Dạng hộp thông báo thông báo riêng) cho tất cả các lời gọi AfxMessageBox trong UINT hlpIndex = 0 // Số hiệu mục giúp đỡ (WinHelp) ứng dụng. ); Hành vi này được kích hoạt với tham số tương ứng mỗi khi trong • Hàm AfxMessageBox sử dụng DoMessageBox để hiển thị hộp chương trình sử dụng hàm AfxMessageBox để hiển thị hộp thông 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 báo. nó. int AfxMessageBox ( Ví dụ: AfxMessageBox( "Chao Ban", MB_ICONSTOP | MB_OK, 0 ); LPCTSTR lpszPrompt, UINT nType, UINT hlpIndex = 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. 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 12 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Thö vieän MFC cuûa Microsoft & öùng duïng cô baûn trong windows 13
  • 13. 2.6 THỰC HIỆN ỨNG DỤNG ÐƠN GIẢN: VC hiển thị hộp hội thoại New Project Information để thông báo Trong phần này, chúng ta thực hiện ứng dụng với đối tượng thuộc lớp các thông tin liên quan đến dự án vừa tạo. Chọn OK. CWinApp quản lý tiểu trình chính. Ðặt tên cho dự án của ứng dụng là Một dự án đã được tạo ra trên đĩa. Với thông tin nhập như trên, VD0. dự án mới tạo ra có tên là VD0, toàn bộ phần chương trình Các bước thực hiện dự án VD0 như sau: nguồn của dự án được lưu trong thư mục VD0 thuộc thư mục C:VC6. 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. Tiếp tục thực hiện các bước sau để hoàn tất dự án theo yêu cầu. Thực hiện ứng dụng Microsoft Visual C++ 6.0 (VC). Ðăng ký sử dụng lớp CWinApp của thư viện MFC: Lớp CWinApp Chọn mục File / New từ hệ thống menu của VC. được khai báo trong afxwin.h của MFC. Bổ sung tập tin stdafx.h Trong hộp hội thoại New, chọn trang Projects : 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: - 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. - C/C++ Header File : Loại nội dung tập tin (.h). - An empty project : Tạo dự án rỗng. - Add To Project : Bổ sung tập tin vào dự án VD0. - Finish : Hoàn tất việc khởi tạo dự án. - 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: 14 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Thö vieän MFC cuûa Microsoft & öùng duïng cô baûn trong windows 15
  • 14. #if !defined( _DU_AN_0_ ) resource và đối tượng lập trình tương ứng của MFC trong dự án. #define _DU_AN_0_ Thực hiện như sau: - Right-click trên mục tên resource (VD0 Resource): // _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 Properties: • Chọn mục File / New. Trong hộp hội thoại New, chọn trang Files. 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: - 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 Chọn phiên bản biên dịch ( chẳng hạn Win32 Debug ). Chọn OK. 16 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Thö vieän MFC cuûa Microsoft & öùng duïng cô baûn trong windows 17
  • 15. Ấn định biên dịch với thư viện MFC: Chọn mục Project / Setting. - C++ Source File : Loại nội dung tập tin (.cpp). - Add To Project : Bổ sung tập tin vào dự án. Trong hộp hội thoại Project Settings, - File Name : Tên tập tin (MAIN). Sau đó chọn OK. - Setting For: : Chọn phiên bản ấn định (ví dụ: Win32 Debug ), • Trong màn hình soạn thảo của main.cpp, nhập nội dung tập tin: - General : Các ấn định chung cho dự án. Microsoft Foundation Classes: Cách liên kết thư viện MFC vào #include "stdafx.h" // Tập tin chứa đăng ký thư viện của MFC ứng dụng. Có thể tùy chọn một trong hai cách sau: CWinApp theApp; // Ðối tượng quản lý tiểu trình chính Use MFC in Shared DLL: Chương trình sử dụng thư viện Sau khi nhập xong, chọn mục File / Save để lưu tập tin. MFC theo cơ chế liên kết động. Tập tin chương trình có kích Biên dịch chương trình: Chọn mục Build / Build <project name>.exe thước nhỏ nhưng khi thực hiện cần có các tập tin thư viện hoặc chọn mục trên thanh công cụ. (DLL) của MFC trong thư mục hệ thống của windows. Ta đã thực hiện xong một ứng dụng đơn giản trong môi trường Use MFC in Static Library: Thư viện MFC được nhúng vào windows. Tập tin chương trình được lưu trong thư mục DEBUG chương trình trong lúc biên dịch. Tập tin chương trình có kích (phiên bản biên dịch debug) hoặc RELEASE (phiên bản biên dịch thước lớn hơn nhưng ứng dụng có thể hoạt động độc lập. release). Sau khi ấn định xong, chọn OK. Chạy chương trình: Có thể chạy chương trình trực tiếp trong VC Khai báo đối tượng thuộc lớp CWinApp: Dùng bất kỳ tập tin CPP bằng cách nhấn phím F5 hoặc click chọn trên thanh công cụ. nào của dự án để thực hiện công việc này. Vì dự án VD0 đang thự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 hiện ở đây chưa có tập tin CPP, chúng ta tạo mới tập tin CPP cho gì cả bởi nó chỉ là một ứng dụng khung - được xây dựng hoàn toàn từ dự án. Giả sử tập tin CPP này có tên là MAIN.CPP. Cách thực hiện lớp CWinApp của MFC mà không có một xử lý bổ sung nào. như sau: 2.7 THỰC HIỆN ỨNG DỤNG GIAO TÁC ÐƠN GIẢN: • Chọn mục File / New. Trong hộp hội thoại New, chọn trang Files: 18 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Thö vieän MFC cuûa Microsoft & öùng duïng cô baûn trong windows 19
  • 16. 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ụ. Class Type = Generic Class: Chọn loại lớp thông thường vì • Chọn trang ClassView: 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: • Right-click trên mục VD01 Classes, chọn New Class. VD01.H : Chứa nội dung khai báo (header) của lớp. • Khai báo lớp CEmpApp thông qua hộp hội thoại New Class. 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. 20 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Thö vieän MFC cuûa Microsoft & öùng duïng cô baûn trong windows 21
  • 17. 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: • Ð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(); Phần bổ sung 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" Bổ sung #include "Emp.h" Chọn Add All, sau đó chọn OK. BEGIN_MESSAGE_MAP(CEmpApp, CWinApp) • Trong hộp hội thoại MFC Class Wizard, Chọn OK để kết thúc. //{{AFX_MSG_MAP(CEmpApp) // Bảng message map, Thông tin ClassWizard được lưu trong tập tin có cùng tên với tên //}}AFX_MSG_MAP // sẽ đề cập đến ở các của dự án và phần mở rộng là .CLW. END_MESSAGE_MAP() // phần sau 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: 22 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Thö vieän MFC cuûa Microsoft & öùng duïng cô baûn trong windows 23
  • 18. • Trong màn hình Workspace của dự án, chọn ClassView, right- UINT stop; // Biến kiểm tra đồng ý dừng? click trên tiêu đề của lớp CEmpApp: 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" • Chọn mục Add Virtual Function. 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. • 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() { 24 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Thö vieän MFC cuûa Microsoft & öùng duïng cô baûn trong windows 25
  • 19. Chọn mục Insert... 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 Chọn mục Icon, sau đó chọn New: resource. Ta nhận được màn hình thiết kế icon. Vẽ icon có nội dung tùy ý. 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. Ấn định các thông số 2.10 LỚP CString CỦA MFC: thuộc tính của icon (số CString là lớp đối tượng của MFC cho phép quản lý một nội dung hiệu icon, tên thư mục chuỗi trong bộ nhớ với những đặc tính ưu việt sau: và tên tập tin chứa - Nội dung chuỗi lưu trữ có độ dài lớn với cơ chế sử dụng bộ nhớ tối icon) trong dự án: Chọn ưu. ResourceView trong - Xây dựng dựa trên kiểu TCHAR nên thích nghi với bộ mã Workspace của dự án, UNICODE. rigth-click trên icon mới - Các hành vi xử lý sẵn sàng cho các tác vụ chuỗi thông thường. thêm. Một số hành vi được sử dụng phổ biến của CString như sau: Chọn mục Properties. 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. 26 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Thö vieän MFC cuûa Microsoft & öùng duïng cô baûn trong windows 27
  • 20. 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; 28 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 21. CHƯƠNG 3: Cấu trúc quản lý 1 điểm: typedef struct _POINT { Các lớp GIAO DIỆN đồ họa của MFC int x, y // Tọa độ ( hoành độ, tung độ ) của điểm } POINT ; 3.1 CÁC CÔNG CỤ GIAO DIỆN ÐỒ HỌA: Cấu trúc quản lý 1 vùng hình chữ nhật: Ðể hỗ trợ ứng dụng trong việc trang trí giao diện đồ họa (Graphic typedef struct _RECT { Device Interface - GDI) như màn hình, máy in., windows cung cấp một int top, left; // Tọa độ góc trái trên hình chữ nhật. hệ thống các công cụ đồ họa cơ bản như sau: int right, bottom; // Tọa độ góc phải dưới hình chữ nhật. Pen : Công cụ vẽ điểm hoặc đường thẳng. } RECT ; Brush : Công cụ tô màu. Cấu trúc quản lý chiều rộng và chiều cao vùng hình chữ nhật: Font : Công cụ qui định kiểu ký tự cho nội dung văn bản. typedef struct _SIZE { Bitmap : Công cụ quản lý vùng ảnh điểm. int cx, cy; // Chiều rộng, chiều cao vùng hình chữ Palette : Công cụ quản lý bộ màu hiển thị. nhật. Region : Công cụ quản lý vùng hiển thị có dạng bất kỳ. } SIZE ; Thông qua các công cụ nói trên, ứng dụng trong windows có thể thực 3.4 CÁC LỚP MFC HỖ TRỢ GDI: 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 MCF cung cấp một hệ thống phong phú các lớp với đầy đủ chức năng đế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ụ 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ỹ GDI. thuật OOP trên các lớp GDI của MFC, người dùng dễ dàng tạo ra ứng 3.2 DEVICE CONTEXT: dụng mong muốn mà không phải viết quá nhiều mã lệnh trong chương Việc khai thác khả năng của các công cụ GDI được thực hiện thông trình. qua một cấu trúc chứa thông tin quản lý thiết bị hiển thị: Device Context 3.4.1 Các lớp đối tượng điểm, hình chữ nhật: (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ị CPoint : Lớp đối tượng điểm, tương ứng với cấu trúc POINT. đồ 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 CRect : Lớp đối tượng vùng hình chữ nhật trên giao diện đồ họa, công cụ GDI mới thì DC phải chấm dứt sử dụng công cụ tương ứng mà tương ứng với cấu trúc RECT. CRect có các hành vi đặc trưng sau: nó đang dùng. • CRect( ); Tạo lập đối tượng vùng hình chữ nhật rỗ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 • CRect (int left, int top, int right, int bottom); Tạo lập đối tượng cụ GDI (trừ bitmap) mặc nhiên cho nó. Ứng dụng có thể tùy nghi thay đổi vùng hình chữ nhật có thông số xác định. các công cụ này cho phù hợp với nhu cầu của ứng dụng. • int Width( ) const; Trả về độ rộng vùng hình chữ nhật. 3.3. TỌA ÐỘ TRÊN GIAO DIỆN ÐỒ HỌA: • int Heigth( ) const; Trả về độ cao vùng hình chữ nhật. 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 • void NormalizeRect( ); Hợp lý hóa các thành phần tọa độ của độ có gốc (0,0) là góc trái-trên (top-left corner) của giao diện đồ họa, rect mà không làm thay đổi vị trí và kích thước của nó. 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 VD: Giả sử khởi tạo một rect không hợp lệ như sau: của trục tung (trục y) hướng từ trên xuống dưới. Trên mặt phẳng giao CRect rect( 100, 0, 0, 50 ); // rect.left = 100 > rect.right = 0 diện đồ họa đó: rect. NormalizeRect(); Ðiểm: Biểu diễn bằng cặp tọa độ (x,y). rect trở nên hợp lệ với: rect ( 0, 0, 100, 50 ); 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 CSize : Lớp đối tượng kích thước, tương ứng với cấu trúc SIZE. dưới. 3.4.2 Lớp CPen: Thông tin về điểm, vùng hình chữ nhật và kích thước của các đối CPen là lớp đối tượng quản lý pen, một công cụ GDI quan trọng của tượng trong mặt phẳng giao diện đồ họa được đặc tả thông qua các cấu DC. Thông qua đối tượng này, DC có thể thay đổi màu sắc, nét vẽ của trúc sau: Caùc lôùp giao dieän ñoà hoïa cuûa MFC 29 30 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 22. điểm hay đường thẳng mà DC sẽ trực hiện. CPen có các hành vi đặc 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 sau: trưng: CPen( ); Tạo lập đối tượng pen rỗng. Chúng ta phải khởi tạo tham CFont( ); Tạo lập đối tượng font rỗng. số cho đối tượng này trước khi sử dụng. CFont(const LOGFONT* lpLogFont ); Tạo lập đối tượng font với CPen ( // Tạo lập đối tượng pen với tham số thông số đầy đủ. Giá trị thông số được ấn định bởi tham số kiểu int nPenStyle, // Kiểu nét vẽ cấu trúc LOGFONT chứa thông tin. LOGFONT được khai báo như int nWidth, // Ðộ rộng nét vẽ (=1: mặc nhiên) sau: COLORREF crColor // Màu sắc của nét vẽ typedef struct tagLOGFONT { ); LONG lfHeight; // chiều cao của ký tự nPenStyle có thể nhận một trong các giá trị sau: LONG lfWidth; // chiều rộng trung bình các ký tự PS_SOLID : PS_DASH : LONG lfEscapement; // góc (1/10) giữa hướng in và trục X PS_DOT : PS_DASHDOT : LONG lfOrientation; // góc (1/10) giữa ký tự và trục X (No 9x) crColor có thể nhận giá trị từ macro phối màu RGB( ) như sau: LONG lfWeight; // mức độ đậm của font chữ (0 - 1000) RGB (int màu_đỏ , int màu_xanh_lá_cây , int màu_xanh_dương BYTE lfItalic; // = TRUE : Chữ nghiêng ) BYTE lfUnderline; // = TRUE : Chữ gạch dưới Mỗi màu được đặc trưng bằng một giá trị trong đoạn 0255 phản BYTE lfStrikeOut; // = TRUE : Chữ gạch ngang thân ánh độ sáng của nó. Bộ phối màu theo qui tắc phối màu tự BYTE lfCharSet; // bộ ký tự (=DEFAULT_CHARSET ) nhiên. BYTE lfOutPrecision; // = OUT_DEFAULT_PRECIS BOOL CreatePen( int nPenStyle, int nWidth, COLORREF crColor BYTE lfClipPrecision; // = CLIP_DEFAULT_PRECIS ); Khởi tạo thông số cho đối tượng pen. Ý nghĩa tham số như trên. BYTE lfQuality; // = DEFAULT_QUALITY operator HPEN() const; Toán tử chuyển kiểu, trả về handle của BYTE lfPitchAndFamily; // =DEFAULT_PITCH|FF_DONTCARE pen (HPEN) quản lý bởi đối tượng. TCHAR lfFaceName[LF_FACESIZE]; // Chuỗi tên của font 3.4.3 Lớp CBrush: } LOGFONT ; CBrush là lớp đối tượng quản lý brush, công cụ GDI của DC. Thông Win9x chỉ dùng lfEscapement. qua đối tượng này, DC có thể thay đổi màu sắc, dạng của nét tô trong int GetLogFont( LOGFONT * pLogFont ); Lấy thông tin của font một vùng hình chữ nhật mà DC sẽ trực hiện. CBrush có các hành vi đặc quản lý bởi đối tượng font chữ. Kết quả được điền vào biến kiểu trưng sau: LOGFONT chỉ bởi tham số kiểu con trỏ LOGFONT* : pLogFont. CBrush( ); Tạo lập đối tượng brush rỗng. operator HFONT( ); Toán tử chuyển kiểu, trả về handle của font CBrush( COLORREF crColor ); Tạo lập đối tượng brush có màu tô được quản lý bởi đối tượng. tương ứng với màu qui định bởi tham số crColor. BOOL CreateFontIndirect( LOGFONT *lpLogFont ); Khởi tạo thông CBrush( int nIndex, COLORREF crColor ); Tạo lập đối tượng brush số cho đối tượng font từ thông tin lưu trong cấu trúc chỉ bởi có màu tô crColor, và nét tô nIndex. lpLogFont. Giá trị nét tô có thể là: HS_VERTICAL (đường kẻ sọc đứng), 3.4.5 Lớp CBitmap: HS_HORIZAONTAL (đường kẻ sọc ngang). CBitmap là lớp đối tượng quản lý bitmap, một công cụ GDI quan trọng BOOL CreateSolidBrush( COLORREF crColor ); Tạo đặc tính tô giúp quản lý vùng ảnh điểm (pixels) của DC. Thông qua đối tượng này, đặc với màu crColor cho đối tượng brush chưa có thông số. DC có thể dễ dàng tạo nội dung trang trí trên giao diện đồ họa từ nội operator HBRUSH() const; Toán tử chuyển kiểu, trả về handle của 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ử brush (HBRUSH) quản lý bởi đối tượng. lý ảnh cơ bản trên nội dung đó. CBitmap cung cấp các hành vi đặc trưng 3.4.4 Lớp CFont: sau: CFont là lớp đối tượng quản lý font, công cụ GDI của DC. Thông qua CBitmap( ); Tạo lập đối tượng bitmap rỗng. đố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ý Caùc lôùp giao dieän ñoà hoïa cuûa MFC 31 32 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 23. BOOL LoadBitmap( UINT nIDResource ); Tạo nội dung cho đối Mỗi phần tử của palPalEntry có kiểu PALETTEENTRY phản ánh tượng bitmap với thông tin được lấy từ một ảnh trong resource. giá trị màu dùng hiển thị màu chỉ mục (color index) tương ứng với vị nIDResource : số hiệu của ảnh bitmap trong resource của chương trí thứ tự của nó. Cấu trúc PALETTEENTRY có nội dung như sau: trình. BOOL CreateCompatibleBitmap ( typedef struct tagPALETTEENTRY { CDC* pDC, // Con trỏ đối tượng DC tương ứng BYTE peRed ; // Giá trị thành phần màu đỏ int nWidth, // Chiều rộng, BYTE peGreen ; // Giá trị thành phần màu xanh lá cây int nHeight // chiều cao tính bằng pixel của bitmap được tạo. BYTE peBlue ; // Giá trị thành phần màu xanh dương ); Tạo nội dung cho đối tượng bitmap với thông tin về màu sắc, độ BYTE peFlags ; // Vai trò màu trong hệ thống. phân giải tương ứng với DC chỉ bởi con trỏ tham số pDC. } PALETTEENTRY; int GetBitmap( BITMAP* pBitMap ); Lấy thông tin về bitmap được operator HPALETTE( ) const; Toán tử chuyển kiểu, trả về handle quản lý bởi đối tượng. Kết quả nhận được sẽ được điền vào biến có của palette quản lý bởi đối tượng. kiểu BITMAP chỉ bởi tham số kiểu con trỏ BITMAP* : pBitmap. 3.4.7 Lớp CRgn: Cấu trúc BITMAP bao gồm các trường có ý nghĩa như sau: CRgn là lớp đối tượng quản lý region, một công cụ GDI quan trọng typedef struct tagBITMAP { /* bm */ giúp DC ấn định vùng ảnh xử lý có hình dạng tùy ý trên giao diện đồ họa int bmType ; // Kiểu bitmap, của nó. int bmWidth ; // Chiều rộng bitmap tính bằng pixel CRgn( ); Tạo lập đối tượng vùng ảnh rỗng. int bmHeight ; // Chiều cao bitmap tính bằng pixel BOOL CreateRectRgn( int x1, int y1, int x2, int y2 ); Khởi tạo thông int bmWidthBytes ; // Kích thước 1 dòng pixel trong bitmap số cho đối tượng vùng ảnh bằng 1 hình chữ nhật với tọa độ góc trái BYTE bmPlanes ; // Số màu. trên và góc phải dưới lần lượt là (x1, y1) và (x2, y2). BYTE bmBitsPixel ; // Số bit màu của 1 pixel BOOL CreateEllipticRgn( int x1, int y1, int x2, int y2 ); Khởi tạo LPVOID bmBits ; // Ðịa chỉ vùng nhớ chứa pixel của thông số cho đối tượng vùng ảnh bởi hình ellipse nội tiếp hình chữ bitmap nhật có góc trái trên (x1, y1) và góc phải dưới (x2, y2). } BITMAP; BOOL CreatePolygonRgn ( operator HBITMAP() const; Toán tử chuyển kiểu, trả về handle của LPPOINT lpPoints, // Mảng chứa tọa độ các điểm ziczac bitmap được quản lý bởi đối tượng. int nCount, // Số phần tử POINT trong mảng trên int nMode // = WINDING 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. Khởi tạo thông số cho đối tượng vùng ảnh bởi một đường ziczac Thông qua đối tượng này, DC có thể tạo ra các hiệu ứng màu trên giao khép kín qua các điểm có tọa độ xác định và được lưu trong một diện đồ họa bằng cách thay đổi các bộ màu một cách phù hợp. mảng. CPalette( ); Tạo lập đối tượng palette rỗng. int CombineRgn ( CreatePalette( LPLOGPALETTE lpLogPalette ); Khởi tạo thông số CRgn* pRgn1, // Con trỏ đối tượng quản lý vùng ảnh thứ nhất cho đối tượng palette rỗng. Con trỏ tham số lpLogPalette chỉ đến CRgn* pRgn2, // Con trỏ đối tượng quản lý vùng ảnh thứ hai biến kiểu cấu trúc LOGPALETTE chứa thông tin bộ màu dùng khởi int nCombineMode // Cách kết hợp hai vùng ảnh tạo. ); Tạo thông số cho đối tượng vùng ảnh trên cơ sở kết hợp hai vùng typedef struct tagLOGPALETTE { ảnh đã có. Tham số nCombineMode có thể là: WORD palVersion; // Số hiệu palette hệ thống RGN_AND : Vùng ảnh kết quả là vùng giao nhau giữa hai vùng WORD palNumEntries; // Số màu sử dụng ảnh. PALETTEENTRY palPalEntry[1]; // Chứa các giá trị màu, RGN_OR : Vùng ảnh kết quả là vùng hợp giữa hai vùng ảnh. // có số phần tử mảng bằng palNumEntries RGN_DIFF : Vùng ảnh kết quả là vùng bù giữa hai vùng ảnh. } LOGPALETTE ; Caùc lôùp giao dieän ñoà hoïa cuûa MFC 33 34 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 24. operator HRGN() const; Toán tử chuyển kiểu, trả về handle của UINT nFormat // Chứa thông tin canh chỉnh chuỗi hiển vùng ảnh quản lý bởi đối tượng. thị. ); In nội dung chuỗi lên giao diện đồ họa của DC với các canh 3.5 LỚP CDC: chỉnh. 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 đồ lpRect : Chỉ đến biến kiểu RECT chứa thông tin giới hạn vùng hiển thị. 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. 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à: virtual BOOL CreateCompatibleDC( CDC* pDC ); Khởi tạo thông DT_CENTER : Chỉnh giữa theo chiều ngang số cho đối tượng DC một cách tương thích với một DC có sẵn được DT_VCENTER : Chỉnh giữa theo chiều dọc chỉ bởi con trỏ tham số pDC. DT_RIGHT : Chỉnh phải. virtual BOOL DeleteDC( ); Hủy bỏ đối tượng DC. CPoint MoveTo( int x, int y ); Ấn định điểm vẽ hiện hành. CPen* SelectObject( CPen* pPen ); Chọn công cụ vẽ mới cho DC. BOOL LineTo( int x, int y ); Vẽ đường thẳng từ điểm vẽ hiện hành pPen : con trỏ đến đối tượng pen sẽ được dùng cho DC. đến điểm có tọa độ (x, y). Hàm trả về con trỏ chỉ đến đối tượng pen mà DC đang sử dụng. void FillRect ( Có thể sử dụng hành vi này cho các công cụ trang trí khác của LPCRECT lpRect, // Con trỏ chỉ đến biến kiểu RECT. DC. Kết quả trả về là con trỏ đến đối tượng đang dùng tương ứng. CBrush* pBrush // Con trỏ đến đối tượng brush dùng tô màu. CPent* GetCurrentPen( ); Trả về giá trị con trỏ của đối tượng pen ); Tô màu vùng hình chữ nhật được xác định bởi các giá trị chứa đang được sử dụng bởi DC. trong biến kiểu RECT do tham số lpRect chỉ đến. Một cách tương tự cho các công cụ trang trí khác. void Draw3dRect ( // Vẽ hình chữ nhật 3 chiều virtual COLORREF SetBkColor( COLORREF crColor ); Ðặt màu LPCRECT lpRect, // Con trỏ đến biến RECT nền cho DC. crColor là giá trị màu đặt. COLORREF clrTopLeft, // Màu vẽ cạnh trái và cạnh trên. COLORREF GetBkColor( ); Trả về giá trị màu nền của DC. COLORREF clrBottomRight // Màu vẽ cạnh phải và cạnh dưới 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. BOOL DrawEdge ( COLORREF GetTextColor( ); Trả về giá trị màu hiện dùng để hiển LPRECT lpRect, // Con trỏ đến biến kiểu RECT. thị các nội dung văn bản trên DC. UINT nEdge, // Cách vẽ trên các gờ (trong, ngoài) cạnh. int SetBkMode ( int nBkMode ); Ấn định chế độ hiển thị nền ký tự UINT nFlags // Các cạnh được vẽ. biểu diễn nội dung văn bản. nbkMode chứa thông số ấn định: ); Vẽ khung chữ nhật với hiệu ứng 3 chiều. TRANSPARENT : Nền chữ hiển thị trong suốt. OPAQUE : Chữ hiển thị có màu nền. nEdge có thể kết hợp các giá trị sau: BDR_RAISEDINNER : Vẽ nổi gờ trong int GetBkMode( ); Lấy chế độ hiển thị chữ của DC. BDR_SUNKENINNER : Vẽ chìm gờ trong virtual BOOL TextOut ( BDR_RAISEDOUTER : Vẽ nổi gờ ngoài int x, y , // Tọa độ bắt đầu hiển thị BDR_SUNKENOUTER : Vẽ chìm gờ ngoài LPCTSTR lpszString, // Nội dung chuỗi hiển thị. int nCount // Chiều dài chuỗi. nFlags có thể kết hợp các giá trị sau: BF_RECT : Vẽ tất cả các cạnh ); Hiển thị nội dung chuỗi văn bản lên giao diện đồ họa của DC. BF_TOPLEFT : Vẽ cạnh trái và cạnh trên virtual int DrawText ( BF_BOTTOMRIGHT : Vẽ cạnh phải và cạnh dưới LPCTSTR lpszString, // Nội dung chuỗi hiển thị BOOL DrawState ( int nCount, // Chiều dài chuỗi CPoint pt, // Ðiểm đặt góc trái trên của ảnh trên DC LPRECT lpRect, // Con trỏ đến biến kiểu RECT CSize size, // Kích thước vùng hiển thị ảnh CBitmap* pBitmap, // Con trỏ đối tượng bitmap được vẽ Caùc lôùp giao dieän ñoà hoïa cuûa MFC 35 36 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 25. UINT nFlags, // = DST_BITMAP (vẽ bitmap) DWORD dwRop // Cách chụp pixel từ ảnh nguồn. CBrush* pBrush // Con trỏ đối tượng Brush, sử dụng khi vẽ ); Tương tự BitBlt nhưng ảnh đích và ảnh nguồn có thể có kích // Bitmap ẩn: nFlags |= DSS_DISABLED thước khác nhau nên tạo hiệu ứng co dãn ảnh chép được so với ); Vẽ bitmap hoặc icon lên DC. ảnh nguồn. BOOL BitBlt ( BOOL DrawIcon ( int x, int y, // Tọa độ góc trái trên và int x, int y, // Tọa độ góc trái trên nơi đặt icon trên DC int nWidth, int nHeight, // kích thước vùng nhận ảnh. HICON hIcon // Handle của icon CDC* pSrcDC, // Con trỏ đối tượng quản lý DC nguồn. ); Vẽ icon hIcon lên vị trí (x, y) của DC quản lý bởi đối tượng. int xSrc, int ySrc, // Góc trái trên phần ảnh nguồn được 3.6 LỚP CImagelist: chép. CImageList là lớp đối tượng imagelist. Mỗi imagelist cho phép quản lý DWORD dwRop // Cách chụp pixel từ ảnh nguồn. danh sách ảnh có cùng kích thước và hỗ trợ nhiều tiện ích trên chúng. ); Chụp nội dung phần ảnh bắt đầu từ vị trí (xSrc,ySrc) trong DC CImageList( ); Tạo lập đối tượng imagelist rỗng. nguồn sang vùng nhận ảnh bắt đầu từ vị trí (x, y), với kích thước BOOL Create ( (nWidth, nHeight) trong DC quản lý bởi đối tượng. UINT nBitmapID, // Số hiệu của resource bitmap chứa các Giá trị pixel được chuyển vào vùng nhận ảnh tùy thuộc vào giá trị ảnh tham số dwRop. Một số giá trị dùng cho tham số này có thể như int cx, // Ðộ rộng mỗi ảnh trong bitmap nói trên sau: int nGrow, // Số ảnh trong bitmap • SRCCOPY : Giá trị pixel lấy trực tiếp từ pixel của ảnh nguồn. COLORREF crMask // Màu mặt nạ (không hiển thị) • SRCPAINT : Là kết quả OR của pixel ảnh nguồn và ảnh nhận. ); Khởi tạo nội dung cho đối tượng từ một bitmap trong resource. • SRCAND : Là kết quả AND của pixel ảnh nguồn và ảnh int GetImageCount( ); Số ảnh của imagelist quản lý bởi đối tượng. nhận. int Add ( BOOL MaskBlt ( CBitmap* pbmImage, // Con trỏ đối tượng bitmap của ảnh int x, int y, // Tọa độ góc trái trên và mới. int nWidth, int nHeight, // Kích thước vùng nhận ảnh CBitmap* pbmMask | // Ðối tượng bitmap mặt nạ hoặc CDC* pSrcDC, // Con trỏ đối tượng quản lý DC nguồn [ COLORREF crMask ] // màu mặt nạ của ảnh mới. int xSrc, int ySrc, // Góc trái trên phần ảnh được chép ); Thêm một ảnh (bitmap) vào imagelist. CBitmap& maskBitmap, // Con trỏ đối tượng bitmap mặt nạ BOOL BeginDrag( int nImage, CPoint ptHotSpot ); Chuẩn bị int xMask, int yMask, // Góc trái trên vùng ảnh làm mặt nạ chuyển ảnh thứ nImage trong imagelist với vị trí bắt đầu ptHotSpot. DWORD dwRop // Cách chụp pixel từ ảnh nguồn. static BOOL DragEnter( CWnd* pWndLock, CPoint point ); Cấm ); Tương tự BitBlt nhưng sử dụng mặt nạ lọc pixel. Ðối tượng cửa sổ pWndLock, nơi mà imagelist đang thực hiện chuyển ảnh. maskBitmap sử dụng ảnh trắng đen (monochrome bmp) mà mỗi static BOOL DragMove(CPoint pt); Chuyển ảnh nImage đến vị trí pixel "đen" sẽ ngăn việc chuyển pixel ở vị trí tương ứng từ DC pt. nguồn sang DC quản lý bởi đối tượng, các vị trí khác được chuyển static BOOL DragLeave( CWnd* pWndLock ); Chấm dứt tình trạng bình thường. bị cấm của cửa sổ pWndLock. BOOL StretchBlt ( static void EndDrag( ); Chấm dứt tác vụ chuyển ảnh. int x, int y, // Tọa độ góc trái trên và static BOOL DragShowNolock( BOOL bShow ); Hiển thị hoặc che int nWidth, int nHeight, // Kích thước vùng nhận ảnh. ảnh trong quá trình chuyển hình. CDC* pSrcDC, // Con trỏ đối tượng DC nguồn. BOOL Draw ( int xSrc, int ySrc, // Tọa độ góc trái trên và CDC* pdc, // Ðối tượng DC dùng vẽ hình int nSrcWidth, int nSrcHeight, // Kích thước phần ảnh được int nImage, // Số thứ tự hình được vẽ trong imagelist chép. POINT pt, // Tọa độ góc trái trên nơi vẽ hình Caùc lôùp giao dieän ñoà hoïa cuûa MFC 37 38 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 26. 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( ); Caùc lôùp giao dieän ñoà hoïa cuûa MFC 39
  • 27. CHƯƠNG 4: 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. Cửa sổ giao diện và lớp CWnd WS_MAXIMIZEBOX : Có hộp phóng to trên caption của cửa sổ. 4.1 CỬA SỔ GIAO DIỆN: WS_MINIMIZEBOX : Có hộp thu nhỏ trên caption của cửa sổ. Cửa sổ giao diện là thành phần quan trọng của ứng dụng. Nó không WS_THICKFRAME : Viền cho phép thay đổi kích thước cửa chỉ đóng vai trò trung gian trong trao đổi thông tin giữa ứng dụng với sổ. người dùng bởi giao diện đồ họa dễ nhìn mà còn là công cụ xử lý WS_VISIBLE : Cửa sổ nhìn thấy được (hiển thị). message hiệu quả và không thể thiếu cho cơ chế điều phối message của Ví dụ: WS_POPUP | WS_CAPTION : Cửa sổ chính có tiêu đề. ứng dụng windows. lpszClassName là một tên đã đăng ký cho lớp cửa sổ. Ngoài các Bên cạnh đó, cửa sổ giao diện còn làm chức năng nhận diện ứng tên mà windows đã đăng ký như STATIC, BUTTON, EDIT, ... dụng, là thẻ thông hành cho ứng dụng trong hành trình tồn tại, hoạt động (chương 8), ta có thể đăng ký tên lớp cửa sổ riêng của mình một độ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 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 windows. trong hai cách sau: 4.2 LỚP CWnd: • Ðăng ký trực tiếp: CWnd là lớp đối tượng quản lý cửa sổ của windows. Thông qua các LPCTSTR AFXAPI AfxRegisterWndClass ( 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 UINT nClassStyle, // Thông số dạng của cửa sổ 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 HCURSOR hCursor = 0, // Cursor hiển thị trong cửa sổ cách dễ dàng. HBRUSH hbrBackground = 0, // Brush dùng tô nền cửa sổ HWND m_hWnd : Thuộc tính lưu handle của cửa sổ. HICON hIcon = 0 // Icon trên tiêu đề của cửa sổ CWnd( ); Hành vi tạo lập đối tượng cửa sổ. ); Trả về chuỗi tên lớp cửa sổ được đăng ký. Các lần đăng ký virtual BOOL Create ( tên lớp cửa sổ có tham số giống nhau sẽ nhận được một tên duy LPCTSTR lpszClassName, // Tên đăng ký của lớp cửa sổ nhất. LPCTSTR lpszWindowName, // Tên cửa sổ. Tham số nClassStyle có thể kết hợp từ các giá trị sau: DWORD dwStyle, // Các thông số về dạng cửa sổ CS_HREDRAW : Cửa sổ được vẽ lại khi chiều rộng thay đổi. const RECT& rect, // Qui định vị trí, kích thước cửa sổ CS_VREDRAW : Cửa sổ được vẽ lại khi chiều cao thay đổi. CWnd* pParentWnd, // Con trỏ đối tượng cửa sổ cha CS_NOCLOSE : Cấm hộp đóng [] trên tiêu đề của cửa sổ. UINT nID, // Số hiệu cửa sổ Ví dụ: Ðăng ký lớp cửa sổ có nền màu xanh dương. CCreateContext* pContex = NULL CString myClassName; ); Khởi tạo thông số cho cửa sổ quản lý bởi đối tượng. CBRUSH myBrush; Tham số dwStyle qui định đặc điểm và kiểu dáng cửa sổ. Giá trị myBrush.CreateSolidBrush( RGB ( 0, 0, 255 ) ); dùng cho tham số này có thể kết hợp một số trong các giá trị sau: myClassName = AfxRegisterWndClass ( WS_POPUP : Cửa sổ được tạo là cửa sổ chính. CS_VREDRAW | CS_HREDRAW, WS_CHILD : Cửa sổ được tạo là cửa sổ con. NULL, myBrush, NULL ); WS_TABSTOP : Cửa sổ con, chuyển được bằng phím tab. WS_OVERLAPPED : Cửa sổ chính. • Ðăng ký qua cấu trúc chứa các thông số: WS_SYSMENU : Cửa sổ có hộp menu hệ thống. BOOL AFXAPI AfxRegisterClass( WNDCLASS* lpWndClass ); WS_BORDER : Cửa sổ có viền. Hàm trả về giá trị TRUE nếu tác vụ đăng ký thành công. Thực WS_CAPTION : Cửa sổ có tiêu đề (caption) hiện đăng ký theo cách này tránh được sự dùng chung tên lớp WS_DISABLED : Cửa sổ bị cấm. cửa sổ ở hai ứng dụng khác nhau khi hai ứng dụng này tình cờ WS_DLGFRAME : Cửa sổ có viền đậm kiểu hộp thoại, đăng ký các tên lớp cửa sổ giống nhau về thông số. 40 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Cöûa soå giao dieän vaø lôùp CWnd 41
  • 28. lpWndClass là con trỏ chỉ đến biến có kiểu cấu trúc LPVOID lpCreateParams; // Con trỏ vùng chứa thông số cửa WNDCLASS. sổ typedef struct _WNDCLASS { HANDLE hInstance; // Handle của ứng dụng UINT style; // Dạng của lớp đăng ký HMENU hMenu; // Handle của menu gắn với cửa sổ WNDPROC lpfnWndProc; // Con trỏ hàm WindowProc của HWND hwndParent; // Handle của cửa sổ cha // cửa sổ. Có thể lấy hàm do int cy; int cx; // Chiều rộng và cao của cửa sổ MFC int y; int x; // Tọa độ góc trái trên của cửa sổ // khai báo sẵn: AfxWndProc LONG style; // Thông số ấn định dạng cửa sổ int cbClsExtra; // Dành riêng của hệ thống LPCSTR lpszName; // Tên cửa sổ được tạo int cbWndExtra; // Dành riêng của hệ thống LPCSTR lpszClass; // Tên lớp cửa sổ dùng cho cửa sổ HINSTANCE hInstance; // Instance handle của ứng DWORD dwExStyle; // Thông số ấn định dạng mở rộng dụng } CREATESTRUCT; HICON hIcon; // Handle của icon Trong các lớp kế thừa CWnd, hành vi này được dùng để can HCURSOR hCursor; // Handle của cursor 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 HBRUSH hbrBackground; // Handle của brush vẽ nền sổ. LPCTSTR lpszMenuName; // Chuỗi tên menu trong BOOL EnableWindow( BOOL bEnable = TRUE ); Cho phép hoặc resource cấm hoạt động của cửa sổ. LPCTSTR lpszClassName; // Tên lớp cửa sổ đăng ký BOOL ShowWindow( int nCmdShow ); Ấn định trạng thái hiển thị } WNDCLASS; của cửa sổ trên màn hình. Giá trị cho tham số nCmdShow có thể BOOL CreateEx ( là: DWORD dwExStyle, // Các thông số dạng mở rộng SW_HIDE : Dấu cửa sổ LPCTSTR lpszClassName, // Tên lớp SW_MINIMIZE : Thu nhỏ cửa sổ LPCTSTR lpszWindowName, // Tên cửa sổ SW_RESTORE : Ðưa cửa sổ về trạng thái trước đó DWORD dwStyle, // Dạng cửa sổ SW_SHOW : Hiển thị cửa sổ int x, int y, // Tọa độ góc trái trên của cửa sổ SW_SHOWNA : Hiển thị nhưng không kích hoạt cửa int nWidth, int nHeight, // Chiều rộng và cao của cửa sổ sổ HWND hwndParent, // Handle của cửa sổ cha SW_SHOWMAXIMIZED : Hiển thị và phóng to cửa sổ HMENU nIDorHMenu, // Handle của menu gắn với cửa sổ SW_SHOWMINIMIZED : Hiển thị và thu nhỏ cửa sổ LPVOID lpParam = NULL BOOL SetWindowPos ( ); 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. const CWnd* pWndInsertAfter, // Con trỏ cửa sổ làm mốc Tham số dwExStyle qui định dạng mở rộng của cửa sổ có thể kết int x, int y, // Tọa độ góc trái trên của cửa sổ hợp từ các giá trị sau: int cx, int cy, // Kích thước cửa sổ WS_EX_TOPMOST : Cửa sổ không bị che khuất. UINT nFlags // Thông số trạng thái WS_EX_TOOLWINDOW : Cửa sổ không hiển thị trên taskbar. ); Ấn định vị trí cửa sổ trên màn hình. WS_EX_TRANSPARENT : Cửa sổ có nền trong suốt. Giá trị pWndInsertAfter qui định vị trí đặt cửa sổ theo chiều thứ 3 WS_EX_CLIENTEDGE : Cửa sổ có gờ quanh vùng client. (z-order). Giá trị này có thể như sau: virtual BOOL PreCreateWindow( CREATESTRUCT& cs ); Hành vi wndBottom : Cửa sổ được đặt dưới mọi cửa sổ. được thực hiện trước khi windows khởi tạo thông số cho cửa sổ. wndTop : Cửa sổ được đặt trên các cửa sổ thông thường. Tham biến cs kiểu CREATESTRUCT chứa thông số khởi tạo. 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ổ: typedef struct tagCREATESTRUCT { SWP_SHOWWINDOW : Hiển thị cửa sổ. 42 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Cöûa soå giao dieän vaø lôùp CWnd 43
  • 29. SWP_DRAWFRAME : Vẽ lại frame của cửa sổ. BOOL bRedraw = TRUE // Vẽ lại cửa sổ sau tác vụ đặt font ? SWP_NOREDRAW : Không cập nhật lại thông tin cửa sổ. ); Ấn định font chữ cho cửa sổ. void MoveWindow ( CMenu* GetMenu( ); Trả về con trỏ đối tượng menu gắn với cửa int x, int y, // Tọa độ mới cho góc trái trên sổ. int nWidth, int nHeight, // Chiều rộng và chiều cao của cửa sổ BOOL SetMenu( CMenu* pMenu ); Gắn menu cho cửa sổ. BOOL bRepaint = TRUE // Yêu cầu windows vẽ lại cửa sổ CWnd* GetParent( ); Trả về con trỏ đến đối tượng cửa sổ cha. ); Thay đổi vị trí và kích thước của cửa sổ. int GetScrollPos( int nBar ); Trả về vị trí hiện hành của nút cuộn void GetWindowRect( LPRECT lpRect ); Lấy thông tin tọa độ, kích trên thanh cuộn. nBar chứa số hiệu thanh cuộn quan tâm. nBar có thước của cửa sổ, lpRect chỉ đến biến kiểu RECT chứa kết quả. thể là: void GetClientRect( LPRECT lpRect ); Lấy thông tin tọa độ, kích SB_HORZ : Thanh cuộn ngang. thước vùng client của cửa sổ, lpRect chỉ đến biến RECT chứa kết SB_VERT : Thanh cuộn dọc. quả. int SetScrollPos ( int GetWindowRgn(HRGN hRgn); Xác định vùng hiển thị của cửa int nBar, // Thanh cuộn được chọn sổ. int nPos, // Vị trí đặt int SetWindowRgn ( BOOL bRedraw = TRUE // Vẽ lại thanh cuộn sau tác vụ đặt HRGN hRgn, // Handle của region quản lý vùng ấn định ); Ðặt vị trí nút cuộn cho thanh cuộn tương ứng. BOOL bRedraw // Vẽ lại cửa sổ (TRUE) hay không (FALSE) UINT SetTimer ( ); Ấn định vùng hiển thị của cửa sổ theo dạng của region. UINT nIDEvent, // Số hiệu của timer, phân biệt duy nhất void GetWindowText( CString rString ); Lấy nội dung chuỗi tiêu đề UINT nElapse, // Chu kỳ timer (tính bằng mili-second) của cửa sổ và lưu vào biến đối tượng chuỗi rString. NULL // Sử dụng hành vi OnTimer xử lý timer int GetWindowTextLength( ); Trả về chiều dài của chuỗi tiêu đề. ); Ðặt biến cố định thời (timer) cho cửa sổ quản lý bởi đối tượng. void ClientToScreen( LPPOINT lpPoint / LPRECT lpRect ); Mỗi khi hết một chu kỳ của timer, hệ thống gửi WM_TIMER kèm Chuyển tọa độ điểm hay vùng hình chữ nhật trong client của cửa theo số hiệu của timer đó đến cho cửa sổ. sổ sang hệ trục tọa độ của màn hình. BOOL KillTimer( int nIDEvent ); Hủy bỏ timer có số hiệu nIDEvent. void ScreenToClient( LPPOINT lpPoint / LPRECT lpRect ); afx_msg void OnTimer( UINT nIDEvent ); Hành vi xử lý WM_TIMER Chuyển tọa độ điểm hay vùng hình chữ nhật trên màn hình sang của cửa sổ. Tham số nIDEvent chứa số hiệu của timer liên quan. hệ trục tọa độ của vùng client trong cửa sổ. void Invalidate( BOOL bErase = TRUE ); Kích hoạt cơ chế vẽ lại HICON GetIcon( BOOL bBigIcon ); Trả về handle của icon mà cửa vùng client của cửa sổ. Nếu bErase = FALSE, windows không thực sổ đang sử dụng. Giá trị tham số bBigIcon có ý nghĩa như sau: hiện xóa thông tin trong vùng cần vẽ lại. TRUE : Handle của icon hiển thị trên taskbar (big Icon) void InvalidateRect( LPCRECT lpRect, BOOL bErase = TRUE ); FALSE : Handle của icon hiển thị trên caption (small Icon) Kích hoạt cơ chế vẽ lại một vùng trong client của cửa sổ. Thông tin HICON SetIcon ( 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 HICON hIcon, // handle của icon RECT chỉ bởi lpRect. Tham số bErase có ý nghĩa như Invalidate. BOOL bBigIcon // TRUE (đặt bigIcon) , FALSE (đặt smallIcon) int MessageBox ( ); Ðặt icon mới cho cửa sổ. LPCTSTR lpszText, // Nội dung thông báo static CWnd* PASCAL GetFocus( ); Trả về con trỏ chỉ đến đối LPCTSTR lpszCaption = NULL // Tiêu đề hộp thông báo tượng CWnd đang được phép nhận thông tin nhập từ bàn phím. UINT nType = MB_OK // Dạng hộp thông báo CWnd* SetFocus( ); Kích hoạt cửa sổ. Hàm trả về con trỏ của đối ); Hiển thị hộp thông báo và trả về số hiệu của nút được chọn. tượng CWnd đã được kích hoạt trước đó. LRESULT SendMessage ( CFont* GetFont( ); Trả về đối tượng font chữ của cửa sổ. UINT message, // Số hiệu message void SetFont ( WPARAM wParam = 0, // Tham số kiểu WORD CFont* pFont, // Con trỏ đến đối tượng font chữ LPARAM lParam = 0 // và kiểu LONG kèm theo message 44 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Cöûa soå giao dieän vaø lôùp CWnd 45
  • 30. ); Gửi message và tham số kèm theo đến hàm WindowProc của MK_SHIFT : Phím SHIFT được nhấn kèm theo cửa sổ quản lý bởi đối tượng, và chờ đến khi hàm WindowProc xử afx_msg void OnLButtonDown( UINT nFlags, CPoint point ); Hành lý xong. vi xử lý WM_LBUTTONDOWN, message do windows gửi đến cửa BOOL PostMessage( UINT message, sổ khi người dùng ấn nút chuột trái. Các thông tin như trên. WPARAM wParam = 0, LPARAM lParam=0 afx_msg void OnLButtonUp( UINT nFlags, CPoint point ); Hành vi ); Ðặt message và các tham số kèm theo vào message queue của xử lý WM_LBUTTONUP, message do windows gửi đến cửa sổ khi ứng dụng. Hành vi kết thúc mà không chờ message đó được xử lý. người dùng nhả nút chuột trái. Các thông tin như trên. afx_msg void OnSize( UINT nType, int cx, int cy ); Hành vi xử lý Một cách tương tự cho các hành vi xử lý message của nút chuột WM_SIZE, message do windows gửi đến cửa sổ khi một tác vụ phải. 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 afx_msg void OnMouseMove( UINT nFlags, CPoint point ); Hành cửa sổ. vi xử lý WM_MOUSEMOVE, message do windows gửi đến cửa sổ afx_msg int OnCreate( LPCREATESTRUCT lpCreateStruct ); khi người dùng di chuyển chuột trong cửa sổ. Các thông tin như Hành vi xử lý WM_CREATE, message do windows gửi đến cửa sổ trên. khi tác vụ khởi tạo thông số cho cửa sổ được thực hiện xong. int GetDlgCtrlID( ); Trả về số hiệu của đối tượng cửa sổ con. afx_msg void OnClose( ); Hành vi xử lý WM_CLOSE, message do afx_msg void OnPaint( ); Hành vi xử lý WM_PAINT, message do windows gửi đến cửa sổ khi tác vụ đóng cửa sổ đang xảy ra. windows gửi đến cửa sổ khi hệ thống hoặc ứng dụng có nhu cầu afx_msg void OnDestroy( ); Hành vi xử lý WM_DESTROY, trang trí lại một phần hay toàn bộ giao diện của cửa sổ. message do windows gửi đến cửa sổ khi tác vụ hủy bỏ 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 đang xảy ra. trì trên bề mặt giao diện của cửa sổ. Ðể thực hiện việc này, afx_msg void OnKeyDown ( OnPaint sử dụng một đối tượng CDC và dùng nó cho các thao tác UINT nChar, // Mã phím đồ họa cần thiết nhằm hoàn thành yêu cầu nói trên. UINT nRepCnt, // Số lần gõ phím Bố cục xử lý thông thường của hành vi OnPaint như sau: 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 PAINTSTRUCT ps ; // Biến chứa thông tin trang trí cửa sổ khi cửa sổ đang được kích hoạt, đồng thời có phím vừa được CDC* pDC = BeginPaint(&ps); // Lấy DC của giao diện cửa sổ ấn xuống mà không có sự sử dụng phím Alt kèm theo. . // Xử lý trang trí giao diện đồ họa afx_msg void OnKeyUp ( // Các tham số tương tự như trên EndPaint(&ps); // Chấm dứt. UINT nChar, UINT nRepCnt , UINT nFlags afx_msg void OnHScroll ( ); Hành vi xử lý WM_KEYUP. Một cách tương tự WM_KEYDOWN. UINT nSBCode, // Số hiệu ghi nhận đặc điểm tác động afx_msg void OnChar ( UINT nPos, // Vị trí nút cuộn / nút trượt trên mục UINT nChar , // Mã ASCII CScrollBar* pScrollBar // Con trỏ đối tượng quản lý mục UINT nRepCnt , // Số lần gõ ); Hành vi xử lý WM_HSCROLL, message do windows gửi đến cửa UINT nFlags // Trạng thái các phím kèm theo sổ khi có một mục là thanh cuộn hay thanh trượt đặt ngang ); Hành vi xử lý WM_CHAR, message do windows gửi đến cửa sổ (horizontal scrollbar hoặc horizontal sliderCtrl) trong cửa sổ bị tác khi một phím ký tự được gõ. động. afx_msg void OnLButtonDblClk ( nSBCode ghi nhận đặc điểm tác động lên nút cuộn / trượt như sau: UINT nFlags, // Chứa giá trị phím được nhấn kèm SB_LEFT : Giảm nút về vị trí thấp nhất CPoint point // Vị trí double-click chuột SB_ENDSCROLL : Chấm dứt tác vụ chuyển nút ); Hành vi xử lý WM_LBUTTONDBLCLK, message do windows gửi SB_LINELEFT : Giảm nút một vị trí đến cửa sổ khi người dùng double-click vào nút chuột trái. SB_LINERIGHT : Tăng nút một vị trí Tham số nFlag có thể là kết hợp của các giá trị sau: SB_PAGELEFT : Giảm nút một đoạn MK_CONTROL : Phím CTRL được nhấn kèm theo 46 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Cöûa soå giao dieän vaø lôùp CWnd 47
  • 31. SB_PAGERIGHT : Tăng nút một đoạn • Ðặt điểm chỉ (hotpot) của cursor: Trong màn hình thiết kế SB_RIGHT : Tăng nút đến vị trí cao nhất cursor: SB_THUMBPOSITION : Chuyển nút bằng chuột SB_THUMBTRACK : Ðang chuyển nút bằng chuột . - Click chọn biểu tượng trên thanh công cụ. nPos được sử dụng trong các tác vụ định vị nút tuyệt đối ( ). - Click tại vị trí hotpot của cursor trên màn hình thiết kế. Dùng hành vi GetDlgCtrlID của đối tượng chỉ bởi pScrollBar để Dùng đối tượng CWnd làm cửa sổ giao diện chính của ứng dụng: xác định số hiệu của mục phát sinh message WM_HSCROLL. Ðược thực hiện bởi hành vi InitInstance (xem 2.4) của đối tượng Ðây là cơ sở giúp phân biệt mục này với các mục khác trong CEmpApp quản lý tiểu trình chính. Kế thừa hành vi này từ cùng cửa sổ giao diện nhằm lựa chọn xử lý thích hợp cho CWinApp cho lớp CEmpApp (xem 2.7). Nội dung cài đặt của hành WM_HSCROLL. vi như sau: afx_msg void OnVScroll ( CWnd* main = new CWnd(); // Con trỏ đối tượng CWnd. UINT nSBCode, // Số hiệu ghi nhận đặc điểm tác động HICON myIcon; // Khai báo biến quản lý UINT nPos, // Vị trí nút cuộn / nút trượt trên mục HCURSOR myCursor; // handle của cursor và icon CScrollBar* pScrollBar // Con trỏ đối tượng quản lý mục CBrush myBrush; ); 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 // Nạp cursor và icon từ resource vào bộ nhớ. (vertical scrollbar hoặc vertical sliderCtrl) trong cửa sổ bị tác động. myIcon = LoadIcon ( IDR_MAINFRAME ); Xử lý của hành vi này được cài đặt tương tự hành vi OnHScroll. myCursor = LoadCursor ( IDR_MAINFRAME ); afx_msg BOOL OnSetCursor ( // Tạo brush tô nền cửa sổ với màu RGB(190, 190, 0) CWnd* pWnd, // Con trỏ đến đối tượng cửa sổ chứa cursor myBrush. CreateSolidBrush (RGB(190, 190, 0) ); UINT nHitTest, // Thông tin về vị trí cursor // Khởi tạo thông số cho đối tượng cửa sổ main UINT message // Chứa các số hiệu message có liên quan đến main->CreateEx( WS_EX_TOPMOST, // trạng thái hiện thời của các nút con chuột AfxRegisterWndClass( ); Hành vi xử lý WM_SETCURSOR, message do windows gửi đến CS_HREDRAW|CS_VREDRAW, cửa sổ khi windows cần ấn định lại hình dạng cursor cho phù hợp myCursor, myBrush, myIcon), với vị trí hiện thời của nó trên cửa sổ. "Emp.Example 2", nHitTest chứa thông tin vị trí hiện thời của cursor: WS_SYSMENU | WS_VISIBLE | WS_MINIMIZEBOX, HTBORDER : Cursor hiện nằm trên biên cửa sổ 100, 100, 300, 200, NULL, NULL ); HTCLIENT : Cursor hiện nằm trong vùng client // Dùng main làm cửa sổ giao diện chính HTCAPTION : Cursor hiện nằm trên tiêu đề của cửa sổ m_pMainWnd = main; virtual LRESULT WindowProc( UINT message, main->ShowWindow ( SW_SHOW ); // Kích hoạt cửa sổ main WPARAM wParam, LPARAM lParam ); Khi đối tượng cửa sổ main ngừng hoạt động thì ứng dụng cũng kết Hành vi xử lý các message gửi đến cửa sổ. Mặc nhiên, hành vi này thúc. dựa vào bảng MessageMap để chuyển message đến hành vi xử lý Xem VD02: Cửa sổ main với ExStyle là WS_EX_TOPMOST có thể nổi message tương ứng của đối tượng quản lý cửa sổ. 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 4.3 SỬ DỤNG ÐỐI TƯỢNG CWnd: ExStyle là WS_EX_TOOLWINDOW, cửa sổ sẽ không hiển thị trên 4.3.1 Sử dụng CWnd làm giao diện chính của ứng dụng: taskbar. Tạo dự án VD02 như dự án VD01. Thực hiện các bổ sung sau: 4.3.2 Ứng dụng chỉ chạy một bản (instance) tại mỗi thời điểm: Tạo icon có số hiệu là IDC_MAINFRAME. Tham khảo (2.8). Ðể ứng dụng chỉ được thực hiện với 1 bản duy nhất, ta cài đặt cơ chế Tạo cursor có số hiệu là IDC_MAINFRAME: đánh dấu và kiểm tra. Trong chương trình của ứng dụng, ta qui ước đăng • Tạo mới cursor: Thực hiện tương tự như tạo mới icon, (2.8). 48 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Cöûa soå giao dieän vaø lôùp CWnd 49
  • 32. 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ổ. 50 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 33. CHÖÔNG 5: UINT nID, // Soá hieäu command message int nCode, Xử lý message void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo 5.1 LÔÙP XÖÛ LYÙ MESSAGE CCmdTarget: ); Ñieàu phoái command message. Neáu baûn thaân ñoái töôïng laø cöûa soå giao 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ô dieän chính thì caùc WM_COMMAND ñöôïc öu tieân gôûi ñeán cho ñoái 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 töôïng. Thoâng qua haønh vi naøy, ñoái töôïng coù theå ñieàu phoái command 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. message cho caùc ñoái töôïng khaùc (öùng duïng, caùc control, view…). Löu yù Treân quan ñieåm ñoù, MFC cung caáp lôùp ñoái töôïng CCmdTarget phuïc vuï xöû lyù laø ñoái töôïng ñöôïc ñieàu phoái coù theå khoâng coù chöùc naêng xöû lyù command vaø ñieàu phoái messages trong phaïm vi öùng duïng, giöõa öùng duïng vôùi heä thoáng message göûi ñeán, do ñoù caàn kieåm tra keát quaû cuûa haønh vi OnCmdMsg 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: treân ñoái töôïng ñöôïc ñieàu phoái. Boá cuïc xöû lyù ñieàu phoái nhö sau: void BeginWaitCursor( ); Hieån thò cursor chôø xöû lyù (ñoàng hoà caùt). if (Ñoái_töôïng->OnCmdMsg(...) != 0) { void EndWaitCursor( ); Chaám döùt hieån thò cursor chôø xöû lyù. return; // Ñoái töôïng ñöôïc ñieàu phoái ñaõ xöû lyù message Ñò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 … // Chuû theå phaûi xöû lyù message keá thöøa lôùp CCmdTarget. Caùc macro giuùp caøi ñaët cô cheá naøy nhö sau: 5.2 KHAI BAÙO MUÏC XÖÛ LYÙ MESSAGE TRONG MESSAGE MAP: • DECLARE_MESSAGE_MAP( ): AÁn ñònh ñaëc tính xöû lyù message Muïc xöû lyù message trong baûng MessageMap cho pheùp aán ñònh moät xöû lyù cho lôùp ñoái töôïng xöû lyù message thoâng qua caùc caøi ñaët boå sung sau: duy nhaát cho moät message. Caùc loaïi message khaùc nhau coù kieåu muïc xöû lyù - Thuoäc tính private kieåu caáu truùc maûng chöùa caùc phaàn töû coù kieåu message khaùc nhau. Caùc kieåu muïc xöû lyù message phoå bieán nhö sau: AFX_MSGMAP_ENTRY. Moãi phaàn töû cuûa maûng ñöôïc duøng löu Caùc message cuûa heä thoáng, ñöôïc bieåu dieãn bôûi caùc haèng soá baét ñaàu tröõ moät muïc xöû lyù message maø lôùp keá thöøa khai baùo boå sung. baèng WM_ *, muïc xöû lyù message töông öùng coù daïng ON_WM_* (). - Thuoäc tính protected kieåu caáu truùc AFX_MSGMAP vôùi teân laø Ví duï: WM_PAINT ON_WM_PAINT() MessageMap chæ ñeán baûng caùc muïc xöû lyù message noùi treân. WM_SIZE ON_WM_SIZE() - Haønh vi protected: virtual AFX_MSGMAP GetMessageMap( ); Caùc message cuûa ngöôøi duøng: Soá hieäu message ñöôïc choïn tuøy yù trong traû veà ñòa chæ cuûa baûng MessageMap chöùa caùc muïc xöû lyù. ñoaïn WM_USER ÷ WM_USER+0×7FFF. Muïc xöû lyù message cho caùc DECLARE_MESSAGE_MAP ñöôïc ñaët cuoái phaàn khai baùo lôùp: message cuûa ngöôøi duøng coù daïng nhö sau: class MyClass : public CCmdTarget { // Taäp tin .H cuûa lôùp ON_MESSAGE( userMessageID , UserFuncName ) … // Caùc noäi dung khai baùo cuûa lôùp DECLARE_MESSAGE_MAP() Trong ñoù: }; - userMessageID : Soá hieäu message do ngöôøi duøng choïn tröôùc • BEGIN_MESSAGE_MAP( Teân_lôùp_keá thöøa, Teân_lôùp_cô_sôû ): Baét - UserFuncName : Haøm xöû lyù message, coù khai baùo nhö sau: ñaàu noäi dung khai baùo caùc muïc xöû lyù cuûa baûng MessageMap. afx_msg LRESULT UserFuncName ( • END_MESSAGE_MAP( ): Keát thuùc khai baùo baûng MessageMap. WPARAM wParam, // Tham soá kieåu WORD vaø Toaøn boä noäi dung khai baùo cuûa baûng MessageMap ñöôïc ñaët trong LPARAM lParam // Tham soá kieåu LONG keøm theo message 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 ( Xöû lyù Message 51 52 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 34. Caùc message coù ñaêng kyù cuûa ngöôøi duøng: Ngoaøi caùc message töï ñònh void [ClassName::]PreFunctionName (CCmdUI* pCmdUI ) { nghóa vaø söû duïng theo qui öôùc trong moät öùng duïng, windows cho pheùp pCmdUI->Enabled (FALSE ); // Caám ñoái töôïng hoaït ñoäng öù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: Caùc message do ñoái töôïng con (controls) göûi ñeán cöûa soå cha: Tham soá UINT RegisterWindowMessage (LPCSTR Chuoãi_teân_message ); wParam chöùa soá hieäu control, giaù trò WORD cao cuûa tham soá lParam Haøm traû veà soá hieäu ñaêng kyù ñöôïc cuûa message. Giaù trò naøy naèm trong chöùa thoâng tin veà traïng thaùi control ôû thôøi ñieåm göûi message ñeán cöûa soå ñoaïn 0×C000÷0×FFFF. Caùc öùng duïng ñang chaïy treân moät heä thoáng coù cha (ví duï BN_CLICKED laø moät traïng thaùi cuûa button control,…). Muïc theå chia xeû message duøng rieâng vôùi ñieàu kieän chuùng phaûi thöïc hieän xöû lyù message cho message göûi töø control coù daïng nhö sau: thao taùc ñaêng kyù cuøng moät chuoãi teân message ñeå laáy soá hieäu message. ON_CONTROL (Traïng_thaùi_control, Soá_hieäu_Control, Haøm_xöû_lyù ) Muïc xöû lyù message cho caùc message coù ñaêng kyù cuûa ngöôøi coù daïng: Ví duï: Ta coù ví duï minh hoïa ñònh höôùng xöû lyù message nhö sau: ON_REGISTERED_MESSAGE(UserRegMessageID, UserFuncName) * Khai baùo lôùp (teâp tin .H): Sau ñaây laø moät ví duï: class CMyClass: public CBasedWnd { // Ñaêng kyù message vôùi teân laø “MY_MESS” public: CMyClass(); const UINT myMess = RegisterWindowMessage(“MY_MESS”); void myProc(void); // Khai baùo muïc xöû lyù cho message ñöôïc ñaêng kyù void mySerach(); BEGIN_MESSAGE_MAP ( CMyWnd, CMyBasedWndClass ) void myWork(); //{{AFX_MSG_MAP ( CMyWnd ) void PremyWork(); ON_REGISTERED_MESSAGE ( myMess, myFunc ) void OnExit(void); // ... DECLARE_MESSAGE_MAP() //}}AFX_MSG_MAP } END_MESSAGE_MAP ( ) * Phaàn caøi ñaët cuûa lôùp (teâp tin .CPP): Message WM_COMMAND: Khi WM_COMMAND ñöôïc göûi ñeán ñoái #define MY_MESSAGE WM_USER + 1 töôïng xöû lyù message thì tham soá wParam keøm theo chöùa soá hieäu static UINT NEAR MY_MESS = RegisterWindowMessage(“MY_MESS”); BEGIN_MESSAGE_MAP(CMyClass, CDerivedWnd) (CommandID) cuûa ñoái töôïng phaùt sinh message. Muïc xöû lyù message //{{AFX_MSG_MAP(CMyClass) WM_COMMAND aán ñònh xöû lyù töông öùng, vaø coù daïng nhö sau: ON_WM_PAINT() // WindowsMessage ON_COMMAND ( CommandID, FunctionName ) ON_MESSAGE (MY_MESSAGE, myProc) // UserMessage ON_REGISTERED_MESSAGE(MY_MESS,OnSearch) 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 // UserRegMessage WM_COMMAND thoâng qua muïc xöû lyù ñieàu khieån message nhö sau: ON_COMMAND(ID_DO, myWork) // CommandMessage // Command Preprocess ON_UPDATE_COMMAND_UI( CommandID, PreFunctionName ) ON_UPDATE_COMMAND_UI(ID_DO, PremyWork) PreFunctionName laø haønh vi thöïc hieän xöû lyù ñieàu khieån treân ñoái töôïng //Control IDC_EXIT ON_CONTROL(BN_CLICKED, IDC_EXIT, OnExit) phaùt sinh WM_COMMAND, tham soá nhaän ñöôïc laø giaù trò con troû ñeán //}}AFX_MSG_MAP ñoái töôïng CCmdUI*. Haønh vi Enable ( BOOL isEnabled ) cuûa ñoái END_MESSAGE_MAP() 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 Caùc muïc xöû lyù message do Classwizard quaûn lyù ñaët giöõa //{{ vaø //}} töôïng phaùt sinh WM_COMMAND. Xöû lyù cuûa haønh vi naøy coù theå laø: Xöû lyù Message 53 54 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 35. 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ô - Choïn WM_CREATE. Sau ñoù choïn Add and Edit. sôû keá thöøa töø lôùp CWnd cuûa MFC: - Haønh vi OnCreate vôùi tham soá thích hôïp ñöôïc boå sung vaøo lôùp • Haønh vi OnCreate thöïc hieän caùc aán ñònh caàn thieát cho CEmpWnd CEmpWnd, ñoàng thôøi muïc xöû lyù ON_WM_CREATE() ñöôïc ñaët tröôùc khi ñi vaøo hoaït ñoäng. Boå sung vaø caøi ñaët haønh vi nhö sau: vaøo baûng MessageMap. Caøi ñaët noäi dung cuûa OnCreate nhö sau: - Trong maøn hình Workspace cuûa döï aùn, choïn trang ClassView. int CEmpWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) - Right-click treân tieâu ñeà cuûa lôùp CEmpWnd: { 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: - Choïn muïc Add Windows Message Handler... : void CEmpWnd::OnTimer( UINT nIDEvent ) { Xöû lyù Message 55 56 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 36. if (nIDEvent == 100) { // Timer do chuùng ta caøi ñaët Ta nhaän ñöôïc hoäp hoäi thoaïi Resource Symbols chöùa danh saùch caùc giaù char s[200], ch; trò ñaõ khai baùo. Coù theå thöïc hieän theâm, xoùa caùc giaù trò khai baùo naøy. 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ôû Choïn muïc New: 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: Nhaäp teân cuûa giaù trò khai baùo trong hoäp Name, nhaäp giaù trò khai baùo Choïn trang ResourceView trong maøn hình Workspace. trong hoäp Value. Sau ñoù choïn OK Right-click treân project resources: Ñ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 Choïn Resource Symbols...: 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: Xöû lyù Message 57 58 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 37. 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å. Xöû lyù Message 59
  • 38. 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). - Choïn Bitmap, Import. Sau ñoù choïn taäp tin chöùa aûnh bitmap thoâng 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 qua hoäp hoäi thoaïi File-Folder. resource cuûa öùng duïng. ÔÛ phaàn xöû lyù, caùc resource naøy ñöôïc taûi vaøo boä nhôù - AÁn ñònh caùc thoâng soá cuûa bitmap (soá hieäu laø IDB_MYPICT). 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õ Boå sung ñoái töôïng thuoäc tính m_myPict kieåu CBitmap cho CEmpWnd: ñöôï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. - Choïn trang ClassView trong maøn hình Workspace cuûa döï aùn. 6.2 ÖÙNG DUÏNG VÔÙI CÖÛA SOÅ CHÍNH HIEÅN THÒ AÛNH: - Right-click treân tieâu ñeà cuûa lôùp CEmpWnd: 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: - Choïn Add Member Variable… : • 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: - 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 - Choïn Insert: laøm noäi dung cuûa m_myPict. Xöû lyù ñöôïc caøi ñaët nhö sau: 60 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com ÖÙng duïng coâng cuï GDI 61
  • 39. int CEmpWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) Ñ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ò if (CWnd::OnCreate(lpCreateStruct) == -1) ñoà hoïa ñöôïc quaûn lyù bôûi chính noù thoâng qua moät soá haønh vi sau: return -1; - BitBlt : Sao cheùp vaø giöõ nguyeân tyû leä trong noäi dung aûnh. // Khôûi ñoäng bitmap töø bitmap resource IDB_MYPICT - StretchBlt : Sao cheùp vaø thay ñoåi tyû leä trong noäi dung aûnh. mypict.LoadBitmap( IDB_MYPICT ); 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. return 0; } - 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. Duøng haønh vi OnPaint cuûa CEmpWnd, veõ aûnh bitmap trong m_myPict Vieäc thöïc hieän caàn löu yù caùc böôùc sau: thoâng qua haønh vi DrawState cuûa ñoái töôïng CPaintDC dc. - Cöûa soå chính cuûa öùng duïng coù thuoäc tính WS_THICKFRAME. void CEmpWnd::OnPaint() - 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ò. CPaintDC dc(this); Caùc böôùc thöïc hieän nhö sau: RECT rect; Taïo döï aùn VD08 töông töï döï aùn VD07. GetClientRect( &rect ); // Kích thöôùc vuøng client // draw on client Haønh vi OnPaint cuûa CEmpWnd söû duïng DC trong boä nhôù ñeå loàng aûnh dc.DrawState ( CPoint(0,0), /* Goùc traùi treân cuûa aûnh */ bitmap, töø ñoù veõ leân vuøng client cuûa cöûa soå. Xöû lyù caøi ñaët nhö sau: CSize (rect.right-rect.left, rect.bottom-rect.top), void CEmpWnd::OnPaint() &m_myPict, DST_BITMAP); { } CPaintDC dc(this); RECT rt; Haønh vi OnDestroy cuûa CEmpWnd giaûi phoùng ñoái töôïng m_myPict. CDC memDC; void CEmpWnd::OnDestroy() CBitmap *oldBmp; { BITMAP bmpInfo; CWnd::OnDestroy(); m_myPict.DeleteObject(); GetClientRect(&rect); // Kích thöôùc vuøng client } mypict.GetBitmap(&bmpInfo); // Laáy thoâng tin cuûa aûnh bitmap 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 memDC.CreateCompatibleDC(&dc); gaây ra hieän töôïng "chôùp", ta coù theå söû duïng moät soá giaûi phaùp sau: // Loàng bitmap m_myPict vaøo memDC vaø löu laïi bitmap cuõ cuûa noù. - Khoâng söû duïng ñoái töôïng brush cho cöûa soå lieân quan: Duøng giaù trò NULL oldBmp = memDC.SelectObject(&m_myPict); 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å. // Cheùp aûnh töø memDC leân DC quaûn lyù vuøng client cuûa cöûa soå: dc - 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) dc.StretchBlt( 0, 0, rt.right-rt.left, rt.bottom-rt.top, &memDC, 0, 0, bmpInfo.bmWidth, bmpInfo.bmHeight, - Duøng moät DC trong boä nhôù laøm coâng cuï trang trí trung gian. Thöïc hieän caùc SRCCOPY); 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 // Phuïc hoài aûnh bitmap cuõ cuûa memDC trí caàn thieát thì chuyeån noäi dung DC coâng cuï leân DC cuûa maøn hình. memDC.SelectObject(oldBmp); memDC.DeleteDC(); 6.3 SAO CHEÙP AÛNH TÖØ DC VAØO DC, PHOÙNG TO & THU NHOÛ AÛNH: } // Xem VD08 6.4 DC TRONG BOÄ NHÔÙ (DC AÛO) - VUØNG VEÕ ÑEÄM LYÙ TÖÔÛNG: 62 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com ÖÙng duïng coâng cuï GDI 63
  • 40. 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 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 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 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õ moãi noäi dung trang trí, nhö theá seõ caûi thieän ñaùng keå chaát löôïng ñoà hoïa. 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à ÖÙ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 hai haønh vi OnCreate vaø OnDestroy cuûa CEmpWnd moät caùch phuø hôïp. 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 Baïn haõy thöû aùp duïng ñieàu löu yù naøy cho VD09. 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 6.5 AÛNH CHUYEÅN ÑOÄNG TRONG VUØNG CLIENT: xöû lyù cuûa haønh vi OnPaint coù söû duïng ñoái töôïng DC aûo nhö sau: Ñöôï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ò CClientDC dc(this); // Ñoái töôïng DC hieån thò 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 RECT rect; aûnh theo trình töï vôùi khoaûng thôøi gian chôø hôïp lyù. CDC memDrawDC; // Ñoái töôïng DC aûo ñeå veõ trung gian 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 memDrawBmp; CBitmap: Moãi bitmap quaûn lyù ñöôïc moät aûnh. Ta duøng nhieàu bitmap. CBitmap *memDrawOldBmp; AÛnh veõ baèng haønh vi DrawState cuûa ñoái töôïng DC quaûn lyù thieát bò hieån GetClientRect ( &rt ); int CX = rect.right–rect.left ; int CY = rect.bottom–rect.top; thò. Kích thöôùc aûnh hieån thò khoâng thay ñoåi. memDrawBmp.CreateCompatibleBitmap( &dc, CX, CY ); 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 memDrawDC.CreateCompatibleDC( &dc ); kyø phaàn aûnh caàn veõ naøo sang DC hieån thò. Coù theå thay ñoåi kích thöôùc memDrawOldBmp = memDrawDC.SelectObject( &memDrawBmp ); aûnh tuøy yù: StretchBlt. ... // Trang trí memDrawDC 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. // Chuyeån noäi dung DC aûo sang dc: Trong phaàn naøy ta xaây döïng öùng duïng vôùi hình aûnh chuù böôùm bay trong dc.StretchBlt ( 0, 0, CX,CY, &memDrawDC, CX,CY, SRCCOPY ); vuøng client cuûa cöûa soå. Taäp tin butterfly.bmp trong thö muïc BMP chöùa caùc // Huûy boû caùc ñoái töôïng GDI: memDrawDC.SelectObject(&memDrawOldBmp); 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ø memDrawBmp.DeleteObject(); veõ leân DC hieån thò. Caùc böôùc thöïc hieän döï aùn nhö sau: memDrawDC.DeleteDC(); 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 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 ñöôïc laáy töø taäp tin chöùa caùc aûnh hoaït hình. Ghi nhôù soá aûnh trong bitmap chöõ chaïy theo kieåu baûng chöõ ñieän töû trong vuøng client cuûa cöûa soå chính. ñoù. Chaúng haïn, choïn taäp tin butterfly.bmp trong thö muïc BMP. Taäp tin Taïo döï aùn VD09 töông töï döï aùn VD08. naøy coù 4 aûnh, kích thöôùc 32x28. Xöû lyù Trang trí memDrawDC trong OnPaint cuûa CEmpWnd nhö sau: Boå sung caùc ñoái töôïng thuoäc tính protected cho lôùp CEmpWnd: BITMAP bmpInfo; - m_butterDC : Ñoái töôïng CDC, quaûn lyù DC loàng aûnh. m_myPict.GetBitmap( &bmpInfo ); - m_butterBmp : Ñoái töôïng CBitmap, quaûn lyù caùc aûnh hoaït hình. memDrawDC.StretchBlt( 0, 0, CX, CY, &memDC, 0, 0, bmpInfo.bmWidth, bmpInfo.bmHeight, - m_butterOldBmp : Ñoái töôïng CBitmap*, quaûn lyù con troû chæ ñeán SRCCOPY ); ñoái töôïng bitmap cuõ cuûa m_butterDC. memDrawDC.SetTextColor( RGB(255,0,0) ); // text color - m_pictNo : Kieåu int, quaûn lyù soá thöù töï cuûa hình ñang ñöôïc memDrawDC.SetBkMode( TRANSPARENT ); // transparent hieån thò trong caùc aûnh hoaït hình noùi treân. memDrawDC.TextOut( 30, 100, Chuoãi, I ); Haønh vi OnCreate cuûa CEmpWnd thöïc hieän caùc chuaån bò: Xem VD09. int CEmpWnd::OnCreate( LPCREATESTRUCT lpCreateStruct ) 64 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com ÖÙng duïng coâng cuï GDI 65
  • 41. { Haønh vi OnCreate cuûa CEmpWnd thöïc hieän caùc chuaån bò nhö sau: if (CWnd::OnCreate(lpCreateStruct) == -1) int CEmpWnd::OnCreate( LPCREATESTRUCT lpCreateStruct ) return -1; { // TODO: Add your specialized creation code here if (CWnd::OnCreate(lpCreateStruct) == -1) SetTimer( IDD_TIMER, 250, NULL ); return -1; m_myPict.LoadBitmap( IDB_MYPICT ); // TODO: Add your specialized creation code here // Animation objects by EX10 SetTimer(IDD_TIMER, 250, NULL); m_butterBmp.LoadBitmap( IDB_ANIMATION ); m_mypict.LoadBitmap(IDB_MYPICT); m_butterDC.CreateCompatibleDC( NULL ); // animation object by EX10 m_butterOldBmp = butterDC.SelectObject( &m_butterBmp ); m_butterImg.Create(IDB_ANIMATION,32,4,RGB(255,255,255)); m_pictNo = 0; m_pictNo = 0; return 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ù: Haønh vi OnPaint söû duïng haønh vi Draw cuûa m_butterImg veõ aûnh: memDrawDC.StretchBlt( 20, 50, 32, 28, &m_butterDC, m_butterImg.Draw( &memDrawDC, m_pictNo, CPoint(30, 170), m_pictNo*32 , 0 , 32 , 28 , SRCCOPY ); ILD_NORMAL); m_pictNo++; // Choïn aûnh keá tieáp m_pictNo++; if (m_pictNo >= 4) m_pictNo = 0; if (m_pictNo >= 4) m_pictNo = 0; Haønh vi OnDestroy huûy boû caùc thuoäc tính GDI: Haønh vi OnDestroy huûy boû ñoái töôïng CImageList: m_butterDC.SelectObject(m_butterOldBmp); m_butterImg.DeleteImageList(); m_butterBmp.DeleteObject(); m_butterDC.DeleteDC(); 6.7 CRgn – CÖÛA SOÅ COÙ HÌNH DAÏNG TUØY YÙ: 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 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 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 haønh vi SetWindowRgn cuûa ñoái töôïng cöûa soå. Phaàn sau ñaây minh hoïa cho vaán ñònh phaàn noäi dung ñöôïc veõ treân aûnh hoaït hình. ñeà treân vaø ñöôïc caøi ñaët trong haønh vi OnCreate cuûa cöûa soå (VD12). Haønh vi MaskBlt cuûa CDC cho pheùp duøng monochrome bitmap laøm löôùi CRgn newShape; 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 newShape.CreateEllipticRgn( 0, 0, 200, 100 ); (95/98/Me unsupported). Baïn haõy thöû thöïc hieän vôùi VD10 nhö baøi taäp. SetWindowRgn( newShape, TRUE ); 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 THÖÏC HAØNH: quaûn lyù bôûi ñoái töôïng CImageList: 1. Vieát öùng duïng vôùi cöûa soå giao dieän chính coù hình tam giaùc. Taïo döï aùn VD11 töông töï döï aùn VD10. 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. Boå sung ñoái töôïng thuoäc tính m_butterImg kieåu CImageList laøm nhieäm 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öï vuï quaûn lyù caùc aûnh. Xoùa caùc thuoäc tính m_butterBmp, m_butterDC vaø 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. m_butterOldBmp vì khoâng coøn caàn thieát. 4. Vieát öùng duïng hieån thò aûnh cuoän (scroll) töø traùi sang phaûi. 66 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com ÖÙng duïng coâng cuï GDI 67
  • 42. 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. 68 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 43. 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: - 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: - 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). - Prompt: Noäi dung giaûi thích (ñöôïc hieån thò treân StatusBar) vaø noäi 7.2 MENU RESOURCE: dung giaûi thích vaén taét (Tiptext treân thanh coâng cuï). Giöõa hai noäi Ñeå tieän vieäc söû duïng vaø chænh söûa menu trong chöông trình, VC cho pheùp dung naøy ñöôïc ngaên caùch baèng kyù töï n. 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, - ID: Soá hieäu cuûa muïc choïn (menu-ID). Neân ñaët teân gôïi nhôù. 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ø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 Caùch taïo menu trong resource: Separator trong hoäp Menu Item Properties. Taïo môùi menu resource: Thöïc hieän töông töï vieäc taïo môùi icon (2.8). • 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í Löu yù: Choïn Resource Type laø Menu. cheøn, sau ñoù nhaán phím Insert. Ñaët soá hieäu cho menu (ví duï IDR_MAINFRAME vôùi menu chính). • Xoùa muïc caøi ñaët: Ñöa veät saùng ñeán vò trí xoùa, goõ phím Delete. Thieát keá menu thoâng qua maøn hình thieát keá maø ta vöøa nhaän ñöôïc töø Taïo môùi döï aùn VD13 nhö VD12, sau ñoù thieát keá menu resource vôùi soá böôùc treân. Caùc thao taùc cô baûn nhö sau: hieäu IDR_MAINFRAME. Soá hieäu caùc muïc choïn laàn löôït laø: • Caøi ñaët muïc popup: Double-click (hoaëc goõ phím - Start = ID_GAME_START Enter) treân vò trí döï ñònh caøi ñaët muïc popup: - Option = ID_GAME_OPTION Ta nhaän ñöôïc hoäp hoäi thoaïi Menu Item Properties: - About = ID_GAME_ABOUT - Exit = ID_EXIT Menu & Phím taét 69 70 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 44. 7.3 SÖÛ DUÏNG MENU RESOURCE: 7.4 MUÏC XÖÛ LYÙ COMMAND MESSAGE TÖØ MUÏC CHOÏN CUÛA MENU: Menu resource laø cô sôû khôûi taïo heä thoáng menu duøng trong öùng duïng. Heä Ñ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. 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 Khi ngöôøi duøng choïn moät muïc treân menu, heä thoáng laäp töùc göûi naøy ñöôïc thöïc hieän thoâng qua caùc böôùc sau: WM_COMMAND ñeán öùng duïng vôùi tham soá wParam chöùa soá hieäu (ID) cuûa Naïp menu resource vaøo boä nhôù: 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öû HMENU LoadMenu ( lyù mesage ñeàu coù theå ñaûm nhaän vieäc xöû lyù caùc message naøy. HINSTANCE hInstance, // Handle cuûa öùng duïng Tieáp theo, ta xaây döïng öùng duïng vôùi heä thoáng menu nhö VD13. Muïc choïn LPCTSTR lpMenuName // Chuoãi teân resource cuûa menu About hieån thò hoäp thoâng baùo giôùi thieäu taùc giaû vaø saûn phaåm. ); Haøm traû veà handle cuûa menu trong boä nhôù. Taïo döï aùn VD14 nhö VD13. - Giaù trò handle cuûa öùng duïng nhaän ñöôïc töø haøm sau: Duøng lôùp CEmpWnd caøi ñaët HINSTANCE AfxGetInstanceHandle( ); muïc xöû lyù message: - Moãi ñoái töôïng trong resource ñöôïc nhaän dieän baèng moät soá hieäu hoaëc - Trong maøn hình Workspace, chuoãi teân. Haøm sau ñaây giuùp chuyeån soá hieäu cuûa ñoái töôïng resource choïn ClassView. Right-click sang chuoãi teân töông öùng: treân tieâu ñeà lôùp CEmpWnd: 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ïn Add Windows Message Handler... 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; - Choïn soá hieäu ID_GAME_ABOUT, click choïn COMMAND. Sau ñoù } // Xem VD13 (heä thoáng menu chöa coù xöû lyù) choïn muïc Add and Edit. Menu & Phím taét 71 72 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 45. - 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. - Ñaët teân haønh vi xöû lyù message WM_COMMAND. Choïn OK. • Xoùa ñònh nghóa phím taét: Choïn doøng ñònh nghóa phím, goõ phím Del. - Noäi dung caøi ñaët cuûa haønh vi naøy nhö sau: 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. void CEmpWnd::OnGameAbout() 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ôù: MessageBox( "The program was written by Mr.EMPn" HACCEL LoadAccelerators ( "This product is a not-licensed one.", HINSTANCE hInstance, // Handle cuûa öùng duïng "About", LPCTSTR lpTableName // Chuoãi teân resource MB_OK | MB_ICONINFORMATION ); ); 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: Xem baûng MessageMap cuûa lôùp CEmpWnd, muïc ID_GAME_ABOUT ? int TranslateAccelerator ( 7.5 PHÍM TAÉT (HOT KEY) CHO MUÏC CHOÏN TREÂN MENU: HWND hWnd, // Handle cöûa soå giao dieän duøng phím taét 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 HACCEL hAccTable, // Handle cuûa baûng phím taét treân heä thoáng menu. Caùc phím taét ñöôïc ñònh nghóa trong phaàn resource cuûa LPMSG lpMsg // Con troû bieán chöùa message ñieàu phoái öùng duïng. Chöông trình seõ duøng leänh ñeå naïp baûng phím taét khi caàn. ); Haøm naøy phaûi ñöôïc thöïc hieän treân taát caû caùc message maø öùng 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, duïng nhaän ñöôïc. Do ñoù, noù ñöôïc loàng vaøo voøng laëp MessageLoop Ctrl+P, Ctrl+A vaø Ctrl+E cho caùc muïc menu: Start, Option, About vaø Exit. cuûa öùng duïng. Lôùp CWinThread (xem 2.4) cho pheùp caøi ñaët ñaëc tính Taïo döï aùn VD15 töông töï VD14. naøy thoâng qua haønh vi sau cuûa lôùp: Taïo môùi baûng phím taét trong resource (Accelerator resource): Thöïc BOOL CWinThread::PreTranslateMessage( MSG *pMsg ); hieän töông töï vieäc taïo môùi icon (2.8). Resource Type = Accelerator. Trong caùc lôùp keá thöøa CWinThread, caøi ñaët naøy coù boá cuïc nhö sau: Ñaët soá hieäu cho Accelerator ( giaû söû laø IDR_MAINFRAME ). BOOL CEmpApp::PreTranslateMessage (MSG *pMsg) Thieát keá baûng phím taét. Caùc thao taùc cô baûn nhö sau: { // CEmpApp laø lôùp keá thöøa CWinApp (töø CWinThread) • Boå sung ñònh nghóa phím taét: Double-click treân doøng roãng: // 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: Menu & Phím taét 73 74 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 46. - Thuoäc tính m_hAccel kieåu HACCEL löu handle baûng phím taét. UINT nCheck // Caùch thöùc ñaùnh daáu muïc choïn - Haønh vi InitInstance: Boå sung leänh naïp baûng phím taét vaø giöõ giaù ); Ñaùnh daáu hoaëc huûy boû ñaùnh daáu muïc choïn treân menu. trò handle cuûa noù vaøo bieán m_hAccel ñeå söû duïng sau naøy: nCheck laø giaù trò keát hôïp cuûa hai noäi dung: m_hAccel = LoadAccelerators( AfxGetInstanceHandle(), - Caùch ñaùnh daáu muïc: = MF_CHECKED : Ñaùnh daáu MAKEINTRESOURCE( IDR_MAINFRAME ) ); = MF_UNCHECKED : Boû ñaùnh daáu - Caùch chæ ñònh muïc: = MF_BYPOSITION : Theo vò trí - Haønh vi keá thöøa PreTranslateMessage coù caøi ñaët nhö treân. = MF_BYCOMMAND : Theo soá hieäu muïc 7.6 LÔÙP QUAÛN LYÙ MENU - CMenu: nIDCheckItem töông öùng chöùa soá hieäu hoaëc vò trí cuûa muïc choïn. Ñeå tieän thao taùc treân menu, MFC cung caáp lôùp ñoái töôïng CMenu cho pheùp UINT EnableMenuItem ( quaûn lyù menu thoâng qua caùc thuoäc tính vaø haønh vi ñaëc tröng sau: UINT nIDEnableItem, // Soá hieäu | vò trí muïc choïn (nhö treân) CMenu( ); Haønh vi taïo laäp ñoái töôïng menu. UINT nEnable // Caùch thöùc aán ñònh muïc choïn. BOOL LoadMenu( UINT nIDResource ); Khôûi taïo thoâng soá cho ñoái ); Caám hoaëc cho pheùp muïc choïn hoaït ñoäng. töôïng menu töø menu resource. nIDEnableItem laø giaù trò keát hôïp cuûa hai noäi dung: BOOL DestroyMenu( ); Huûy boû ñoái töôïng menu. - Caùch ñònh vò muïc choïn: Nhö treân. BOOL DeleteMenu( UINT nPosition, UINT nFlags ); Xoùa moät muïc - Traïng thaùi muïc: = MF_ENABLED : Cho pheùp muïc hoaït ñoäng. choïn trong menu. Boä giaù trò (nPosition, nFlags) xaùc ñònh muïc choïn. = MF_DISABLED : Caám muïc hoaït ñoäng. nFlags = MF_BYCOMMAND : nPosition laø soá hieäu cuûa muïc choïn = MF_GRAYED : Che môø muïc choïn. (menu-ID). int GetMenuString ( = MF_BYPOSITION : nPosition laø vò trí thöù töï cuûa muïc UINT nIDItem, // Soá hieäu muïc choïn choïn (ñeám töø 0). CString& rString, // Tham bieán nhaän keát quaû BOOL AppendMenu ( UINT nFlags // Caùch ñònh vò muïc choïn UINT nFlags, // Ñaëc ñieåm muïc choïn ); Laáy noäi dung thoâng baùo cuûa moät muïc choïn. UINT nIDNewItem = 0, // Soá hieäu muïc choïn BOOL ModifyMenu ( LPCTSTR lpszNewItem=NULL // Chuoãi thoâng baùo cuûa muïc UINT nPosition, // Soá hieäu | vò trí cuûa muïc choïn ); Theâm muïc choïn vaøo cuoái heä thoáng menu. UINT nFlags, // Caùch ñònh vò muïc choïn nFlags = MF_SEPARATOR : Caùc tham soá khaùc khoâng coù yù nghóa. UINT nIDNewItem = 0, // Soá hieäu | vi trí môùi cuûa muïc choïn = MF_STRING : Caùc thoâng soá ñöôïc hieåu nhö treân. LPCTSTR lpszNewItem = NULL // Thoâng baùo môùi cuûa muïc choïn = MF_POPUP : nIDNewItem laø handle cuûa menu popup. ); Thay ñoåi caùc thoâng soá lieân quan ñeán muïc choïn. BOOL InsertMenu ( Löu yù: Haønh vi GetMenu cuûa CWnd traû veà con troû ñeán ñoái töôïng menu UINT nPosition, // Vò trí ñöôïc cheøn. 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. UINT nFlags, // Caùc thoâng tin khaùc Giaû söû coù yeâu caàu vieát öùng duïng VD16 töông töï VD15; trong ñoù muïc choïn UINT nIDNewItem = 0, // töông töï AppendMenu(). Start töï ñoäng chuyeån thaønh Stop vaø ngöôïc laïi moãi khi ngöôøi duøng choïn LPCTSTR lpszNewItem = NULL muïc naøy. Coâng vieäc treân ñöôïc thöïc hieän thoâng qua muïc xöû lyù command ); Cheøn theâm muïc choïn vaøo tröôùc muïc ñöôïc chæ bôûi nPosition. message ID_GAME_START. Baïn haõy thöû thöïc hieän öùng duïng naøy (xem UINT CheckMenuItem ( VD16). UINT nIDCheckItem, // Soá hieäu | vò trí muïc choïn 7.7 XÖÛ LYÙ ÑIEÀU KHIEÅN MUÏC CHOÏN CUÛA MENU: Menu & Phím taét 75 76 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 47. 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. Menu & Phím taét 77
  • 48. CHÖÔNG 8: 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. Caùc lôùp ñoái Töôïng nhaäp lieäu 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: 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 SS_BITMAP : Coù chöùc naêng hieån thò aûnh bitmap. 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 SS_ICON : Coù chöùc naêng hieån thò aûnh icon hoaëc cursor. 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: 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 8.1 CStatic: 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 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 is", muïc thöù hai hieån thò icon cuûa öùng duïng. dieän. Caùc thuoäc tính vaø haønh vi ñaëc tröng cuûa lôùp naøy nhö sau: Duøng hai ñoái töôïng thuoäc lôùp CStatic ñeå taïo vaø quaûn lyù hai muïc thoâng CStatic( ); Taïo laäp ñoái töôïng roãng. baùo. Ñoái töôïng CEmpWnd laáy chuùng laøm thuoäc tính ñeå tieän quaûn lyù. BOOL Create ( Döï aùn ñöôïc thöïc hieän qua caùc böôùc sau: LPCTSTR lpszText, // Noäi dung thoâng baùo cuûa muïc Taïo döï aùn VD18 töông töï VD15. Chænh söûa lôùp CEmpWnd nhö sau: DWORD dwStyle, // Thoâng soá daïng muïc thoâng baùo Boå sung hai ñoái töôïng thuoäc tính protected: m_staticIcon vaø const RECT& rect, // Toïa ñoä, kích thöôùc cuûa muïc m_staticText coù kieåu CStatic. CWnd* pParentWnd, // Con troû ñoái töôïng cöûa soå cha Haønh vi OnCreate thöïc hieän khôûi taïo thoâng soá cho hai ñoái töôïng naøy: 78 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Caùc lôùp ñoái töôïng nhaäp lieäu 79
  • 49. int CEmpWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) void SetMargins ( { UINT nLeft, // Leà traùi vaø if (CWnd::OnCreate(lpCreateStruct) == -1) UINT nRight // leà phaûi tính baèng pixel return -1; ); AÁn ñònh bieân traùi vaø bieân phaûi cuûa hoäp nhaäp. m_staticText.Create( _T("This is my Icon:"), DWORD GetMargins( ); Traû veà giaù trò chöùa thoâng tin bieân traùi (WORD WS_CHILD|WS_VISIBLE, CRect(10, 15, 120, 35), this ); thaáp) vaø bieân phaûi (WORD cao) cuûa hoäp nhaäp. m_staticIcon.Create( _T(""), void GetSel ( WS_CHILD | WS_VISIBLE | SS_ICON, int& nStartChar, // Bieán chöùa vò trí kyù töï ñaàu tieân vaø CRect( 125,7,157,39 ), this ); int& nEndChar // kyù töï cuoái cuøng cuûa ñoaïn vaên baûn. m_staticIcon.SetIcon ( ); Laáy thoâng tin veà ñoaïn vaên baûn ñang ñöôïc ñaùnh daáu trong hoäp nhaäp. AfxGetApp()->LoadIcon(IDR_MAINFRAME) ); void SetSel ( return 0; 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 Bieân dòch vaø chaïy thöû öùng duïng. BOOL bNoScroll = FALSE 8.2 CEdit: ); Ñaùnh daáu moät ñoaïn vaên baûn trong hoäp nhaäp. 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 BOOL SetReadOnly( BOOL bReadOnly = TRUE ); Xaùc laäp traïng thaùi 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å chæ xem ñoái vôùi döõ lieäu cuûa hoäp nhaäp. cha cuûa hoäp nhaäp veà tình hình nhaäp lieäu ñang dieãn ra trong hoäp. void Copy( ); Cheùp noäi dung ñoaïn vaên baûn ñang ñöôïc ñaùnh daáu trong CEdit( ); Taïo laäp ñoái töôïng roãng. hoäp nhaäp vaøo vuøng nhôù heä thoáng (clipboard). BOOL Create ( void Paste( ); Cheøn noäi dung vaên baûn trong clipboard vaøo hoäp nhaäp baét DWORD dwStyle, // Thoâng soá daïng hoäp nhaäp ñaàu töø vò trí ñang choïn (hoaëc vò trí daáu carret). const RECT& rect, // Toïa ñoä vaø kích thöôùc hoäp nhaäp void Clear( ); Xoùa noäi dung ñoaïn vaên baûn ñang ñöôïc ñaùnh daáu. CWnd* pParentWnd, // Con troû ñoái töôïng cöûa soå cha void Cut( ); Thöïc hieän caùc thao taùc Copy vaø Clear. UINT nID // Soá hieäu hoäp nhaäp, phaûi duy nhaát void SetPasswordChar ( ); Khôûi taïo thoâng soá cho ñoái töôïng hoäp nhaäp lieäu. TCHAR ch // Kyù töï ñöôïc choïn dwStyle: Goàm thoâng soá qui ñònh ñoái vôùi control vaø caùc daïng boå sung: ); Ñaët kyù töï ‘che’ cho noäi dung cuûa password trong hoäp nhaäp. ES_MULTILINE : Hoäp nhaäp cho pheùp nhieàu doøng. int GetLineCount( ); Traû veà soá doøng vaên baûn trong hoäp nhaäp. ES_PASSWORD : Hoäp nhaäp duøng nhaäp password. int GetLine ( ES_READONLY : Hoäp nhaäp chæ xem noäi dung. int nIndex, // Chæ soá doøng vaên baûn trong hoäp nhaäp ES_xxx : Xem thoâng tin trong MSDN. LPTSTR lpszBuffer, // Vuøng ñeäm chöùa keát quaû void GetRect ( int nMaxLength // Chieàu daøi vuøng ñeäm LPRECT lpRect // Con troû ñeán bieán RECT chöùa keát quaû ); Laáy noäi dung moät doøng vaên baûn trong hoäp nhaäp. ); Laáy thoâng tin veà toïa ñoä, kích thöôùc hoäp nhaäp. int GetFirstVisibleLine( ); Traû veà chæ soá doøng vaên baûn ñöôïc nhìn thaáy BOOL GetModify( ); Traû veà TRUE neáu noäi dung hoäp nhaäp thay ñoåi. ñ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 void SetModify( BOOL bModified = TRUE ); Xaùc laäp hoaëc xoùa côø laø bò che khuaát. hieäu ghi nhaän söï thay ñoåi noäi dung trong hoäp nhaäp. 80 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Caùc lôùp ñoái töôïng nhaäp lieäu 81
  • 50. int LineFromChar ( Thöïc haønh 1: Vieát öùng duïng vôùi muïc thoâng baùo "Enter your name:" vaø hoäp int nIndex = -1 // Chæ soá kyù töï. –1 laø kyù töï cuoái cuøng. nhaäp döõ lieäu beân caïnh treân maøn hình giao dieän chính. ); Traû veà chæ soá doøng vaên baûn chöùa kyù töï (Hoäp nhaäp coù nhieàu doøng). Taïo döï aùn VD19 töông töï VD18. Chænh söûa CEmpWnd nhö sau: int LineIndex ( Boå sung hai thuoäc tính protected: m_staticName kieåu CStatic vaø int nLine = -1 // Chæ soá doøng vaên baûn, -1 laø doøng cuoái cuøng m_editName kieåu CEdit. ); Traû veà chæ soá cuûa kyù töï ñaàu tieân trong doøng vaên baûn laøm tham soá. Trong haønh vi OnCreate, thöïc hieän khôûi taïo hai ñoái töôïng naøy: int LineLength ( int CEmpWnd::OnCreate (LPCREATESTRUCT lpCreateStruct) 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. if (CWnd::OnCreate(lpCreateStruct) == -1) CPoint PosFromChar ( return -1; UINT nChar // Chæ soá kyù töï trong hoäp nhaäp m_staticName.Create( _T("Enter your name:" ), ); Traû veà toïa ñoä ñieåm ôû goùc traùi treân cuûa kyù töï. WS_CHILD | WS_VISIBLE, int CharFromPos ( CRect(10, 75, 130, 95), this ); m_editName.Create( WS_CHILD | WS_VISIBLE | WS_BORDER, CPoint pt // Toïa ñoä cuûa ñieåm CRect(135, 75, 280, 95), this, -1 ); ); Traû veà chæ soá cuûa kyù töï gaàn ñieåm ñang xeùt nhaát. return 0; void LineScroll ( } int nLines, // Soá doøng cuoän doïc, < 0 laø cuoän xuoáng. 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 int nChars = 0 // Soá kyù töï cuoän ngang, < 0 laø cuoän traùi. 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. ); Cuoän noäi dung vaên baûn ñang hieån thò trong hoäp nhaäp. HD: Cöûa soå cha coù haønh vi xöû lyù message thoâng baùo söï thay ñoåi döõ lieäu 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 trong hoäp nhaäp thoâng qua muïc xöû lyù message ON_EN_CHANGE. 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 Taïo döï aùn VD20 töông töï VD19, Chænh söûa lôùp CEmpWnd nhö sau: xöû lyù caùc message thoâng qua muïc xöû lyù message coù daïng nhö sau: Boå sung haønh vi xöû lyù: afx_msg void OnYourNameChange() ON_Notification ( ID, memberFxn ) void CEmpWnd::OnYourNameChange () 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: CString yourname; afx_msg void memberFxn( void ); m_editName.GetWindowText(yourname); ON_Notification coù theå laø moät trong caùc muïc xöû lyù cuï theå sau: SetWindowText(yourname); 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. Taïo môùi soá hieäu resource: IDC_YOURNAME, duøng giaù trò naøy laøm soá ON_EN_HSCROLL Ngöôøi duøng click choïn thanh tröôït ngang. hieäu cho ñoái töôïng m_editName. Trong haønh vi OnCreate: ON_EN_VSCROLL Ngöôøi duøng click choïn thanh tröôït doïc. int CEmpWnd::OnCreate ( LPCREATESTRUCT lpCreateStruct ) 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. if (CWnd::OnCreate(lpCreateStruct) == -1) return -1; ON_EN_SETFOCUS Edit baét ñaàu hoaït ñoäng. m_staticName.Create ( _T("Enter your name:"), ON_EN_UPDATE Döõ lieäu nhaäp ñang ñöôïc caäp nhaät cho edit. WS_CHILD | WS_VISIBLE, CRect( 10, 75, 130, 95 ), this ); 82 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Caùc lôùp ñoái töôïng nhaäp lieäu 83
  • 51. m_editName.Create( WS_CHILD | WS_VISIBLE | WS_BORDER, Thöïc haønh 1: Vieát öùng duïng nhö VD19. Boå sung nuùt choïn "Nhap xong", CRect( 135, 75, 280, 95 ), this, IDC_YOURNAME ); maø khi choïn, seõ duøng hoäp thoâng baùo ñeå hieån thò noäi dung vöøa nhaäp. return 0; 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() Trong baûng MessageMap, boå sung muïc xöû lyù message: void CEmpWnd::OnClickNhapxong () BEGIN_MESSAGE_MAP(CEmpWnd, CWnd) { //{{AFX_MSG_MAP(CEmpWnd) CString yourname; ON_WM_CREATE() m_editName.GetWindowText( yourname ); ON_WM_DESTROY() Muïc boå sung MessageBox ( yourname, "Hello !", ON_WM_PAINT() MB_OK | MB_ICONEXCLAMATION ); //}}AFX_MSG_MAP } ON_EN_CHANGE( IDC_YOURNAME, OnYourNameChange ) Khai baùo ID resource: IDC_NHAPXONG, boå sung ñoái töôïng thuoäc tính END_MESSAGE_MAP() protected m_buttonNhapxong kieåu CButton. Trong OnCreate: 8.3 CButton: int CEmpWnd::OnCreate( LPCREATESTRUCT lpCreateStruct ) 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. if (CWnd::OnCreate(lpCreateStruct) == -1) CButton( ); Taïo laäp ñoái töôïng nuùt choïn roãng. return -1; BOOL Create ( m_staticName.Create( _T("Enter your name:"), LPCTSTR lpszCaption, // Noäi dung thoâng baùo WS_CHILD | WS_VISIBLE, CRect(10, 75, 130, 95), this ); DWORD dwStyle, // Thoâng soá daïng nuùt (BS_PUSHBUTTON) m_editName.Create( WS_CHILD | WS_VISIBLE | WS_BORDER, const RECT& rect, // Toïa ñoä, kích thöôùc nuùt choïn CRect( 135, 75, 280, 95 ), this, -1 ); CWnd* pParentWnd, // Con troû cöûa soå cha m_buttonNhapxong.Create ( UINT nID // Soá hieäu nuùt choïn _T("Nhap xong"), WS_CHILD | WS_VISIBLE, ); Khôûi taïo thoâng soá cho ñoái töôïng nuùt choïn. CRect(10, 115, 90, 140), this, IDC_NHAPXONG ); HBITMAP GetBitmap( ) const ; Handle cuûa aûnh bitmap ñang duøng. return 0; HBITMAP SetBitmap(HBITMAP hBitmap); Gaén aûnh bitmap vaøo nuùt. } HICON GetIcon( ) const; Handle cuûa icon ñang duøng. Trong baûng MessageMap cuûa CEmpWnd, boå sung muïc xöû lyù message: HICON SetIcon( HICON hIcon ); Gaén icon vaøo nuùt. virtual void DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct ); ON_BN_CLICKED ( IDC_NHAPXONG , OnClickNhapxong ) 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. 8.4 CListBox: Muïc ON_Notification maø cöûa soå cha duøng xöû lyù message töø nuùt choïn laø: 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 Muïc xöû lyù message YÙ nghóa cuûa message ñöôïc xöû lyù pheùp ñaùnh daáu choïn moät hoaëc nhieàu muïc ñoàng thôøi trong listbox. ON_BN_CLICKED Ngöôøi duøng click treân nuùt. CListBox( ); Taïo laäp ñoái töôïng roãng. ON_BN_DOUBLECLICKED Ngöôøi duøng double-click treân nuùt 84 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Caùc lôùp ñoái töôïng nhaäp lieäu 85
  • 52. BOOL Create ( virtual void DrawItem ( DWORD dwStyle, // Thoâng soá aán ñònh daïng listbox LPDRAWITEMSTRUCT lpDrawItemStruct const RECT& rect, // Toïa ñoä, kích thöôùc cuûa listbox ); Haønh vi keá thöøa nhaèm thöïc hieän trang trí caùc muïc theo caùch rieâng. CWnd* pParentWnd, // Con troû ñoái töôïng cöûa soå cha virtual void MeasureItem ( UINT nID // Soá hieäu cuûa listbox LPMEASUREITEMSTRUCT lpMeasureItemStruct ); Khôûi taïo thoâng soá cho ñoái töôïng ListBox. ); Laáy thoâng tin laøm cô sôû cho vieäc töï trang trí caùc muïc trong listbox. dwStyle: Goàm thoâng soá qui ñònh ñoái vôùi control vaø caùc daïng boå sung: virtual void DeleteItem ( LBS_MULTIPLESEL : Cho pheùp choïn nhieàu muïc ñoàng thôøi LPDELETEITEMSTRUCT lpDeleteItemStruct LBS_NOTIFY : Thoâng tin cho cöûa soå cha ); Haønh vi keá thöøa ñeå tuøy nghi xöû lyù khi moät muïc bò xoùa khoûi listbox. LBS_SORT : Caùc muïc ñöôïc xeáp thöù töï virtual int VKeyToItem ( LBS_MULTICOLUMN : Coù nhieàu coät chöùa caùc muïc UINT nKey, // Maõ phím (virtual key) ñöôïc goõ LBS_STANDARD : = LBS_NOTIFY | LBS_SORT UINT nIndex // Chæ soá muïc hieän haønh trong listbox int GetCount( ); Traû veà soá muïc choïn trong Listbox. ); Haønh vi keá thöøa cho pheùp tuøy nghi xöû lyù treân phím. int GetCurSel( ); Traû veà chæ soá cuûa muïc ñöôïc choïn (single). virtual int CharToItem ( int SetCurSel ( UINT nKey, // Maõ phím (character) ñöôïc goõ int nSelect // Chæ soá muïc ñöôïc choïn UINT nIndex // Chæ soá muïc hieän haønh trong listbox ); AÁn ñònh muïc choïn trong listbox. ); Haønh vi keá thöøa cho pheùp tuøy nghi xöû lyù phím kyù töï. int GetSelCount( ); Traû veà soá muïc ñöôïc choïn trong moät listbox. Chæ ListbBox vaø cöûa soå cha: ListBox vôùi thoâng soá daïng LBS_NOTIFY coù theå duøng cho listbox cho pheùp choïn nhieàu muïc. 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ù. int GetSelItems ( Muïc ON_Notification maø cöûa soå cha duøng xöû lyù message töø listbox laø: int nMaxItems, // Soá muïc ñöôïc choïn vaø LPINT rgIndex // maûng chöùa caùc chæ soá cuûa chuùng Muïc xöû lyù message YÙ nghóa cuûa message ñöôïc xöû lyù ); Laáy chæ soá cuûa caùc muïc ñöôïc choïn trong listbox. ON_LBN_DBLCLK Ngöôøi duøng double-click treân listbox. int AddString ( ON_LBN_KILLFOCUS Keát thuùc hoaït ñoäng nhaäp. LPCTSTR lpszItem // Thoâng baùo cuûa muïc ON_LBN_SELCANCEL Huûy boû thao taùc choïn. ); Theâm moät muïc vaøo listbox. Neáu listbox khoâng coù ñaëc tính xeáp thöù töï ON_LBN_SELCHANGE Thay ñoåi muïc choïn trong listbox. thì muïc môùi theâm ñöôïc ñaët vaøo cuoái danh saùch caùc muïc. ON_LBN_SETFOCUS Baét ñaàu nhaäp lieäu treân listbox. int DeleteString ( ON_WM_CHARTOITEM Duøng cho ownerDraw listbox. UINT nIndex // Chæ soá cuûa muïc bò xoùa ON_WM_VKEYTOITEM Xöû lyù WM_KEYDOWN ); Xoùa moät muïc trong listbox. Thöïc haønh: Vieát öùng duïng töông töï VD21, theâm listbox coù ba muïc choïn: int InsertString ( "Ong A", "Ba B" vaø "Co C". Khi ngöôøi duøng click choïn moät muïc trong int nIndex, // Vò trí cheøn, -1 laø vò trí cuoái listbox listbox thì noäi dung cuûa muïc aáy ñöôïc ñieàn vaøo hoäp nhaäp Name. LPCTSTR lpszItem // Thoâng baùo cuûa muïc HD: Duøng ON_LBN_SELCHANGE ñònh höôùng xöû lyù message lieân quan. ); Cheøn moät muïc vaøo listbox taïi vò trí xaùc ñònh. Taïo öùng duïng VD22 nhö VD21. Chænh söûa lôùp CEmpWnd nhö sau: void ResetContent( ); Xoùa taát caû caùc muïc hieän coù trong listbox, laøm Boå sung haønh vi protected: afx_msg void OnSelectDanhsach() roãng noäi dung listbox quaûn lyù bôûi ñoái töôïng. void CEmpWnd::OnSelectDanhsach() 86 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Caùc lôùp ñoái töôïng nhaäp lieäu 87
  • 53. { BOOL Create ( CString info; DWORD dwStyle, // Chöùa thoâng soá veà daïng cuûa comboBox int iSel = m_listboxDanhsach.GetCurSel(); const RECT& rect, // Toïa ñoä, kích thöôùc comboBox if (iSel == LB_ERR) // Khoâng coù löïa choïn CWnd* pParentWnd, // Con troû ñoái töôïng cöûa soå cha iSel = 0; // Xem nhö choïn muïc ñaàu tieân UINT nID // Soá hieäu comboBox m_listboxDanhsach.GetText( iSel, info ); ); Khôûi taïo thoâng soá cho ñoái töôïng comboBox. m_editName.SetWindowText( info ); 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. Khai baùo ID resource: IDC_DANHSACH, thuoäc tính protected CBS_SIMPLE : Simple comboBox. m_listboxDanhsach kieåu CLisBox quaûn lyù listbox. CBS_DROPDOWN : Drop-Down comboBox. Haønh vi OnCreate thöïc hieän caùc khôûi taïo caàn thieát cho listbox. CBS_SORT : Danh saùch caùc muïc xeáp thöù töï. int CEmpWnd::OnCreate( LPCREATESTRUCT lpCreateStruct ) int GetCount( ); Traû veà soá muïc choïn trong comboBox. { int GetCurSel( ); Traû veà chæ soá muïc ñöôïc choïn trong comboBox. if (CWnd::OnCreate(lpCreateStruct) == -1) return -1; int SetCurSel( int nSelect ); AÁn ñònh muïc choïn trong comboBox. ... // Thöïc hieän töông töï döï aùn VD21, void GetLBText ( // Vaø boå sung caùc noäi dung sau: int nIndex, // Chæ soá muïc trong comboBox m_listboxDanhsach.Create ( CString& rString // Bieán chöùa keát quaû WS_CHILD | WS_VISIBLE | WS_BORDER | ); Laáy noäi dung thoâng baùo cuûa moät muïc trong comboBox. LBS_NOTIFY | WS_VSCROLL, void ShowDropDown ( CRect( 195, 7, 280, 65 ), this, IDC_DANHSACH ); BOOL bShowIt = TRUE // TRUE = hieån thò ; FALSE = daáu m_listboxDanhsach.AddString( "Ong A" ); ); Hieån thò hoaëc danh saùch chöùa caùc muïc hoã trôï trong comboBox. m_listboxDanhsach.AddString( "Ba B" ); int AddString(LPCTSTR lpszString ); Nhö listbox. m_listboxDanhsach.AddString( "Co C" ); int DeleteString( UINT nIndex ); Nhö listbox. return 0; int InsertString( int nIndex , LPCTSTR lpszString ); Nhö listbox. } void ResetContent( ); Nhö listbox. Trong MessageMap cuûa CEmpWnd, boå sung muïc xöû lyù message: virtual void DrawItem ( ON_LBN_SELCHANGE( IDC_DANHSACH, OnSelectDanhsach ) LPDRAWITEMSTRUCT lpDrawItemStruct ); Nhö listbox. 8.5 CComboBox: virtual void MeasureItem ( CComboBox laø lôùp ñoái töôïng quaûn lyù hoäp nhaäp vaø phaàn hoã trôï nhaäp vôùi LPMEASUREITEMSTRUCT lpMeasureItemStruct 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 ); Nhö listbox. saùch hoã trôï taïo thaønh caùc daïng khaùc nhau cuûa comboBox: virtual void DeleteItem ( - Drop-list : Giaù trò nhaäp chæ ñöôïc choïn töø danh saùch. LPDELETEITEMSTRUCT lpDeleteItemStruct - Simple : Nhö Drop-list maø danh saùch hieån thò thöôøng tröïc. ); Nhö listbox. - 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. 88 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Caùc lôùp ñoái töôïng nhaäp lieäu 89
  • 54. ComboBox vaø cöûa soå cha: Ñoái töôïng comboBox coù theå göûi message ñeán ... // Nhö VD22, boå sung caùc noäi dung sau: 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 m_Combobox.Create ( ON_Notification maø cöûa soå cha duøng xöû lyù message töø comboBox laø: WS_CHILD | WS_VISIBLE | WS_BORDER | CBS_DROPDOWNLIST, Muïc xöû lyù message YÙ nghóa cuûa message ñöôïc xöû lyù CRect( 135, 100, 280, 225 ), this, ON_CBN_CLOSEUP Danh saùch vöøa ñöôïc ñoùng laïi IDC_COMBOBOX ); ON_CBN_DBLCLK Double-click treân muïc choïn m_Combobox.AddString( "Vo van A" ); ON_CBN_DROPDOWN Danh saùch vöøa ñöôïc môû ra m_Combobox.AddString( "Nguyen thi B" ); ON_CBN_EDITCHANGE Noäi dung hoäp nhaäp ñang thay ñoåi m_Combobox.AddString( "Tran thi C" ); return 0; 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 Trong MessageMap cuûa CEmpWnd, khai baùo muïc xöû lyù message: ON_CBN_KILLFOCUS Keát thuùc nhaäp lieäu trong comboBox ON_CBN_SELCHANGE( IDC_COMBOBOX,OnSelectCombobox ) 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 8.6 CSpinButtonCtrl: Thöïc haønh: Vieát öùng duïng töông töï VD22, Boå sung combobox kieåu CSpinButtonCTrl laø lôùp ñoái töôïng quaûn lyù nuùt taêng-giaûm treân cöûa soå giao dropdown coù ba muïc choïn: "Vo van A", "Nguyen thi B" vaø "Tran thi C". dieän. Nuùt taêng-giaûm ñöôïc duøng hoã trôï cho caùc hoäp nhaäp soá nguyeân. Khi choïn treân combobox, noäi dung choïn ñöôïc ñieàn vaøo hoäp nhaäp Name. CSpinButtonCtrl( ); Taïo laäp ñoái töôïng roãng. HD: Duøng ON_CBN_SELCHANGE ñònh höôùng xöû lyù message lieân quan. BOOL Create ( Taïo döï aùn VD23 töông töï VD22. Chænh söûa lôùp CEmpWnd nhö sau: DWORD dwStyle, // Chöùa thoâng soá daïng nuùt taêng giaûm Boå sung haønh vi protected: afx_msg void OnSelectCombobox () 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 void CEmpWnd::OnSelectCombobox() 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. CString info; int iSel = m_Combobox.GetCurSel( ); dwStyle: Goàm thoâng soá qui ñònh ñoái vôùi control vaø caùc daïng boå sung: if (iSel == LB_ERR) // no selection UDS_HORZ : Hai nuùt taêng-giaûm naèm ngang iSel = 0; UDS_SETBUDDYINT : Duøng cho hoäp nhaäp soá nguyeân. m_Combobox.GetLBText( iSel, info ); UDS_ALIGNRIGHT : Naèm beân phaûi hoäp nhaäp. m_editName.SetWindowText( info ); 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. Khai baùo ID resource: IDC_COMBOBOX. Khai baùo ñoái töôïng thuoäc CWnd* SetBuddy ( tính protected m_Combobox kieåu CComboBox quaûn lyù comboBox. CWnd* pWndBuddy // Con troû ñoái töôïng ñöôïc hoã trôï. Haønh vi OnCreate thöïc hieän caùc khôûi taïo caàn thieát cho comboBox: ); 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ù. int CEmpWnd::OnCreate (LPCREATESTRUCT lpCreateStruct) { CWnd* GetBuddy( ); Traû veà con troû ñoái töôïng hoäp nhaäp ñöôïc hoã trôï. if (CWnd::OnCreate(lpCreateStruct) == -1) return -1; 90 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Caùc lôùp ñoái töôïng nhaäp lieäu 91
  • 55. void SetRange ( Haønh vi OnClickNhapxong thöïc hieän hieån thò thoâng tin nhaäp: int nLower, // Giaù trò caän döôùi void CEmpWnd::OnClickNhapxong( ) 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. CString yourname, yourage, mess; void GetRange ( m_editName.GetWindowText( yourname ); int &lower, // Tham bieán chöùa giaù trò caän döôùi m_editAge.GetWindowText( yourage ); int& upper // Tham bieán chöùa giaù trò caän treân mess.Format ( "%sn is %s years old", yourname, yourage ); ); Laáy thoâng tin veà giôùi haïn cuûa nuùt taêng-giaûm. MessageBox( mess,"Hello!", MB_OK | MB_ICONEXCLAMATION ); } 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. 8.7 CProgressCtrl: Thöïc haønh: Vieát öùng duïng töông töï VD21; muïc thoâng baùo "Enter your CProgressCtrl laø lôùp ñoái töôïng quaûn lyù thanh tieán ñoä xöû lyù treân giao dieän. 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- CProgressCtrl( ); Taïo laäp ñoái töôïng roãng. 250. Nuùt choïn "Nhap xong" cho pheùp hieån thò teân vaø tuoåi vöøa nhaäp. BOOL Create ( DWORD dwStyle, // Thoâng soá daïng thanh tieán ñoä xöû lyù Taïo döï aùn VD24 töông töï VD21. Chænh söûa lôùp CEmpWnd nhö sau: const RECT& rect, // Toaï ñoä, kích thöôùc cuûa thanh Khai baùo thuoäc tính m_editAge kieåu CEdit quaûn lyù hoäp nhaäp. CWnd* pParentWnd, // Con troû ñoái töôïng cöûa soå cha Haønh vi OnCreate thöïc hieän khôûi taïo thoâng soá cho caùc muïc. Rieâng muïc UINT nID // Soá hieäu cuûa thanh tieán ñoä 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 ); Haønh vi khôûi taïo thoâng soá cho thanh tieán ñoä treân giao dieän. quaûn lyù chuùng seõ ñöôïc khai baùo static trong OnCreate: dwStyle: Goàm thoâng soá qui ñònh ñoái vôùi control vaø caùc daïng boå sung: int CEmpWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) 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. if (CWnd::OnCreate(lpCreateStruct) == -1) return -1; void SetRange ( ... // Töông töï VD21, vaø caùc noäi dung boå sung sau: short nLower, // Giaù trò nhoû nhaát m_editAge.Create ( WS_CHILD | WS_VISIBLE | WS_BORDER | ES_NUMBER, short nUpper // Giaù trò lôùn nhaát CRect( 135, 45, 190, 65 ), this, -1 ); ); AÁn ñònh giôùi haïn tieán ñoä xöû lyù chæ bôûi thanh tieán ñoä. void GetRange( static CStatic m_staticAge; static CSpinButtonCtrl m_spinAge; int& nLower, // Bieán chöùa giaù trò nhoû nhaát m_staticAge.Create ( _T( "Enter your age:" ), int& nUpper // Bieán chöùa giaù trò lôùn nhaát WS_CHILD | WS_VISIBLE, ); Laáy thoâng tin veà giôùi haïn tieán ñoä xöû lyù chæ bôûi thanh tieán ñoä. CRect( 10, 45, 130, 65 ), this ); int SetPos( int nPos ); AÁn ñònh vò trí hieän taïi cuûa thanh tieán ñoä. m_spinAge.Create ( WS_CHILD | WS_VISIBLE | int GetPos( ); Traû veà vò trí hieän taïi cuûa thanh tieán ñoä xöû lyù. UDS_ARROWKEYS | UDS_SETBUDDYINT | UDS_ALIGNRIGHT, int OffsetPos( int nPos ); AÁn ñònh möùc taêng (giaûm) treân moät ñôn vò cuûa CRect(0,0,1,1), this, -1 ); chæ muïc tieán ñoä trong thanh tieán ñoä baèng nPos, ñoàng thôøi caäp nhaät traïng m_spinAge.SetBase( 1 ); m_spinAge.SetRange( 15, 250 ); m_spinAge.SetBuddy ( &m_editAge ); thaùi hieån thò cuûa thanh tieán ñoä theo giaù trò aán ñònh môùi. return 0; int StepIt( ); Thay ñoåi chæ muïc tieán ñoä moät ñôn vò. } 92 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Caùc lôùp ñoái töôïng nhaäp lieäu 93
  • 56. 8.8 CScrollBar: Khai baùo caùc thuoäc tính protected: m_staticScroll kieåu CStatic quaûn lyù CScrollBar laø lôùp ñoái töôïng quaûn lyù thanh cuoän treân cöûa soå giao dieän. muïc thoâng baùo, m_Scroll kieåu CScrollBar quaûn lyù thanh cuoän. CScrollBar( ); Taïo laäp ñoái töôïng roãng. Haønh vi OnCreate thöïc hieän khôûi taïo thoâng soá cho caùc muïc: BOOL Create ( int CEmpWnd::OnCreate( LPCREATESTRUCT lpCreateStruct ) 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 if (CWnd::OnCreate(lpCreateStruct) == -1) return -1; CWnd* pParentWnd, // Con troû ñoái töôïng cöûa soå cha m_staticScroll.Create( _T(""), UINT nID // Soá hieäu thanh cuoän WS_CHILD | WS_VISIBLE, ); Khôûi taïo thoâng soá cho ñoái töôïng thanh cuoän treân giao dieän. CRect( 10, 15, 120, 35 ), this ); m_Scroll.Create( WS_CHILD | WS_VISIBLE | SBS_HORZ, dwStyle: Goàm thoâng soá qui ñònh ñoái vôùi control vaø caùc daïng boå sung: CRect( 10,45,127,65 ), this, IDC_SCROLLBAR ); SBS_HORZ : Thanh cuoän ñaët ngang (horizontal) m_Scroll.SetScrollRange( 0,100 ); SBS_VERT : Thanh cuoän ñaët ñöùng (vertical) return 0; int GetScrollPos( ); Traû veà vò trí hieän thôøi cuûa moät thanh cuoän. } int SetScrollPos ( Haønh vi OnHScroll xöû lyù WM_HSCROLL: int nPos, // Vò trí ñaët nuùt cuoän void CEmpWnd::OnHScroll( UINT nSBCode, UINT nPos, BOOL bRedraw = TRUE // Caäp nhaät laïi hình aûnh thanh cuoän CScrollBar* pScrollBar ) ); Ñaët vò trí nuùt cuoän treân thanh cuoän. { char s[10]; void SetScrollRange ( int pos = nPos; int nMinPos, // Giaù trò nhoû nhaát switch (nSBCode) { int nMaxPos, // Giaù trò lôùn nhaát case SB_LINELEFT: pos = pScrollBar->GetScrollPos() - 1; BOOL bRedraw = TRUE // Caäp nhaät laïi thanh cuoän if (pos < 0) pos = 0; ); 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. pScrollBar->SetScrollPos( pos ); void GetScrollRange ( sprintf( s, "%d", pos ); m_staticScroll.SetWindowText(s); LPINT lpMinPos, // Chöùa vò trí ñaàu break; LPINT lpMaxPos // Chöùa vò trí cuoái case SB_LINERIGHT: ); 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. pos = pScrollBar->GetScrollPos() + 1; void ShowScrollBar ( BOOL bShow = TRUE ); Baät / Taét thanh cuoän. if (pos > 90) pos = 100; pScrollBar->SetScrollPos(pos); ScrollBar vaø cöûa soå cha: Ñoái töôïng scrollbar göûi WM_HSCROLL (ñoái vôùi sprintf(s, "%d", pos); m_staticScroll.SetWindowText(s); loaïi scrollbar ngang) hoaëc WM_VSCROLL (ñoái vôùi loaïi scrollbar ñöùng) break; ñ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 case SB_THUMBPOSITION: OnVScroll hoaëc OnHScroll cuûa ñoái töôïng CWnd quaûn lyù cöûa soå cha seõ xöû pScrollBar->SetScrollPos(pos); lyù caùc message töông öùng noùi treân. sprintf(s, "%d", pos); m_staticScroll.SetWindowText(s); break; Thöïc hieän öùng duïng nhö VD15. Boå sung thanh cuoän, vaø muïc thoâng baùo ñeå default: CWnd::OnHScroll(nSBCode, nPos, pScrollBar); 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: } Bieân dòch vaø chaïy thöû öùng duïng. 94 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Caùc lôùp ñoái töôïng nhaäp lieäu 95
  • 57. 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. 96 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 58. CHÖÔNG 9: CTLCOLOR_LISTBOX : Listbox CTLCOLOR_SCROLLBAR : Thanh tröôït Hoäp hoäi thoaïi 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 9.1 HOÄP HOÄI THOAÏI (DIALOG): haønh vi EndDialog ñöôïc duøng ñeå keát thuùc 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 void EndDialog ( 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, int nResult // Giaù trò tham soá cuûa haønh vi. goïi laø dialog resource. Coù hai kieåu hoaït ñoäng cuûa dialog: ); Haønh vi ñöôïc duøng ñeå keát thuùc hoaït ñoäng cuûa dialog kieåu khoùa. Dialog khoùa (modal dialog): Taùc vuï thöïc hieän dialog phaûi chôø ñeán khi virtual void OnOK( ); Haønh vi keá thöøa ñeå caøi ñaët xöû lyù choïn button coù dialog chaám döùt hoaït ñoäng. soá hieäu IDOK. Trong CDialog, phaàn caøi ñaët cuûa OnOK chæ laø leänh goïi Dialog khoâng khoùa (modeless dialog): Taùc vuï thöïc hieän dialog coù theå haønh vi EndDialog vôùi tham soá IDOK. tieáp tuïc caùc xöû lyù tieáp theo ngay sau leänh thöïc hieän dialog. virtual void OnCancel( ); Haønh vi keá ñeå caøi ñaët xöû lyù choïn button coù soá 9.2 LÔÙP CDialog: hieäu IDCANCEL (phím taét laø ESC). Trong CDialog, caøi ñaët cuûa CDialog laø lôùp ñoái töôïng keá thöøa töø lôùp CWnd, ñöôïc söû duïng ñeå quaûn lyù OnCancel chæ laø leänh goïi haønh vi EndDialog vôùi tham soá IDCANCEL. dialog. Ngoaøi caùc thuoäc tính vaø haønh vi keá thöøa public töø lôùp CWnd, lôùp BOOL Create ( CDialog coù caùc haønh vi boå sung sau ñaây: UINT nIDTemplate, // Soá hieäu dialog resource CDialog ( CWnd* pParentWnd = NULL // Con troû ñoái töôïng cöûa soå cha. UINT nIDTemplate, // Soá hieäu cuûa dialog resource ); Haønh vi kích hoaït dialog kieåu khoâng khoùa. CWnd* pParentWnd = NULL // Con troû ñoái töôïng cöûa soå cha virtual BOOL DestroyWindow( ); Haønh vi ñöôïc duøng ñeå keát thuùc hoaït ); Taïo laäp ñoái töôïng dialog hoaït ñoäng kieåu khoùa. ñoäng cuûa dialog kieåu khoâng khoùa. CDialog( ); Taïo laäp ñoái töôïng dialog hoaït ñoäng kieåu khoâng khoùa. CWnd* GetDlgItem ( virtual BOOL OnInitDialog( ); Haønh vi maø ñoái töôïng dialog söû duïng ñeå int nID // Soá hieäu cuûa control treân dialog xöû lyù WM_INITDIALOG, message do windows göûi ñeán dialog tröôùc ); Traû veà con troû ñoái töôïng thuoäc lôùp CWnd quaûn lyù control. khi kích hoaït dialog. Keá thöøa haønh vi naøy nhaèm thöïc hieän khôûi taïo int GetDlgItemText ( thoâng soá cho dialog vaø caùc controls cuûa noù. int nID, // Soá hieäu cuûa control treân dialog afx_msg HBRUSH OnCtlColor ( CString& rString // Tham bieán kieåu chuoãi chöùa keát quaû CDC* pDC, // Con troû ñoái töôïng DC cuûa control ); Laáy noäi dung chuoãi thoâng baùo cuûa control. CWnd* pWnd, // Con troû ñoái töôïng cöûa soå quaûn lyù control UINT GetDlgItemInt ( UINT nCtlColor // Thoâng tin veà loaïi control ñöôïc trang trí int nID // Soá hieäu cuûa control treân dialog ); Haønh vi xöû lyù WM_CTLCOLOR, message do windows göûi ñeán ); Traû veà giaù trò soá cuûa noäi dung nhaäp trong control. dialog khi coù nhu caàu trang trí moät control treân dialog. void SetDlgItemText ( nCtlColor coù theå laø moät trong caùc giaù trò sau: int nID, // Soá hieäu cuûa control treân dialog CTLCOLOR_BTN : Ñoái töôïng trang trí laø button LPCTSTR lpszString // Giaù trò kieåu chuoãi CTLCOLOR_DLG : Dialog ); Ñaët noäi dung kieåu chuoãi cho control. CTLCOLOR_EDIT : Hoäp nhaäp lieäu Hoäp hoäi thoaïi 97 98 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 59. void SetDlgItemInt ( Thieát keá dialog thoâng qua maøn hình thieát keá maø ta vöøa nhaän ñöôïc töø int nID, UINT nValue // Soá hieäu control vaø giaù trò gaùn böôùc treân. Caùc thao taùc cô baûn nhö sau: ); Gaùn giaù trò soá nValue cho control. • Baät / Taét thanh coâng cuï hoã trôï thieát keá dialog: UINT IsDlgButtonChecked ( - Choïn muïc menu Tools / Customize... 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. - Ñaùnh daáu hoaëc boû ñaùnh daáu muïc Controls. Choïn Close. 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 (Thanh coâng cuï vôùi caùc loaïi control söû duïng ñöôïc treân dialog) chæ vieäc khai baùo bieán ñoái • AÁn ñònh caùc ñaëc tính cuûa dialog resource: Right-clict treân khung töôïng thuoäc lôùp noùi treân vaø söû dialog resource (vuøng khoâng caøi controls), choïn muïc Properties: 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 ). - Choïn General ñeå aán ñònh caùc thoâng soá chung. Hoäp hoäi thoaïi 99 100 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 60. ID : Soá hieäu cuûa dialog resource. Static edge : Khung chìm. Caption : Noäi dung tieâu ñeà cuûa dialog. • Caøi ñoái töôïng hoäp nhaäp leân dialog: Menu : Soá hieäu cuûa menu resource gaén vaøo dialog. - Click choïn bieåu töôïng treân thanh coâng cuï. Font : AÁn ñònh font duøng cho noäi dung chöõ treân dialog. - Thöïc hieän caøi ñaët vaø aán ñònh thoâng soá nhö vôùi muïc thoâng baùo: - Choïn Styles ñeå aán ñònh thoâng soá daïng cöûa soå cuûa dialog: Multi Line : Hoäp nhaäp cho pheùp nhaäp nhieàu doøng. Style : Ñaëc tính cuûa dialog. Chaúng haïn choïn Popup cho AutoHScroll/AutoVScroll : Töï ñoäng tröôït noäi dung khi thoâng pheùp dialog taïo ra coù thoâng soá daïng WS_POPUP. tin nhaäp vöôït quaù kích thöôùc hoäp nhaäp. Border : Kieåu ñöôøng vieàn cuûa dialog. HorizontalScroll | VerticalScroll : Hieån thò thanh tröôït ngang, Title Bar : Dialog coù tieâu ñeà. doïc cuûa hoäp nhaäp. System Menu : Dialog coù hoäp System Menu. Want return : Söû duïng phím enter ñeå xuoáng doøng trong hoäp - Choïn More Styles ñeå aán ñònh caùc thoâng soá daïng môû roäng: nhaäp nhieàu doøng. Visible : Dialog hieån thò. Ñoái vôùi dialog resource duøng cho Password : Duøng nhaäp password. modeless dialog thì muïc naøy phaûi luoân ñöôïc choïn. • Caøi ñoái töôïng comboBox leân dialog: - Choïn Extended Style ñeå aán ñònh caùc thoâng soá daïng môû roäng: - Click choïn bieåu töôïng treân thanh coâng cuï. ToolWindow : Töông öùng WS_EX_TOOLWINDOW. - Thöïc hieän caøi ñaët vaø aán ñònh thoâng soá nhö vôùi muïc thoâng baùo: Static edge : Vuøng client ñöôïc chìm xuoáng (3D). Data : Chöùa caùc muïc choïn. Caùc muïc naøy ñöôïc nhaäp treân caùc Goõ phím Enter ñeå keát thuùc. doøng khaùc nhau. Löu yù duøng phím Ctrl+Enter ñeå xuoáng doøng. • Caøi ñoái töôïng muïc thoâng baùo leân dialog: Type : Kieåu comboBox. - Click choïn bieåu töôïng treân thanh coâng cuï. Sort : Caùc muïc trong comboBox ñöôïc saép xeáp theo noäi dung. - Drag chuoät treân vuøng daønh cho muïc thoâng baùo treân dialog. • Caøi ñoái töôïng comboBox leâ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 - Click choïn bieåu töôïng treân thanh coâng cuï. Properties. Thöïc hieän caùc aán ñònh caàn thieát: - Thöïc hieän caøi ñaët vaø aán ñònh thoâng soá nhö vôùi muïc thoâng baùo: ID : Soá hieäu muïc thoâng baùo, maëc nhieân IDC_STATIC. Ñeå Selection : Kieåu listbox. dialog nhaän dieän ñöôïc muïc khi xöû lyù message thì giaù trò naøy Multi-column : Listbox coù nhieàu coät. phaûi ñöôïc khai baùo töôøng minh vaø duy nhaát. Want Key Input : Lisbox cho pheùp xöû lyù phím. Caption : chuoãi thoâng baùo • Caøi ñoái töôïng button leân dialog: Style : - Click choïn bieåu töôïng treân thanh coâng cuï. Visible : Neáu ñaùnh daáu thì muïc ñöôïc hieån thò. - Thöïc hieän caøi ñaët vaø aán ñònh thoâng soá nhö vôùi muïc thoâng baùo: Align Text : Canh chænh noäi dung thoâng baùo trong muïc. Default Button: Button öùng vôùi phím taét laø Enter. Center Vertically : Canh chænh giöõa noäi dung thoâng baùo theo Multi-lines: Noäi dung thoâng baùo cuûa button coù nhieàu doøng. chieàu doïc trong muïc. Notify : Button coù khaû naêng thoâng tin cho cöûa soå cha. Border : Coù khung bao quanh muïc thoâng baùo. • Ñaùnh daáu choïn caùc ñoái töôïng treân dialog: Thöïc hieän thao taùc click. Sunken : Khung chìm. Phoái hôïp phím Shift hoaëc Ctrl ñeå ñaùnh daáu nhieàu ñoái töôïng. Notify : Muïc thoâng baùo coù khaû naêng thoâng tin cho cöûa soå cha. • Chænh vò trí cuûa moät ñoái töôïng: Thöïc hieän thao taùc drag ñoái töôïng. Extened style : • Chænh kích thöôùc cuûa moät ñoái töôïng: Transparent : Neàn muïc trong suoát. - Click choïn ñoái töôïng. Hoäp hoäi thoaïi 101 102 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 61. - Thöïc hieän thao taùc Drag treân bieân cuûa - File name = OptDlg : Teân taäp tin, ñoái töôïng ñeå ñaït kích thöôùc mong muoán. - Base class = CDialog : Lôùp cô sôû • Canh chænh vò trí, kích thöôùc moät nhoùm ñoái töôïng: - Dialog ID = IDD_OPTION : Soá hieäu dialog resource. - Ñaùnh daáu nhoùm ñoái töôïng Sau cuøng choïn OK. - Choïn coâng cuï phuø hôïp treân thanh coâng cuï: Ñoùng maøn hình thieát keá dialog. Trong maøn hình Workspace, choïn Canh thaúng theo bieân: ClassView, ta coù lôùp COptionDlg trong danh saùch caùc lôùp cuûa döï aùn. Canh thaúng giöõa dialog: Treân lôùp COptionDlg, ta coù theå thöïc hieän boå sung thuoäc tính, caøi ñaët caùc Caùc ñeàu nhau: haønh vi thoâng thöôøng cuõng nhö caùc haønh vi xöû lyù message. Caùc thao taùc Baèng côõ ñoái töôïng choïn cuoái cuøng trong nhoùm: hoaøn toaøn töông töï nhö ñaõ thöïc hieän vôùi caùc lôùp CEmpApp vaø CEmpWnd. 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: 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ø Khai baùo ñoái töôïng thuoäc lôùp dialog môùi taïo. Duøng chæ thò #include taäp caùc ñoái töôïng nhaäp lieäu ñöôïc moâ taû trong dialog resource ôû treân. tin (.H) chöùa khai baùo lôùp ôû ñaàu chöông trình: Trong maøn hình thieát keá dialog, choïn View / ClassWizard (Ctrl+W). #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ø Choïn OK ñeå taïo lôùp môùi öùng vôùi dialog resource. 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 - Name = COptionDlg : Nhaäp teân lôùp môùi ñoái töôïng cung caáp thoâng tin. Hoäp hoäi thoaïi 103 104 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 62. Ñoái töôïng cung caáp thoâng tin seõ duøng handle cuûa ñoái töôïng nhaän tin ñeå Haønh vi xöû lyù choïn nuùt OK cuûa lôùp COptionDlg: Thöïc hieän vieäc laáy 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 thoâng tin töø hoäp nhaäp cuûa noù ñeå gaùn cho ñoái töôïng hoäp nhaäp cuûa mình vaøo caùc oâ chöùa tin cuûa ñoái töôïng nhaän tin. m_editName treân cöûa soå cha CEmpWnd. Thöïc haønh: Taïo öùng duïng VD26 nhö VD25. Thöïc hieän caùc boå sung: Khi void COptionDlg::OnOK() 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 CString name; cöûa soá chính, ngöôïc laïi muïc choïn Cancel seõ khoâng xöû lyù gì caû. // Laáy thoâng tin nhaäp trong hoäp nhaäp cuûa dialog HD: Muïc nhaäp YourName ñöôïc quaûn lyù bôûi thuoäc tính m_editName cuûa GetDlgItemText( IDC_NAME, name ); ñoái töôïng CEmpWnd, ñaây laø oâ chöùa tin cuûa ñoái töôïng nhaän tin CEmpWnd. // 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 ); Ñoái töôïng COptionDlg laø ñoái töôïng cung caáp tin. Xöû lyù ñieàn thoâng tin chæ // Duøng haønh vi lôùp cô sôû ñeå keát thuùc dialog. 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ø CDialog::OnOK(); ñ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 OnOK cuûa lôùp COptionDlg bò loãi do truy xuaát thuoäc tính kieåu Haønh vi thöïc hieän OptionDlg trong CEmpWnd söû duïng duøng con troû chæ protected m_editName cuûa lôùp CEmpWnd. Ñeå khaéc phuïc loãi naøy, ta ñeán noù laøm tham soá cho haønh vi taïo laäp cuûa ñoái töôïng COptionDlg: khai baùo lôùp COptionDlg laø moät lôùp baïn (friend) cuûa lôùp CEmpWnd. void CEmpWnd::OnGameOption () class CEmpWnd : public CWnd { { COptionDlg dlg( this ); friend class COptionDlg; // COptionDlg is a friend dlg.DoModal(); public: } CEmpWnd(); Boå sung thuoäc tính protected m_parent kieåu con troû CEmpWnd* cho ... // other declarations 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 9.5 SÖÛ DUÏNG DIALOG LAØM GIAO DIEÄN CHÍNH CUÛA ÖÙNG DUÏNG: ñaàu taäp tin khai baùo (.h) cuûa lôùp COptionDlg. Keá thöøa töø CWnd, lôùp CDialog vaø caùc lôùp keá thöøa töø noù coù theå duøng khai Haønh vi taïo laäp cuûa COptionDlg löu giöõ giaù trò con troû cöûa soå cha ñöôïc baùo caùc ñoái töôïng cöûa soå giao dieän chính cuûa öùng duïng. truyeàn cho noù vaøo thuoäc tính m_parent. 9.5.1 Thöïc hieän öùng duïng vôùi giao dieän chính laø dialog: COptionDlg::COptionDlg ( CWnd* pParent ) Taïo döï aùn VD27 töông töï VD03 (döï aùn chæ coù lôùp keá thöøa CWinApp). : CDialog( COptionDlg::IDD, pParent ) { Taïo dialog resource coù noäi dung tuøy yù laøm giao dieän chính. m_parent = (CEmpWnd*) pParent; Taïo lôùp quaûn lyù dialog resource. Giaû söû lôùp coù teân laø CMainDlg coù maõ //{{AFX_DATA_INIT(COptionDlg) nguoàn trong caùc taäp tin MainDlg.H vaø MainDlg.CPP. // NOTE: the ClassWizard will add member initialization here Ñaêng kyù söû duïng lôùp CMainDlg cho phaàn caøi ñaët cuûa lôùp quaûn lyù öùng //}}AFX_DATA_INIT 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. Hoäp hoäi thoaïi 105 106 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 63. BOOL CEmpApp::InitInstance () Ñieàn caùc thoâng tin trong hoäp hoäi thoaïi New, Sau ñoù choïn OK. { 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 muïc Dialog Based, sau ñoù choïn Next. Choïn menu File / New. Hoäp hoäi thoaïi 107 108 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 64. AÁn ñònh caùc muïc choïn nhö treân. Sau ñoù choïn Next. Ñ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 Choïn cô cheá lieân keát vôùi thö vieän MFC. Sau ñoù choïn next. Khai baùo bieán m_szNhap kieåu CString, duøng löu giaù trò hoäp nhaäp lieäu. Cuoái cuøng, aán ñònh teân taäp tin chöùa khai baùo caùc lôùp. Choïn Finish. Caùch thöïc hieän nhö sau: Bieân dòch vaø chaïy thöû öùng duïng. • Môû resource cuûa dialog chính, choïn muïc View/ClassWizard. 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. Hoäp hoäi thoaïi 109 110 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 65. • Choïn trang Member Variables, choïn muïc coù soá hieäu IDC_NHAP. void CEmpDlg::OnDat() Sau ñoù choïn muïc Add Variable…. { 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ÔÏ: - Meber variable name = m_szNhap : Teân bieán ÖÙng duïng phaùt trieån trong VC coù theå deã daøng khai thaùc caùc tieän ích hoã trôï - Category = Value : Loaïi bieán bôûi VC (VC Components) hoaëc bôûi caùc öùng duïng khaùc ñöôïc caøi ñaët trong heä - Variable type = CString : Kieåu cuûa bieán. Choïn OK. thoáng (ActiveX Controls). Vieäc boå sung vaø khai thaùc caùc tieän ích naøy trong Khai baùo bieán m_editNhap kieåu CEdit. Bieán naøy ñöôïc söû duïng ñeå taùc öùng duïng ñöôïc thöïc hieän thoâng qua caùc böôùc sau: ñoäng giaù trò hoäp nhaäp lieäu. Thöïc hieän nhö khai baùo bieán m_szNhap: 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… 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: • Choïn nhoùm tieän ích: Double-click muïc nhoùm tieän ích caàn duøng. Hoäp hoäi thoaïi 111 112 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 66. 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: (Danh saùch caùc tieän ích cuûa MS Visual C++) 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 • Choïn tieän ích: cuûa öùng duïng laø lôùp söû duïng. Hai haønh vi boå sung töï ñoäng cho lôùp: Choïn muïc thích hôïp trong danh saùch tieän ích chi tieát. Choïn Insert. - 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 Choïn OK ñeå khaúng ñònh thao taùc. control naøy leân dialog giao dieän. • Khai baùo thoâng tin lôùp ñoái töôïng quaûn lyù tieän ích boå sung (neáu coù). Duøng MFC Wizard taïo döï aùn XemLich vôùi dialog giao dieän chính. • Khai baùo thoâng tin lôùp ñoái töôïng trong öùng duïng söû duïng tieän ích. Ñaêng kyù 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. • Nhoùm tieän ích = Registered ActiveX Controls. • Tieän ích = Calendar Control 8.0 Hoäp hoäi thoaïi 113 114 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 67. • Khai baùo thoâng tin lôùp ñoái töôïng quaûn lyù tieän ích: 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ø. Choïn OK, Choïn Close ñeå ñoùng hoäp hoäi thoaïi tieän ích. 8. Thöïc hieän öùng duïng vôùi giao dieän chính laø dialog. Dialog naøy cho pheùp • Lôùp ñoái töôïng CXemLichDlg quaûn lyù dialog giao dieän chính cuûa döï 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ù. aùn laøm nhieäm vuï söû duïng control boå sung naøy: 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 - Môû resource dialog giao dieän, caøi ñaët control sau: "Mailto: emp@hcmueco.edu.vn". Hình aûnh chuoät ñoåi thaønh khi di chuyeån - Hoäp xem vaø choïn ngaøy CCalendar IDC_DATE chuoät leân vò trí muïc. Click choïn muïc cho pheùp göûi mail. - Taïo bieán ñieàu khieån m_Lich kieåu CCalendar cho control. HD: - Haønh vi OnInitDialog cuûa lôùp ñaët giaù trò cho control: - Xöû lyù WM_CTLCOLOR ñeå ñaët maøu neàn cuûa dialog vaø maøu chöõ muïc. BOOL CXemLichDlg::OnInitDialog() - 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: CDialog::OnInitDialog(); HINSTANCE ShellExecute ( SetIcon(m_hIcon, TRUE); SetIcon(m_hIcon, FALSE); HWND hWnd, // Handle cöûa soå cha. LPCTSTR lpOperation, // Chuoãi noäi dung taùc vuï m_Lich.SetDay( 19 ); m_Lich.SetMonth( 11 ); LPCTSTR lpFile, // Ñöôøng daãn taäp tin chöông trình m_Lich.SetYear( 2002 ); LPCTSTR lpParameters, // Chuoãi tham soá doøng leänh LPCTSTR lpDirectory, // Ñöôøng daãn thö muïc laøm vieäc return TRUE; } 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. Coù theå söû duïng caùc haønh vi: GetDay, GetMonth, GetYear cuûa VÍ DUÏÏ: Ñeå göûi mail, ta söû duïng haøm treân nhö sau. ñoái töôïng m_List ñeå laáy thoâng tin veà ngaøy ñöôïc choïn. ShellExecute( NULL, "open", "Mailto:emp@hcmueco.edu.vn","","", SW_SHOW ); Bieân dòch vaø chaïy thöû öùng duïng. Hoäp hoäi thoaïi 115 116 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 68. CHÖÔNG 10: CStatusBar( ); Taïo laäp ñoái töôïng roãng. BOOL Create ( KHUNG CÖÛA SOÅ GIAO DIEÄN CHÍNH CWnd* pParentWnd, /* Con troû ñoái töôïng cöûa soå cha */ 10.1 KHUNG CÖÛA SOÅ GIAO DIEÄN (FRAME WINDOW): /* Thoâng soá daïng cuûa statusbar vaø giaù trò maëc nhieân */ Frame window laø loaïi cöûa soå chuyeân duøng laøm maøn hình chính cuûa öùng DWORD dwStyle WS_CHILD | WS_VISIBLE | CBRS_BOTTOM, duïng. Frame window coù caùc ñaëc ñieåm nhö sau: /* 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 Cho pheùp loàng vaøo frame window thanh traïng thaùi (statusbar), thanh ID_INDICATOR_SCRL : Pane traïng thaùi phím scrolllock coâng cuï (toolbar), menu vaø caùc phím taét treân menu. void SetWindowText ( Cho pheùp loàng moät ñoái töôïng view (thuoäc lôùp keá thöøa töø CWnd) vaøo LPCTSTR lpszString // Noäi dung thoâng baùo caäp nhaät vuøng client cuûa frame window ñeå hoaït ñoäng phoái hôïp trong vieäc hieån ); Caäp nhaät thoâng baùo cho pane coù soá hieäu laø 0. thò noäi dung trao ñoåi cuûa öùng duïng. Haønh vi OnSetFocus cuûa frame BOOL SetPaneText ( window thöïc hieän haønh vi OnSetFocus cuûa view ñeå taïo söï ñoàng boä giöõa int nIndex, // Soá hieäu pane frame vaø view khi kích hoaït. Thoâng qua haønh vi OnCmdMsg, frame LPCTSTR lpszNewText, // Noäi dung thoâng baùo caäp nhaät window coù theå ñieàu phoái command message cho view. BOOL bUpdate=TRUE // Veõ laïi thoâng tin caäp nhaät 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 ); Caäp nhaät noäi dung thoâng baùo trong pane moät pane. ñoái töôïng tröïc thuoäc: menu, toolbar, statusbar, view. void SetPaneInfo ( Cho pheùp cô cheá thöïc hieän WinHelp vaø töï ñoäng keát thuùc WinHelp khi int nIndex, // Soá thöù töï pane trong statusbar frame window chaám döùt hoaït ñoäng. UINT nID, // Soá hieäu gaùn cho pane 10.2 THANH TRAÏNG THAÙI (STATUSBAR) & LÔÙP CStatusBar: UINT nStyle, // Thoâng soá daïng cuûa pane StatusBar laø khung bao goàm caùc hoäp (pane) chöùa thoâng baùo. Thoâng qua int cxWidth // Ñoä roäng pane (tính baèng pixel) statusbar, öùng duïng coù theå thoâng tin cho ngöôøi duøng veà caùc hoaït ñoäng cuûa öùng ); AÁn ñònh caùc thoâng soá lieân quan hoaït ñoäng hieån thò cuûa pane. duïng vaø caùc thoâng soá lieân quan. Statusbar thöôøng ñöôïc ñaët ôû caïnh döôùi cuûa Giaù trò nStyle coù theå laø: frame window. Moãi pane treân statusbar coù theå ñöôïc aán ñònh moät kieåu daïng SBPS_NOBORDERS : Khoâng vieàn. theå hieän vaø noäi dung thoâng tin rieâng. SBPS_POPOUT : Vieàn noåi. Vieäc quaûn lyù statusbar trong öùng duïng ñöôïc MFC hoã trôï thoâng qua lôùp ñoái SBPS_DISABLED : Caám. töôïng CStatusBar. Caùc haønh vi ñaëc tröng cuûa lôùp naøy nhö sau: SBPS_STRETCH : Töï chænh kích thöôùc (cho 1 pane duy nhaát ). Khung cöûa soå giao dieän chính 117 118Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 69. SBPS_NORMAL : Khoâng coù kieåu daùng ñaëc bieät, void SetHeight( int cyHeight ); AÁn ñònh chieàu cao cuûa toolbar. void SetPaneStyle ( void EnableDocking ( int nIndex, // Soá thöù töï pane trong statusbar DWORD dwStyle // Caùch keát toolbar vaøo frame window UINT nStyle // Thoâng soá daïng cuûa pane // xem EnableDocking() cuûa CFrameWnd ); AÁn ñònh thoâng soá daïng cuûa pane. ); 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 10.3 THANH COÂNG CUÏ (TOOLBAR) & LÔÙP CToolBar: 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 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 phuø hôïp treân töøng nuùt choïn. 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 Thöïc hieän toolbar trong öùng duïng: Ta tieán haønh caùc böôùc sau ñaây. do MFC cung caáp nhaèm hoã trôï vieäc quaûn lyù toolbar trong öùng duïng. 10.3.1 Thieát keá toolbar resource: CToolBar( ); Taïo laäp ñoái töôïng roãng. Toolbar resource chöùa thoâng tin veà hình aûnh, soá hieäu, noäi dung thoâng baùo BOOL Create ( vaø caùc höôùng daãn cho töøng muïc choïn treân thanh toolbar. CWnd* pParentWnd, /* Con troû ñoái töôïng cöûa soå cha */ Môû döï aùn caàn boå sung toolbar resource trong VC. /* Thoâng soá daïng cuûa toolbar vôùi giaù trò maëc nhieân */ Taïo môùi toolbar resource: Thöïc hieän töông töï taïo môùi icon (2.8). DWORD dwStyle = WS_CHILD | WS_VISIBLE | CBRS_TOP, Löu yù: Choïn Resource Type = ToolBar. /* Soá hieäu cuûa toolbar, giaù trò maëc nhieân cho toolbar chính */ Ñaët soá hieäu cho toolbar (ví duï IDR_MAINFRAME cho toolbar chính). UINT nID = AFX_IDW_TOOLBAR Thieát keá toolbar thoâng qua maøn hình thieát keá maø ta vöøa nhaän ñöôïc töø ); Khôûi taïo thoâng soá cho ñoái töôïng toolbar. böôùc treân. Caùc thao taùc cô baûn nhö sau: dwStyle coù theå nhaän caùc thoâng soá sau: • Khai baùo thoâng soá cho nuùt choïn: CBRS_GRIPPER : Toolbar di chuyeån ñöôïc - Double-click treân nuùt: 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 - AÁn ñònh caùc thoâng soá cho nuùt: CRect rcBorders = CRect ( 0, 0, 0, 0 ), ID : Soá hieäu cuûa nuùt choïn, coù theå laø soá hieäu cuûa muïc menu. UINT nID = AFX_IDW_TOOLBAR Width, Height : Chieàu roäng vaø chieàu cao cuûa nuùt. ); Khôûi taïo ñoái töôïng toolbar vôùi thoâng soá daïng môû roäng. Prompt : Töông töï nhö Prompt cuûa muïc choïn treân menu. dwCtrlStyle coù theå laø TBSTYLE_TRANSPARENT (trong suoát). BOOL LoadToolBar ( • Theâm moät nuùt môùi: Double-click treân . Sau ñoù thöïc hieän khai UINT nIDResource // Soá hieäu cuûa toolbar resource baùo thoâng soá cho nuùt nhö treân. ); Taïo daïng cho toolbar töø toolbar resource. • Chuyeån vò trí cuûa nuùt: Drag nuùt ñeán vò trí thích hôïp. Khung cöûa soå giao dieän chính 119 120Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 70. • Taùch nhoùm nuùt: Drag nuùt ra xa vò trí nuùt keá caän. DWORD dwStyle = WS_OVERLAPPEDWINDOW, • Xoùa nuùt: Drag nuùt ra khoûi thanh toolbar. /* Toïa ñoä, kích thöôùc cuûa frame • Trang trí nuùt: Thöïc hieän nhö trang trí icon. rectDefault: Giaù trò maëc nhieân */ Khi thieát keá xong, choïn muïc Save vaø ñoùng maøn hình thieát keá toolbar. const RECT& rect = rectDefault, 10.3.2 Duøng toolbar resource cho ñoái töôïng CToolBar cuûa FrameWnd: // Con troû ñoái töôïng cöûa soå cha Khai baùo ñoái töôïng thuoäc tính kieåu CToolBar trong lôùp CFrameWnd CWnd* pParentWnd = NULL, cuûa öùng duïng: // Chuoãi teân menu resource CToolBar m_toolbar; // Ñaët trong khai baùo lôùp CFrameWnd LPCTSTR lpszMenuName = NULL, DWORD dwExStyle // Thoâng soá daïng frame môû roäng Haønh vi OnCreate cuûa FrameWnd khôûi taïo thoâng soá cho ñoái töôïng ); Khôûi taïo thoâng soá cho frame window. toolbar . Sau ñoù keát ñoái töôïng toolbar vaøo frame window. afx_msg int OnCreate( LPCREATESTRUCT lpCreateStruct ); Haønh vi int CEmpFrame::OnCreate( LPCREATESTRUCT lpCreateStruct ) 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 ( if (CFrameWnd::OnCreate(lpCreateStruct) == -1) UINT nIDResource, // Soá hieäu caùc resource lieân quan: icon, return -1; // cursor, baûng phím taét, menu (baét buoäc). // Create the main toolbar for frame window DWORD dwDefaultStyle // Thoâng soá daïng frame window m_toolbar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP = WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY); CWnd* pParentWnd // Con troû ñoái töôïng cöûa soå cha // Initiate toolbar’s appearance by toolbar resource ); Khôûi taïo thoâng soá cho frame window. m_toolbar.LoadToolBar(IDR_MAINFRAME); BOOL LoadAccelTable ( m_toolbar.EnableDocking(CBRS_ALIGN_ANY); LPCTSTR Baûng_phím_taét // Teân baûng phím taét trong resource // attach the toolbar to frame window ); Naïp baûng phím taét, chæ duøng khi frame ñöôïc khôûi taïo bôûi Create. this->EnableDocking(CBRS_ALIGN_ANY); virtual void ActivateFrame ( this->DockControlBar(&m_toolbar, AFX_IDW_DOCKBAR_TOP); int nCmdShow = -1 // Thoâng soá veà traïng thaùi kích hoaït return 0; } ); 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 ( 10.4 LÔÙP CFrameWnd: DWORD dwDockStyle // Thoâng soá aán ñònh CFrameWnd laø lôùp ñoái töôïng keá thöøa töø CWnd cho pheùp quaûn lyù frame ); Qui ñònh caùch keát thanh coâng cuï vaøo frame window. window trong öùng duïng. Ngoaøi caùc thuoäc tính vaø haønh vi keá thöøa public töø dwDockStyle coù theå nhaän moät trong caùc giaù trò sau: CWnd, CFrameWnd coù caùc thuoäc tính vaø haønh vi ñaëc tröng giuùp vieäc aán ñònh CBRS_ALIGN_TOP : Keát ôû caïnh treân vuøng client. vaø ñieàu khieån frame window ñöôïc deã daøng vaø hieäu quaû. CBRS_ALIGN_BOTTOM : Keát ôû caïnh döôùi CFrameWnd( ); Haønh vi taïo laäp. CBRS_ALIGN_LEFT : Keát ôû caïnh traùi BOOL Create ( CBRS_ALIGN_RIGHT : Keát ôû caïnh phaûi LPCTSTR lpszClassName, // Teân lôùp ñaõ ñaêng kyù cuûa frame CBRS_ALIGN_ANY : Keát ôû moïi vò trí noùi treân. LPCTSTR lpszWindowName, // Teân, tieâu ñeà cuûa frame window /* thoâng soá daïng cuûa frame */ Khung cöûa soå giao dieän chính 121 122Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 71. void DockControlBar ( Thöïc haønh 2: Thöïc hieän öùng duïng töông töï VD28, caøi heä thoáng menu CControlBar * pBar, // Con troû ñoái töôïng toolbar töông töï ví duï chöông 7 cho ñoái töôïng frame window. UINT nDockBarID // Thoâng soá aán ñònh Taïo môùi döï aùn VD29 töông töï döï aùn VD28. ); Keát ñoái töôïng toolbar vaøo frame window, söû duïng khi tröôùc ñoù ñònh Taïo môùi menu resource vôùi soá hieäu IDR_MAINFRAME, thieát keá menu caùch keát toolbar cho frame window laø CBRS_ALIGN_ANY. Thoâng soá naøy nhö moâ taû ôû chöông 7. 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: Taïo môùi baûng phím taét vôùi soá hieäu IDR_MAINFRAME. Khai baùo noäi AFX_IDW_DOCKBAR_TOP : Keát ôû caïnh treân dung baûng phím taét nhö muïc (7.5). AFX_IDW_DOCKBAR_BOTTOM : Keát ôû caïnh döôùi Haønh vi InitInstance cuûa CEmpApp thöïc hieän khai baùo con troû ñoái AFX_IDW_DOCKBAR_LEFT : Keát ôû caïnh traùi töôïng CFrameWnd*. Duøng haønh vi LoadFrame cuûa ñoái töôïng naøy ñeå AFX_IDW_DOCKBAR_RIGHT : Keát ôû caïnh phaûi khôûi ñoäng thoâng soá cho noù töø caùc resource lieân quan: virtual BOOL OnCreateClient ( BOOL CEmpApp::InitInstance() LPCREATESTRUCT lpcs, // Con troû ñeán caáu truùc chöùa { CCreateContext* pContext // Caùc thoâng soá lieân keát. CFrameWnd *main = new CFrameWnd; ); Haønh vi ñöôïc thöïc hieän khi caùc view ñaõ ñöôïc taïo xong. Keá thöøa haønh m_pMainWnd = main; main->LoadFrame(IDR_MAINFRAME); vi naøy ñeå aán ñònh caùc thoâng soá rieâng cuûa öùng duïng. main->ShowWindow(SW_SHOW); // Show the frame window virtual CWnd* GetMessageBar( ); Traû veà con troû troû ñeán ñoái töôïng return TRUE; statusbar tröïc thuoäc. } 10.5 SÖÛ DUÏNG FRAME WINDOW LAØM GIAO DIEÄN CHÍNH: 10.5.2 String Table vaø CFrameWnd: Keá thöøa töø CWnd, CFrameWnd vaø caùc lôùp keá thöøa töø noù coù theå duøng khai StringTable, moät thaønh phaàn trong resource cuûa öùng duïng, duøng chöùa caùc baùo caùc ñoái töôïng cöûa soå giao dieän chính cuûa öùng duïng. 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 10.5.1 Thöïc hieän öùng duïng vôùi giao dieän chính laø CFrameWnd: haèng chuoãi trong resource cöûa öùng duïng ñöôïc thöïc hieän nhö sau: Thöïc haønh 1: Thöïc hieän öùng duïng vôùi cöûa soå chính laø frame window. Taïo môùi resource (nhö 2.8). Löu yù choïn resource type laø String Table. 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 Double-click hoaëc goõ Enter treân doøng troáng cuûa StringTable: 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; } Khung cöûa soå giao dieän chính 123 124Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 72. - ID = Soá hieäu haèng chuoãi. int CEmpFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) - 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. if (CFrameWnd::OnCreate( lpCreateStruct ) == -1) return -1; Φ Söû duïng haèng chuoãi trong StringTable: Coù theå söû duïng haèng chuoãi trong // The IDs of all statusbar’panes StringTable laøm giaù trò cho bieán chuoãi trong chöông trình. Ñoái vôùi bieán UINT ID_array[3] = { 1, 1, ID_SEPARATOR }; chuoãi ñöôïc quaûn lyù bôûi ñoái töôïng chuoãi CString, xöû lyù naøy ñöôïc thöïc hieän m_status.Create( this ); // Thanh statusbar chính thoâng qua haønh vi sau: m_status.SetIndicators( ID_array, 3 ); BOOL CString::LoadString ( m_status.SetPaneText( 0, "Mr.Emp" ); UINT nID // Soá hieäu haèng chuoãi trong resource m_status.SetPaneText( 1, "Hello world!" ); ); // Set the size of each pane on statusbar Sau ñaây laø moät ví duï khôûi taïo giaù trò chuoãi myString töø string resource: m_status.SetPaneInfo( 0, 1000, 0, 40 ); CString myString; m_status.SetPaneInfo( 1, 1001, 0, 70 ); myString.LoadString (ID_GAME_OPTION ); m_status.SetPaneInfo( 2, ID_SEPARATOR, 0, 300 ); return 0; Φ 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õ Thöïc haønh 4: Vieát öùng duïng nhö VD30 vôùi thanh coâng cuï coù 4 nuùt choïn ñöôïc söû duïng laøm tieâu ñeà cuûa frame window naøy. töông öùng 4 muïc choïn trong heä thoáng menu. Môû döï aùn VD29. Taïo döï aùn VD31 nhö VD30. Taïo môùi haèng chuoãi “Emp.Example 29” trong StringTable vôùi soá hieäu Taïo môùi toolbar resource coù soá hieäu IDR_MAINFRAME vôùi caùc nuùt laø IDR_MAINFRAME. choïn töông öùng caùc muïc menu. Thöïc hieän chaïy thöû öùng duïng vaø quan saùt tieâu ñeà cöûa frame window. 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 Thöïc haønh 3: Thöïc hieän öùng duïng nhö VD29; thanh statusbar vôùi ba muïc thoâng soá cho caùc ñoái töôïng m_status vaø m_toolbar, sau ñoù keát ñoái töôïng (pane): muïc thöù nhaát chöùa noäi dung "Mr.Emp", muïc thöù hai chöùa noäi dung m_toolbar vaøo frame window "Hello world!", muïc thöù ba hieån thò thoâng tin hoaït ñoäng cuûa öùng duïng. int CEmpFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) 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 ... // Caùc caøi ñaët nhö VD30 CEmpFrame thöïc hieän khôûi taïo thoâng soá cho ñoái töôïng statusbar. Duøng m_toolbar.CreateEx ( this, CEmpFrame khai baùo ñoái töôïng cöûa soá chính cuûa öùng duïng. TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP Taïo döï aùn VD30 nhö VD29. | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY ); Boå sung lôùp CEmpFrame keá thöøa CFrameWnd. Xem (5.4.1). m_toolbar.LoadToolBar ( IDR_MAINFRAME ); Boå sung ñoái töôïng thuoäc tính protected m_status thuoäc lôùp CStatusBar m_toolbar.EnableDocking ( CBRS_ALIGN_ANY ); cho lôùp CEmpFrame: this->EnableDocking ( CBRS_ALIGN_ANY ); this->DockControlBar( &m_toolbar, AFX_IDW_DOCKBAR_TOP ); CStatusBar m_status; return 0; Boå sung haønh vi OnCreate (xöû lyù WM_CREATE) cho CEmpFrame vaø } thöïc hieän caøi ñaët nhö sau: Khung cöûa soå giao dieän chính 125 126Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 73. Haønh vi InitInstance cuûa CEmpApp söû duïng lôùp CEmpFrame khai baùo - Haønh vi OnPaint thöïc hieän veõ chöõ chaïy: ñoái töôïng cöûa soå chính cuûa öùng duïng: void CEmpView::OnPaint() BOOL CEmpApp::InitInstance() { { static char mess[] = "Chao cac ban ! "; CEmpFrame *main = new CEmpFrame; char ch; m_pMainWnd = main; UINT i; main->LoadFrame(IDR_MAINFRAME); CPaintDC dc(this); // device context for painting main->ShowWindow(SW_SHOW); ch = mess[0]; return TRUE; for (i=0; i < strlen(mess)-1; i++) } mess[i] = mess[i+1]; mess[i] = ch; Thöïc haønh 5: Thöïc hieän öùng duïng töông töï VD31. Trong frame window, dc.TextOut(10, 10, mess, 15); 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 Duøng lôùp CEmpView khai baùo ñoái töôïng view trong CEmpFrame: hieån thò noäi dung chöõ chaïy. Caùc caøi ñaët caàn thieát nhö sau: - Boå sung thuoäc tính protected m_view thuoäc lôùp CEmpView vaøo lôùp - Haønh vi OnCreate thöïc hieän caøi ñaët timer: CEmpFrame. - Haønh vi OnCreate cuûa CEmpFrame thöïc hieän khôûi taïo thoâng soá phuø int CEmpView::OnCreate(LPCREATESTRUCT lpCreateStruct) { hôïp cho ñoái töôïng m_view; duøng soá hieäu cho m_view laø if (CWnd::OnCreate( lpCreateStruct) == -1 ) AFX_IDW_PANE_FIRST (view maëc nhieân cuûa frame) return -1; int CEmpFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) SetTimer( ID_TIMER, 300, NULL ); // Interval = 300ms { return 0; ... // Nhö caøi ñaët cuûa VD31 } m_view.Create ( NULL, NULL, AFX_WS_DEFAULT_VIEW, - Haønh vi OnDestroy huûy boû timer: CRect(0,0,0,0), this, AFX_IDW_PANE_FIRST); void CEmpView::OnDestroy() return 0; { } KillTimer( ID_TIMER ); - Haønh vi PreCreateWindow thöïc hieän huûy thoâng soá aán ñònh daïng CWnd::OnDestroy(); "chìm xuoáng" cho vuøng client (chöùa view – to get a nice look): } BOOL CEmpFrame::PreCreateWindow(CREATESTRUCT& cs) - Haønh vi OnTimer kích hoaït OnPaint: { void CEmpView::OnTimer(UINT nIDEvent) if (!CFrameWnd::PreCreateWindow(cs)) { return FALSE; if (nIDEvent == ID_TIMER) { cs.dwExStyle &= ~WS_EX_CLIENTEDGE; Invalidate(); // Generates a WM_PAINT return TRUE; } } CWnd::OnTimer(nIDEvent); Duøng CEmpFrame laøm cöûa soå chính cuûa öùng duïng (nhö VD31). } Khung cöûa soå giao dieän chính 127 128Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 74. Thöïc haønh 6: Thöïc hieän öùng duïng nhö VD32. Khi choïn muïc Start cuûa BOOL CEmpFrame::OnCmdMsg ( menu thì maøn hình view thöïc hieän chöõ chaïy, ñoàng thôøi noäi dung muïc UINT nID, int nCode, void *pExtra, chuyeån thaønh Stop. Neáu ngöôøi duøng choïn laïi muïc naøy (Stop), hoaït ñoäng AFX_CMDHANDLERINFO *pHandlerInfo ) chaïy chöõ döøng laïi vaø noäi dung muïc choïn chuyeån thaønh Start. { // Dispatch command messages to m_view 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 if (m_view.OnCmdMsg(nID, nCode, pExtra, pHandlerInfo)) seõ laøm côø hieäu cho chöõ chaïy. Moät soá chænh söûa sau cuûa CEmpView: return TRUE; // message was processed by m_view - Khôûi ñaàu aán ñònh khoâng chaïy chöõ: return CFrameWnd::OnCmdMsg ( nID, nCode, pExtra, int CEmpView::OnCreate(LPCREATESTRUCT lpCreateStruct) pHandlerInfo ); { } if (CWnd::OnCreate(lpCreateStruct) == -1) 10.5.3 Duøng MFC wizard taïo öùng duïng vôùi giao dieän chính framewindow: return -1; isRun = FALSE; // no animation Ñ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 SetTimer( ID_TIMER, 300, NULL ); hieän caùc coâng vieäc nhö treân, MFC wizard cung caáp chöùc naêng hoã trôï taïo return 0; 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: - Haønh vi OnTimer() döïa treân m_isRun ñeå haønh ñoäng: Choïn menu File / New. 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 Ñieàn caùc thoâng tin trong hoäp hoäi thoaïi New, Sau ñoù choïn OK. 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. Khung cöûa soå giao dieän chính 129 130Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 75. AÁn ñònh nhö treân. Choïn Next. Choïn Next. AÁn ñònh nhö treân. Choïn Next. Choïn StatusBar vaø ToolBar. Sau ñoù choïn Next Khung cöûa soå giao dieän chính 131 132Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 76. 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. Khung cöûa soå giao dieän chính 133
  • 77. CHÖÔNG 11: 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. Caùc KIEÁN TRUÙC Document & View virtual BOOL OnOpenDocument ( LPCTSTR lpszPathFileName // Ñöôøng daãn vaø teân taäp tin 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 ); Haønh vi ñöôïc thöïc hieän khi ñoái töôïng CDocument chuaån bò nhaän noäi 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 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. baûn – rich text format vaø löu döôùi daïng maõ nhò phaân – compound file), daïng virtual BOOL OnSaveDocument ( 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. LPCTSTR lpszPathName // Ñöôøng daãn vaø teân taäp tin ÖÙng duïng söû duïng döõ lieäu coù theå deã daøng phaùt trieån treân VC nhôø MFC ); Haønh vi ñöôïc thöïc hieän khi noäi dung cuûa document saép ñöôïc löu vaøo cung caáp boä khung chuaån cho caùc döï aùn thao taùc döõ lieäu. Boä khung naøy bao 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 goàm ba thaønh phaàn: Document-View-Frame (DVF). Trong ñoù: caùch rieâng cuûa öùng duïng. Document: Quaûn lyù toaøn boä noäi dung döõ lieäu cuûa öùng duïng ñöôïc BOOL IsModified( ); Traû veà tình traïng caäp nhaät döõ lieäu trong document löu tröõ trong boä nhôù. ; =TRUE (coù chænh söûa) hoaëc =FALSE (khoâng coù chænh söûa). View: Thöïc hieän chöùc naêng hieån thò vaø quaûn lyù moät phaàn 11.2 CView: döõ lieäu cuûa document. CView, lôùp keá thöøa töø lôùp CWnd, giuùp quaûn lyù thaønh phaàn view cuûa öùng Frame Window: Chöùa view, ñieàu phoái command message töø ngöôøi duïng. Trong boä ba DVF, view laø thaønh phaàn giao dieän quan troïng cho pheùp duøng ñeán caùc view moät caùch thích hôï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û. Boä khung naøy ñöôïc thöïc hieän thoâng qua caùc lôùp lieân quan sau ñaây. CView( ); Taïo laäp ñoái töôïng view. 11.1 CDocument: virtual void OnInitialUpdate( ); Haønh vi ñöôïc thöïc hieän khi ñoái töôïng CDocument laø lôùp ñoái tuôïng quaûn lyù moät noäi dung döõ lieäu (Document). view ñöôïc keát vaøo danh saùch caùc ñoái töôïng view cuûa document. Vieäc CDocument( ); Taïo laäp ñoái töôïng roãng. keá thöøa nhaèm caøi ñaët caùc aán ñònh khôûi taïo thoâng soá cho view. void AddView ( virtual void OnActivateView ( CView* pView // Con troû ñoái töôïng view BOOL bActivate, // =TRUE: kích hoaït ; vaø ngöôïc laïi ); Boå sung view vaøo danh saùch caùc view cuûa document. CView* pActivateView, // Ñoái töôïng view ñöôïc kích hoaït void RemoveView ( CView* pDeactiveView // Ñoái töôïng view bò ngöøng hoaït ñoäng CView* pView // Con troû ñoái töôïng view ); Haønh vi ñöôïc thöïc hieän moãi khi ñoái töôïng view ñöôïc kích hoaït hoaëc ); Loaïi boû moät view ra khoûi danh saùch caùc view cuûa document. thoâi kích hoaït. void UpdateAllViews ( virtual void OnActivateFrame ( CView* pSender, // Ñoái töôïng view mieãn caäp nhaät UINT nState, // Traïng thaùi kích hoaït LPARAM lHint = 0L, // Soá hieäu caäp nhaät CFrameWnd* pFrameWnd // Con troû ñoái töôïng frame chöùa view CObject* pHint = NULL // Caáu truùc chöùa thoâng tin caäp nhaät ); Haønh vi ñöôïc thöïc hieän moãi khi ñoái töôïng frame chöùa view ñöôïc kích ); Thoâng baùo caùc view trong danh saùch view cuûa document caäp nhaät laïi hoaït. noäi dung hieån thò. Traïng thaùi kích hoaït cuûa frame chöùa view coù theå laø: const CString& GetTitle( ); Traû veà noäi dung tieâu ñeà cuûa döõ lieäu. WA_INACTIVE : Frame chöùa view ngöøng hoaït ñoäng. virtual void DeleteContents( ); Xoùa roãng noäi dung document. WA_ACTIVE : Frame chöùa view ñöôïc kích hoaït. 134 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Caùc kieán truùc Document & View 135
  • 78. CDocument* GetDocument( ); Traû veà con troû ñoái töôïng CDocument virtual BOOL GetDocString ( ñang söû duïng view. CString& rString, // Bieán chuoãi chöùa keát quaû virtual void OnUpdate ( enum DocStringIndex index // Chæ soá muïc thoâng tin caàn laáy. CView* pSender, // Ñoái töôïng view laøm thay ñoåi döõ lieäu ); LPARAM lHint, // Töông töï UpdateAllViews() Chæ soá muïc thoâng tin caàn laáy coù theå laø: CObject* pHint // cuûa CDocument - CDocTemplate::windowTitle : Tieâu ñeà ); Haønh vi ñöôïc thöïc hieän khi noäi dung döõ lieäu trong document lieân - CDocTemplate::docName : Teân document. quan ñeán view ñöôïc caäp nhaät. - CDocTemplate::fileNewName : Teân maëc nhieân duøng cho taäp tin BOOL DoPreparePrinting( CPrintInfo* pInfo ); Môû hoäp in aán. 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 11.3 CFrameWnd: ñoái töôïng löu tröõ döõ lieäu thoâng qua haønh vi keá thöøa ñöôïc: Serialize. CFrameWnd laø lôùp ñoái töôïng quaûn lyù khung cöûa soå giao dieän chính cuûa virtual void Serialize( CArchive& ar ); öùng duïng (chöông 10). Tham gia vaøo boä ba DVF cuûa öùng duïng söû duïng döõ throw( CMemoryException ); // Duøng khi ar lieân quan boä nhôù trong. lieäu, lôùp ñoái töôïng CFrameWnd coù caùc hoaït ñoäng xöû lyù boå sung nhö sau: throw( CArchiveException ); // Duøng khi ar laø Archive treân ñóa. Khi frame ñöôïc kích hoaït, noù goïi haønh vi OnActivateView cuûa view. throw( CFileException ); // Duøng khi ar laø File. 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 11.5 HOÃ TRÔÏ TÖØ PHÍA ÑOÁI TÖÔÏNG QUAÛN LYÙ ÖÙNG DUÏNG: ñöa leân tieâu ñeà cuûa frame. 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öõ Frame thöïc hieän ñieàu phoái command message cho view. lieäu vaø thao taùc döõ lieäu döïa treân boä khung DVF nhö sau: void AddDocTemplate ( 11.4 CDocTemplate: CDocTemplate* pTemplate // Con troû ñoái töôïng quaûn lyù boä DVF CDocTemplate laø lôùp ñoái töôïng quaûn lyù boä ba DVF cuûa MFC. Boä ba naøy ); Ñöa moät boä ba DVF vaøo danh saùch döõ lieäu quaûn lyù bôûi öùng duïng. bao goàm CDocument – CView – CFrameWnd. BOOL ProcessShellCommand ( CCommandLineInfo& rCmdInfo ); CDocTemplate ( Thöïc hieän taùc vuï xöû lyù döõ lieäu theo yeâu caàu cuûa system shell. ÖÙng UINT nIDResource, // Soá hieäu caùc resource lieân quan: 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 CRuntimeClass* pDocClass, // menu, icon, phím taét, stringTable caùc boä DVF trong danh saùch döõ lieäu quaûn lyù bôûi öùng duïng. CRuntimeClass* pFrameClass, rCmdInfo : Chöùa caùc thoâng soá doøng leänh (neáu coù) bao goàm teân döõ CRuntimeClass* pViewClass lieäu, leänh thao taùc (edit, open, ...) treân döõ lieäu do shell chuyeån ñeán. ); Taïo laäp vaø khôûi taïo thoâng soá cho ñoái töôïng CDocTemplate. void ParseCommandLine ( CCommandLineInfo& rCmdInfo ); - pDocClass: Con troû ñoái töôïng CRuntimeClass quaûn lyù thoâng tin cuûa Chuaån bò thoâng soá caàn thieát trong rCmdInfo ñeå chuyeån cho haønh vi lôùp document taïi thôøi ñieåm thöïc thi chöông trình. ProcessShellCommand. Caùc thoâng soá naøy töông öùng vôùi noäi dung tham - pFrameClass: Con troû ñoái töôïng CRuntimeClass quaûn lyù thoâng tin soá doøng leänh cuûa öùng duïng. cuûa lôùp frame window taïi thôøi ñieåm thöïc thi chöông trình. afx_msg void OnFileNew(); Haønh vi traû lôøi cho WM_COMMAND - pViewClass: Con troû ñoái töôïng CRuntimeClass quaûn lyù thoâng tin ñöôïc phaùt ra bôûi muïc menu coù soá hieäu ID_FILE_NEW. cuûa lôùp view taïi thôøi ñieåm thöïc thi chöông trình. afx_msg void OnFileOpen(); Haønh vi traû lôøi cho WM_COMMAND Con troû chöùa thoâng tin thi haønh cuûa moät lôùp nhaän ñöôïc töø macro sau: ñöôïc phaùt ra bôûi muïc menu coù soá hieäu ID_FILE_OPEN. CRuntimeClass* RUNTIME_CLASS ( Teân_Lôùp ) 136 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Caùc kieán truùc Document & View 137
  • 79. afx_msg void OnFilePrintSetup(); Haønh vi xöû lyù WM_COMMAND Ñoái töôïng view: ñöôï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: 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: Ñoái töôïng Frame window: AÁn ñònh nhö treân. Choïn OK. 138 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Caùc kieán truùc Document & View 139
  • 80. AÁn ñònh nhö treân. Choïn Next. Choïn None (döõ lieäu chæ chöùa vaên baûn). Choïn Next. Choïn None (khoâng söû duïng cô sôû döõ lieäu). Choïn Next. AÁn ñònh caùc muïc caàn caàn thieát: 140 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Caùc kieán truùc Document & View 141
  • 81. - Printing and print preview: Cho pheùp chöùc naêng in aán. 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. - MAPI: Söû duïng dòch vuï mail cho döõ lieäu cuûa öùng duïng. Löu yù: Choïn lôùp CTxtDVFView, khai baùo lôùp cô sôû laø CEditView ñeå Choïn Next. 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. 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. AÁn ñònh nhö treân. Choïn Next. 142 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Caùc kieán truùc Document & View 143
  • 82. Choïn None (khoâng söû duïng cô sôû döõ lieäu). Choïn Next. Choïn caùc muïc caàn thieát (11.7). Choïn Next. ÖÙng duïng söû duïng OLE (Container) töø öùng duïng khaùc. Choïn Next. Choïn caùc muïc caàn thieát (11.7). Choïn Next. 144 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Caùc kieán truùc Document & View 145
  • 83. 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. Choïn None (khoâng söû duïng cô sôû döõ lieäu). Choïn Next. 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. Choïn None. Choïn Next. 146 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Caùc kieán truùc Document & View 147
  • 84. 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 AÁn ñònh caùc muïc caàn thieát; choïn chöùc naêng in aán. Choïn Next. 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. Choïn caùc muïc caàn thieát (11.7). Choïn Next. 148 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Caùc kieán truùc Document & View 149
  • 85. CImageList* SetImageList ( CImageList* pImagelist, // Con troû ñoái töôïng imagelist CImageList* pImagelist, // Ñoái töôïng imagelist int imgStyle // Thoâng soá qui ñònh caùch söû duïng 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. ); 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ø: Caùch söû duïng coù theå laø: TVSIL_NORMAL : AÛnh duøng cho caùc muïc bình thöôøng. LVSIL_NORMAL : AÛnh bình thöôøng. TVSIL_STATE : AÛnh duøng cho caùc muïc ñaëc tröng do ngöôøi LVSIL_SMALL : AÛnh nhoû. duøng ñònh nghóa. int InsertItem ( UINT GetCount( ); Traû veà soá muïc cuûa treeview. int nItem, // Chæ soá muïc ñöôïc theâm HTREEITEM GetRootItem( ); Traû veà handle cuûa phaàn töû ñaàu goác. LPCTSTR lpszItem, // Noäi dung thoâng baùo cuûa muïc HTREEITEM GetFirstVisibleItem( ); Traû veà handle cuûa phaàn töû hieån int nImage // Chæ soá aûnh trong Imagelist maø muïc söû duïng thò ñaàu tieân trong vuøng nhìn thaáy cuûa treeview (NULL: Khoâng coù). ); Theâm moät muïc vaøo listview. HTREEITEM GetSelectedItem(); Traû veà handle cuûa phaàn töû ñang ñöôïc BOOL DeleteItem ( choïn. int nItem // Soá hieäu cuûa muïc HTREEITEM GetNextVisibleItem( HTREEITEM hItem ); Traû veà ); Xoùa moät muïc trong listview. handle cuûa phaàn töû hieån thò keá sau phaàn töû coù handle laø hItem. BOOL DeleteAllItems( ); Xoùa roãng listview. HTREEITEM GetPrevVisibleItem( HTREEITEM hItem ); Traû veà BOOL GetItem ( handle cuûa phaàn töû hieån thò keá tröôùc phaàn töû coù handle laø hItem. LVITEM* pItem // Con troû ñeán caáu truùc nhaän thoâng tin HTREEITEM InsertItem ( ); Laáy thoâng tin lieân quan ñeán muïc coù soá thöù töï nItem. LPCTSTR lpszItem, // Noäi dung thoâng baùo cuûa muïc BOOL SetItem ( int nImage, // Chæ soá aûnh duøng cho muïc ôû traïng thaùi LVITEM* pItem // Con troû ñeán caáu truùc chöùa thoâng soá int nImageSelected, // bình thöôøng vaø khi muïc ñöôïc choïn. ); Ñaët thoâng soá cho muïc coù chæ soá laø pItem ->iItem. HTREEITEM parent = TVI_ROOT, // Con troû muïc cha BOOL EnsureVisible ( HTREEITEM hInsertAfter = TVI_LAST // Con troû muïc ñöùng tröôùc int nItem, // Chæ soá phaàn töû caàn nhìn thaáy. ); Theâm moät muïc vaøo treeview, traû veà handle cuûa phaàn töû môùi theâm. BOOL bPartialIsOK // =FALSE: Toaøn boä, =TRUE: Moät phaàn BOOL DeleteItem ( ); Cuoän danh saùch ñeå nhìn thaáy phaàn töû nItem neáu phaàn töû naøy khoâng HTREEITEM hItem /* handle cuûa muïc*/ ); Xoùa muïc cuûa treeview. ñöôïc nhìn thaáy trong vuøng hieån thò cho pheùp cuûa view. BOOL DeleteAllItems( ); Xoùa roãng noäi dung treeview. 11.10.2 CTreeView: BOOL GetItem ( CTreeView laø lôùp ñoái töôïng quaûn lyù maøn hình view coù caáu truùc caây. TVITEM* pItem // Con troû ñeán caáu truùc nhaän thoâng tin CTreeView( ); Taïo laäp ñoái töôïng treeview. ); Laáy thoâng tin cuûa phaàn töû pItem->iItem. CTreeCtrl& GetTreeCtrl( ); Traû veà ñoái töôïng CTreeCtrl laøm cô sôû cho BOOL SetItem ( caùc taùc vuï lieân quan TreeView. 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. Caùc haønh vi ñaëc tröng cuûa CTreeCtrl: BOOL SetItemImage ( BOOL SetBkColor( COLOREF cr ); Ñaët maøu neàn cho treeview. HTREEITEM hItem, // handle cuûa phaàn töû COLORREF GetBkColor( ); Traû veà giaù trò maøu neàn cuûa treeview. int nImage, // Chæ soá aûnh duøng cho muïc ôû traïng thaùi CImageList* SetImageList ( 150 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Caùc kieán truùc Document & View 151
  • 86. int nSelectedImage // bình thöôøng vaø khi muïc ñöôïc choïn. BOOL Create ( ); AÁn ñònh chæ soá aûnh trong imagelist duøng cho muïc. CWnd* pParentWnd, // Con troû ñoái töôïng cöûa soå cha BOOL SetItemText ( int nMaxRows, // Soá haøng toái ña cuûa caùc pane HTREEITEM hItem, // handle cuûa muïc int nMaxCols, // Soá coät toái ña cuûa caùc pane LPCTSTR lpszItem // Noäi dung thoâng baùo SIZE sizeMin, // Kích thöôùc toái thieåu cuûa moãi pane ); AÁn ñònh laïi noäi dung thoâng baùo cuûa muïc trong treeview. CCreateContext* pContext, // Thoâng soá lieân keát, laáy töø frame DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_HSCROLL | 11.10.3 CSplitterWnd: WS_VSCROLL | SPLS_DYNAMIC_SPLIT, Vuøng client trong frame window cho pheùp caøi ñaët moät cöûa soå view duy UINT nID = AFX_IDW_PANE_FIRST nhaát. Ñeå loàng ñöôïc nhieàu view vaøo frame ta phaûi phaân chia vuøng client cuûa ); Khôûi taïo thoâng soá spliiter window vôùi soá haøng, coät thay ñoåi ñöôïc. frame. Vieäc phaân chia naøy ñöôïc hoã trôï bôûi coâng cuï splitter window. 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 Moãi splitter window cho pheùp taùch vuøng client cuûa frame window thaønh lôùp view töông öùng taïi thôøi ñieåm thöïc thi chöông trình. Xem (11.4). nhieàu haøng vaø coät. Sau ñoù, moãi oâ (pane) nhaän ñöôïc töø splitter naøy coù theå laïi void SetColumnInfo ( ñöôï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: int col, // Chæ soá coät trong splitter - Splitter thöù nhaát taùch frame window thaønh hai doøng vaø 1 coät. int cxIdeal, // Ñoä roäng mong muoán vaø - Splitter thöù hai taùch pane thöù nhaát cuûa splitter thöù nhaát thaønh 2 coät int cxMin // ñoä roäng toái thieåu (tính baèng pixel) vaø 1 doøng. ); AÁn ñònh thoâng soá veà ñoä roäng cho coät trong splitter window. Moãi pane nhaän ñöôïc töø caùc splitter window cho pheùp gaén moät maøn hình void GetColumnInfo ( view. Nhö vaäy, thoâng qua caùc splitter window, frame window coù theå chöùa int col, // Chæ soá coät nhieàu maøn hình view ñoàng thôøi. int& cxCur, // Tham bieán chöùa ñoä roäng hieän thôøi Nhaèm tieän vieäc thao taùc vôùi coâng cuï splitter window, MFC cung caáp lôùp int& cxMin // Tham bieán chöùa ñoä roäng toái thieåu ñoái töôïng CSplitterWnd cho pheùp quaûn lyù caùc spliiter window trong öùng duïng. ); Laáy thoâng tin veà ñoä roäng cuûa coät. Caùc haønh vi ñaëc tröng cuûa lôùp CSplitterWnd nhö sau: void SetRowInfo ( CSplitterWnd( ); Taïo laäp ñoái töôïng splitter window. 152 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Caùc kieán truùc Document & View 153
  • 87. int row, // Chæ soá haøng Thöïc haønh 1: Vieát öùng duïng nhö VD30. Taïo splitter trong CEmpFrame vôùi int cyIdeal, // Ñoä cao mong muoán hai view: beân traùi laø treeview (duøng lôùp view keá thöøa töø CTreeView), beân int cyMin // Ñoä cao toái thieåu phaûi laø list (duøng lôùp view keá thöøa töø ListView). ); AÁn ñònh thoâng soá veà ñoä cao cho haøng trong splitter window. Taïo döï aùn VD35 töông töï VD30. void GetRowInfo ( Ñaêng kyù söû duïng CTreeView vaø CListView: int row, // Chæ soá haøng Trong taäp tin stdafh.h cuûa döï aùn, boå sung chæ thò: int& cyCur, // Tham bieán chöùa ñoä cao hieän thôøi #include <afxcview.h> int& cyMin // Tham bieán chöùa ñoä cao toái thieåu Boå sung vaøo döï aùn hai lôùp môùi: ); Laáy thoâng tin veà ñoä cao cuûa haøng. CEmpTree keá thöøa töø CTreeView void RecalcLayout( ); Caäp nhaät thoâng soá aán ñònh môùi cuûa splitter. CEmpList keá thöøa töø CListView. CWnd* GetPane ( Caùch thöïc hieän töông töï nhö ñaõ laøm vôùi CEmpWnd, muïc (5.4.1). int row, int col // Chæ soá haøng vaø coät cuûa pane Khai baùo ñoái töôïng thuoäc tính protected m_splitter kieåu CSplitterWnd. ); Traû veà con troû ñoái töôïng view caøi trong pane. Haønh vi OnCreateClient cuûa CEmpFrame thöïc hieän khôûi taïo vaø caøi ñaët 11.10.4 SÖÛ DUÏNG SPLITTERWND TRONG FRAME WINDOW: caùc pane, view caàn thieát: Khai baùo ñoái töôïng thuoäc lôùp SplitterWnd nhö laø thuoäc tính cuûa frame. BOOL CEmpFrame::OnCreateClient( LPCREATESTRUCT lpcs, CCreateContext* pContext ) CSplitterWnd m_splitter; { if (!CFrameWnd::OnCreateClient(lpcs, pContext)) Duøng haønh vi OnCreateClient cuûa frame ñeå taïo caùc pane vaø caøi view: return FALSE; BOOL CEmpFrame::OnCreateClient ( LPCREATESTRUCT lpcs, m_splitter.CreateStatic(this, 1, 2); CCreateContext* pContext ) m_splitter.CreateView( 0, 0, RUNTIME_CLASS(CEmpTree), { CSize(120,0), NULL ); if (!CFrameWnd::OnCreateClient(lpcs, pContext)) m_splitter.CreateView(0,1, RUNTIME_CLASS(CEmpList), return FALSE; CSize(0,0), NULL ); return TRUE; // 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: Thöïc haønh 2: Thöïc hieän öùng duïng töông töï VD35. Töï ñoäng thöïc hieän boå m_splitter.CreateView ( 0, 0, RUNTIME_CLASS(viewClass1), sung ba phaàn töû trong treeview, moãi phaàn töû coù hai phaàn töû con. Caùc phaàn CSize(120,0), NULL); töû ñeàu coù hình minh hoïa cho traïng thaùi ñöôïc choïn vaø khoâng ñöôïc choïn. m_splitter.CreateView(0,1, RUNTIME_CLASS(viewClass2), Taïo döï aùn VD36 töông töï VD35. CSize(0,0), NULL); Boå sung bitmap resource chöùa hai aûnh cuøng kích thöôùc: . Ñaët soá ... // Thöïc hieän caùc caøi ñaët khaùc hieäu cho bitmap resource laø IDB_IMGTREE. return TRUE; 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: 11.10.5 CAÙC VÍ DUÏ THÖÏC HAØNH: int CEmpTree::OnCreate(LPCREATESTRUCT lpCreateStruct) 154 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Caùc kieán truùc Document & View 155
  • 88. { 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 if (CTreeView::OnCreate(lpCreateStruct) == -1) password baûo veä döõ lieäu. Chæ môû ñöôïc döõ lieäu neáu coù password hôïp leä. return -1; 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); static CImageList img; // use only in this function Backward, Forward, hoäp combobox nhaäp vaø ghi nhôù caùc URL ñaõ nhaäp. img.Create(IDB_IMGTREE, 16, 2, RGB(255,255,255)); 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 CTreeCtrl& myCtrl = GetTreeCtrl(); // Based control treân maùy nhö windows explorer. myCtrl.SetImageList(&img, TVSIL_NORMAL); 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 HTREEITEM hihi; // Add needed items vaø caäp nhaät döõ lieäu cho caùc baûng trong cô sôû döõ lieäu. hihi = myCtrl.InsertItem("Muc 1", 0, 1); 6. Vieát öùng duïng RTF View. Trong maøn hình view, khi di chuyeån chuoät leân myCtrl.InsertItem("Muc 11", 0, 1, hihi); 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 myCtrl.InsertItem("Muc 12", 0, 1, hihi); thaønh , ngöôïc laïi chænh daïng chuoät veà daïng maëc nhieân cuûa heä thoáng. hihi = myCtrl.InsertItem("Muc 2", 0, 1); myCtrl.InsertItem("Muc 21", 0, 1, hihi); 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 myCtrl.InsertItem("Muc 22", 0, 1, hihi); 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 hihi = myCtrl.InsertItem("Muc 3", 0, 1); ñ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. myCtrl.InsertItem("Muc 31", 0, 1, hihi); 8. Quan saùt chöông trình tra cöùu töø ñieån. Vieát öùng duïng RTF view söû duïng myCtrl.InsertItem("Muc 321", 0, 1, 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 myCtrl.InsertItem("Muc 32", 0, 1, hihi)); 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. return 0; 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 Haønh vi keá thöøa PreCreateWindow aán ñònh thoâng soá daïng treeview: 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, BOOL CEmpTree::PreCreateWindow(CREATESTRUCT& cs) { Khi click vaøo cöûa soå view, noäi dung chænh söûa ñöôïc caäp nhaät vaøo view. cs.style |= TVS_HASLINES|TVS_LINESATROOT| 10. Quan saùt Yahoo Messenger!. Thöïc hieän öùng duïng giao dieän rtf nhö sau: 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: 156 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Caùc kieán truùc Document & View 157
  • 89. CHÖÔNG 12: 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: Moät soá vaán ñeà trong windows free((void*)m_pszProfileName); // Huûy boû vuøng nhôù caáp phaùt m_pszProfileName=_tcsdup(_T(“ÑöôøngDaãn-TeânTaäpTin_INI”)); 12.1 TAÄP TIN INI: BOOL WriteProfileString ( 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 LPCTSTR lpszSection, // Teân thaønh phaàn cuûa öùng duïng trong moâi tröôøng windows phieân baûn 3.x vaø 9x. Caùc noäi dung LPCTSTR lpszEntry, // Teân muïc naøy ñöôïc chia thaønh caùc thaønh phaàn (section) phaân bieät theo chöùc naêng hoaëc LPCTSTR lpszValue // Giaù trò cuûa muïc (kieåu chuoãi) 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 ); Löu giaù trò kieåu chuoãi cuûa moät muïc trong thaønh phaàn 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 BOOL WriteProfileInt ( 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 LPCTSTR lpszSection, // Teân thaønh phaàn ngaên caùch vôùi teân muïc baèng daáu "=". 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. Xeùt ví duï laø taäp tin WIN.INI noùi treân: UINT GetProfileInt ( - windows : Teân thaønh phaàn (section). LPCTSTR lpszSection, // Teân thaønh phaàn - NullPort : Teân muïc (entry). LPCTSTR lpszEntry, // Teân muïc. Neáu muïc ñoïc khoâng - None : Giaù trò cuûa muïc NullPort. int nDefault // coù thì söû duïng giaù trò naøy. 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 ); Traû veà giaù trò kieåu soá nguyeân cuûa moät muïc trong thaønh töông öùng. töôïng quaûn lyù öùng duïng CWinApp thoâng qua caùc thuoäc tính, haønh vi sau: BOOL GetProfileBinary ( const char* m_pszAppName : Löu chuoãi teân cuûa öùng duïng. Giaù trò LPCTSTR lpszSection, // Teân thaønh phaàn thuoäc tính naøy coù theå ñöôïc thay ñoåi ñöôïc nhö sau: LPCTSTR lpszEntry, // Teân muïc LPBYTE *pData, // Ñòa chæ con troû vuøng ñeäm free( (void*) m_pszAppName ); // Giaûi phoùng vuøng nhôù UINT *nBytes // Ñòa chæ bieán nhaän kích thöôùc. m_pszAppName =_tcsdup( _T(“Teân_môùi_cuûa_öùng_duïng”) ); ); Ñoïc khoái maõ nhò phaân cuûa moät muïc vaøo vuøng ñeäm. 158 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Moät soá vaán ñeà trong Windows 159
  • 90. Haønh vi traû veà giaù trò TRUE neáu taùc vuï ñoïc thaønh coâng. - Moãi muïc trong caáu truùc caây (tree) goïi laø khoùa (key). Vôùi: pData : Ñòa chæ bieán con troû quaûn lyù vuøng ñeäm nhaän thoâng tin. - Khoùa laù (khoâng coù con) laø thaønh phaàn chöùa caùc muïc. nBytes : Ñòa chæ bieán chöùa kích thöôùc thoâng tin ñoïc ñöôïc. - Moãi muïc coù moät teân ñeå nhaän bieát vaø coù moät giaù trò xaùc ñònh. ÖÙng duïng caàn giaûi phoùng vuøng ñeäm pData khi chaám döùt söû duïng. Haønh vi SetRegistryKey cuûa lôùp ñoái töôïng CWinApp cho pheùp ñònh höôùng Ñoaïn chöông trình sau thöïc hieän ghi xuoáng thaønh phaàn MY_TEST vieäc ñoïc/ghi giaù trò caùc muïc leân system registry thay vì söû duïng taäp tin INI cuûa taäp tin INI cuûa öùng duïng: MyName = Mr.Emp vaø MyVer = 11. nhö (12.1). Haønh vi loaïi protected naøy coù cuù phaùp nhö sau: CWinApp* pApp = AfxGetApp(); // Ñoái töôïng quaûn lyù öùng duïng void SetRegistryKey ( UINT lpszRegistryKey ); pApp->WriteProfileString ("MY_TEST", "MyName", "Mr.Emp"); lpszRegistryKey : Thoâng thöôøng laø chuoãi chöùa teân haõng phaàn meàm; ví pApp->WriteProfileInt ("MY_TEST", "MyVer", 11); duï Netscape. Giaù trò naøy trôû thaønh khoùa con cuûa khoùa Software thuoäc Ñoaïn chöông trình sau thöïc hieän ñoïc töø thaønh phaàn MY_TEST cuûa khoùa goác HKEY_CURRENT_USER trong system registry. taäp tin INI giaù trò hai muïc noùi treân. 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 CWinApp* pApp = AfxGetApp(); // Ñoái töôïng quaûn lyù öùng duïng m_pszAppName cuûa ñoái töôïng öùng duïng) trôû thaønh khoùa con cuûa khoùa xaùc CString myName = pApp->GetProfileString ( ñònh bôûi lpszRegistryKey, vaø caùc thaønh phaàn chöùa caùc muïc trôû thaønh khoùa "MY_TEST", "MyName", "Mr.Emp" ); con cuûa khoùa m_pszAppName. Moät thöù töï ñöôïc thieát laäp nhö sau: UINT myVer = pApp->GetProfileInt ("MY_TEST", "MyVer", 11); HKEY_CURRENT_USERSoftware<Teân_haõng_phaàn_meàm> 12.2 SYSTEM REGISTRY: <Teân_öùng_duïng><Teân_thaønh_phaàn><Caùc_muïc>. System Registry laø cô sôû döõ lieäu do windows quaûn lyù, ñöôïc söû duïng ñeå löu Thöïc hieän öùng duïng IniReg. ÖÙng duïng ñaêng kyù söû duïng system registry 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. 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ö System registry coù caáu truùc nhö sau (chöông trình RegEdit.exe). 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: (System registry ôû moät maùy söû duïng phieân baûn Windows-Me ) - Môû dialog resource, caøi ñaët caùc control sau: 160 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Moät soá vaán ñeà trong Windows 161
  • 91. - Hoäp nhaäp giaù trò muïc MyName Edit IDC_WRITE_NAME Taskbar laø thanh coâng cuï ñaëc bieät cuûa öùng duïng desktop trong windows. - Hoäp nhaäp giaù trò muïc MyVer Edit IDC_WRITE_VERSION Noäi dung cuûa taskbar ñöôïc chia thaønh 4 thaønh phaàn chính: - Hoäp hieån thò muïc MyName Static IDC_READ_NAME - Start menu: Muïc kích hoaït heä thoáng menu caùc öùng duïng. - Hoäp hieån thò muïc MyVer Static IDC_READ_VERSION - Quick Launch Bar: Danh muïc caùc öùng duïng thöôøng duøng. - Nuùt choïn thöïc hieän ghi Button IDC_WRITE - Taskbar Buttons: Danh saùch caùc öùng duïng ñang chaïy. - Nuùt choïn thöïc hieän ñoïc Button IDC_READ - Status Area: Chöùa icon giao dieän cuûa caùc öùng duïng ñang chaïy. - Haønh vi OnWrite öùng vôùi nuùt IDC_WRITE löu giaù trò caùc muïc: ÖÙng duïng coù theå nhaän ñöôïc tín hieäu nhaäp cuûa void CIniRegDlg::OnWrite() 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. CWinApp* pApp = AfxGetApp(); Vieäc caøi ñaët hoaëc huûy boû icon giao dieän cuûa öùng duïng treân status area CString myName; ñuôïc thöïc hieän thoâng quan haøm sau: UINT myVer; BOOL Shell_NotifyIcon ( GetDlgItemText(IDC_WRITE_NAME, myName); DWORD dwMessage, // Taùc vuï thöïc hieän myVer = GetDlgItemInt(IDC_WRITE_VERSION); PNOTIFYICONDATA lpdata // Caáu truùc chöùa thoâng soá lieân quan pApp->WriteProfileString("MY_TEST", "MyName", myName); ); Traû veà giaù trò TRUE neáu taùc vuï thöïc hieän thaønh coâng. pApp->WriteProfileInt("MY_TEST", "MyVer", myVer); 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. - Haønh vi OnRead öùng vôùi nuùt IDC_READ ñoïc giaù trò caùc muïc: NIM_MODIFY : Thay ñoåi thoâng soá lieân quan icon giao dieän. void CIniRegDlg::OnRead() 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á. CWinApp* pApp = AfxGetApp(); CString myName; Caùc tröôøng trong caáu truùc NOTIFYICONDATA coù yù nghóa nhö sau: UINT myVer; typedef struct _NOTIFYICONDATA { myName = pApp->GetProfileString( "MY_TEST", DWORD cbSize; // Kích thuôùc caáu truùc "MyName", "NoName" ); HWND hWnd; // Handle cuûa cöûa soå xöû lyù message töø icon myVer = pApp->GetProfileInt( "MY_TEST", "MyVer", 0 ); UINT uID; // Soá hieäu cuûa icon treân status area SetDlgItemText( IDC_READ_NAME, myName ); UINT uFlags; // Qui ñònh caùc thoâng soá coù yù nghóa SetDlgItemInt( IDC_READ_VERSION, myVer ); UINT uCallbackMessage; // Soá hieäu message cuûa icon göûi cöûa soå. } HICON hIcon; // Handle cuûa icon ñöôïc söû duïng Bieân dòch vaø chaïy öùng duïng. TCHAR szTip[64]; // Noäi dung chuù thích cuûa icon giao dieän. 12.3 VUØNG STATUS AREA TREÂN TASKBAR: } 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. 162 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Moät soá vaán ñeà trong Windows 163
  • 92. 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 Caùc böôùc thöïc hieän döï aùn cuûa öùng duïng: moät message ñeán cöûa soå xöû lyù lieân quan icon vôùi noäi dung nhö sau: Duøng MFC Wizard taïo öùng duïng TaskbarIcon coù giao dieän laø dialog. - message : Soá hieäu message cuûa icon (trong uCallbackMessage). Thöïc hieän caùc boå sung sau ñaây cho lôùp dialog CTaskbarIconDlg: - wParam : Soá hieäu cuûa icon. - Môû dialog resource, caøi ñaët caùc control sau: - lParam : Chöùa caùc traïng thaùi cuûa chuoät hoaëc phím maø ngöôøi - Hoäp thoâng baùo traïng thaùi icon Static IDC_ICON_INFO duøng ñaõ söû duïng ñeå taùc ñoäng leân icon giao dieän. - Nuùt thöïc hieän ñaët icon Button IDC_ICON_SET Haønh vi WindowProc cuûa cöûa soå xöû lyù lieân quan seõ tuøy nghi xöû lyù: - Nuùt thöïc hieän xoùa icon Button IDC_ICON_REMOVE LRESULT CTaskbarIconDlg::WindowProc ( UINT message, - Khai baùo thuoäc tính protected m_isIconShow kieåu luaän lyù, ñeå ghi WPARAM wParam, LPARAM lParam ) 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. if ( message == Icon_uCallbackMessage ) { - Haønh vi OnInitDialog chuaån bò caùc thoâng soá: switch ( lParam ) { BOOL CTaskbarIconDlg::OnInitDialog() … // Xöû lyù bieán coá phím / chuoät trong lParam { } CDialog::OnInitDialog(); return 0 ; m_isIconShow = FALSE; // Baét ñaàu, icon chöa ñöôïc ñaët. } return TRUE; return CDialog::WindowProc(message, wParam, lParam); } } - Haønh vi OnIconSet öùng vôùi nuùt choïn IDC_ICON_SET thöïc hieän caøi Giaû söû caàn thöïc hieän öùng duïng nhö sau: 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 - 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. - Haønh vi OnIconRemove öùng vôùi nuùt choïn IDC_ICON_REMOVE - Hoäp thoâng baùo cho bieát caùc bieán coá nhaäp taùc ñoäng leân icon. thöïc hieän xoùa icon giao dieän khoûi status area: 164 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Moät soá vaán ñeà trong Windows 165
  • 93. void CTaskbarIconDlg::OnIconRemove() 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ôû if ( !m_isIconShow ) return; roäng .SCR. Ñeå söû duïng öùng duïng ScreenSaver, ta cheùp taäp tin chöông trình NOTIFYICONDATA dt; 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 memset(&dt, 0, sizeof(NOTIFYICONDATA)); Control Panel (Desktop Properties) caøi ñaët öùng duïng ScreenSaver cho heä dt.cbSize = sizeof(NOTIFYICONDATA); dt.uID = 100; thoáng thoâng qua trang Screen Saver: 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; } Teân taäp tin chöông trình cuûa öùng duïng ScreenSaver ñöôïc duøng laøm teân return 0; ScreenSaver trong danh saùch löïa choïn caùc ScreenSaver. Neáu ta khai baùo } return CDialog::WindowProc(message, wParam, lParam); 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 Bieân dòch vaø chaïy öùng duïng. laøm teân ScreenSaver trong danh saùch noùi treân. 166 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Moät soá vaán ñeà trong Windows 167
  • 94. Khi khoaûng thôøi gian maø ngöôøi duøng ngöøng töông taùc vôùi heä thoáng vöôït (a) Chaïy minh hoïa tröïc tieáp ScreenSaver: Vuøng chaïy maãu laø cöûa soå con quaù giaù trò aán ñònh Wait thì heä thoáng töï ñoäng thöïc hieän öùng duïng trong hoäp hoäi thoaïi Display Properties. Handle cuûa cöûa soå naøy laø moät ScreenSaver. giaù trò trong tham soá doøng leänh coù noäi dung nhö sau: 12.4.1 Ñaëc ñieåm: "/p xxxx" Khaùc vôùi caùc öùng duïng thoâng thöôøng khaùc, öùng duïng ScreenSaver phaûi coù Trong ñoù: khaû naêng öùng xöû khaùc nhau trong caùc tình huoáng khaùc nhau maø öùng duïng - /p (hoaëc /P): Giaù trò phaûn aùnh tình huoáng thöïc hieän. ñöôï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 - xxxx : Caùc chöõ soá phaûn aùnh giaù trò handle cuûa cöûa soå con. ScreenSaver laø: Caùch laáy giaù trò handle naøy töø tham soá doøng leänh nhö sau: (a) Chaïy minh hoïa tröïc tieáp ScreenSaver trong maøn hình con cuûa hoäp hoäi HWND parent; // Bieán chöùa handle thoaïi: Khi ngöôøi duøng click choïn öùng duïng ScreenSaver trong danh sscanf(m_lpCmdLine+3, "%d", &parent); saùch caùc ScreenSaver cuûa hoäp hoäi thoaïi Display Properties / Screen ÔÛ cheá ñoä naøy, ScreenSaver ñöôïc thieát keá theo kieåu öùng duïng coù Saver. 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 (b) Thöïc hieän chöùc naêng aán ñònh thoâng soá cuûa ScreenSaver: Khi ngöôøi thöïc. Cöûa soå naøy ñöôïc loàng vaøo vò trí cuûa cöûa soå con noùi treân. duøng click choïn muïc Setting... sau khi ñaõ choïn öùng duïng ScreenSaver (b) Thöïc hieän chöùc naêng aán ñònh thoâng soá: Noäi dung tham soá doøng leänh trong danh saùch caùc ScreenSaver. nhö sau: (c) Thöïc hieän chöùc naêng ñaët Password cuûa ScreenSaver: Khi ngöôøi duøng "/c xxxx" click choïn muïc Password Setting... sau khi ñaõ choïn öùng duïng Trong ñoù: ScreenSaver trong danh saùch caùc ScreenSaver. Chæ söû duïng cho caùc - /c (hoaëc /C) : Giaù trò phaûn aùnh tình huoáng thöïc hieän. phieân baûn Win9x trôû veà tröôùc. - xxxx : Handle cuûa hoäp hoäi thoaïi (dialog). (d) Chaïy minh hoïa ScreenSaver trong maøn hình thöïc: Khi ngöôøi duøng ÔÛ cheá ñoä naøy, ScreenSaver ñöôïc thieát keá theo kieåu öùng duïng coù click choïn muïc Preview sau khi ñaõ choïn öùng duïng ScreenSaver trong maøn hình giao dieän chính laø dialog vôùi caùc muïc nhaäp cho pheùp ñieàu danh saùch caùc ScreenSaver. Cheá ñoä chaïy naøy töông töï cheá ñoä chaïy chænh thoâng soá lieân quan ñeán caùch thöùc hoaït ñoäng cuûa ScreenSaver thöïc nhaèm giuùp ngöôøi duøng hình dung ñöôïc hoaït ñoäng thöïc cuûa ôû cheá ñoä thöïc. Dialog giao dieän laø dialog khoùa (modal dialog) vaø ñoái ScreenSaver. töôïng cöûa soå cha cuûa noù laø hoäp hoäi thoaïi noùi treân. (e) Chaïy ScreenSaver: Khi khoaûng thôøi gian maø heä thoáng ngöøng töông (c) Thöïc hieän chöùc naêng ñaët Password: Noäi dung tham soá doøng leänh nhö taùc vôùi ngöôøi duøng lôùn hôn khoaûng thôøi gian chôø cho pheùp. Ñaây laø sau: cheá ñoä chaïy thöïc cuûa ScreenSaver. "/a xxxx" Trong ñoù: 12.4.2 Tham soá doøng leänh (Command Line Parameters): - /a (hoaëc /A): Giaù trò nhaän dieän tình huoáng thöïc hieän. Moãi khi thöïc hieän öùng duïng ScreenSaver, heä thoáng cung caáp thoâng tin veà - xxxx : Handle cuûa cöûa soå hoäi thoaïi. tình huoáng cuï theå maø öùng duïng ñöôïc thöïc hieän thoâng qua noäi dung tham soá ÔÛ cheá ñoä naøy, ScreenSaver ñöôïc thieát keá theo kieåu öùng duïng coù doøng leänh göûi ñeán cho chöông trình cuûa öùng duïng. ÖÙng duïng ScreenSaver maøn hình giao dieän chính laø dialog. Dialog giao dieän coù theå laø dialog 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. duøng ñaët password cuûa heä thoáng (thö vieän MPR.DLL) hoaëc dialog Thuoäc tính m_lpCmdLine cuûa ñoái töôïng quaûn lyù tieåu trình chính trong öùng cuûa ngöôøi duø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 (d) Chaïy minh hoïa ScreenSaver: Noäi dung tham soá doøng leänh nhö sau: 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 "/s" öùng caùc tröôøng hôïp (12.4.1), noäi dung tham soá doøng leänh coù theå laø: 168 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Moät soá vaán ñeà trong Windows 169
  • 95. Trong ñoù: Giaû söû caàn thöïc hieän öùng duïng ScreenSaver vôùi noäi dung hoaït ñoäng laø - /s (hoaëc /S): Giaù trò nhaän dieän tình huoáng thöïc hieän. hieån thò caâu chaøo "Hello !". Caùc böôùc thöïc hieän nhö sau: ÔÛ cheá ñoä naøy, ScreenSaver thöïc hieän xöû lyù nhö chaïy thöïc. Taïo döï aùn ScreenSaver töông töï döï aùn VD01. (e) Chaïy ScreenSaver: ÔÛ cheá ñoä naøy, ScreenSaver ñöôïc thieát keá theo Boå sung lôùp CEmpScreenSaverWnd keá thöøa töø lôùp CWnd cho döï aùn. kieåu öùng duïng coù maøn hình giao dieän chính laø cöûa soå vôùi noäi dung Thöïc hieän caøi ñaët cho lôùp CEmpScreenSaverWnd nhö sau: 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å - Haønh vi OnPaint hieån thò thoâng baùo "Hello !" ôû chính giöõa vuøng desktop cuûa heä thoáng. client cuûa cöûa soå. Phaàn löïa choïn trình huoáng xöû lyù cuûa öùng duïng ScreenSaver ñöôïc caøi void CEmpScreenSaverWnd::OnPaint() ñaët trong haønh vi InitInstance cuûa ñoái töôïng quaûn lyù öùng duïng. { CPaintDC dc(this); // device context ñeå veõ 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 // Do ScreenSaver's works here : 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). LOGFONT lf; Do ñoù, chöông trình ScreenSaver phaûi xöû lyù caùc message lieân quan vieäc nhaäp CFont font, *oldFont; lieäu: - Caùc message do taùc ñoäng leân baøn phím: memset(&lf, 0, sizeof(LOGFONT)); WM_KEYDOWN, WM_KEYUP strcpy(lf.lfFaceName, "Arial"); - Caùc message do taùc ñoäng leân chuoät: lf.lfHeight = 50; lf.lfWidth = 14; WM_MOUSEMOVE, font.CreateFontIndirect(&lf); // Taïo font chöõ ñeå söû duïng WM_LBUTTONDOWN, WM_LBUTTONUP, oldFont = dc.SelectObject(&font); // vaø löu font chöõ cuõ. WM_RBUTTONDOWN, WM_RBUTTONUP, RECT rect; WM_MBUTTONUP, WM_MBUTTONDOWN dc.GetClipBox(&rect); // Xoùa neàn DC Thoâng thöôøng, khi nhaän ñöôïc moät trong caùc message naøy thì öùng dc.FillRect(&rect, &CBrush(RGB(0, 128,128))); 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 dc.SetBkMode(TRANSPARENT); Ctrl+Alt+Del ñeå ‘qua maët’ öùng duïng. Vieäc ngaên caám naøy thöïc hieän nhö sau: rect.top += 3; rect.left+= 3; dc.SetTextColor(RGB(0, 0, 128)); UINT oldval; // Duøng baûo löu traïng thaùi dc.DrawText("Hello !", 7, &rect, // Baét ñaàu, caám phím: DT_CENTER | DT_VCENTER | DT_SINGLELINE); SystemParametersInfo ( SPI_SETSCREENSAVERRUNNING, rect.top -= 3; rect.left -= 3; 1 , &oldval, 0 ); rect.bottom -= 3; rect.right -= 3; ... // Phaàn thöïc hieän cuûa ScreenSaver dc.SetTextColor(RGB(255, 255, 0)); // Cuoái cuøng, thoâi caám phím: dc.DrawText("Hello !", 7, &rect, SystemParametersInfo ( SPI_SETSCREENSAVERRUNNING, DT_CENTER | DT_VCENTER | DT_SINGLELINE); 0, &oldval, 0); dc.SelectObject(oldFont); // Khoâi phuïc laïi font chöõ cuõ } 12.4.4 Thöïc hieän öùng duïng ScreenSaver ñôn giaûn: 170 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Moät soá vaán ñeà trong Windows 171
  • 96. - Caùc haønh vi xöû lyù message cuûa chuoät vaø baøn phím: OnKeyDown, case 'a': OnLButtonDown, OnMouseMove, OnRButtonDown thöïc hieän göûi case 'A': message ñoùng cöûa soå: // Ñaët Password (khoâng duøng cho WinNT-Win2000) PostMessage( WM_CLOSE, 0, 0 ); // Söû duïng hoäp Password cuûa heä thoáng cho töông thích. typedef VOID (WINAPI *PWDCHANGEPASSWORD) ( Taïo môùi dialog resource vaø lôùp CEmpScreenSaverDlg keá thöøa töø LPCSTR lpcRegkeyname, CDialog söû duïng dialog resource naøy. Dialog CEmpScreenSaverDlg HWND hwnd,UINT uiReserved1, 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 UINT uiReserved2 ); cuûa öùng duïng ScreenSaver. Coù theå löu caùc thoâng soá aán ñònh bôûi ngöôøi PWDCHANGEPASSWORD PwdChangePassword; duøng vaøo system registry (12.2). HINSTANCE hmpr; Boå sung vaø chænh söûa lôùp quaûn lyù öùng duïng CEmpApp nhö sau: hmpr = ::LoadLibrary("MPR.DLL"); - Boå sung caùc thuoäc tính protected quaûn lyù hoaït ñoäng ScreenSaver: if (hmpr == NULL) return FALSE; BOOL m_bFullDemo; PwdChangePassword = (PWDCHANGEPASSWORD) ::GetProcAddress(hmpr, "PwdChangePasswordA"); UINT Ctrl_Alt_Del_State; if (PwdChangePassword != NULL) - Haønh vi InitInstance löïa choïn xöû lyù ñeå thöïc hieän moät caùch phuø hôïp PwdChangePassword("SCRSAVE",parent,0,0); vôùi caùc tình huoáng hoaït ñoäng cuûa öùng duïng: FreeLibrary(hmpr); BOOL CEmpApp::InitInstance() return FALSE; { case 'p': m_bFullDemo = FALSE; // Löu cheá ñoä minh hoïa case 'P': HWND parent; // Handle cöûa soå cha // Xem minh hoïa trong maøn hình con RECT rect; // Vò trí cöûa soå öùng duïng style = WS_CHILD | WS_VISIBLE | WS_DISABLED ; DWORD exstyle = 0, style; // Daïng cöûa soå öùng duïng break; default: sscanf(m_lpCmdLine + 3, "%d", &parent); // Cheá ñoä chaïy thöïc cuûa ScreenSaver switch (m_lpCmdLine[1]) { m_bFullDemo = TRUE; case 'c': parent = GetDesktopWindow(); case 'C': exstyle = WS_EX_TOOLWINDOW | WS_EX_TOPMOST; // Chöùc naêng aán ñònh thoâng soá style = WS_POPUP | WS_VISIBLE; CEmpScreenSaverDlg* main; } CWnd* pr; // Xaùc ñònh cheá ñoä chaïy cuï theå pr = new CWnd(); CEmpScreenSaverWnd* main; pr->Attach(parent); main = new CEmpScreenSaverWnd; main = new CEmpScreenSaverDlg(pr); m_pMainWnd = main; m_pMainWnd = main; main->DoModal(); POINT p1, p2; // Goùc traùi treân, phaûi döôùi pr->Detach(); GetWindowRect (parent, &rect); // Xaùc ñònh vò trí cöûa soå cha delete main; p1.x = rect.left; p1.y = rect.top; delete pr; p2.x = rect.right; p2.y = rect.bottom; return FALSE; 172 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Moät soá vaán ñeà trong Windows 173
  • 97. if (!m_bFullDemo) { 12.5 ÖÙNG DUÏNG SÖÛ DUÏNG NHIEÀU TIEÅU TRÌNH: // Chaïy trong cöûa soå con : 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 // Xaùc ñònh toïa ñoä cöûa soå con trong hoäp Display Properties 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 ScreenToClient ( parent, &p1 ); 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 ScreenToClient ( parent, &p2 ); 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). // Cöûa soå giao dieän chính coù toïa ñoä vaø kích thöôùc thích hôïp 12.5.1 Tieåu trình xöû lyù noäi: main->CreateEx(exstyle, _T("STATIC"),"Emp.ScreenSaver", 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 style, p1.x, p1.y, p2.x, p2.y, parent, NULL); 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 // Daáu con chuoät vaø khoùa phím neáu chaïy ScreenSaver thöïc trình ñöôïc thöïc hieän thoâng qua caùc noäi dung sau ñaây: if (m_bFullDemo) { 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 ShowCursor(FALSE); main->SetCapture(); tieåu trình (Thread Procedure). Haøm naøy coù khai baùo nhö sau: SystemParametersInfo ( UINT MyThreadProc ( LPVOID pParam ); SPI_SETSCREENSAVERRUNNING, pParam : Tham soá duy nhaát maø haøm ñieàu khieån nhaän ñöôïc khi 1,&Ctrl_Alt_Del_State, 0 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 main->UpdateWindow(); 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. return TRUE; } Thöïc hieän khôûi ñoäng tieåu trình xöû lyù noäi thoâng qua haøm sau: CWinThread* AfxBeginThread ( - Haønh vi ExitInstance thöïc hieän gôõ boû caùc caøi ñaët: AFX_THREADPROC pfnThreadProc, // Haøm ñieàu khieån int CEmpApp::ExitInstance() LPVOID pParam, // Tham soá cuûa haøm. { int nPriority = THREAD_PRIORITY_NORMAL, if (m_bFullDemo) { UINT nStackSize = 0, ReleaseCapture(); DWORD dwCreateFlags = 0, ShowCursor(TRUE); LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL SystemParametersInfo ( ); SPI_SETSCREENSAVERRUNNING, 0, &Ctrl_Alt_Del_State, 0 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 return CWinApp::ExitInstance(); … // Thöïc hieän caùc xöû lyù caàn thieát. } return ( coù_loãi ) ? 1 : 0; 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ä … // Chuaån bò khôûi ñoäng tieåu trình thoáng vaø ñoåi teân taäp tin vôùi phaàn môû roäng laø .SCR. pInfo = new MyInfo ; // Chæ ñeán vuøng chöùa caùc giaù trò thoâng soá Söû duïng Control Panel / Display / ScreenSaver kieåm tra keát quaû. AfxBeginThread( MyThreadProc, pInfo ); 174 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Moät soá vaán ñeà trong Windows 175
  • 98. Giaû söû caàn thöïc hieän öùng duïng sau: 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 - 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 m_isTextScrolled = TRUE; doøng chöõ trong hoäp thoâng baùo cho ñeán khi coù tín hieäu ngöøng. // Khôûi ñoäng tieåu trình vôùi tham soá laø dialog giao dieän - Tieåu trình giao dieän quaûn lyù dialog nhaän yeâu caàu ngöôøi duøng: AfxBeginThread( TextScrolling, this ); 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. TextScrolling laø haøm xöû lyù cuûa tieåu trình chaïy chöõ. Haøm nhaän tham soá Muïc Close chaám döùt öùng duïng. void* laø con troû chæ ñeán ñoái töôïng dialog giao dieän. Coù theå khai baùo Döï aùn cuûa öùng duïng ñöôïc thöïc hieän nhö sau: haøm trong phaàn caøi ñaët cuûa lôùp CWorkerThreadDlg ñeå tieän söû duïng. Taïo döï aùn WorkerThread vôùi giao dieän chính laø dialog. UINT TextScrolling(void* pParam) { Thöïc hieän caùc caøi ñaët sau cho lôùp CWorkerThreadDlg laøm giao dieän: // Con troû pParam thöïc chaát laø con troû ñoái töôïng dialog giao dieän - Môû dialog resource, caøi ñaët caùc control sau: CWorkerThreadDlg* pDlg = (CWorkerThreadDlg*)pParam; - Hoäp chöùa doøng chöõ chaïy Static IDC_INFO static CString info = " Welcome to multi-thread programming"; - Nuùt leänh cho pheùp chöõ chaïy | ngöøng Button IDOK while (pDlg->m_isTextScrolled) { - Thuoäc tính public m_isTextScrolled kieåu BOOL ghi nhaän thoâng tin // Giaù trò thoâng baùo cho pheùp tieåu trình tieáp tuïc thöïc hieän: veà hoaït ñoäng chaïy chöõ. info = info.Mid(1) + info.Left(1); - Haønh vi OnInitDialog khôûi ñoäng caùc thoâng soá: pDlg->SetDlgItemText(IDC_INFO, info); Sleep(100); // Taïm nghæ BOOL CWorkerThreadDlg::OnInitDialog() } { return 0; // Keát thuùc tieåu trình xöû lyù noäi CDialog::OnInitDialog(); } SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon Bieân dòch vaø chaïy thöû öùng duïng. m_isTextScrolled = FALSE; // Chöa thöïc hieän chaïy chöõ 12.5.2 Tieåu trình giao dieän: return TRUE; 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) - Haønh vi OnOK öùng vôùi nuùt leänh IDOK thöïc hieän khôûi ñoäng hoaëc 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 thoâng baùo ngöøng tieåu trình xöû lyù chaïy chöõ: hieän thoâng qua caùc noäi dung sau ñaây: 176 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Moät soá vaán ñeà trong Windows 177
  • 99. Chuaån bò giao dieän (cöûa soå hoaëc dialog) cuûa tieåu trình giao dieän. BOOL CSubUserThread::InitInstance() 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. CSubUserDlg dlg; Thöïc hieän khôûi ñoäng tieåu trình giao dieän thoâng qua haøm sau: m_pMainWnd = &dlg; dlg.DoModal(); CWinThread* AfxBeginThread ( return TRUE; CRuntimeClass* pThreadClass, } int nPriority = THREAD_PRIORITY_NORMAL, UINT nStackSize = 0, Thöïc hieän caùc caøi ñaët sau cho lôùp dialog CUserIntThreadDlg: DWORD dwCreateFlags = 0, - Môû dialog resource, caøi ñaët caùc control sau: LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL - 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 pThreadClass : Con troû ñeán caáu truùc quaûn lyù thoâng tin thi haønh cuûa lôùp - Haønh vi OnOK cho nuùt choïn IDOK kích hoaït tieåu trình giao dieän: ñoái töôïng quaûn lyù tieåu trình giao dieän ñöôïc kích hoaït. Xem (11.4). void CUserIntThreadDlg::OnOK() { 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 AfxBeginThread( RUNTIME_CLASS(CSubUserThread) ); 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 Bieân dòch vaø chaïy thöû öùng duïng. dieän cuûa tieåu trình giao dieän chính. 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 Caùc böôùc thöïc hieän nhö sau: töôïng CWinThread quaûn lyù tieåu trình. 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, 12.6 LAÄP TRÌNH MULTIMEDIA VÔÙI MCI: caøi nuùt thoaùt vôùi soá hieäu IDCANCEL. MCI (Media Control Interface) cung caáp boä leänh cô baûn coù tính thích nghi Boå sung lôùp CSubUserDlg keá thöøa töø CDialog söû duïng resource treân. cao vôùi nhieàu thieát bò media trong vieäc thöïc hieän caùc noäi dung multimedia. Boå sung lôùp ñoái töôïng CSubUserThread keá thöøa töø CWinThread cho Moãi thieát bò media söû duïng cho vieäc thöïc hieän noäi dung multimedia ñöôïc pheùp quaûn lyù caùc tieåu trình giao dieän con. Ñoái töôïng CSubUserThread MCI quaûn lyù thoâng qua cöûa soå giao dieän MCI thuoäc lôùp MCIWnd. Ñaây laø lôùp nhaän ñoái töôïng CSubUserDlg laøm cöûa soå giao dieän chính thoâng qua cöûa soå do MCI ñaêng kyù tröôùc nhaèm phuïc vuï cho muïc ñích naøy. haønh vi InitInstance cuûa noù. Cöûa soå giao dieän MCI nhö sau: 178 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Moät soá vaán ñeà trong Windows 179
  • 100. - 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ù Sau ñaây laø caùc haøm MCI söû duïng phoå bieán (Vfw.h): thieát bò media ñöôïc söû duïng. HWND MCIWndCreate ( - Haønh OnInitDialog khôûi ñoäng thieát bò media: HWND hwndParent, // Handle cöûa soå cha cuûa cöûa soå MCI BOOL CMCIDlg::OnInitDialog() HINSTANCE hInstance, // Handle cuûa öùng duïng { DWORD dwStyle, // Daïng cöûa soå giao dieän MCI CDialog::OnInitDialog(); LPSTR szFile // Ñöôøng daãn, teân taäp tin media. SetDlgItemText(IDC_FILE, "HappyNewYear.rmi"); ); Môû thieát bò media vaø söû duïng noäi dung multimedia trong taäp tin töông m_mciWnd = MCIWndCreate ( this->GetSafeHwnd(), öùng. Haøm traû veà con troû cöûa soå MCI quaûn lyù thieát bò ñöôïc môû. AfxGetInstanceHandle(), Thoâng soá dwStyle cuûa cöûa soå MCI ñöôïc keát hôïp töø caùc giaù trò sau: /*invisible*/ ~WS_VISIBLE, NULL ); MCIWNDF_SHOWALL : Hieån thò caùc muïc cuûa cöûa soå. return TRUE; MCIWNDF_NOMENU : Khoâng hieån thò nuùt choïn menu. } MCIWNDF_NOPLAYBAR : Khoâng hieån thò progressbar. - Haønh vi OnPlay öùng vôùi nuùt IDC_PLAY thöïc hieän noäi dung media: LONG MCIWndOpen ( // Traû veà giaù trò 0 neáu thaønh coâng. void CMCIDlg::OnPlay() HWND hwnd, // Handle cöûa soå MCI { LPSTR szFile // Ñöôøng daãn, teân taäp tin media. char fName[1024]; // Laáy teân taäp tin multimedia DWORD dwStyle = 0 GetDlgItemText(IDC_FILE, fName, 1023); ); Môû noäi dung multimedia môùi cho thieát bò media quaûn lyù bôûi hwnd. if ( MCIWndOpen( m_mciWnd, fName, 0 ) == 0 ) { LONG MCIWndClose( HWND hwnd ); Ñoùng noäi dung multimedia. MCIWndPlay( m_mciWnd ); 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. - Haønh vi OnStop ngöøng thöïc hieän: LONG MCIWndResume( HWND hwnd ); Tieáp tuïc. void CMCIDlg::OnStop() 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 MCIWndStop( m_mciWnd ); 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: Bieân dòch vaø chaïy thöû öùng duïng. Duøng MFC Wizard taïo döï aùn MCI vôùi giao dieän chính laø dialog. 12.7 AÁN ÑÒNH MOÄT SOÁ TÍNH NAÊNG CUÛA WINDOWS: Khai baùo söû duïng thö vieän MCI trong taäp tin STDAFX.H: Moâi tröôøng windows cho pheùp ngöôøi duøng aán ñònh moät soá tính naêng tieän #include <Vfw.h> í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å #pragma comment (lib, "Vfw32.lib") // MCI library ñöôï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: Trong lôùp dialog giao dieän chính: CMCIDlg 180 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Moät soá vaán ñeà trong Windows 181
  • 101. BOOL SystemParametersInfo ( 12.8.1 Caùc kieåu hook (Hook Type): UINT uiAction, // Soá hieäu cuûa chöùc naêng caàn thöïc hieän Hook ñöôïc phaân chia thaønh caùc kieåu khaùc nhau tuøy thuoäc vaøo kieåu UINT uiParam, // AÁn ñònh tuøy thuoäc uiAction message ñöôïc hook. Moät soá kieåu hook phoå bieán nhö sau: PVOID pvParam, // Con troû vuøng ñeäm, tuøy thuoäc uiAction WH_KEYBOARD : Hook caùc message lieân quan baøn phím. UINT fWinIni // Ñeà nghò caäp nhaät user profile. = 0: khoâng. WH_MOUSE : Hook caùc message lieân quan con chuoät. ); Laáy hoaëc ñaët thoâng soá qui ñònh tính naêng töông öùng cuûa heä thoáng. WH_CBT : Hook caùc thao taùc treân cöûa soå giao dieän. Giaù trò uiAction coù theå laø: WH_CALLWNDPROCRET : Hook giaù trò traû veà töø haøm xöû lyù message SPI_GETLOWPOWERTIMEOUT : Laáy thoâng soá low power timeout WindowProc coù kieåu CWPRETSTRUCT. SPI_GETPOWEROFFTIMEOUT : Laáy thoâng soá power timeout WH_CALLWNDPROC : Hook caùc message tröôùc khi message ñöôïc SPI_GETSCREENSAVETIMEOUT : Laáy thoâng soá S.saver timeout chuyeån ñeán thuû tuïc WindowProc. SPI_SETLOWPOWERTIMEOUT : Ñaët thoâng soá low power timeout 12.8.2 Danh saùch hook (Hook Chain): SPI_SETPOWEROFFTIMEOUT : Ñaët thoâng soá power timeout Danh saùch hook laø danh saùch caùc con troû chæ ñeán caùc thuû tuïc hook. Moãi SPI_SETSCREENSAVETIMEOUT : Ñaët thoâng soá S.saver timeout. kieåu hook coù moät danh saùch hook rieâng. Khi moät message phaùt sinh, noù ñöôïc Khi uiAction laø giaù trò coù yù nghóa laáy thoâng soá: 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 uiParam : Coù giaù trò baèng 0 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: pvParam : Chæ ñeán vuøng ñeäm nhaän giaù trò thoâng soá hieän haønh. ghi nhaän message, chænh söûa message, hoaëc ngaên caám message khoâng ñeå noù Khi uiAction laø giaù trò coù yù nghóa ñaët thoâng soá: ñeán ñöôïc thuû tuïc hook keá tieáp. uiParam : Giaù trò thoâng soá aán ñònh. 12.8.3 Thuû tuïc hook (Hook Procedure): pvParam : = NULL Thuû tuïc hook laø chöông trình con chuyeân duïng cho vieäc hook loaïi message Ñoaïn chöông trình sau thöïc hieän caám tính naêng screen saver: lieân quan. Chöông trình con xöû lyù hook coù khai baùo nhö sau: UINT oldStatus; LRESULT CALLBACK HookProc ( int nCode, WPARAM wParam, // Laáy thoâng soá qui ñònh tính naêng ScreenSaver, löu vaøo oldStatus LPARAM lParam ); SystemParametersInfo( SPI_GETSCREENSAVETIMEOUT, Caùc tham soá göûi cho chöông trình con naøy khaùc nhau theo töøng kieåu hook: 0, &oldStatus, 0 ); WH_KEYBOARD – xöû lyù message baøn phím - KeyboardProc: // Caám tính naêng ScreenSaver code : - HC_ACTION: Message cuûa phím ñöôïc thöïc hieän. SystemParametersInfo( SPI_SETSCREENSAVETIMEOUT, - HC_NOREMOVE: Message cuûa phím chöa ñöôïc laáy khoûi 0, NULL, 0 ); message queue. … // Caùc xöû lyù trong ñieàu kieän ScreenSaver bò caám wParam: Maõ phím lieân quan. // Traû laïi aán ñònh tröôùc ñoù cho tính naêng ScreenSaver : oldStatus lParam : - Caùc bit 0÷15 : Giaù trò cho bieát soá laàn goõ phím SystemParametersInfo( SPI_SETSCREENSAVETIMEOUT, - Caùc bit 16÷23 : Maõ scan code cuûa phím. oldStatus, NULL, 0 ); - 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: 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 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 coù theå can thieäp ñeå caøi ñaët thuû tuïc xöû lyù message (hook procedure) tröôùc khi message queue. message ñoù ñeán ñöôïc ñoái töôïng xöû lyù message maø heä thoáng ñieàu phoái. wParam : Soá hieäu message cuûa con chuoät 182 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Moät soá vaán ñeà trong Windows 183
  • 102. lParam : Con troû ñeán caáu truùc MOUSEHOOKSTRUCT. hMod : Handle cuûa öùng duïng hoaëc DLL chöùa thuû tuïc hook. typedef struct tagMOUSEHOOKSTRUCT { LRESULT CallNextHookEx ( POINT pt; // Vò trí chæ ñieåm cuûa con chuoät HHOOK hhk, // Handle cuûa thuû tuïc hook chieám quyeàn HWND hwnd; // Handle cöûa soå lieân quan. int nCode, // Chuyeån giao giaù trò caùc tham soá UINT wHitTestCode; // Xem (4.2): WM_SETCURSOR WPARAM wParam, // maø thuû tuïc hook chieám quyeàn ULONG_PTR dwExtraInfo; // Caùc thoâng tin boå sung khaùc. LPARAM lParam // nhaän ñöôïc töø heä thoáng } MOUSEHOOKSTRUCT, *PMOUSEHOOKSTRUCT; ); Thöïc hieän thuû tuïc hook bò chieám quyeàn, giuùp oån ñònh cho windows. BOOL UnhookWindowsHookEx ( WH_CBT – Xöû lyù thao taùc treân cöûa soå - CBTProc: HHOOK hhk // Handle cuûa thuû tuïc hook huûy boû. Quan heä giöõa caùc thoâng soá nhö sau: ); Huûy boû thuû tuïc hook trong danh saùch hook. Code wParam lParam Neáu thuû tuïc hook ñöôïc caøi trong DLL thì caàn söû duïng caùc haøm sau: HCBT_ACTIVATE Handle cuûa cöûa soå Con troû caáu truùc HMODULE LoadLibrary ( ( Kích hoaït cöûa soå ) chöùa thoâng tin. LPCTSTR lpFileName // Ñöôøng daãn, teân taäp tin DLL HCBT_CREATEWND Handle cuûa cöûa soå. Con troû caáu truùc ); Traû veà giaù trò handle cuûa DLL. ( Taïo môùi cöûa soå ) chöùa thoâng tin. FARPROC GetProcAddress ( HMODULE hModule, // Handle cuûa DLL chöùa thuû tuïc HCBT_DESTROYWND Handle cuûa cöûa soå. =NULL LPCSTR lpProcName // Teân thuû tuïc ( Huûy boû cöûa soå ) ); Traû veà con troû cuûa thuû tuïc töông öùng. HCBT_MINMAX Handle cuûa cöûa soå. Word thaáp chöùa 12.8.5 ÖÙng duïng hook messages cuûa keyboard: ( Phoùng to hay Thu nhoû thoâng soá hieån thò Trong phaàn naøy, ta thöïc hieän öùng duïng hook message cuûa baøn phím. Xöû lyù cöûa soå ) cöûa soå ( SW_xxx ). hook cuûa öùng duïng baät tieáng beep ñeå thoâng baùo coù goõ phím vaø chuyeån HCBT_MOVESIZE Handle cuûa cöûa soå. Con troû caáu truùc message nhaän ñöôïc cho thuû tuïc xöû lyù hook ñaõ bò xöû lyù naøy chieám quyeàn. ( Di chuyeån hoaëc thay RECT quaûn lyù toïa Caùc böôùc thöïc hieän nhö sau: ñoåi kích thöôùc cöûa soå ) ñoä, kích thöôùc môùi. 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: 12.8.4 Caùc dòch vuï lieân quan hook: - Trong phaàn caøi ñaët, boå sung bieán löu vaø haøm xöû lyù hook: HHOOK SetWindowsHookEx ( HHOOK oldHook; // Chöùa ñòa chæ thuû tuïc hook bò chieám quyeàn int idHook, // Kieåu hook HOOKPROC lpfn, // Ñòa chæ thuû tuïc hook LRESULT CALLBACK myHook ( int code, WPARAM wParam, HINSTANCE hMod, // Handle cuûa ñôn theå chöùa hook LPARAM lParam) { DWORD dwThreadId // Soá hieäu tieåu trình söû duïng hook MessageBeep( -1 ); // Thöïc hieän beep ñeå thoâng tin ); Caøi ñaët thuû tuïc hook vaøo danh saùch hook töông öùng. Haøm traû veà // Thöïc hieän thuû tuïc bò chieám quyeàn. handle cuûa thuû tuïc hook ñöôïc caøi ñaët tröôùc thuû tuïc bò chieám quyeàn. return CallNextHookEx(oldHook, code, wParam, lParam); 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 - Haønh vi OnInitDialog xöû lyù caøi ñaët thuû tuïc hook: ñaët noù trong moät taäp tin DLL. BOOL CHookDlg::OnInitDialog() { 184 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Moät soá vaán ñeà trong Windows 185
  • 103. 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: SOFTWAREMicrosoftWindowsCurrentVersionRun 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:Gamemci.exe" caøi trong thaønh phaàn : HKEY_CURRENT_USERSOFTWAREMicrosoftWindowsCurrentVersionRun 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_USERSOFTWAREMicrosoftInternet ExplorerTypedURLs 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ø. 186 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 104. CHÖÔNG 13: 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 MFC vôùi Internet 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 13.1 GIAO THÖÙC TRUYEÀN THOÂNG TCP/IP: laäp ñoù cuõng giuùp TCP/IP nhanh choùng thích nghi vôùi caùc coâng ngheä 13.1.1 Giôùi thieäu: maïng môùi nhö ATM (Asynchronous Transfer Mode). TCP/IP (Transmission Control Protocol/Internet Protocol) bao goàm giao Taàng Internet (Internet Layer): 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 Taàng internet ñaûm nhaän chöùc naêng ñònh vò, ñoùng goùi thoâng tin vaø (host) treân heä thoáng maïng ñònh vò ñòa chæ IP (IP Host Address Internetwork). 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, TCP/IP ra ñôøi töø naêm 1969 bôûi cô quan nghieân cöùu caùc döï aùn cao caáp ARP, ICMP, vaø IGMP. thuoäc boä quoác phoøng Hoa Kyø (Department of Defence Advanced Research - Giao thöùc IP (Internet Protocol): Giao thöùc truyeàn thoâng ñònh tuyeán; Projects Agency - DARPA) nhaèm muïc tieâu xaây döïng moät giao thöùc truyeàn coù nhieäm vuï ñònh vò ñòa chæ IP, taùch vaø keát caùc packet. 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ô - Giao thöùc ARP (Address Resolution Protocol): Coù nhieäm vuï thöï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öø hieän hoaùn chuyeån caùc giaù trò ñòa chæ moät caùch töông öùng giöõa taàng thaønh quaû phaùt trieån maïng ARPANET, tieàn thaân cuûa Internet ngaøy nay. internet (logic address) vaø taàng giao tieáp maïng (physic address). 13.1.2 Kieán truùc cuûa giao thöùc TCP/IP treân moâ hình DARPA: - Giao thöùc ICMP (Internet Control Message Protocol): Coù nhieäm vuï Moâ hình DARPA vôùi giao thöùc truyeàn thoâng TCP/IP laø moät kieán truùc bao 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 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: 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 Taàng giao tieáp maïng (Network Interface Layer): nhaän qua ñöôøng truyeàn naøy. Giao thöùc naøy ñaûm baûo thoâng tin ñöôïc Taàng giao tieáp maïng (taàng truy xuaát maïng) ñaûm nhaän nhieäm vuï nhaän chuyeån ñeán host nhaän chính xaùc vaø an toaø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ò Taàng öùng duïng (Application Layer): MFC vôùi Internet 187 188 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 105. 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 Treân 4 bytes ñòa chæ IP, ta coù theå choïn moät soá bytes tuøy yù chöùa ñòa chæ taàng khaùc, ñoàng thôøi ñònh nghóa caùc giao thöùc truyeàn thoâng maø öùng maïng, soá bytes coøn laïi duøng chöùa ñòa chæ host. Moãi caùch choïn khaùc nhau duïng cuûa ngöôøi duøng coù theå söû duïng ñeå truyeàn döõ lieäu qua heä thoáng taïo thaønh moät lôùp ñòa chæ IP. Coù 3 lôùp ñòa chæ IP phoå bieán: maïng. Caùc giao thöùc truyeàn thoâng phoå bieán nhö sau: - Lôùp A : 1 byte cho ñòa chæ maïng, 3 bytes cho ñòa chæ host - Giao thöùc HTTP (HyperText Transfer Protocol): Duøng chuyeån taûi - Lôùp B : 2 bytes cho ñòa chæ maïng, 2 bytes cho ñòa chæ host caùc taäp tin tham gia vaøo noäi dung trang WEB (World Wide Web). - Lôùp C : 3 bytes cho ñòa chæ maïng, 1 byte cho ñòa chæ host - Giao thöùc FTP (File Transfer Protocol): Duøng chuyeån taûi caùc taäp tin Löu yù: thoâng thöôøng. - Giaù trò ñòa chæ host vôùi taát caû caùc bits baèng 1 laø ñòa chæ chæ cho moïi - Giao thöùc SMTP (Simple Mail Transfer Protocol): Duøng chuyeån taûi host treân heä thoáng maïng (host broadcast address) chöùa host. Khoâng noäi dung thö tín bao goàm thoâng ñieäp vaø caùc döõ lieäu keøm theo. moät host naøo ñöôïc söû duïng ñòa chæ naøy. - Giao thöùc Telnet: Duøng cho hoaït ñoäng thaâm nhaäp host töø xa thoâng - Moät ñòa chæ IP coù phaàn ñòa chæ host vôùi taát caû caùc bits baèng 0 chính qua caùc thieát bò ñaàu cuoái (Terminal). laø ñòa chæ cuûa heä thoáng maïng. Khoâng duøng ñòa chæ naøy cho host. Beân caïnh caùc giao thöùc truyeàn thoâng noùi treân, taàng öùng duïng coøn Address Class First Host ID Last Host ID cung caáp caùc dòch vuï sau: Class A w.0.0.1 w.255.255.254 - Dòch vuï chuyeån ñoåi domain name thaønh ñòa chæ IP töông öùng. Class B w.x.0.1 w.x.255.254 - Dòch vuï cung caáp thoâng tin ñònh vò ñòa chæ IP. Class C w.x.y.1 w.x.y.254 - Dòch vuï quaûn lyù caùc thieát bò maïng (boä ñònh tuyeán, caàu noái, hub 13.1.4 Subnet: thoâng minh) nhaèm thu thaäp vaø trao ñoåi thoâng tin quaûn lyù maïng. Vôùi soá bits duøng cho ñòa chæ host trong caùc lôùp ñòa chæ, soá löôïng host cuûa 13.1.3 Ñòa chæ IP: 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ù, Ñòa chæ IP laø giaù trò giuùp xaùc ñònh moät host duy nhaát treân heä thoáng maïng. 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 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æ 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 cuûa host treân maïng ñoù. nöõa, 16 trieäu giaù trò ñòa chæ cho moät heä thoáng maïng laø quaù dö thöøa. - Ñòa chæ maïng (Network address - Network ID): Soá hieäu duøng cho moät 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 heä thoáng maïng caùc host cuøng chung moät ñaëc ñieåm ñònh tuyeán. Caùc heä nhoùm nhoû hôn goïi laø maïng con (SubNet). Moãi subnet töông öùng vôùi moät ñòa thoáng maïng keát vaøo internet phaûi coù ñòa chæ maïng phaân bieät. chæ maïng subnet vaø giôùi haïn ñòa chæ IP caùc host tröïc thuoäc. Ñòa chæ subnet laø - Ñòa chæ host (host address - host ID): Soá hieäu duøng cho moät host giaù trò hình thaønh töø moät phaàn bits trong ñòa chæ host cuûa ñòa chæ IP thuoäc heä (workstation, server, router, TCP/IP host). Caùc host trong cuøng moät heä maïng ban ñaàu. Coù theå xem Subnet laø taäp con cuûa heä maïng. 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 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 Hay: 192.168.3.24 laø 139.12.0.0. Heä maïng naøy cho pheùp xaùc laäp 65535 ñòa chæ host. Thöïc MFC vôùi Internet 189 190 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 106. hieän chia heä maïng treân thaønh 256 subnet döïa treân byte thöù ba, ta ñöôïc caùc Xaùc ñònh ñòa chæ maïng: Ñeå taùch ñòa chæ maïng töø moät ñòa chæ IP baát kyø subnet 8-bit ñòa chæ lôùp B: 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: Caùc subnet ñöôïc taïo thaønh laø: 139.12.1.0, 139.12.2.0 vaø 139.12.3.0. Stt Ñòa chæ Subnet theo heä nhò phaân Giôùi haïn ñòa chæ IP 13.1.5 Subnet Mask: 1 11000000.10101000.00000000.00000001- 192.168.0.1 - Subnet mask laø moät giaù trò 32 bits giuùp taùch giaù trò ñòa chæ maïng (hoaëc ñòa 11000000.10101000.00011111.11111110 192.168.31.254 chæ subnet) vaø ñòa chæ host töø moät ñòa chæ IP baát kyø (trong moät lôùp ñòa chæ baát 2 11000000.10101000.00100000.00000001- 192.168.32.1 - kyø, caùch phaân chia subnet baát kyø). Giaù trò naøy ñöôïc xaây döïng nhö sau: 11000000.10101000.00111111.11111110 192.168.63.254 - Caùc giaù trò bit töông öùng vôùi ñòa chæ maïng coù giaù trò laø 1. 3 11000000.10101000.01000000.00000001- 192.168.64.1 - - Caùc giaù trò bit töông öùng vôùi ñòa chæ host coù giaù trò laø 0. 11000000.10101000.01011111.11111110 192.168.95.254 Giaù trò subnet mask cuõng ñöôïc bieåu dieãn döôùi daïng num-dot. 4 11000000.10101000.01100000.00000001- 192.168.96.1 - Ta coù subnet mask maëc nhieân cho caùc lôùp ñòa chæ nhö sau: 11000000.10101000.01111111.11111110 192.168.127.254 Class Bits for Subnet Mask Subnet Mask 5 11000000.10101000.10000000.00000001- 192.168.128.1 - Class A 11111111 00000000 00000000 00000000 255.0.0.0 11000000.10101000.10011111.11111110 192.168.159.254 Class B 11111111 11111111 00000000 00000000 255.255.0.0 6 11000000.10101000.10100000.00000001- 192.168.160.1 - Class C 11111111 11111111 11111111 00000000 255.255.255.0 11000000.10101000.10111111.11111110 192.168.191.254 7 11000000.10101000.11000000.00000001- 192.168.192.1 - 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æ 11000000.10101000.11011111.11111110 192.168.223.254 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ò 8 11000000.10101000.11100000.00000001- 192.168.224.1 - mask treân ñòa chæ subnet. 11000000.10101000.11111111.11111110 192.168.255.254 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 13.1.6 Host domain name: mask söû duïng toång coäng 24 bits (255.255.255.0) ñeå ñònh nghóa ñòa chæ 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 maïng subnet. Ñòa chæ maïng subnet vaø giaù trò subnet mask töông öùng ñöôïc 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 bieåu dieãn theo daïng num-dot nhö sau: 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á, 138.96.58.0, 255.255.255.0 caùc kyù töï ‘-‘ vaø ‘.’ vaø coù yù nghóa töông ñöông vôùi ñòa chæ IP trong vieäc quaûn lyù Hay: 138.96.58.0/24 (24-bit mask) ñò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: MFC vôùi Internet 191 192 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 107. - Nick name: Moät nhaõn ñöôïc duøng cho moät ñòa chæ IP duy nhaát. thoâng tin yeâu caàu khoâng xaùc ñònh ñöôïc thì noù seõ chuyeån ñeán DNS server - Domain name: Teân ñöôïc hình thaønh töø caáu truùc phaân lôùp. Caáu truùc 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 phaân lôùp naøy ñöôïc qui ñònh phoå bieán thaønh luaät vaø ñöôïc goïi laø heä ñöôïc traû veà theo loä trình ngöôïc laïi. 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 13.1.7 IP Routing: EDU Caùc cô quan giaùo duïc, nghieân cöùu IP routing laø tieán trình xöû lyù göûi packet ñeán host nhaän döïa treân ñòa chæ IP GOV Toå chöùc chính phuû 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ø MIL Cô quan quaân söï ôû thieát bò ñònh tuyeán (router device) nhaèm thöïc hieän quyeát ñònh löïa choïn vò trí NET cô quan quaûn lyù maïng chính maø packet seõ ñöôïc chuyeån ñeán. ORG Caùc toå chöùc khaùc Ñeå thöïc hieän quyeát ñònh treân, taàng IP tham khaûo baûng ñònh tuyeán ñöôïc löu INT Caùc toå chöùc quoác teá tröõ trong boä nhôù. Noäi dung baûng ñònh tuyeán ñöôïc khôûi taïo maëc nhieân khi <country code> Caùc nhaùnh cho caùc quoác gia tröø Hoa Kyø 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 Moät teân mieàn ñaày ñuû (Fully Qualified Domain Name – FQDN) chöùa töï ñoäng trong quaù trình lieân laïc vôùi caùc boä ñònh tuyeán. ñöôø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. Coù hai daïng phoå bieán khi göûi packet; göûi tröïc tieáp vaø göûi giaùn tieáp. Ví duï: ftpsrv.wcoast.slate.com Göûi tröïc tieáp (Direct delivery): Xaûy ra khi host nhaän vaø host göûi ñöôïc Vieäc chuyeån ñoåi giöõa ñòa chæ IP vaø Domain name ñöôïc thöïc hieän döïa treân 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 baûng chuyeån ñoåi IP-DomainName do DNS server, moät host chuyeân duïng ñònh cuûa taàng giao tieáp maïng vaø ñöôïc göûi ñi. 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 Göûi giaùn tieáp (Indirect delivery): Xaûy ra khi host nhaän vaø host göûi ñöôïc baûng thoâng tin naøy thoâng qua caùc dòch vuï cung caáp bôûi windows socket. keát noái thoâng qua moät trung gian (boä ñònh tuyeán). Khi ñoù seõ coù moät quaù Windows socket truyeàn yeâu caàu cuûa öùng duïng ñeán boä phaän phaân giaûi 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 domain name cuûa giao thöùc truyeàn thoâng TCP/IP. Boä phaän naøy chuyeån ñeán host nhaän (hoaëc giaùn tieáp ñeán moät boä ñònh tuyeán khaùc). yeâu caàu ñeán DNS server. DNS server nhaän yeâu caàu vaø thöïc hieän; neáu MFC vôùi Internet 193 194 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 108. - 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 Metric Purpose Address Interface A göûi tröïc tieáp ñeán B 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 A göûi giaùn tieáp packet ñeán router1 , router 1 göûi giaùn tieáp ñeán DirectyAttached router 2, router 2 göûi tröïc tieáp ñeán C. 157.55.16.0 255.255.240.0 157.55.27.90 157.55.27.90 1 Network Baûng ñònh tuyeán: 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 Baûng ñònh tuyeán ñöôïc xaùc laäp treân taát caû caùc host (node, router) vaø 224.0.0.0 224.0.0.0 157.55.27.90 157.55.27.90 1 Multicast Address ñöôïc ñaët bôûi caùc giaù trò maëc nhieân trong quaù trình khôûi ñoäng cuûa giao 255.255.255.255 255.255.255.255 157.55.27.90 157.55.27.90 1 Limited Broadcast thöùc TCP/IP. Noäi dung cuûa baûng chöùa thoâng tin veà heä thoáng caùc ñòa chæ ( Moät baûng ñònh tuyeán cuûa Windows NT ) IP treân maïng, caùch keát noái vôùi caùc ñòa chæ aáy. Xöû lyù ñònh tuyeán: Moãi khi moät goùi thoâng tin ñöôïc göûi ñi, baûng ñònh tuyeán seõ ñöôïc söû Xöû lyù ñònh tuyeán laø xöû lyù thöïc hieän löïa choïn muïc ñònh tuyeán trong duïng ñeå xaùc ñònh: 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 - Ñò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 ñöôïc thöïc hieän thoâng qua caùc böôùc sau: chæ cuûa host nhaän packet, ngöôïc laïi, laø ñòa chæ cuûa boä ñònh tuyeán. - Treân moãi muïc ñònh tuyeán, thöïc hieän pheùp toaùn AND giöõa ñòa chæ - Giao dieän söû duïng ñeå göûi: Bao goàm thoâng tin veà caáu truùc vaät lyù host nhaän vaø giaù trò subnet mask. Kieåm tra keát quaû naøy vôùi vaø logic cuûa thieát bò keát noái maïng ôû nôi göûi vaø nôi nhaän. Network ID ñeå ñaùnh giaù ñoä phuø hôïp (ñoä töông töï). Caáu truùc noäi dung cuûa moät muïc trong baûng ñònh tuyeán: - Choïn ra caùc muïc ñònh tuyeán coù möùc ñoä phuø hôïp cao nhaát. Trong [ Network ID, Subnet Mask, Next Hop, Interface, Metric ] caùc muïc ñònh tuyeán naøy, choïn ra caùc muïc coù chi phí tuyeán truyeàn Trong ñoù: nhoû nhaát. Cuoái cuøng, töø caùc muïc ñònh tuyeán choïn ñöôïc, muïc ñònh - Network ID: Ñòa chæ maïng töông öùng vôùi tuyeán truyeàn tin. tuyeán ñöôïc söû duïng laø muïc coøn roãi. - Subnet Mask: Giaù trò duøng taùch ñòa chæ maïng töø ñòa chæ IP. Xöû lyù ñònh tuyeán khaùc nhau treân caùc loaïi host khaùc nhau: - Next Hop: Ñòa chæ IP cuûa host trung gian keá tieáp. MFC vôùi Internet 195 196 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 109. Host göûi: Packet ñöôïc göûi töø giao thöùc ôû taàng caáp cao hôn cuûa IP (TCP, 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 UDP, ...). Khi ñoù vai troø IP ôû host göûi nhö sau: packet qua ñöôøng truyeàn maïng. Moãi socket coù moät kieåu xaùc ñònh vaø gaén lieàn - Ñaët giaù trò cho tröôøng TTL (Times-To-Live) theo giaù trò qui ñònh cuûa vôùi moät tieán trình xöû lyù truyeàn thoâng. Coù hai loaïi socket: öùng duïng taàng caáp cao hoaëc laáy giaù trò maëc nhieân cuûa heä thoáng. Stream Socket: Cô cheá truyeàn döõ lieäu theo doøng. - Xaùc ñònh tuyeán toái öu cho packet truyeàn ñi. Datagram Socket: Cô cheá truyeàn döõ lieäu theo packet. - Neáu khoâng xaùc ñònh ñöôïc tuyeán truyeàn thì thoâng baùo loãi ñeán taàng Ñòa chæ socket laø moät giaù trò bao goàm ñòa chæ cuûa host vaø soá hieäu port truyeàn thoâng ôû caáp cao hôn. Ngöôïc laïi, thöïc hieän truyeàn theo tuyeán. maø tieán trình xöû lyù truyeàn thoâng lieân quan socket ñaõ ñaêng kyù söû duïng. Host ñònh tuyeán: Vai troø cuûa IP nhö sau: 13.2.3 Moät soá caáu truùc döõ lieäu cuûa Winsock API: - Kieåm tra checksum cuûa packet. Neáu sai thì huûy packet. Ñòa chæ num-dot cuûa host: - Kieåm tra ñòa chæ IP cuûa host nhaän treân packet. Neáu ñòa chæ naøy laø ñòa Ñöôïc bieåu dieãn bôûi moät giaù trò chuoãi coù noäi dung laø boán giaù trò soá coù chæ moät boä ñònh tuyeán thì noäi dung packet (tröø phaàn noäi dung IP ñoä lôùn baèng byte vaø ñöôïc ngaên caùch baèng daáu ‘.’ header) ñöôïc chuyeån cho giao thöùc taàng caáp cao töông öùng. Ngöôïc Ví duï: "127.0.0.1" laïi, giaûm giaù trò tröôøng TTL ñi 1; neáu giaù trò tröôøng naøy baèng 0 thì Caáu truùc khôûi ñoäng winsock : huûy boû packet vaø göûi thoâng ñieäp "ICMP Time Expired-TTL typedef struct WSAData { Expired" cho host göûi, ngöôïc laïi xaùc ñònh tuyeán göûi vaø göûi packet. WORD wVersion; Host nhaän: Vai troø cuûa IP nhö sau: WORD wHighVersion; - Kieåm tra checksum cuûa packet. Neáu sai thì huûy packet. char szDescription[WSADESCRIPTION_LEN+1]; char szSystemStatus[WSASYS_STATUS_LEN+1]; - Neáu ñòa chæ host nhaän ghi treân packet khoâng phaûi laø ñòa chæ cuûa host unsigned short iMaxSockets; ñang xöû lyù thì huûy packet. unsigned short iMaxUdpDg; - Göûi noäi dung packet (tröø IP header) leân giao thöùc taàng cao hôn. char FAR * lpVendorInfo; 13.2 LAÄP TRÌNH TCP/IP VÔÙI WINSOCK: } WSADATA, *LPWSADATA; Winsock (Windows Socket) coù xuaát xöù töø BSD (Berkeley Software szDescription: Thoâng tin veà phieân baûn winsock ñang söû duïng. Distribution - UNIX), töông thích vôùi windows qua phieân baûn WinSock1.1. szSystemStatus: Thoâng tin veà phieân baûn heä ñieàu haønh windows. 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 Caáu truùc chöùa thoâng tin cuûa host : thoâng TCP vaø UDP. Thoâng qua winsock, öùng duïng coù theå trieån khai deã daøng struct hostent { caùc taùc vuï truyeàn thoâng treân taàng truyeàn thoâng cuûa moâ hình maïng. char FAR * h_name; // Domain name 13.2.1 Port: char FAR * FAR * h_aliases; // Teân duøng thay domain name 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 short h_addrtype; // Kieåu ñòa chæ, vôùi TCP/IP laø AF_INET 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 short h_length; // Kích thöôùc ñòa chæ, 4 bytes cho AF_INET öù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 char FAR * FAR * h_addr_list; // Danh saùch ñòa chæ. Phaàn töû 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. // ñaàu danh saùch h_addr_list[0] // (hay h_addr) laø ñòa chæ host. 13.2.2 Socket: } HOSTENT, *PHOSTENT; Ñòa chæ socket treân moät host: struct sockaddr { MFC vôùi Internet 197 198 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 110. unsigned short sa_family; // Hoï ñòa chæ cuûa host. - Low-order byte = winsock major version number. char sa_data[14]; // Ñòa chæ (cho pheùp nhieàu loaïi ñòa chæ) - Ví duï: MAKEWORD (1, 1 ) Winsock version 1.1. } SOCKADDR ; int gethostname ( // Haøm traû veà SOCKET_ERROR neáu coù loãi Caáu truùc naøy ñöôïc töông thích bôûi SOCKADDR_IN cuûa MicroSoft: char FAR *name, // Vuøng ñeäm chöùa thoâng tin int namelen // Kích thöôùc vuøng ñeäm struct sockaddr_in { ); Laáy thoâng tin veà teân cuûa host. short sin_family; // Coù giaù trò laø AF_INET PHOSTENT gethostbyname ( unsigned short sin_port; // Soá hieäu port const char FAR *name // Tham soá chöùa teân host struct in_addr sin_addr; // Ñòa chæ IP 4 bytes cuûa host ); Haøm traû veà con troû ñeán caáu truùc HOSTENT chöùa thoâng tin cuûa host. char sin_zero[8]; // Chæ ñeå töông thích vôùi SOCKADDR int WSACleanup( ); Chaám döùt söû duïng dòch vuï winsock. } SOCKADDR_IN ; sin_addr : Ñòa chæ IP 4 bytes cuûa host, coù caùc caùch dieãn taû nhö sau: 13.3 MFC VÔÙI LAÄP TRÌNH WINSOCK: struct in_addr { Thö vieän söû duïng: AfxSock.h union { 13.3.1 Khôûi ñoäng Winsock: struct { BOOL AfxSocketInit ( WSADATA* lpwsaData = NULL ); unsigned char s_b1, s_b2, s_b3, s_b4; AfxSocketInit ñaûm nhaän vieäc thöïc hieän WSAStartup khi baét ñaàu öùng } S_un_b; // Ñòa chæ IP baèng 4 bytes duïng vaø WSACleanup khi öùng duïng keát thuùc. Lôøi goïi AfxSocketInit ñöôïc struct { thöïc hieän trong haønh vi InitInstance cuûa ñoái töôïng quaûn lyù tieåu trình chính unsigned short s_w1, s_w2; cuûa öùng duïng. Tham soá truyeàn cho haøm coù yù nghóa nhö vôùi WSAStartup. } S_un_w; // Ñòa chæ IP baèng 2 words 13.3.2 Lôùp CAsyncSocket: unsigned long S_addr; // Ñòa chæ IP baèng 1 long CAsyncSocket laø lôùp ñoái töôïng quaûn lyù socket. Baèng söï bao haøm caùc dòch } S_un; 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 13.2.4 Moät soá dòch vuï cuûa Winsock API: hoaït ñoäng truyeàn thoâng treân taàng truyeàn taûi cuûa giao thöùc TCP/IP. char FAR * inet_ntoa ( Caùc haønh vi ñaëc tröng lôùp CAsyncSocket nhö sau: struct in_addr in // Ñòa chæ IP 4 bytes CAsyncSocket( ); Khôûi taïo ñoái töôïng socket roãng. ); Traû veà chuoãi ñòa chæ num-dot töông öùng. BOOL Create ( unsigned long inet_addr ( UINT nSocketPort = 0, const char FAR *cp // Ñòa chæ IP num-dot int nSocketType = SOCK_STREAM, ); Haøm traû veà giaù trò kieåu long cuûa ñòa chæ IP 4 bytes töông öùng. long lEvent = FD_READ | FD_WRITE | FD_OOB | int WSAStartup ( // Haøm traû veà giaù trò 0 neáu thaønh coâng FD_ACCEPT | FD_CONNECT | FD_CLOSE, WORD version, // Phieân baûn winsock LPCTSTR lpszSocketAddress = NULL LPWSADATA pMyInfo // Con troû caáu truùc nhaän thoâng tin. ); 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ù). ); Khôûi ñoäng, chuaån bò cho vieäc khai thaùc caùc dòch vuï cuûa winsock. Trong ñoù: version: Chöùa soá hieäu phieân baûn winsock caàn duøng - nSocketPort : Soá hieäu port cuûa socket. Giaù trò naøy coù theå xaùc ñònh - High-order byte = winsock minor version number. 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. MFC vôùi Internet 199 200 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 111. - n SocketType : AÁn ñònh giao thöùc söû duïng; SOCK_STREAM cho int nLevel = SOL_SOCKET TCP hoaëc SOCK_DGRAM cho UDP. BOOL Listen ( - lEvent : Bao goàm caùc thoâng soá lieân quan ñeán caùc bieán coá int nConnectionBacklog = 5 // Chieàu daøi doøng chôø keát noái truyeàn thoâng maø öùng duïng muoán winsock phaûn hoài ); Chôø nhaän keát noái töø host ñoái taùc (server chôø caùc clients). ngay treân socket quaûn lyù bôûi ñoái töôïng socket. BOOL Connect ( FD_READ : Nhaän ñöôïc thoâng tin. LPCTSTR lpszHostAddress, // Ñòa chæ num.dot cuûa host ñoái taùc FD_WRITE : Göûi ñöôïc thoâng tin. UINT nHostPort // Soá hieäu port treân host ñoái taùc FD_ACCEPT : Ñoàng yù keát noái. ); Xin keát noái vôùi host ñoái taùc (clients keát noái vôùi server). FD_CONNECT : Ñeà nghò keát noái. BOOL Connect ( FD_CLOSE : Chaám döùt keát noái. const SOCKADDR* lpSockAddr, // Ñòa chæ socket host ñoái taùc FD_OOB : Thoâng tin ngoaøi tuyeán. int nSockAddrLen // Kích thöôùc lpSockAddr - lpszSocketAddress : Chuoãi chöùa ñòa chæ num-dot cuûa host ñoái taùc maø ); Xin keát noái vôùi host ñoái taùc (clients keát noái vôùi server). socket ñöôïc keát (bind). INADDR_ANY laø ñòa chæ virtual BOOL Accept ( duøng keát vôùi taát caû caùc host trong heä thoáng maïng. CAsyncSocket& rConnectedSocket, BOOL Bind ( SOCKADDR* lpSockAddr = NULL, UINT nSocketPort, // Soá hieäu port int* lpSockAddrLen = NULL LPCTSTR lpszSocketAddress = NULL // Ñòa chæ num-dot cuûa host ); 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). ); Keát socket vôùi moät host xaùc ñònh. Trong ñoù: BOOL Bind ( - rConnectedSocket : Bieán chöùa ñoái töôïng socket ñöôïc taïo môùi vôùi const SOCKADDR* lpSockAddr, // Ñòa chæ socket host ñoái taùc caùc ñaëc tính gioáng nhö ñoái töôïng chuû theå vaø int nSockAddrLen // Kích thöôùc lpSockAddr duøng ñeå quaûn lyù lieân keát vöøa thieát laäp. ); Keát socket vôùi moät host xaùc ñònh. - lpSockAddr : Ñòa chæ bieán kieåu SOCKADDR ñöôïc duøng ñeå BOOL SetSockOpt ( nhaän ñòa chæ host ñoái taùc. int nOptionName, // Thuoäc tính caàn aán ñònh - lpSockAddrLen : Ñòa chæ bieán ñöôïc duøng ñeå nhaän kích thöôùc cuûa const void* lpOptionValue, // Ñòa chæ bieán chöùa giaù trò aán ñònh ñòa chæ traû veà trong lpSockAddr. int nOptionLen, // Kích thöôùc bieán chöùa giaù trò virtual int Send ( // Söû duïng cho Stream Socket int nLevel = SOL_SOCKET // Möùc ñaët thoâng soá cho socket const void* lpBuf, // Ñòa chæ vuøng ñeäm chöùa döõ lieäu truyeàn ); AÁn ñònh ñaëc tính hoaït ñoäng cuûa socket. int nBufLen, // Kích thöôùc vuøng ñeäm nOptionName cho pheùp löïa choïn thuoäc tính aán ñònh cuûa socket : int nFlags = 0 // Thoâng soá aán ñònh ñaëc tính göûi - SO_BROADCAST : BOOL → Göûi message ñeán moïi host. ); Göûi döõ lieäu thoâng qua moät socket ñöôïc keát noái. - SO_DONTROUTE : BOOL → Göûi tröïc tieáp khoâng qua router. Thoâng soá duøng cho ñaëc tính göûi: Ví duï: Neáu aán ñònh ñaëc tính cuûa socket laø cho pheùp göûi message ñeán - MSG_DONTROUTE = Göûi thaúng khoâng qua router. moïi host thì haønh vi treân ñöôïc thöïc hieän vôùi tham soá nhö sau: - MSG_OOB = Göûi ngoaïi tuyeán (khaån caáp) int nOptionName, = SO_BROADCAST int SendTo ( // Söû duïng cho Datagram const void* lpOptionValue, = Ñòa chæ bieán luaän lyù baèng TRUE const void* lpBuf, // Vuøng ñeäm döõ lieäu int nOptionLen, = sizeof (BOOL) int nBufLen, // Kích thöôùc vuøng ñeäm MFC vôùi Internet 201 202 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 112. UINT nHostPort, // Soá hieäu port ñoái taùc virtual void OnConnect ( LPCTSTR lpszHostAddress = NULL, // Ñòa chæ num-dot ñoái taùc int nErrorCode // Maõ loãi int nFlags = 0 // Ñaëc tính göûi. ); Nhaän ñöôïc yeâu caàu xin keát noái cuûa host ñoái taùc. ); Göûi packet ñeán host ñoái taùc. Haøm traû veà soá bytes döõ lieäu göûi ñöôïc. virtual void OnAccept ( Ñeå göûi packet ñeán taát caû caùc host, ñaët lpszHostAddress = NULL. int nErrorCode // Maõ loãi, = 0 is OK int SendTo ( // Söû duïng cho Datagram ); Nhaän ñöôïc söï ñoàng yù keát noái cuûa host ñoái taùc. const void* lpBuf, // Nhö treân … virtual void OnSend ( int nBufLen, int nErrorCode const SOCKADDR* lpSockAddr, // Ñòa chæ socket ñoái taùc ); Socket ñaõ saün saøng cho vieäc göûi döõ lieäu. int nSockAddrLen, // Kích thöôùc ñòa chæ virtual void OnReceive ( int nFlags = 0 int nErrorCode ); Göûi packet ñeán host ñoái taùc. Haøm traû veà soá bytes döõ lieäu ñöôïc göûi. ); Döõ lieäu ñaõ saün saøng chôø nhaän thoâng qua socket. Ñeå göûi packet ñeán taát caû caùc host, giaù trò ñòa chæ ñoái taùc ñaët nhö sau: virtual void OnOutOfBandData ( lpSockAddr->sin_addr.s_addr = htonl ( INADDR_BROADCAST ); int nErrorCode virtual int Receive ( // Söû duïng cho Stream Socket ); Coù döõ lieäu khaån caáp saün saøng chôø nhaän thoâng qua socket. void* lpBuf, // Ñòa chæ vuøng ñeäm nhaän döõ lieäu virtual void OnClose ( int nBufLen, // Kích thöôùc vuøng ñeäm int nErrorCode int nFlags = 0 // Ñaëc tính nhaän döõ lieäu. ); Socket chuaån bò chaám döùt hoaït ñoäng. ); Nhaän döõ lieäu thoâng qua moät socket ñöôïc keát noái. BOOL ShutDown ( int ReceiveFrom ( // Söû duïng cho Datagram int nHow // 0 = receive, 1 = send ; 2 = both void* lpBuf, // Ñòa chæ vuøng ñeäm chöùa döõ lieäu ); Chaám döùt taùc vuï truyeàn thoâng töông öùng treân socket. int nBufLen, // Kích thöôùc vuøng ñeäm virtual void Close( ); Huûy boû socket. CString& rSocketAddress, // Ñòa chæ num-dot ñoái taùc 13.4 LAÄP TRÌNH WINSOCK CHO GIAO THÖÙC UDP: UINT& rSocketPort, // Soá hieäu port ñoái taùc Trong phaàn naøy ta söû duïng giao thöùc UDP ñeå thöïc hieän truyeàn thoâng ñieäp int nFlags = 0 // Ñaëc tính göûi giöõa hai hay nhieàu host. ÖÙng duïng thieát keá cho pheùp ngöôøi duøng soaïn thaûo ); Nhaän döõ lieäu töø host ñoái taùc. 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. 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. Caùch thöïc hieän nhö sau: BOOL AsyncSelect ( long lEvent = FD_READ | FD_WRITE | Duøng MFC Wizard taïo döï aùn Udp vôùi cöûa soå giao dieän chính laø dialog. FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE ); ÔÛ böôùc ‘Step 2 of 4’: Choïn hoã trôï Windows Sockets: Ñaêng kyù bieán coá truyeàn thoâng mong muoán (xem Create ). MFC vôùi Internet 203 204 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 113. } - 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); } Choïn Finish hoaøn ñeå hoaøn taát vieäc khôûi taïo döï aùn. else Tieáp tuïc thöïc hieän caùc boå sung sau : SendTo(m_Buffer, BUF_LEN, RECEIV_PORT, peerAddr); 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: - Haønh vi keá thöøa OnReceive nhaän thoâng tin göûi ñeán vaø hieån thò trong - Khai baùo caùc haèng, soá hieäu port söû duïng trong öùng duïng: hoäp thoâng baùo coù soá hieäu laø IDC_READ cuûa dialog lieân quan: const BUF_LEN = 512; // Chieàu daøi vuøng ñeäm void CEmpUdp::OnReceive(int nErrorCode) const SENT_PORT = 2051; // port göûi thoâng tin { const RECEIV_PORT = 2050; // port nhaän thoâng tin CString peerAddr; // Ñòa chæ host ñoái taùc vaø - Caùc ñoái töôïng thuoäc tính söû duïng trong lôùp: UINT port; // soá hieäu port söû duïng char *m_Buffer; // Vuøng ñeäm chöùa thoâng tin nhaän-göûi ReceiveFrom(m_Buffer, BUF_LEN, peerAddr, port); CDialog *m_Parent; // Con troû ñoái töôïng dialog lieân quan sprintf (m_Buffer, "%sn(from %s)", m_Buffer, peerAddr ); - Haønh vi khôûi taïo cuûa lôùp nhaän tham soá laø con troû ñoái töôïng dialog m_Parent->SetDlgItemText ( IDC_READ, m_Buffer ); giao dieän lieân quan; thöïc hieän löu giaù trò con troû vaøo thuoäc tính cuûa AsyncSelect(FD_READ); // Duy trì vieäc nhaän thoâng tin 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ôû 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ò m_Parent = parent; thoâng tin nhaän, vaø hoäp nhaäp IP vôùi bieán m_IP duøng nhaäp ñòa chæ IP. m_Buffer = new char[BUF_LEN + 1]; MFC vôùi Internet 205 206 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 114. Thöïc hieän caùc boå sung cho lôùp CUDPDlg quaûn lyù dialog giao dieän: CSocket sockSrvr; CSocket sockClient; - Khai baùo caùc ñoái töôïng thuoäc tính quaûn lyù socket nhaän vaø göûi thoâng // Taïo socket 1,2 // Taïo socket 2 tin cuûa öùng duïng: sockSrvr.Create(nPort); sockClient.Create( ); CEmpUdp *m_sentUDP; // Quaûn lyù socket göûi thoâng tin // Chôø nhaän keát noái CEmpUdp *m_receivUDP; // Quaûn lyù socket nhaän thoâng tin sockSrvr.Listen( ); - Haønh vi OnInitDialog: Caáp phaùt vaø khôûi taïo thoâng soá cho caùc ñoái // Xin pheùp keát noái 3,4 töôïng CEmpUdp: sockClient.Connect(strAddr,nPort); m_sentUDP = new CEmpUdp(this); // Chuaån bò socket keát noái m_receivUDP = new CEmpUdp(this); CSocket sockRecv; m_sentUDP->Create(SENT_PORT, SOCK_DGRAM, 0); // Ñoàng yù keát noái 5 m_receivUDP->Create(RECEIV_PORT,SOCK_DGRAM,FD_READ); sockSrvr.Accept( sockRecv ); - Haønh vi OnOK (töông öùng nuùt choïn OK) thöïc hieän göûi thoâng ñieäp: // Truyeàn döõ lieäu 6 . // Truyeàn döõ lieäu 6 . void CUDPDlg::OnOK() ... ... { // Keát thuùc keát noái 7 . sockClient.Close() m_sentUDP->AsyncSelect(FD_WRITE); // Ñaêng kyù göûi sockSrvr.Close(); } Caùch thöïc hieän: Bieân dòch vaø chaïy thöû öùng duïng. Taïo taäp döï aùn roãng (Blank Workspace): 13.5 LAÄP TRÌNH WINSOCK CHO GIAO THÖÙC TCP: - Choïn muïc File / New 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öï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 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ø server coù nhieäm vuï chôø keát noái vaø cung caáp döõ lieäu cho caùc client. host client nhö sau: - Trong maøn hình Worksapce, right-click treân muïc Workspace. Server Client // Khai baùo socket // Khai baùo socket MFC vôùi Internet 207 208 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 115. 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 - Choïn Add New Project to Workspace. // IDC_FILE : Soá hieäu hoäp nhaäp teân taäp tin treân dialog - Duøng Wizard taïo döï aùn TcpServer vôùi giao dieän chính laø dialog, vaø m_Parent->GetDlgItemText(IDC_FILE, fileName); coù söû duïng windows socket. Caùch thöïc hieän töông töï (13.4). fileOK = file.Open(fileName, CFile::modeRead); Thöïc hieän caùc coâng vieäc sau cho döï aùn TcpServer : total = 0; // Chöùa kích thöôùc thoâng tin göûi 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 if (!fileOK || ñöôïc keát noái (OnSend), vaø chaám döùt keát noái khi ñaõ truyeàn xong ( buf.length = file.Read( buf.info, BUFFER_LEN ) ) (Close). Caøi ñaët cuûa lôùp CEmpTcpWriter nhö sau: < BUFFER_LEN ) - Khai baùo kieåu caáu truùc cho vuøng ñeäm chöùa döõ lieäu göûi: fileReady = FALSE; // Khoâng coù file hoaëc ñaõ göûi heát const BUFFER_LEN = 1024; // Kích thöôùc vuøng chöùa döõ lieäu Send( &buf, BUFFER_LEN + sizeof(int) ); typedef struct _tagBuf { total += buf.length; int length; // Kích thöôùc döõ lieäu thöïc if (fileReady) { char info[BUFFER_LEN]; // Vuøng chöùa döõ lieäu Sleep( 300 ); // Thôøi gian nghæ cho client } BUFFER; AsyncSelect( FD_WRITE ); // Göûi tieáp } - Caùc thuoäc tính protected: else { BOOL m_isBusy; // Traïng thaùi phuïc vuï. if ( fileOK ) file.Close(); CDialog* m_Parent; // Ñoái töôïng dialog lieân quan Close(); - Haønh vi taïo laäp nhaän tham soá laø con troû ñoái töôïng dialog lieân quan, m_isBusy = FALSE; // Saün saøng nhaän döõ lieäu vaø xaùc ñònh traïng thaùi saün saøng: CString result; CEmpTcpWriter::CEmpTcpWriter( CDialog* parent ) result.Format( "nReady to connect to clients !n" { "%d (bytes) transfered completed", total ); m_Parent = parent; // Ñoái töôïng dialog lieân quan m_Parent->SetDlgItemText( IDC_INFO, result ); } m_isBusy = FALSE; // Saün saøng nhaän döõ lieäu } } Boå sung lôùp CEmpTcpServer keá thöøa CAsyncSocket ñaûm nhaän caùc - Haønh vi OnSend thöïc hieän göûi döõ lieäu cho client lieân keát: 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: void CEmpTcpWriter::OnSend( int nErrorCode ) { - Caùc thuoäc tính protected cuûa lôùp CEmpTcpServer: static BOOL fileOK = TRUE; CEmpTcpWriter* m_pDoSendObject; // Ñoái töôïng göûi döõ lieäu MFC vôùi Internet 209 210 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 116. CDialog* m_Parent; // Dialog lieân quan // Xaùc ñònh ñòa chæ IP cuûa server host - Haønh vi taïo laäp nhaän tham soá laø con troû ñoái töôïng dialog lieân quan: char name[1024]; CEmpTcpServer::CEmpTcpServer( CDialog* parent ) gethostname( name, 1024 ); { PHOSTENT phost = gethostbyname( name ); SetDlgItemText( IDC_HOSTIP, m_Parent = parent; // Con troû ñoái töôïng dialog lieân quan inet_ntoa(*(in_addr*)phost->h_addr) ); m_pDoSendObject = new CEmpTcpWriter( m_Parent ); m_Tcp = new CEmpTcpServer( this ); } m_Tcp->Create( PORT_NO ); // Khôûi taïo thoâng soá - Haønh vi huûy boû giaûi phoùng ñoái töôïng m_pDoSendObject: m_Tcp->Listen(); // Chôø keát noái CEmpTcpServer::~CEmpTcpServer( ) return TRUE; { } delete m_pDoSendObject; } - Haønh vi OnDestroy thöïc hieän giaûi phoùng ñoái töôïng truyeàn thoâng void CTcpServerDlg::OnDestroy() - Haønh vi OnAccept chaáp nhaän keát noái neáu ñang roãi: { void CEmpTcpServer::OnAccept( int nErrorCode ) CDialog::OnDestroy(); { delete m_Tcp; if ( m_pDoSendObject->m_isBusy ) } return ; // Ñang baän phuïc vuï Taïo döï aùn TcpClient. Thao taùc töông töï döï aùn TcpServer. SOCKADDR_IN Addr; int Len = sizeof(SOCKADDR_IN); Thöïc hieän caùc coâng vieäc sau ñaây vôùi döï aùn TcpClient : if (Accept(*m_pDoSendObject, (SOCKADDR*) &Addr, &Len)) Boå sung lôùp CEmpTcpReader keá thöøa CAsyncSocket ñaûm nhaän chöùc // Khôûi ñoäng hoaït ñoäng göûi döõ lieäu treân m_pDoSendObject naêng xin keát noái (Connect), vaø nhaän döõ lieäu (OnReceive) töø server: m_pDoSendObject->AsyncSelect(FD_WRITE); - Thuoäc tính public chöùa traïng thaùi truyeàn thoâng: } BOOL m_isBusy; // = TRUE : Ñang baän Thöïc hieän caùc caøi ñaët boå sung cho lôùp ñoái töôïng dialog CTcpServerDlg - Thuoäc tính protected chöùa con troû ñoái töôïng dialog lieân quan: laøm giao dieän chính cuûa öùng duïng server: CDialog* m_Parent; - Môû dialog resource, caøi ñaët caùc control sau: - Haønh vi taïo laäp nhaän tham soá laø ñoái töôïng dialog lieân quan: - Hoäp nhaäp teân taäp tin : Edit Soá hieäu IDC_FILE CEmpTcpReader::CEmpTcpReader(CDialog* parent) - 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 m_isBusy = FALSE; // Saün saøng laøm vieäc - Ñoái töôïng thuoäc tính protected laøm nhieäm vuï truyeàn thoâng: m_Parent = parent; CEmpTcpServer* m_Tcp; } - Haønh vi OnInitDialog cuûa dialog khôûi taïo thoâng soá cho dialog vaø caùc - Haønh vi OnReceive nhaän döõ lieäu vaø löu xuoáng taäp tin: thoâng soá caàn thieát cho hoaït ñoäng truyeàn thoâng vôùi m_Tcp: void CEmpTcpReader::OnReceive(int nErrorCode) BOOL CTcpServerDlg::OnInitDialog() { { static BOOL fileOK = TRUE; CDialog::OnInitDialog(); SetIcon( m_hIcon, TRUE ); static BOOL fileReady = FALSE; SetDlgItemText( IDC_FILE, "C:/AUTOEXEC.BAT" ); static CFile file; static long total; MFC vôùi Internet 211 212 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 117. BUFFER buf; - Nuùt leänh download taäp tin töø server : Button IDOK Receive(&buf, BUFFER_LEN + sizeof(int)); - Taïo thuoäc tính bieán m_serverIP cho hoäp nhaäp IDC_HOSTIP. if ( fileOK && (!fileReady) ) { - Ñoái töôïng thuoäc tính protected laøm nhieäm vuï truyeàn thoâng: m_Parent->SetDlgItemText(IDC_INFO, "nDownloading..."); CEmpTcpReader *m_readTcp; fileReady = TRUE; - Haønh vi OnInitDialog cuûa dialog khôûi taïo thoâng soá cho dialog vaø CString fileName; // Teân taäp tin chöùa döõ lieäu nhaän caùc thoâng soá caàn thieát cho hoaït ñoäng truyeàn thoâng vôùi m_readTcp: // IDC_FILE : Soá hieäu hoäp nhaäp teân taäp tin treân dialog BOOL CTcpClientDlg::OnInitDialog() m_Parent->GetDlgItemText( IDC_FILE, fileName ); { fileOK = file.Open ( fileName, CDialog::OnInitDialog(); CFile::modeWrite | CFile::modeCreate ); SetIcon(m_hIcon, TRUE); // Set big icon total = 0; // Kích thöôùc döõ lieäu nhaän ñöôïc SetIcon(m_hIcon, FALSE); // Set small icon } m_serverIP.SetWindowText( "127.0.0.1" ); // local host if ( fileOK && buf.length > 0 ) { SetDlgItemText( IDC_FILE, "C:/Autoexec.000" ); file.Write( buf.info, buf.length ); m_readTcp = new CEmpTcpReader( this ); total += buf.length; return TRUE; if ( buf.length < BUFFER_LEN ) } fileReady = FALSE; // Ñaõ nhaän ñuû döõ lieäu töø server - Haønh vi OnDestroy giaûi phoùng ñoái töôïng truyeàn thoâng: } void CTcpClientDlg::OnDestroy() else { fileReady = FALSE; CDialog::OnDestroy(); if (fileReady) delete m_readTcp; CAsyncSocket::OnReceive(nErrorCode); // Nhaän tieáp } else { - Haønh vi OnOK öùng vôùi nuùt choïn download baét ñaàu nhaän döõ lieäu: m_isBusy = FALSE; // Trôû laïi traïng thaùi saün saøng @ void CTcpClientDlg::OnOK() Close(); { if (fileOK) file.Close(); CString s; CString result; m_serverIP.GetWindowText(s); result.Format( "nReady to connect to server !n" if ( m_readTcp->m_isBusy || s == "0.0.0.0" ) return; "%d (bytes) download completed.", total ); m_readTcp->m_isBusy = TRUE; // Traïng thaùi baän @ m_Parent->SetDlgItemText(IDC_INFO, result); m_readTcp->Create(); } m_readTcp->Connect(s, PORT_NO); } } Thöïc hieän caùc caøi ñaët boå sung cho lôùp ñoái töôïng dialog CTcpClientDlg Bieân dòch caùc döï aùn vaø thöû nghieäm treân moät hoaëc nhieàu maùy. laøm giao dieän chính cuûa öùng duïng client: Choïn muïc : Project / Set Active Project ñeå aán ñònh döï aùn laøm vieäc - Môû dialog resource, caøi ñaët caùc control sau: trong taäp döï aùn (Workspace) nhö tröôøng hôïp noùi treân. - Hoäp nhaäp teân taäp tin : Edit IDC_FILE Söû duïng CSocket vaø CSocketFile cho taùc vuï truyeàn taäp tin noùi treân. - 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 MFC vôùi Internet 213 214 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 118. Lôùp CSocket: Sau khi nhaän ñöôïc tín hieäu traû lôøi nhö treân töø öùng duïng nhaän mail, CSocket laø lôùp keá thöøa CAsyncSocket maø caùc haønh vi göûi vaø nhaän öù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öï. 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 ‘Trình dieän’ vôùi öùng duïng nhaän mail: taát. Nhö vaäy, seõ khoâng gaëp loãi taùc vuï ngheõn (WSAEWOULDBLOCK) Göûi: HELO <SP> <domain> <CRLF> khi thöïc hieän truyeàn döõ lieäu vôùi CSocket. Ñieàu naøy raát quan troïng vôùi Trong ñoù: SP : Kyù töï khoaûng traéng 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). CRLF : rn // return & newline in C Trong phaàn noäi dung tieáp theo, CSocket seõ ñöôïc söû duïng ñeå thay theá Nhaän: OK : 250 BBN-UNIX.ARPA cho CAsyncSocket trong caùc ví duï minh hoïa. ERROR : Soá hieäu loãi (keát noái bò töø choái). 13.6 TCP VÔÙI SMTP (SIMPLE MAIL TRANSFER PROTOCOL): Neáu nhaän ñöôïc traû lôøi “250 <Server Name>” töø öùng duïng nhaän mail, SMTP laø giao thöùc ñôn giaûn vaø hieäu quaû cho vieäc truyeàn taûi e-mail töø host öùng duïng göûi mail coù theå tieáp tuïc caùc coâng vieäc keá tieáp. göûi ñeán host nhaän mail; ví duï töø moät mail client ñeán moät mail server. Quaù Ñaêng kyù ñòa chæ ngöôøi göûi mail: 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 Göûi: MAIL <SP> FROM:<ñòa_chæ_nôi_göûi> <CRLF> 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. Nhaän: OK : 250 OK 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 ERROR : Ñaêng kyù khoâng ñöôïc chaáp nhaän keát thuù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: Ñ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 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 ERROR : 550 Failure nhaän ñeå xin keát noái. Truyeàn noäi dung cuûa mail: Coù theå laëp nhieàu laàn thao taùc sau ñaây tuøy 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 theo soá ñoaïn vaên baûn trong noäi dung cuûa mail. tuïc chuyeån phaàn noäi dung keá tieáp cuûa mail. Göûi: Noäi dung ñoaïn vaên baûn thöù (i) 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 Nhaän: Khoâng coù traû lôøi cuûa host nhaän. dung töø choái töø phía host nhaän. Chaám döùt truyeàn noäi dung cuûa mail: 13.6.1 Qui öôùc giao taùc giöõa öùng duïng göûi mail vaø öùng duïng nhaän mail: Göûi: <CRLF> . <CRLF> 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 Nhaän: 250 OK giao thöùc TCP keát noái vôùi öùng duïng nhaän mail treân host nhaän thoâng qua Keát thuùc keát noái vôùi host nhaän: ñòa chæ IP cuûa host nhaän vaø soá hieäu port cuûa öùng duïng nhaän mail. Göûi: QUIT <CRLF> Göûi: Môû socket vaø lieân laïc vôùi öùng duïng nhaän mail (port = 25). Nhaän: 221 Terminated Info Nhaän: 220 <Domain> <ServerName> ready 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: MFC vôùi Internet 215 216 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 119. 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 void CSMTPDlg::OnOK() 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. char s[1025]; Duøng MFC Wizard taïo döï aùn vôùi cöûa soå giao dieän chính laø dialog, coù söû UINT port; CSocket m_sock; 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): GetDlgItemText(IDC_SERVER_IP, s, 1024); port = GetDlgItemInt(IDC_SERVER_PORT); - Môû dialog resource, caøi ñaët caùc control sau: - Hoäp nhaäp ñòa chæ mail server : Edit IDC_SERVER_IP m_sock.Create(); - Hoäp nhaäp soá hieäu port : Edit IDC_SERVER_PORT if (!m_sock.Connect(s, port)) return; - Hoäp nhaäp ñòa chæ ngöôøi nhaän : Edit IDC_MAIL_TO if (!m_sock.Receive(s, 1024) || GetErrorCode(s) != 220) - Hoäp nhaäp tieâu ñeà cuûa mail : Edit IDC_MAIL_SUBJECT return; - Hoäp soaïn thaûo noäi dung mail : Edit IDC_MAIL strcpy(s, "HELO Mr.Emprn"); - Nuùt leänh thöïc hieän göûi mail : Button IDOK m_sock.Send(&s, strlen(s)); if (!m_sock.Receive(s, 1024) || GetErrorCode(s) != 250) - Haønh vi OnInitDialog thöïc hieän caùc khôûi taïo caàn thieát: return; BOOL CSMTPDlg::OnInitDialog() // Ñòa chæ ngöôøi göûi { strcpy(s, "MAIL FROM:Mr.Emprn"); CDialog::OnInitDialog(); m_sock.Send(&s, strlen(s)); SetIcon(m_hIcon, TRUE); if (!m_sock.Receive(s, 1024) || GetErrorCode(s) != 250) SetIcon(m_hIcon, FALSE); return; SetDlgItemText(IDC_SERVER_IP, "omail.hcmueco.edu.vn"); // Ñòa chæ ngöôøi nhaän SetDlgItemText(IDC_SERVER_PORT, "25"); strcpy(s, "RCPT TO:"); SetDlgItemText(IDC_MAIL_TO, "emp@hcmueco.edu.vn"); GetDlgItemText(IDC_MAIL_TO, s + strlen(s), 1024); SetDlgItemText(IDC_MAIL_SUBJECT, strcpy(s + strlen(s), "rn"); "A Lesson of Mr.Emp"); m_sock.Send(&s, strlen(s)); SetDlgItemText(IDC_MAIL, "Hello Mr.Emp!rnrn" if (!m_sock.Receive(s, 1024) || GetErrorCode(s) == 550) "It's nice to meet You.rnrn" return; "Thanks for your lessons."); return TRUE; // Chuaån bò truyeàn noäi dung mail } strcpy(s, "DATArn"); m_sock.Send(&s, strlen(s)); - Haønh vi kieåm tra loãi treân giaù trò nhaän ñöôïc töø öùng duïng nhaän mail: if (!m_sock.Receive(s, 1024) || GetErrorCode(s) != 354) Caøi ñaët haønh vi protected: GetErrorCode cho lôùp CSMTPDlg: return; UINT CSMTPDlg::GetErrorCode(char *sReply) { // Chuû ñeà mail UINT rs = 0; strcpy(s, "Subject:"); sscanf(sReply, "%d", &rs); GetDlgItemText(IDC_MAIL_SUBJECT, s + strlen(s), 1024); return rs; // Traû veà soá hieäu loãi ghi trong döõ lieäu nhaän ñöôïc strcpy(s + strlen(s), "rn"); } m_sock.Send(&s, strlen(s)); - Haønh vi OnOK öùng vôùi nuùt choïn IDOK thöïc hieän göûi mail: // Noäi dung mail MFC vôùi Internet 217 218 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 120. GetDlgItemText(IDC_MAIL, s, 1024); -ERR error_message keát thuùc. sprintf(s, "%s%s", s, "rn"); 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: m_sock.Send(&s, strlen(s)); Laáy thoâng tin veà hoäp mail: // Keát thuùc Göûi: STAT <CRLF> strcpy(s, "rn.rn"); Nhaän: +OK <SP> <number_of_mail> <SP> <mail_total_size> m_sock.Send(&s, strlen(s)); -ERR error_message strcpy(s, "QUITrn"); Laáy thoâng tin chi tieát cuûa caùc mail trong hoäp mail: m_sock.Send(&s, strlen(s)); Göûi: LIST <CRLF> m_sock.Close(); Nhaän: +OK <SP> Mailbox scan listing follows MessageBox("The Mail was sent OK !", "Send mail"); -ERR error_message } Ñoïc mail: 13.7 TCP VÔÙI POP3 (Post Office Protocol - Version 3): Göûi: RETR <SP> <soá_hieäu_mail_ñöôïc_ñoïc> <CRLF> POP3 laø giao thöùc cho pheùp mail client host keát noái vôùi mail server host ñeå Nhaän: +OK kích_thöôùc_message octets laáy thoâng tin veà hoäp mail cuûa ngöôøi duøng treân mail server. Hoaït ñoäng truy … message do mail server göûi veà, keát thuùc bôûi daáu ‘.’ 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 -ERR error_message hoäp mail cuûa hoï treân mail server. Töông töï SMTP, quaù trình taûi mail töø server Xoùa mail: 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 Göûi: DELE <SP> <soá_hieäu_mail_xoùa> <CRLF> 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. Nhaän: +OK message <n> deleted Mail server tieáp nhaän yeâu caàu cuûa client vaø traû lôøi hoaëc göûi döõ lieäu. -ERR error_message Chaám döùt lieân keát vôùi mail server: 13.7.1 Qui öôùc giao taùc giöõa hai öùng duïng mail client vaø mail server: Göûi: QUIT <CRLF> Thieát laäp lieân keát: Ñaàu tieân, öùng duïng mail client söû duïng giao thöùc Nhaän: + OK goodbye_message TCP keát noái vôùi öùng duïng mail server thoâng qua ñòa chæ IP cuûa mail - ERR error_message 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). 13.7.2 Thieát keá öùng duïng nhaän mail: Nhaän: +OK ok_message 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 -ERR error_message vaø laáy mail töø moät POP mail server. Thoâng soá lieân quan mail server vaø thoâng Sau khi nhaän ñöôïc tín hieäu traû lôøi ‘OK’ töø öùng duïng mail server, öù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 mail client tieáp tuïc thöïc hieän caùc taùc vuï sau theo thöù töï. Duøng MFC Wizard taïo döï aùn vôùi cöûa soå giao dieän chính laø dialog, coù söû Ñaêng kyù taøi khoaûn truy caäp mail server: duïng winsock (xem muïc 13.4). Ñaët teân cho döï aùn laø POP3. Khai baùo user name: Thöïc hieän caùc caøi ñaët sau cho dialog giao dieän chính (CPOP3Dlg): Göûi: USER <SP> <teân_ngöôøi_söû_duïng> <CRLF> - Môû dialog resource, caøi ñaët caùc control sau: Nhaän: +OK ok_message - Hoäp nhaäp ñòa chæ mail server : Edit IDC_SERVER_IP -ERR error_message keát thuùc. - Hoäp nhaäp soá hieäu port : Edit IDC_SERVER_PORT Khai baùo password: - Hoäp nhaäp teân ngöôøi truy caäp : Edit IDC_USER_NAME Göûi: PASS <SP> <noäi_dung_password> <CRLF> - Hoäp nhaäp password truy caäp : Edit IDC_USER_PASSWORD Nhaän: +OK ok_message MFC vôùi Internet 219 220 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 121. - Hoäp nhaäp soá hieäu mail nhaän veà : Edit - Haønh vi protected : isOK kieåm tra traû lôøi cuûa mail server treân döõ IDC_MAIL_NO lieäu nhaän ñöôïc sau moãi taùc vuï lieân laïc: - Hoäp hieån thò noäi dung mail : Edit IDC_MAIL BOOL CPOP3Dlg::isOK(char *result) - 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 return ( result[0] == '+' && - Haønh vi OnOK öùng vôùi nuùt OK thöïc hieän laáy thoâng tin veà hoäp mail: result[1] == 'O' && void CPOP3Dlg::OnOK() result[2] == 'K' ); // +OK : Thaønh coâng { } char s[1025]; - Haønh vi OnReadMail (nuùt choïn IDC_READ_MAIL) taûi mail veà: UINT port; void CPOP3Dlg::OnReadMail() CSocket m_sock; { char s[10241]; GetDlgItemText (IDC_SERVER_IP, s, 1024); UINT port; port = GetDlgItemInt(IDC_SERVER_PORT); CSocket m_sock; m_sock.Create(); GetDlgItemText(IDC_SERVER_IP, s, 1024); if (!m_sock.Connect(s, port)) return; port = GetDlgItemInt(IDC_SERVER_PORT); if ( !m_sock.Receive(s, 1024) || !isOK(s) ) return; 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); strcpy(s, "USER "); // Ñaêng nhaäp strcat(s, "rn"); GetDlgItemText(IDC_USER_NAME, s + strlen(s), 1024); m_sock.Send(&s, strlen(s)); strcat(s, "rn"); if ( !m_sock.Receive(s, 1024) || !isOK(s) ) return; 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); strcpy(s, "PASS "); // Hôïp leä ? strcat(s, "rn"); GetDlgItemText(IDC_USER_PASSWORD, s+strlen(s), 1024); m_sock.Send(&s, strlen(s)); strcat(s, "rn"); if ( !m_sock.Receive(s, 1024) || !isOK(s) ) return; m_sock.Send(&s, strlen(s)); if ( !m_sock.Receive(s, 1024) || !isOK(s) ) return; strcpy(s, "LISTrn"); // Laáy thoâng tin hoäp mail m_sock.Send(&s, strlen(s)); strcpy(s, "RETR "); // Taûi mail veà if ( (port = m_sock.Receive(s, 1024)) < 1 || !isOK(s) ) GetDlgItemText (IDC_MAIL_NO, s + strlen(s), 1024); return; strcat(s, "rn"); m_sock.Send(&s, strlen(s)); s[port] = '0'; if ( (port = m_sock.Receive(s, 10240)) == 0 || !isOK(s) ) SetDlgItemText(IDC_MAIL, s+4); // Boû qua +OK<SP> return; // Keát thuùc... s[port] = '0'; SetDlgItemText(IDC_MAIL, strstr(s, "From")); strcpy(s, "QUITrn"); m_sock.Send(&s, strlen(s)); strcpy(s, "QUITrn"); // Keát thuùc m_sock.Send(&s, strlen(s)); m_sock.Close(); m_sock.Close(); } } MFC vôùi Internet 221 222 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 122. 13.8 TCP VÔÙI HTTP & FTP: pstrProxyName : Proxy. Söû duïng cho truy xuaát thoâng qua proxy. HTTP vaø FTP laø caùc giao thöùc taàng öùng duïng ñöôïc xaây döïng döïa treân giao pstrProxyBypass : Danh saùch ñòa chæ caùc server ñöôïc truy xuaát tröïc thöùc TCP ôû taàng truyeàn taûi (moâ hình DARPA). tieáp (duøng cho aán ñònh truy xuaát qua proxy). HTTP: Giao thöùc phuïc vuï moâ hình öùng duïng Client/Server, duøng phoå dwFlags : Thoâng soá veà cheá ñoä toái öu trong truy xuaát server. bieán trong vieäc truyeàn taûi caùc noäi dung HTML (www) giöõa INTERNET_FLAG_DONT_CACHE : client vaø server. Trong ñoù öùng duïng client keát noái vôùi öùng duïng Khoâng söû duïng cache ôû taát caû caùc host lieân server thoâng qua coång TCP xaùc ñònh, thoâng thöôøng laø 80. quan ñeán caùc taùc vuï taäp tin cuûa giao taùc. FTP: Giao thöùc truyeàn taûi taäp tin. ÖÙng duïng client keát noái vôùi öùng INTERNET_FLAG_OFFLINE : duïng server thoâng qua hai coång TCP; moät duøng ñieàu khieån Söû duïng cache cho caùc taùc vuï taäp tin. truyeàn, moät duøng truyeàn döõ lieäu; thoâng thöôøng laø 20 vaø 21. CFtpConnection* GetFtpConnection ( MFC hoã trôï raát maïnh cho vieäc khai thaùc caùc giao thöùc noùi treân thoâng LPCTSTR pstrServer, // Ñòa chæ FTP server qua caùc lôùp ñoái töôïng trong thö vieän AfxInet.h. LPCTSTR pstrUserName = NULL, // Teân ñaêng nhaäp 13.8.1 CInternetSession: LPCTSTR pstrPassword = NULL, // password hôïp leä CInternetSession laø lôùp ñoái töôïng quaûn lyù moät giao taùc xaùc ñònh vôùi maïng INTERNET_PORT nPort = /* soá hieäu port keát noái */ internet, keå caû vieäc thöïc hieän keát noái vôùi proxy server. INTERNET_INVALID_PORT_NUMBER, 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 BOOL bPassive = FALSE // Cô cheá keát noái treân caùc internet server thoâng qua caùc dòch vuï ñaëc bieät nhö FTP, HTTP. ); Traû veà con troû ñoái töôïng quaûn lyù lieân keát vôùi FTP server. CInternetSession ( bPassive : Qui ñònh cô cheá choïn port cho keát noái. LPCTSTR pstrAgent = NULL, - TRUE : Do ngöôøi duøng choïn. DWORD dwContext = 1, - FALSE: Do FTP Server choïn (laø cô cheá maëc nhieân). DWORD dwAccessType = CHttpConnection* GetHttpConnection ( INTERNET_OPEN_TYPE_PRECONFIG, LPCTSTR pstrServer, // Ñòa chæ HTTP server LPCTSTR pstrProxyName = NULL, INTERNET_PORT nPort = /* soá hieäu port */ LPCTSTR pstrProxyBypass = NULL, INTERNET_INVALID_PORT_NUMBER, DWORD dwFlags = 0 LPCTSTR pstrUserName = NULL, // Teân ñaêng nhaäp ); Haønh vi taïo laäp vaø khôûi taïo thoâng soá cho ñoái töôïng giao taùc internet. LPCTSTR pstrPassword = NULL // password hôïp leä pstrAgent : Teân öùng duïng. Moät soá öùng duïng duøng teân laøm giaù ); Traû veà con troû ñoái töôïng quaûn lyù lieân keát vôùi HTTP server. trò nhaän dieän ñoái vôùi server. 13.8.2 CInternetFile: dwContext : Soá hieäu nhaän dieän dieãn tieán cuûa taùc vuï. CInternetFile laø lôùp ñoái töôïng quaûn lyù moät taäp tin treân maïng internet. dwAccessType : Kieåu truy xuaát. CInternetFile( ); Taïo laäp ñoái töôïng quaûn lyù taäp tin. INTERNET_OPEN_TYPE_PRECONFIG : virtual LONG Seek ( Theo aán ñònh maëc nhieân cuûa heä thoáng. LONG lOffset, // Cöï ly dôøi töông ñoái INTERNET_OPEN_TYPE_DIRECT : UINT nFrom // Vò trí laøm moác. Tröïc tieáp khoâng thoâng qua proxy. ); AÁn ñònh vò trí con troû (ñaàu ñoïc/ghi döõ lieäu) trong taäp tin. INTERNET_OPEN_TYPE_PROXY : Caùc giaù trò duøng cho nFrom coù theå laø: Thoâng qua proxy. - CFile::current : Tính töø vò trí hieän haønh cuûa con troû taäp tin. MFC vôùi Internet 223 224 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 123. - CFile::begin : Tính töø ñaàu taäp tin. LPCTSTR pstrNew // Teân môùi cuûa thö muïc - CFile::end : Tính töø cuoái taäp tin. ); Ñoåi teân thö muïc treân FTP server. virtual UINT Read ( BOOL Remove ( void* lpBuf, // Ñòa chæ vuøng ñeäm chöùa döõ lieäu ñoïc LPCTSTR pstrFileName // Ñöôøng daãn vaø teân taäp tin UINT nCount // Kích thöôùc döõ lieäu ñoïc vaøo ); Xoùa taäp tin treân FTP server. ); Ñoïc döõ lieäu töø taäp tin. CInternetFile* OpenFile ( virtual void Write ( LPCTSTR pstrFileName, // Ñöôøng daãn vaø teân taäp tin ñöôïc môû const void* lpBuf, // Ñòa chæ vuøng ñeäm chöùa döõ lieäu ghi ra DWORD dwAccess = GENERIC_READ, UINT nCount // Kích thöôùc döõ lieäu ñöôïc ghi DWORD dwFlags = FTP_TRANSFER_TYPE_BINARY, ); Ghi döõ lieäu ra taäp tin. DWORD dwContext = 1 virtual BOOL ReadString ( ); Môû taäp tin treân FTP server. Traû veà con troû ñoái töôïng CInternetFile CString& rString // Bieán chöùa chuoãi ñoïc vaøo quaûn lyù taäp tin ñöôïc môû. ); Ñoïc moät chuoãi töø taäp tin. dwAccess : Cheá ñoä môû taäp tin, choïn moät trong caùc cheá ñoä môû sau: virtual void WriteString ( GENERIC_WRITE : Môû ñeå ghi. LPCTSTR pstr // Bieán chöùa chuoãi ñöôïc ghi ra GENERIC_READ : Môû ñeå ñoïc. ); Ghi moät chuoãi ra taäp tin. dwFlags : Kieåu noäi dung taäp tin. virtual void Close( ); Ñoùng taäp tin, chaám döùt moïi taùc vuï lieân quan. FTP_TRANSFER_TYPE_ASCII : Maõ ASCII 13.8.3 CFtpConnection: FTP_TRANSFER_TYPE_BINARY : Maõ nhò phaân CFtpConnection laø lôùp ñoái töôïng quaûn lyù moät lieân keát vôùi FTP server. Ñoái BOOL PutFile ( 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 LPCTSTR pstrLocalFile, // Ñöôøng daãn vaø teân taäp tin ôû client thoâng qua haønh vi GetFtpConnection vôùi thoâng soá thích hôïp (13.8.1). Caùc LPCTSTR pstrRemoteFile, // Ñöôøng daãn vaø teân taäp tin ôû server haønh vi ñaëc tröng cuûa lôùp ñoái töôïng CFtpConnection nhö sau: DWORD dwFlags = /* Kieåu noäi dung taäp tin */ BOOL SetCurrentDirectory ( FTP_TRANSFER_TYPE_BINARY, LPCTSTR pstrDirName // Ñöôøng daãn cuûa thö muïc. DWORD dwContext = 1 // Soá hieäu nhaän dieän taùc vuï ); AÁn ñònh thö muïc laøm vieäc maëc nhieân treân FTP server. ); Taûi moät taäp tin töø host laøm vieäc leân FTP server (upload). BOOL GetCurrentDirectory ( BOOL GetFile ( CString& strDirName // Bieán chöùa keát quaû LPCTSTR pstrRemoteFile, // Ñöôøng daãn teân taäp tin treân server ); Laáy ñöôøng daãn cuûa thö muïc laøm vieäc treân FTP server. LPCTSTR pstrLocalFile, // Ñöôøng daãn teân taäp tin treân client BOOL RemoveDirectory ( BOOL bFailIfExists = TRUE, // Cheá ñoä xöû lyù truøng teân taäp tin. LPCTSTR pstrDirName // Ñöôøng daãn thö muïc DWORD dwAttributes = FILE_ATTRIBUTE_NORMAL, ); Xoùa thö muïc treân FTP server. DWORD dwFlags = /* Kieåu noäi dung taäp tin */ BOOL CreateDirectory ( FTP_TRANSFER_TYPE_BINARY, LPCTSTR pstrDirName // Ñöôøng daãn vaø teân thö muïc DWORD dwContext = 1 ); Taïo môùi thö muïc treân FTP server. ); Taûi moät taäp tin töø FTP server veà host laøm vieäc. BOOL Rename ( bFailIfExists : Qui ñònh caùch thöïc hieän khi teân duøng cho taäp tin ghi LPCTSTR pstrExisting, // Ñöôøng daãn vaø teân cuõ cuûa thö muïc truøng vôùi teân moät taäp tin ñaõ coù treân host laøm vieäc. MFC vôùi Internet 225 226 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 124. TRUE Thoâng baùo loãi. BOOL TimThay = TimFile.FindFile(_T("*.TXT")); FALSE Töï ñoäng ghi choàng leân noäi dung ñaõ coù. while (TimThay) { dwAttributes : Thuoäc tính taäp tin. Coù theå keát hôïp caùc giaù trò sau: TimThay = TimFile.FindNextFile(); FILE_ATTRIBUTE_ARCHIVE : Taäp tin ñöôïc caäp nhaät. … // Xöû lyù taäp tin tìm thaáy FILE_ATTRIBUTE_DIRECTORY : Thö muïc. } } FILE_ATTRIBUTE_NORMAL : Taäp tin bình thöôøng. catch (CInternetException* pEx) { FILE_ATTRIBUTE_HIDDEN : Taäp tin aån maët. … // Coù loãi FILE_ATTRIBUTE_READONLY : Taäp tin chæ ñoïc. } FILE_ATTRIBUTE_SYSTEM : Taäp tin heä thoáng. if (pConnect != NULL) pConnect->Close(); FILE_ATTRIBUTE_TEMPORARY : Taäp tin söû duïng taïm thôøi. delete pConnect; virtual void Close( ); Keát thuùc lieân keát vôùi FTP server. 13.8.5 CHttpConnection: 13.8.4 CFtpFindFile: CHttpConnection laø lôùp ñoái töôïng quaûn lyù moät lieân keát vôùi HTTP server. 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 Ñ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 FTP server. Caùc haønh vi ñaëc tröng cuûa lôùp nhö sau: internet thoâng qua haønh vi GetHttpConnection vôùi thoâng soá thích hôïp (13.8.1). CFtpFileFind( CFtpConnection* pConnection ); Taïo laäp vaø khôûi taïo Lôùp CHttpConnection coù haønh vi ñaëc tröng sau: thoâng soá cho ñoái töôïng tìm kieám taäp tin. CHttpFile* OpenRequest ( virtual BOOL FindFile ( int nVerb, LPCTSTR pstrName = NULL, // Daïng teân taäp tin caàn tìm LPCTSTR pstrObjectName, DWORD dwFlags = INTERNET_FLAG_RELOAD LPCTSTR pstrReferer = NULL, ); Khôûi ñoäng quaù trình tìm kieám taäp tin. Traû veà giaù trò TRUE neáu khôûi DWORD dwContext = 1, ñieåm tìm kieám thaønh coâng. LPCTSTR* pstrAcceptTypes = NULL, Coù theå söû duïng ? , * ñeå aán ñònh daïng teân cuûa taäp tin caàn tìm. LPCTSTR pstrVersion = NULL, dwFlags = INTERNET_FLAG_DONT_CACHE khoâng söû duïng cache. DWORD dwFlags = INTERNET_FLAG_EXISTING_CONNECT virtual BOOL FindNextFile( ); Tìm taäp tin keá tieáp thoûa ñieàu kieän. Traû ); Traû veà con troû ñoái töôïng CHttpFile quaûn lyù taäp tin döõ lieäu caàn truy 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 xuaát treân HTTP server. nhö ñaõ tìm heát caùc taäp tin thoûa ñieàu kieän tìm kieám. nVerb: AÁn ñònh loaïi taùc vuï truy xuaát ñoái vôùi taäp tin döõ lieäu. CString GetFileURL( ); Traû veà chuoãi ñöôøng daãn cuûa taäp tin vöøa tìm CHttpConnection::HTTP_VERB_POST : Ghi döõ lieäu ñöôïc theo yeâu caàu. CHttpConnection::HTTP_VERB_GET : Ñoïc döõ lieä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 CHttpConnection::HTTP_VERB_DELETE : Xoùa taäp tin döõ lieäu. môû roäng laø ‘txt’ treân FTP server: 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. CInternetSession sess(_T("FTP - Example")); // Quaûn lyù giao taùc dwContext : Soá hieäu nhaän dieän taùc vuï truy xuaát. CFtpConnection* pConnect = NULL; // Lieân keát vôùi server pstrAcceptTypes : Chöùa caùc kieåu döõ lieäu maø client mong muoán khai try { thaùc trong noäi dung cuûa taäp tin döõ lieäu ñöôïc truy pConnect = sess.GetFtpConnection(“ftp.hcmueco.edu.vn”); xuaát. Ví duï: "text/*" = Chæ laáy noäi dung text, khoâng CFtpFileFind TimFile ( pConnect ); // Ñoái töôïng tìm kieám nhaän döõ lieäu laø hình aûnh, maõ,… MFC vôùi Internet 227 228 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 125. pstrVersion: Giao thöùc söû duïng, maëc nhieân laø "HTTP/1.0" HTTP_ADDREQ_FLAG_REPLACE : Thay theá noäi dung tröôùc dwFlags : Toái öu trong truy xuaát bôûi noäi dugn sau coù cuøng INTERNET_FLAG_RELOAD : Khoâng ñoïc töø cache. loaïi yeâu caàu. INTERNET_FLAG_DONT_CACHE : Khoâng ñeå laïi cache. "Accept: text/*" vaø "Accept: audio/*" "Accept: audio/*" 13.8.6 CHttpFile: HTTP_ADDREQ_FLAG_ADD : Nhö _REPLACE vaø töï 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 ñoäng boå sung neáu loaïi truy xuaát treân HTTP server. yeâu caàu môùi laø chöa coù. BOOL QueryInfo ( BOOL SendRequest ( DWORD dwInfoLevel, // Thoâng soá truy vaán CString& strHeaders, // Noäi dung yeâu caàu. LPVOID lpvBuffer, // Vuøng ñeäm nhaän keát quaû LPVOID lpOptional = NULL, // Caùc dieãn giaûi cuûa client (khoâng LPDWORD lpdwBufferLength, // Chieàu daøi vuøng ñeäm DWORD dwOptionalLen = 0 // baét buoäc ) LPDWORD lpdwIndex = NULL ); Göûi yeâu caàu lieân quan taäp tin döõ lieäu leân HTTP server. Neáu khoâng ); Truy vaán thoâng tin lieân quan ñeán taäp tin döõ lieäu. Traû veà giaù trò TRUE 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 neáu taùc vuï truy vaán thaønh coâng. Thoâng soá truy vaán coù theå laø: vi AddRequestHeaders. HTTP_QUERY_FLAG_REQUEST_HEADERS : Thoâng tin header. BOOL SendRequestEx ( HTTP_QUERY_LAST_MODIFIED : Ngaøy caäp nhaät cuoái cuøng. LPINTERNET_BUFFERS lpBuffIn, // Kích thöôùc döõ lieäu BOOL AddRequestHeaders ( LPINTERNET_BUFFERS lpBuffOut, // Vuøng ñeäm chöùa döõ lieäu CString& str, // Noäi dung thoâng soá yeâu caàu DWORD dwFlags = HSR_INITIATE, DWORD dwFlags = HTTP_ADDREQ_FLAG_ADD_IF_NEW DWORD dwContext = 1 ); 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 ); Ghi thoâng tin leân taäp tin döõ lieäu treân HTTP server. döõ lieäu. Caùc yeâu caàu naøy seõ ñöôïc göûi leân HTTP server thöïc hieän. BOOL EndRequest ( Noäi dung moãi yeâu caàu phaûi keát thuùc baèng <CRLF>. Xem (RFC2616): DWORD dwFlags = 0, - Accept : Ñeà nghò kieåu döõ lieäu truy xuaát trong taäp tin. LPINTERNET_BUFFERS lpBuffIn = NULL, Cuù phaùp: "Accept: (media-range [ accept-params ][,])* " DWORD dwContext = 1 Ví duï: "Accept: audio/*" , "Accept: text/plain" ); Ngöøng taùc vuï ghi treân taäp tin döõ lieäu cuûa HTTP server. - User-Agent : Teân, duøng nhaän dieän öùng duïng yeâu caàu. virtual CString GetFileURL( ); Traû veà ñöôøng daãn vaø teân cuûa taäp tin döõ Cuù phaùp : "User-Agent" ":" Name( product | comment )*" lieäu treân HTTP server. Ví duï : "User-Agent: Mr.EMP" virtual void Close( ); Keát thuùc truy xuaát taäp tin döõ lieäu. - Content-Type : Kieåu noäi dung 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ø Cuù phaùp : "Content-Type: media-type*" hieån thò noäi dung cuûa taäp tin /index.html treân server naøy. 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/*" MFC vôùi Internet 229 230 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 126. CInternetSession session("HTTP - Example"); Sau ñaây laø caùc böôùc thöïc hieän döï aùn cuûa öùng duïng noùi treân: CHttpFile* file=NULL; Duøng MFC Wizard, taïo döï aùn Ftp vôùi giao dieän chính laø dialog. CString strServer = "www.hcmueco.edu.vn"; Boå sung chæ thò: #include <afxinet.h> cho taäp tin stdafx.h cuûa döï aùn. CString strObject("/index.html"); Thöïc hieän caùc caøi ñaët sau cho lôùp dialog CFtpDlg cuûa döï aùn: INTERNET_PORT port = INTERNET_DEFAULT_HTTP_PORT; - Môû dialog resource, caøi ñaët caùc control sau: CString strHeaders ( "Accept: text/*rn” - Hoäp nhaäp ñòa chæ FTP server : Edit IDC_URL “User-Agent: Mr.Emprn" - Hoäp hieån thò danh saùch caùc taäp tin : ListBox IDC_FILE_LIST "Content-Type: application/x-www-form-urlencodedrn"); - Nuùt leänh thöïc hieän tìm kieám taäp tin : Button IDOK CHttpConnection* server = NULL; - Taïo bieán m_fileList cho control IDC_FILE_LIST. try { - 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 server=session.GetHttpConnection(strServer, port); tin trong thö muïc goác cuûa FTP server vaø ñöa vaøo danh saùch: file=server->OpenRequest ( Caøi ñaët töông töï ví duï muïc (13.8.4) CHttpConnection::HTTP_VERB_POST,strObject ); } Phaàn caøi ñaët cuûa Xöû lyù taäp tin tìm thaáy nhö sau: catch (CInternetException* pEx) { m_fileList.ResetContent(); while (TimThay) { … // Coù loãi bWorking = TimFile.FindNextFile(); } m_fileList.AddString(TimFile.GetFileURL()); if (server==NULL) return; } if (file!=NULL) { file->AddRequestHeaders(strHeaders); Bieân dòch vaø chaïy öùng duïng. file->SendRequest(); // Xaùc laäp yeâu caàu truy xuaát 13.8.8 Thöïc hieän öùng duïng HTTP client ñôn giaûn: CString line; // Söû duïng cho ñoïc chuoãi Trình töï tieán haønh caùc xöû lyù cuûa öùng duïng nhö sau: while (file->ReadString(line)) { - Thieát laäp giao taùc internet, taïo lieân keát HTTP töø giao taùc naøy. … // Xöû lyù noäi dung ñoïc ñöôïc - 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 file->Close(); AddRequestHeaders vaø SendRequest treân noäi dung taäp tin. delete file; - Truy xuaát döõ lieäu: Read, ReadString hoaëc Write, WriteString. } server->Close(); Sau ñaây laø caùc böôùc thöïc hieän döï aùn cuûa öùng duïng noùi treân: delete server; Duøng MFC Wizard, taïo döï aùn Http vôùi giao dieän chính laø dialog. 13.8.7 Thöïc hieän öùng duïng FTP client ñôn giaûn: Boå sung chæ thò: #include <afxinet.h> cho taäp tin stdafx.h cuûa döï aùn. Trình töï tieán haønh caùc xöû lyù cuûa öùng duïng nhö sau: Thöïc hieän caùc caøi ñaët sau cho lôùp dialog CHttpDlg cuûa döï aùn: - Thieát laäp giao taùc internet, taïo lieân keát FTP töø giao taùc naøy. - Môû dialog resource, caøi ñaët caùc control sau: - Taïo ñoái töôïng CFtpFileFind töø lieân keát FTP, tìm taäp tin treân ftp server. - Hoäp nhaäp ñòa chæ HTTP server : Edit IDC_URL - Taïo ñoái töôïng CInternetFile töø taäp tin tìm ñöôïc. Thöïc hieän caùc taùc vuï - Hoäp hieån thò noäi dung taäp tin : Edit IDC_SOURCE ñoïc ghi moät caùch thích hôïp. - Nuùt leänh thöïc hieän taûi taäp tin veà : Button IDOK - Ñoùng caùc ñoái töôïng. MFC vôùi Internet 231 232 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com
  • 127. - 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 + "rn"; } 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. MFC vôùi Internet 233
  • 128. PHUÏ LUÏC A: 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 Moät soá vaán ñeà quan. Haønh vi theå hieän maët hoaït ñoäng cuûa ñoái töôïng. Ví duï: laäp trình höôùng ñoái töôïng 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. A.1 LAÄP TRÌNH HÖÔÙNG ÑOÁI TÖÔÏNG (OOP): Ta coù moâ hình cuûa ñoái töôïng nhö sau: 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 Ñoái töôïng = Thuoäc tính + Haønh vi 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. A.2.5 Chöông trình (Program): 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 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 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 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 ñ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 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. 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 Chöông trình = Taäp hôïp caùc ñoái töôïng + Kòch baûn 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.3 ÑAËC ÑIEÅM LAÄP TRÌNH HÖÔÙNG ÑOÁI TÖÔÏNG: A.2 CAÙC KHAÙI NIEÄM: - Tính khaùch quan (Objective): A.2.1 Lôùp (Class): 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 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 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ù. 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. 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 Ví duï: caùch hôïp lyù ñeå ñaït ñöôïc muïc ñích cuûa chöông trình. 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, - Tính ñoùng goùi (Encapsulation): maùu laïnh vaø coù caùc haønh vi: soáng döôùi nöôùc, thôû baèng mang, ñeû tröùng. 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. A.2.2 Ñoái töôïng (Object): - Tính keá thöøa (Inheritance): Ñ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õ 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 coù nhöõng thuoäc tính, haønh vi cuûa lôùp ñoù. laø söï keá thöøa. Caùc lôùp ñaõ coù goïi laø lôùp cô sôû (based class), lôùp ñöôïc 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ôû ñònh nghóa goïi laø lôùp keá thöøa (derived class). Beân caïnh vieäc keá thöøa, 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. lôùp keá thöøa coù theå ñöôïc boå sung nhöõng haønh vi vaø thuoäc tính caàn thieát A.2.3 Thuoäc tính (Attribute): ñeå phuïc vuï cho nhu caàu môùi phaùt sinh. Cô cheá ñoù ñaõ taïo söï phaùt trieån 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 cho öùng duïng maø ñoái töôïng tham gia. 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. - Tính ña hình (Polymorphism): A.2.4 Haønh vi (Method): 234 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Phuï luïc A: Moät soá vaán ñeà laäp trình höôùng ñoái töôïng 235
  • 129. Cô cheá trieån khai nhieàu caùch theå hieän khaùc nhau cho moät haønh vi theo class Teân_lôùp { 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 public: 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 [ Khai baùo caùc thuoäc tính, haønh vi kieåu public ] 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 protected: phuø hôïp ñeå coù caùch theå hieän haønh vi caàn trieån khai theo yù muoán. Cô [ Khai baùo caùc thuoäc tính, haønh vi kieåu private ] cheá naøy taïo khaû naêng öùng xöû phong phuù cuûa ñoái töôïng. privated: A.4 PHAÂN LOAÏI THUOÄC TÍNH VAØ HAØNH VI: [ Khai baùo caùc thuoäc tính, haønh vi kieåu private ] 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. // Phaàn caøi ñaët cuûa lôùp: - Protected: Caùc thuoäc tính, haønh vi aån chöùa beân trong ñoái töôïng, hoã trôï kieåu Teân_lôùp::Teân_haønh_vi_1( [ Danh_saùch_tham_soá ] ) { caùc hoaït ñoäng cuûa ñoái töôïng vaø coù theå truyeàn laïi cho caùc … // Caùc xöû lyù trong haønh vi 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 kieåu Teân_lôùp::Teân_haønh_vi_n( [ Danh_saùch_tham_soá ] ) { caùc lôùp ñoái töôïng keá thöøa. … // Caùc xöû lyù trong haønh vi } 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 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 thaønh. Haønh vi naøy duøng ñeå caøi ñaët caùc xöû lyù khôûi khai baùo (.h) vaø caøi ñaët (.cpp). Trong ñoù: taïo caùc giaù trò thuoäc tính cuûa ñoái töôïng. - Taäp tin .H : Chöùa toaøn boä phaàn khai baùo cuûa lôùp vaø caùc chæ thò Moät lôùp ñoái töôïng coù theå coù moät hoaëc nhieàu haønh ñònh höôùng bieân dòch (neáu caàn). vi taïo laäp. Teân haønh vi taïo laäp truøng vôùi teân lôùp. Caùc - Taäp tin .CPP : Chöùa toaøn boä phaàn caøi ñaët cuûa lôùp. ÔÛ ñaàu taäp tin haønh vi taïo laäp ñöôïc phaân bieät laãn nhau bôûi caáu truùc naøy khai baùo chæ thò söû duïng taäp tin .H: caùc tham soá cuûa chuùng. #include "Teân_taäp_tin_h_lieân_quan" - 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 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 söï toàn taïi cuûa noù. giaù trò kieåu chuoãi cuûa C caàn quaûn lyù vaø truy xuaát. Moät lôùp ñoái töôïng coù moät haønh vi huûy boû duy 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 nhaát. Teân haønh vi huûy boû truøng vôùi teân cuûa lôùp thuoäc tính vaø haønh vi nhö sau: nhöng ñöôïc baét ñaàu baèng daáu ‘~’. Haønh vi huûy boû - Thuoäc tính: char* info ñöôïc söû duïng ñeå xin caáp phaùt vuøng nhôù khoâng coù tham soá. chöùa noäi dung chuoãi. Caû haønh vi taïo laäp vaø huûy boû ñeàu khoâng coù kieåu traû veà. - Haønh vi: - Haønh vi taïo laäp vôùi moät tham soá laø giaù trò chuoãi A.6 KHAI BAÙO LÔÙP, ÑOÁI TÖÔÏNG TRONG C++: laøm noäi dung khôûi ñaàu cho ñoái töôïng chuoãi. A.6.1 Khai baùo lôùp: - Haønh vi huûy boû giaûi phoùng vuøng nhôù info. Lôùp ñoái töôïng ñöôïc khai baùo trong C++ nhö sau: - Haønh vi laáy ñòa chæ vuøng chöùa noäi dung chuoãi. // Phaàn khai baùo cuûa lôùp: Lôùp chuoãi ñöôïc khai baùo trong C++ nhö sau: 236 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Phuï luïc A: Moät soá vaán ñeà laäp trình höôùng ñoái töôïng 237
  • 130. // Taäp tin String1.h C++ cho pheùp ñònh nghóa lôùp keá thöøa töø moät hoaëc nhieàu lôùp cô sôû. Cuù class CString1 { phaùp thöïc hieän khai baùo naøy nhö sau: public: class Teân_lôùp_keá_thöøa: [ public | private ] Teân_lôùp_cô_sôû1 CString1 ( char* s ); // Haønh vi taïo laäp [, [public | private ] Teân_lôùp_cô_sôû2 [ , … ] ~CString1 ( void ); // Haønh vi huûy boû { char* GetInfo( void ); … // Caùc khai baùo boå sung cuûa lôùp keá thöøa protected: }; char* info; }; Ñ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: // Taäp tin String1.cpp CString1::CString1( char* s ) { Thuoäc tính lôùp cô sôû Thuoäc tính nhaän ñöôïc cho lôùp keá thöøa info = new char[ strlen( s ) + 1 ]; strcpy( info, s ); public public private } CString1::~CString1( ) { protected protected private delete info; } private Khoâng truy xuaát ñöôïc Khoâng truy xuaát ñöôïc char* CString1::GetInfo( void ) { Ñaëc ñieåm keá thöøa public Private return info; } Ví duï: Khai baùo lôùp CString1B keá thöøa hoaøn toaøn töø lôùp CString1. A.6.2 Khai baùo ñoái töôïng: class CString1B : public CString1 { }; Ñ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ù. A.7.1 Keá thöøa haønh vi taïo laäp: Cuù phaùp khai baùo bieán ñoái töôïng trong C++ nhö sau: 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 Teân_lôùp Teân_bieán_ñoái_töôïng( [Danh saùch giaù trò laøm tham soá ] ); 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: A.6.3 Söû duïng ñoái töôïng trong chöông trình: Haønh_vi_taïo_laäp_cuûa_lôùp_keá_thöøa( [ Danh saùch thamm soá ] ) : Thöïc hieän haønh vi cuûa bieán ñoái töôïng (caùc haønh vi public) nhö sau: 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á ] ) 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” ); 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 printf( "Gia tri chuoi luu la: %s ", a.GetInfo() ); 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: A.7 KEÁ THÖØA TRONG C++: Haønh_vi_taïo_laäp_cuûa_lôùp_sô_sôû_1 238 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Phuï luïc A: Moät soá vaán ñeà laäp trình höôùng ñoái töôïng 239
  • 131. class CString2 : public CString1 { Haønh_vi_taïo_laäp_cuûa_lôùp_sô_sôû_2 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() ) { } }; Haønh_vi_taïo_laäp_cuûa_lôùp_sô_sôû_n // Chöông trình Main2.cpp söû duïng lôùp CString2 khai baùo ôû treân. #include "String2.h" Haønh_vi_taïo_laäp_cuûa_lôùp_keá_thöøa void main( void ) { CString2 a( “Vo Van B” ); A.7.2 Keá thöøa haønh vi huûy boû: CString2 b( &a ); 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á printf( "Gia tri chuoi luu la: %s ", b.GetInfo() ); thöøa haønh vi huûy boû cuûa lôùp cô sôû maø khoâng caàn phaûi khai baùo. // Keát quaû nhaän ñöôïc: Gia tri chuoi luu la: Vo Van B } 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 A.8 KHAI BAÙO HAØNH VI TOAÙN TÖÛ SOÁ HOÏC: cô sôû seõ ñöôïc thöïc hieän theo thöù töï nhö sau: 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). Haønh_vi_huûy_boû_cuûa_lôùp_keá_thöøa 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. Haønh_vi_huûy_boû_cuûa_lôùp_sô_sôû_(n) Khai baùo: Haønh_vi_huûy_boû_cuûa_lôùp_sô_sôû_(n-1) 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: Haønh_vi_taïo_laäp_cuûa_lôùp_sô_sôû_1 Teân lôùp::operator Kyù_hieäu_haønh_vi ( void ); A.7.3 Thöïc hieän haønh vi lôùp cô sôû: 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öû 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ô gaùn ( = ), coäng ( + ), vaø chuyeån kieåu lôùp ñoái töôïng chuoãi veà kieåu chuoãi sôû cuûa noù. Caùch thöïc hieän haønh vi cuûa lôùp cô sôû nhö sau: 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 Teân_lôùp_cô_sôû::Teân_haønh_vi( [ Danh_saùch_giaù_trò_tham_soá ] ); caùc haønh vi toaùn töû sau ñaây: - Toaùn töû chuyeån kieåu: char * 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 - Toaùn töû gaùn ( = ) vôùi tham soá laø moät giaù trò kieåu chuoãi cuûa C. töôïng CString2 keá thöøa töø CString1 vaø boå sung haønh vi taïo laäp nhaän - Toaùn töû coäng ( + ) vôùi tham soá laø moät giaù trò kieåu chuoãi cuûa C vaø tham soá laø moät ñoái töôïng CString1. traû veà con troû ñeán ñoái töôïng chuoãi môùi. Lôùp CString2 ñöôïc khai baùo trong C++ nhö sau: Lôùp CString3 ñöôïc khai baùo trong C++ nhö sau: // Taäp tin String2.h #include “String1.h” // Taäp tin String3.h 240 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Phuï luïc A: Moät soá vaán ñeà laäp trình höôùng ñoái töôïng 241
  • 132. #include “String1.h” 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 class CString3 : public CString1 { ñaët cuûa noù. Haønh vi toaùn töû = cuûa lôùp CString3 coù theå vieát nhö sau: public: void CString3::operator = ( char* s ) { CString3( char* s ) : CString1( s ) { } delete this->info; // Toaùn töû chuyeån kieåu this->info = new char[ strlen( s ) + 1 ]; operator char* ( void ) { strcpy( this->info, s ); return info; } } void operator = ( char* s ); A.10 HAØNH VI virtual: CString3* operator + ( char* s ); 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. // Taäp tin String3.cpp Trong ví duï sau, lôùp A ñöôïc caøi ñaët vôùi haønh vi khung Action. Trong caùc #include "String3.h" lôùp B vaø C keá thöøa töø A, haønh vi naøy ñöôïc theå hieän khaùc nhau nhö sau: void CString3::operator = ( char* s ) { - Lôùp B : Baät tieáng beep cuûa PC speaker. delete info; - Lôùp C : Baät hoaëc taét kyù töï x. info = new char[ strlen( s ) + 1 ]; strcpy( info, s ); class A { } public: CString3* CString3::operator + ( char* s ) { void Action( void ) { } // Haønh vi khung cô sôû char* ketqua; } ketqua = new char[ strlen(info) + strlen( s ) + 1 ]; class B : public A { sprintf( ketqua, "%s%s", info, s ); public: CString3* kq = new CString3( ketqua ); void Action( void ) { delete ketqua; // Caùch theå hieän Action cuûa lôùp B return kq; putch( 7 ); } } } // Chöông trình Main3.cpp söû duïng lôùp CString3 khai baùo ôû treân. #include "String3.h" class C : public A { void main( void ) { public: CString3 s1( "Chao Cac " ); void Action( void ) { CString3 s2( "Ban" ); // Caùch theå hieän Action cuûa lôùp C ; baät, taét chöõ x CString3 *s = (s1 + s2); static char ch = ‘x’; printf( "Cong hai chuoi la: %s", *s ); putch(x); delete s; ch = ( ch == ‘x’ )? ‘ ‘ : ‘x’ ; // Keát quaû nhaän ñöôïc: Cong hai chuoi la: Chao Cac Ban } } } A.9. CON TROÛ this: void main ( void ) { 242 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Phuï luïc A: Moät soá vaán ñeà laäp trình höôùng ñoái töôïng 243
  • 133. A* a[5]; // 5 phaàn töû kieåu lôùp A class Duongtron { for ( int i = 0; i<5; i++ ) { protected: if ( i % 2 ) float R; a[ i ] = new B(); // Khôûi taïo ngaãu nhieân theo kieåu lôùp B static float pi; else public: a[ i ] = new C(); // hoaëc lôùp C Duongtron( float bankinh ) { } R = bankinh; while ( !kbhit() ) { } for ( i = 0; i < 5 ; i++ ) float Chuvi( void ) a[ i ]->Action( ); // Haønh ñoäng theo caùch cuûa lôùp B hoaëc C { delay( 100 ); // Taïm döøng return R * R * pi; } } for ( i = 0; i < 5 ; i++ ) static float Chuvi( float bankinh ) delete a[ i ]; { } return R * R * pi; } 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 float Duongtron::pi =3.14159; ñöôï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: // Chöông trình minh hoïa söû duïng lôùp Duongtron void main( void ) { static Kieåuthuoäctính Thuoäctính; // Duøng haønh vi tónh Chuvi( . ) cuûa Duongtron ñeå tính chu vi static Kieåutraûveà Haønhvi ( [ Danh_saùch_tham_soá ] ); // cuûa moät ñöôøng troøn baát kyø Trong phaàn caøi ñaët cuûa lôùp: printf( “Chu vi duong tron ban kinh R = 10 la : %0.2f” , Duongtron::Chuvi( 10 ) ); 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á ] ) { // Duøng haønh vi Chuvi() ñeå tính chu vi cuûa ñoái töôïng Duongtron Duongtron a( 20 ); … // Noäi dung caøi ñaët cuûa haønh vi printf( “Chu vi duong tron ban kinh R = 20 la : %0.2f”, a.Chuvi() ); } } Löu yù: Haønh vi static chæ ñöôïc pheùp söû duïng caùc thuoäc tính static vaø haønh Neáu thuoäc tính pi cuûa Duongtron khoâng phaûi laø thuoäc tính static thì vi static cuûa lôùp. haønh vi Chuvi( float Bankinh ) cuûa Duongtron seõ khoâng hôïp leä vì haønh Trong ví duï sau, ta caøi ñaët lôùp Duongtron vôùi thuoäc tính baùn kính, thuoäc vi naøy ñaõ söû duïng moät thuoäc tính khoâng phaûi static. 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: 244 Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Phuï luïc A: Moät soá vaán ñeà laäp trình höôùng ñoái töôïng 245