Tìm hiểu lập trình C trên windows

Tài liệu Tìm hiểu lập trình C trên windows: NGễN NG L P TRèNH Ữ Ậ L P TRèNH C TRấNẬ WINDOWS L PẬ TRèNH C TRấN WINDOWS Trang 1 NGễN NG L P TRèNH Ữ Ậ L P TRèNH C TRấNẬ WINDOWS Ch ng 1ươ T NG QUAN L P TRèNH C TRấN WINDOWSỔ Ậ 1.1. M Đ UỞ Ầ Đ l p trỡnh trờn Microsoft Windowsđ, chỳng ta c n n m đ c cỏc đ c đi m c b nể ậ ầ ắ ượ ặ ể ơ ả nh t c a h đi u hành này. Ch ng này s gi i thi u khỏi quỏt cỏc đ c đi m h đi u hànhấ ủ ệ ề ươ ẽ ớ ệ ặ ể ệ ề Microsoft Windows, cỏc v n đ liờn quan đ n l p trỡnh b ng ngụn ng C, đ ng th i đ a raấ ề ế ậ ằ ữ ồ ờ ư m t ch ng trỡnh m u làm s n cho cỏc ch ng trỡnh đ c vi t sau này. ộ ươ ẫ ườ ươ ượ ế Trong ph n đ u, chỳng ta tỡm hi u s l c l ch s phỏt tri n c a h đi u hànhầ ầ ể ơ ượ ị ử ể ủ ệ ề Microsoft Windowsđ và nh ng đ c đi m n n t ng c a Windows. ữ ặ ể ề ả ủ Ph n ti p theo s trỡnh bày nh ng khỏi ni m và yờu c u căn b n c a vi c l p trỡnh Cầ ế ẽ ữ ệ ầ ả ủ ệ ậ trờn Windows. Ngoài ra, ph n này cũng gi i thi u cỏc c ch và cỏc cụng c mà h đi u hànhầ ớ ệ ơ ế ụ ệ ề cung c p cho ng i l ...

pdf204 trang | Chia sẻ: hunglv | Lượt xem: 1264 | Lượt tải: 0download
Bạn đang xem trước 20 trang mẫu tài liệu Tìm hiểu lập trình C trên windows, để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên
NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS L PẬ TRÌNH C TRÊN WINDOWS Trang 1 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS Ch ng 1ươ T NG QUAN L P TRÌNH C TRÊN WINDOWSỔ Ậ 1.1. M Đ UỞ Ầ Đ l p trình trên Microsoft Windows®, chúng ta c n n m đ c các đ c đi m c b nể ậ ầ ắ ượ ặ ể ơ ả nh t c a h đi u hành này. Ch ng này s gi i thi u khái quát các đ c đi m h đi u hànhấ ủ ệ ề ươ ẽ ớ ệ ặ ể ệ ề Microsoft Windows, các v n đ liên quan đ n l p trình b ng ngôn ng C, đ ng th i đ a raấ ề ế ậ ằ ữ ồ ờ ư m t ch ng trình m u làm s n cho các ch ng trình đ c vi t sau này. ộ ươ ẫ ườ ươ ượ ế Trong ph n đ u, chúng ta tìm hi u s l c l ch s phát tri n c a h đi u hànhầ ầ ể ơ ượ ị ử ể ủ ệ ề Microsoft Windows® và nh ng đ c đi m n n t ng c a Windows. ữ ặ ể ề ả ủ Ph n ti p theo s trình bày nh ng khái ni m và yêu c u căn b n c a vi c l p trình Cầ ế ẽ ữ ệ ầ ả ủ ệ ậ trên Windows. Ngoài ra, ph n này cũng gi i thi u các c ch và các công c mà h đi u hànhầ ớ ệ ơ ế ụ ệ ề cung c p cho ng i l p trình hay ng i phát tri n các ng d ng trên Windows. ấ ườ ậ ườ ể ứ ụ Cu i ch ng là ph n xây d ng m t ch ng trình đ n gi n nh t trên Windows.ố ươ ầ ự ộ ươ ơ ả ấ Ch ng trình này đ c xem nh là khuôn m u c a m t ch ng trình ng d ng đi n hình, vàươ ượ ư ẫ ủ ộ ươ ứ ụ ể h u h t các đo n ch ng trình đ c vi t minh h a trong sách đ u l y ch ng trình này làmầ ế ạ ươ ượ ế ọ ề ấ ươ khung s n đ phát tri n cho phù h p v i t ng yêu c u. Thêm vào đó, m t s ki u d li uườ ể ể ợ ớ ừ ầ ộ ố ể ữ ệ m i đ c đ nh nghĩa trên Windows và nh ng qui c v cách đ t tên bi n cũng đ c gi iớ ượ ị ữ ướ ề ặ ế ượ ớ thi u trong ph n này.ệ ầ Ph n chi ti t và chuyên sâu h n c a vi c l p trình b ng ngôn ng C trên môi tr ngầ ế ơ ủ ệ ậ ằ ữ ườ Windows s đ c trình bày trong các ch ng ti p theo.ẽ ượ ươ ế 1.2. H ĐI U HÀNH MICROSOFT WINDOWSỆ Ề 1.2.1. Gi i thi uớ ệ Gi a th p niên 80, công ty ph n m m máy tính Microsoft công b phiên b n đ u tiênữ ậ ầ ề ố ả ầ c a dòng h đi u hành Windows là ủ ệ ề Microsoft Windows® 1.0. Đây là h đi u hành dùng giaoệ ề di n đ h a khác v i giao di n ký t (ệ ồ ọ ớ ệ ự text hay console) c a ủ MS-DOS. Tuy nhiên ph i đ nả ế phiên b n th hai (Windows 2.0 - tháng 11 năm 1987) thì m i có b c c i ti n đáng k , đó làả ứ ớ ướ ả ế ể s m r ng giao ti p gi a bàn phím và thi t b chu t và giao di n đ h a (ự ở ộ ế ữ ế ị ộ ệ ồ ọ GUI-Graphic User Interface) nh trình đ n (ư ơ menu) và h p tho i (ộ ạ dialog). Trong phiên b n này Windows ch yêuả ỉ c u b vi x lý Intel 8086 hay 8088 ch y real-mode đ truy xu t 1 megabyte b nh .ầ ộ ử ạ ở ể ấ ộ ớ Tháng 5 năm 1990, Microsoft công b phiên b n ti p theo là Windows 3.0. S thay đ iố ả ế ự ổ l n trong phiên b n này là Windows 3.0 h tr protected-mode 16 bit c a các b vi x lý 286,ớ ả ỗ ợ ủ ộ ử 386, và 486 c a Intel. S thay đ i này cho phép các ng d ng trên Windows truy xu t 16ủ ự ổ ứ ụ ấ megabyte b nh . Ti p b c v i s phát tri n là phiên b n Windows 3.1 ra đ i năm 1992,ộ ớ ế ướ ớ ự ể ả ờ Microsoft đ a công ngh Font TrueType, âm nh c (ư ệ ạ multimedia), liên k t và nhúng đ i t ngế ố ượ (OLE- Object Linking and Embedding), và đ a ra các h p tho i chung đã đ c chu n hóa.ư ộ ạ ượ ẩ Trang 2 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS Trong s phát tri n m nh m c a nh ng th p niên 90, Microsoft công b ti p dòng hự ể ạ ẽ ủ ữ ậ ố ế ệ đi u hành Windows v i ng d ng công ngh m i (1993). H đi u hành này l y tên làề ớ ứ ụ ệ ớ ệ ề ấ Windows® NT® (Windows New Technology), đây là phiên b n h đi u hành đ u tiên c aả ệ ề ầ ủ Windows h tr 32 bit cho b x lý 386, 486 và Pentium. Trong h đi u hành này thì các ngỗ ợ ộ ử ệ ề ứ d ng ph i truy xu t b nh v i đ a ch là 32-bit và các t p l nh hay ch th 32-bit. Ngoài raụ ả ấ ộ ớ ớ ị ỉ ậ ệ ỉ ị Windows NT cũng đ c thi t k đ ch y các b vi x lý (ượ ế ế ể ạ ộ ử CPU) khác ngoài Intel và có thể ch y trên các máy tr m (ạ ạ workstation). H đi u hành Windows 95 đ c công b năm 1995 cũng là m t h đi u hành 32-bitệ ề ượ ố ộ ệ ề cho Intel 386 tr v sau. Tuy thi u tính b o m t nh Windows NT và vi c thích nghi v i máyở ề ế ả ậ ư ệ ớ tr m công ngh ạ ệ RISC, nh ng bù l i h đi u hành này yêu c u ph n c ng không cao.ư ạ ệ ề ầ ầ ứ Song song v i s phát tri n ph n m m thì công ngh ph n c ng cũng phát tri n khôngớ ự ể ầ ề ệ ầ ứ ể kém. Đ t n d ng s c m nh c a ph n c ng thì các th h Windows ti p theo ngày càng hoànể ậ ụ ứ ạ ủ ầ ứ ế ệ ế thi n h n. Nh Windows 98 phát tri n t Window 95 và có nhi u c i thi n nh hi u năngệ ơ ư ể ừ ề ả ệ ư ệ làm vi c, h tr các thi t b ph n c ng t t h n, và cu i cùng là vi c tích h p ch t ch v iệ ỗ ợ ế ị ầ ứ ố ơ ố ệ ợ ặ ẽ ớ Internet và Word Wide Web. Windows 2000 là h đi u hành đ c xem là n đ nh và t t c a dòng Windows, phiênệ ề ượ ổ ị ố ủ b n này tăng c ng các tính năng b o m t thích h p trong m i tr ng m ng và giao di nả ườ ả ậ ợ ộ ườ ạ ệ đ p.ẹ 1.2.2. Đ c đi m chung c a h đi u hành Microsoft Windowsặ ể ủ ệ ề Windows là m t h đi u hành s d ng giao ti p ng i dùng đ h a (GUI), hay cònộ ệ ề ử ụ ế ườ ồ ọ g i là h đi u hành tr c quan (ọ ệ ề ự Visual interface). GUI s d ng đ h a d a trên màn hình nhử ụ ồ ọ ự ả nh phân (ị Bitmapped video display). Do đó t n d ng đ c tài nguyên th c c a màn hình, vàậ ụ ượ ự ủ cung c p m t môi tr ng giàu tính tr c quan và sinh đ ng.ấ ộ ườ ự ộ Windows không đ n đi u nh ơ ệ ưMS-DOS (hay m t s h đi u hành giao di n console)ộ ố ệ ề ệ mà màn hình đ c s d ng ch đ th hi n chu i ký t , do ng i dùng gõ t bàn phímượ ử ụ ỉ ể ể ệ ỗ ự ườ ừ (keyboard) hay đ xu t thông tin d ng văn b n. Trong giao di n ng i dùng đ h a, màn hìnhể ấ ạ ả ệ ườ ồ ọ giao ti p v i ng i s d ng đa d ng h n, ng i dùng có th nh p d li u thông qua chu tế ớ ườ ử ụ ạ ơ ườ ể ậ ữ ệ ộ b ng cách nh n vào các nút nh n (ằ ấ ấ button) các hôp ch n (ọ combo box)…thi t b bây gi đ cế ị ờ ượ nh p, có th là bàn phím và thi t b chu t (ậ ể ế ị ộ mouse device). Thi t b chu t là m t thi t b đ nhế ị ộ ộ ế ị ị v trên màn hình, s d ng thi t b chu t ng i dùng có th nh p d li u m t cách tr c quanị ử ụ ế ị ộ ườ ể ậ ữ ệ ộ ự b ng cách kích ho t m t nút l nh, hay làm vi c v i các đ i t ng đ h a liên quan đ n t aằ ạ ộ ệ ệ ớ ố ượ ồ ọ ế ọ đ trên màn hình. ộ Đ giao ti p trong môi tr ng đ h a, Windows đ a ra m t s các thành ph n g i làể ế ườ ồ ọ ư ộ ố ầ ọ các đi u khi n chung (ề ể common control), các đi u khi n chung là các đ i t ng đ c đ a vàoề ể ố ượ ượ ư trong h p tho i đ giao ti p v i ng i dùng. Bao g m : h p văn b n (ộ ạ ể ế ớ ườ ồ ộ ả text box), nút nh nấ (button), nút ch n (ọ check box), h p danh sách (ộ list box), h p ch n (ộ ọ combo box)… Th t ra m t ng d ng trên Windows không ph i là quá ph c t p vì chúng có hình th cậ ộ ứ ụ ả ứ ạ ứ chung. Ch ng trình ng d ng thu ng chi m m t ph m vi hình ch nh t trên màn hình g i làươ ứ ụ ờ ế ộ ạ ữ ậ ọ m t c a s . Trên cùng c a m i c a s là thanh tiêu đ (ộ ử ổ ủ ỗ ử ổ ề title bar). Các ch c năng c a ch ngứ ủ ươ Trang 3 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS trình thì đ c li t kê trong th c đ n l a ch n c a ch ng trình (ượ ệ ự ơ ự ọ ủ ươ menu) , hay xu t hi n d iấ ệ ướ d ng tr c quan h n là các thanh công c (ạ ự ơ ụ toolbar). Các thanh công c này ch a các ch c năngụ ứ ứ đ c s d ng th ng xuyên trong th c đ n đ gi m th i gian cho ng i dùng ph i m th cượ ử ụ ườ ự ơ ể ả ờ ườ ả ở ự đ n và ch n. Thông th ng khi c n l y thông tin hay cung c p thông tin cho ng i dùng thìơ ọ ườ ầ ấ ấ ườ m t ng d ng s đ a ra m t h p tho i, trong h p tho i này s ch a các đi u khi n chung độ ứ ụ ẽ ư ộ ộ ạ ộ ạ ẽ ứ ề ể ể giao ti p v i ng i dùng. Windows cũng ra t o m t s các h p tho i chu n nh ế ớ ườ ạ ộ ố ộ ạ ẩ ư Open Files, và m t s h p tho i t ng t nh nhau.ộ ố ộ ạ ươ ự ư Windows là m t h đi u hành đa nhi m, tùy thu c vào b nh mà ta có th ch yộ ệ ề ệ ộ ộ ớ ể ạ nhi u ng d ng cùng m t lúc, và cũng có th đ ng th i chuy n qua l i gi a các ng d ng vàề ứ ụ ộ ể ồ ờ ể ạ ữ ứ ụ th c thi chúng. Trong các phiên b n c a Windows® 98 và NT® tr v sau, các ch ng trìnhự ả ủ ở ề ươ ng d ng t b n thân chúng chia thành nhi u ti u trình (ứ ụ ự ả ề ể thread) đ x lý và v i t c đ x lýể ử ớ ố ộ ử nhanh t o c m giác nh ng ch ng trình ng d ng này ch y đ ng th i v i nhau.ạ ả ữ ươ ứ ụ ạ ồ ờ ớ Trong Windows, ch ng trình ng d ng khi th c thi đ c chia s nh ng th t c màươ ứ ụ ự ượ ẻ ữ ủ ụ Windows cung c p s n, các t p tin cung c p nh ng th t c trên đ c g i là th vi n liên k tấ ẵ ậ ấ ữ ủ ụ ượ ọ ư ệ ế đ ng (ộ Dynamic Link Libraries - DLL). Windows có c ch liên k t nh ng ch ng trình ngơ ế ế ữ ươ ứ d ng v i các th t c đ c cung c p trong th vi n liên k t đ ng.ụ ớ ủ ự ượ ấ ư ệ ế ộ Kh năng t ng thích c a Windows cũng r t cao. Các ch ng trình ng d ng đ cả ươ ủ ấ ươ ứ ụ ượ vi t cho Windows không truy xu t tr c ti p ph n c ng c a nh ng thi t b đ ho nh mànế ấ ự ế ầ ứ ủ ữ ế ị ồ ạ ư hình và máy in. Mà thay vào đó, h đi u hành cung c p m t ngôn ng l p trình đ h a (g i làệ ề ấ ộ ữ ậ ồ ọ ọ Giao ti p thi t b đ ho ế ế ị ồ ạ - Graphic Device Interface - GDI) cho phép hi n th nh ng đ iể ị ữ ố t ng đ h a m t cách d dàng. Nh v y m t ng d ng vi t cho Windows s ch y v i b tượ ồ ọ ộ ễ ờ ậ ộ ứ ụ ế ẽ ạ ớ ấ c thi t b màn hình nào hay b t kì máy in, mi n là đã cài đ t trình đi u khi n thi t b h trứ ế ị ấ ễ ặ ề ể ế ị ỗ ợ cho Windows. Ch ng trình ng d ng không quan tâm đ n ki u thi t b k t n i v i h th ng.ươ ứ ụ ế ể ế ị ế ố ớ ệ ố Nh gi i thi u ph n trên khái ni m liên k t đ ng là thành ph n quan tr ng c aư ớ ệ ở ầ ệ ế ộ ầ ọ ủ Windows, nó đ c xem nh là h t nhân c a h đi u hành, vì b n thân c a Windows là cácượ ư ạ ủ ệ ề ả ủ t p th vi n liên k t đ ng. Windows cung c p r t nhi u hàm cho nh ng ch ng trình ngậ ư ệ ế ộ ấ ấ ề ữ ươ ứ d ng đ cài đ t giao di n ng i dùng và hi n th văn b n hay đ h a trên màn hình. Nh ngụ ể ặ ệ ườ ể ị ả ồ ọ ữ hàm này đ c cài đ t trong th vi n liên k t đ ng hay còn g i là ượ ặ ư ệ ế ộ ọ DLL. Đó là các t p tin cóậ d ng ph n m r ng là ạ ầ ở ộ *.DLL hay *.EXE, h u h t đ c ch a trong th m cầ ế ượ ứ ư ụ \Windows\System, \Windows\system32 c a ủ Windows® 98 và các th m c ư ụ \WinNT\System, \ WinNT\System32 c a ủ Windows® NT®. Trong các phiên b n sau này, h th ng liên k t đ ng đ c t o ra r t nhi u, tuy nhiên,ả ệ ố ế ộ ượ ạ ấ ề h u h t các hàm đ c g i trong th vi n này phân thành 3 đ n v sau: ầ ế ượ ọ ư ệ ơ ị Kernel, User, và GDI. Kernel cung c p các hàm và th t c mà m t h t nhân h đi u hành truy n th ng qu nấ ủ ụ ộ ạ ệ ề ề ố ả lý, nh qu n lý b nh , xu t nh p t p tin và tác v . Th vi n này đ c cài đ t trong t p tinư ả ộ ớ ấ ậ ậ ụ ư ệ ượ ặ ậ KRNL386.EXE 16 bit và KERNEL32.DLL 32 bit. User qu n lý giao di n ng i dùng, cài đ t t t c khung c a s m c lu n lý. Thả ệ ườ ặ ấ ả ử ổ ở ứ ậ ư vi n User đ c cài đ t trong t p tin ệ ượ ặ ậ USER.EXE 16 bit và USER32.DLL 32 bit. Trang 4 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS GDI cung c p toàn b giao di n thi t b đ ho (ấ ộ ệ ế ị ồ ạ Graphics Device Interface), cho phép ch ng trình ng d ng hi n th văn b n và đ ho trên các thi t b xu t ph n c ng nh mànươ ứ ụ ể ị ả ồ ạ ế ị ấ ầ ứ ư hình và máy in. Trong Windows 98, th vi n liên k t đ ng ch a kho ng vài ngàn hàm, m i hàm có tênư ệ ế ộ ứ ả ỗ đ c t , ví d ặ ả ụ CreateWindow, hàm này dùng đ t o m t c a s cho ng d ng. Khi s d ngể ạ ộ ử ổ ứ ụ ử ụ các hàm mà Windows cung c p cho thì các ng d ng ph i khai báo trong các t p tin tiêu đ ấ ứ ụ ả ậ ề .h hay .hpp (header file). Trong m t ch ng trình Windows, có s khác bi t khi ta g i m t hàm c a th vi n Cộ ươ ự ệ ọ ộ ủ ư ệ và m t hàm c a Windows hay th vi n liên k t đ ng cung c p. Đó là khi biên d ch mã máy,ộ ủ ư ệ ế ộ ấ ị các hàm th vi n C s đ c liên k t thành mã ch ng trình. Trong khi các hàm Windows sư ệ ẽ ượ ế ươ ẽ đ c g i khi ch ng trình c n dùng đ n ch không liên k t vào ch ng trình. Đ th c hi nượ ọ ươ ầ ế ứ ế ươ ể ự ệ đ c các l i g i này thì m t ch ng trình Windows *.EXE luôn ch a m t tham chi u đ n thượ ờ ọ ộ ươ ứ ộ ế ế ư vi n liên k t đ ng khác mà nó c n dùng. Khi đó, m t ch ng trình Windows đ c n p vào bệ ế ộ ầ ộ ươ ượ ạ ộ nh s t o con tr tham chi u đ n nh ng hàm th vi n DLL mà ch ng trình dùng, n u thớ ẽ ạ ỏ ế ế ữ ư ệ ươ ế ư vi n này ch a đ c n p vào b nh tr c đó thì bây gi s đ c n p.ệ ư ượ ạ ộ ớ ướ ờ ẽ ượ ạ 1.3. L P TRÌNH TRÊN MICROSOFT WINDOWSẬ 1.3.1. Đ c đi m chungặ ể Windows là h đi u hành đ h a tr c quan, do dó các tài nguyên c a h th ng cungệ ề ồ ọ ự ủ ệ ố c p r t đa d ng đòi h i ng i l p trình ph i nghiên c u r t nhi u đ phát hay h t s c m nhấ ấ ạ ỏ ườ ậ ả ứ ấ ề ể ế ứ ạ c a h đi u hành. ủ ệ ề Theo nh nh ng m c đích ti p c n c a các nhà l p trình thì các ng d ng trênư ữ ụ ế ậ ủ ậ ứ ụ Windows ph i h t s c thân thi n v i ng i dùng thông qua giao di n đ h a s n có c aả ế ứ ệ ớ ườ ệ ồ ọ ẵ ủ Windows. V lý thuy t thì m t ng i dùng làm vi c đ c v i m t ng d ng c a Windowsề ế ộ ườ ệ ượ ớ ộ ứ ụ ủ thì có th làm vi c đ c v i nh ng ng d ng khác. Nh ng trong th c t đ s d ng m t ngể ệ ượ ớ ữ ứ ụ ư ự ế ể ử ụ ộ ứ d ng cho đ t hi u qu cao trong Windows thì c n ph i có m t s hu n luy n tr giúp hay t iụ ạ ệ ả ầ ả ộ ố ấ ệ ợ ố thi u thì ph i cho bi t ch ng trình ng d ng làm vi c nh th nào.ể ả ế ươ ứ ụ ệ ư ế Đa s các ng d ng trong Windows đ u có chung m t giao di n t ng tác v i ng iố ứ ụ ề ộ ệ ươ ớ ườ dùng gi ng nhau. Ví d nh các ng d ng trong Windows đa s đ u có thanh th c đ n ch aố ụ ư ứ ụ ố ề ự ơ ứ các m c nh : ụ ư File, Edit, Tool, Help… Và trong h p tho i thì th ng ch a các ph n t đi uộ ạ ườ ứ ầ ử ề khi n chung nh : ể ư Edit Control, Button Control, Checkbox…. 1.3.2. S khác bi t v i l p trình trên MS-DOSự ệ ớ ậ Khi m i b c vào l p trình trên Windows đa s ng i h c r t l l m, nh t là nh ngớ ướ ậ ố ườ ọ ấ ạ ẫ ấ ữ ng i đã t ng làm vi c v i MS-DOS. Do MS-DOS là h đi u hành đ n nhi m và giao ti pườ ừ ệ ớ ệ ề ơ ệ ế qua giao di n console. Nên khi vi t ch ng trình không ph c t p.ệ ế ươ ứ ạ Còn đ i v i Windows ng i l p trình s làm vi c v i b công c l p trình đ h a đaố ớ ườ ậ ẽ ệ ớ ộ ụ ậ ồ ọ d ng cùng v i cách x lý đa nhi m, đa lu ng c a Windows. Vì v y vi c l p trình trênạ ớ ử ệ ồ ủ ậ ệ ậ Windows s giúp cho ng i l p trình đ nhàm chán v i giao di n console c a MS-DOS. Vi cẽ ườ ậ ỡ ớ ệ ủ ệ Trang 5 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS c g ng phát huy các s c m nh tài nguyên c a Windows s làm cho nh ng ng d ng càngố ắ ứ ạ ủ ẽ ữ ứ ụ m nh m , đa d ng, thân thi n, và d s d ng.ạ ẽ ạ ệ ễ ử ụ 1.3.3. M t s yêu c u đ i v i ng i l p trìnhộ ố ầ ố ớ ườ ậ Đi u tr c tiên c a ng i h c l p trình C trên Windows là ph i bi t l p trình C, sáchề ướ ủ ườ ọ ậ ả ế ậ này không có tham v ng h ng d n ng i h c có th thông th o l p trình C trên Windows màọ ướ ẫ ườ ọ ể ạ ậ ch a qua m t l p hu n luy n C nào. Tuy nhiên, không nh t thi t ph i hoàn toàn thông th o Cư ộ ớ ấ ệ ấ ế ả ạ m i h c đ c l p trình Windows.ớ ọ ượ ậ Đ có th l p trình trên n n Windows ngoài yêu c u v vi c s d ng công c l pể ể ậ ề ầ ề ệ ử ụ ụ ậ trình, ng i h c còn c n ph i có căn b n v Windows, t i thi u thì cũng đã dùng qua m t sườ ọ ầ ả ả ề ố ể ộ ố ng d ng trong Windows. Th t s yêu c u này không quá khó khăn đ i v i ng i h c vì hi nứ ụ ậ ự ầ ố ớ ườ ọ ệ t i h u nh Windows quá quen thu c v i m i ng i, nh ng ng i mà đã s d ng máy tính.ạ ầ ư ộ ớ ọ ườ ữ ườ ử ụ Ngoài nh ng yêu c u trên, đôi khi ng i l p trình trên Windows cũng c n có khi uữ ầ ườ ậ ầ ế th m m , vì cách trình bày các hình nh, các đi u khi n trên các h p tho i t t thì s làm choẩ ỹ ả ề ể ộ ạ ố ẽ ng d ng càng ti n l i, rõ ràng, và thân thi n v i ng i dùng.ứ ụ ệ ợ ệ ớ ườ 1.3.4. B công c giao di n l p trình ng d ng APIộ ụ ệ ậ ứ ụ H đi u hành Windows cung c p hàng trăm hàm đ cho nh ng ng d ng có th sệ ề ấ ể ữ ứ ụ ể ử d ng truy c p các tài nguyên trong h th ng. Nh ng hàm này đ c g i là giao di n l p trìnhụ ậ ệ ố ữ ượ ọ ệ ậ ng d ng ứ ụ API (Application Programming Interface). Nh ng hàm trên đ c ch a trong các thữ ượ ứ ư vi n liên k t đ ng ệ ế ộ DLL c a h th ng. Nh có c u trúc đ ng này m i ng d ng đ u có thủ ệ ố ờ ấ ộ ọ ứ ụ ề ể truy c p đ n các hàm đó. Khi biên d ch ch ng trình, đ n đo n mã g i hàm API thì ch ngậ ế ị ươ ế ạ ọ ươ trình d ch không thêm mã hàm này vào mã th c thi mà ch thêm tên DLL ch a hàm và tên c aị ự ỉ ứ ủ chính hàm đó. Do đó mã các hàm API th c t không đ c s d ng khi xây d ng ch ng trình,ự ế ượ ử ụ ự ươ và nó ch đ c thêm vào khi ch ng trình đ c n p vào b nh đ th c thi.ỉ ượ ươ ượ ạ ộ ớ ể ự Trong API có m t s hàm có ch c năng duy trì s đ c l p thi t b đ h a, và các hàmộ ố ứ ự ộ ậ ế ị ồ ọ này g i là giao di n thi t b đ h a ọ ệ ế ị ồ ọ GDI (Graphics Device Interface). Do s đ c l p thi t bự ộ ậ ế ị nên các hàm GDI cho phép các ng d ng có th làm vi c t t v i nhi u ki u thi t b đ h aứ ụ ể ệ ố ớ ề ể ế ị ồ ọ khác nhau. 1.3.5. C ch thông đi p ơ ế ệ Không gi ng nh các ng d ng ch y trên MS-DOS, các ng d ng Win32® thì x lýố ư ứ ụ ạ ứ ụ ử theo các s ki n (ự ệ event - driven), theo c ch này các ng d ng khi đ c vi t s liên t c chơ ế ứ ụ ượ ế ẽ ụ ờ cho h đi u hành truy n các d li u nh p vào. H th ng s đ m nhi m vi c truy n t t cệ ề ề ữ ệ ậ ệ ố ẽ ả ệ ệ ề ấ ả các d li u nh p c a ng d ng vào các c a s khác nhau c a ng d ng đó. M i m t c a sữ ệ ậ ủ ứ ụ ử ổ ủ ứ ụ ỗ ộ ử ổ s có riêng m t hàm g i là hàm x lý c a s th ng đ c đ t tên là ẽ ộ ọ ử ử ổ ườ ượ ặ WndProc, h th ng sệ ố ẽ g i hàm này khi có b t c d li u nh p nào đ c truy n đ n c a s , hàm này s x lý các dọ ấ ứ ữ ệ ậ ượ ề ế ử ổ ẽ ử ữ li u nh p đó và tr quy n đi u khi n v cho h th ng.ệ ậ ả ề ề ể ề ệ ố H th ng truy n các d li u nh p vào th t c x lý c a c a s thông qua m t hìnhệ ố ề ữ ệ ậ ủ ụ ử ủ ử ổ ộ th c g i là thông đi p (ứ ọ ệ message). Thông đi p này đ c phát sinh t ng d ng và h th ng.ệ ượ ừ ứ ụ ệ ố Trang 6 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS H th ng s phát sinh m t thông đi p khi có m t s ki n nh p vào (ệ ố ẽ ộ ệ ộ ự ệ ậ input even), ví d nh khiụ ư ng i dùng nh n m t phím, di chuy n thi t b chu t, hay kích vào các đi u khi n (ườ ấ ộ ể ế ị ộ ề ể control) nh thanh cu n,… Ngoài ra h th ng cũng phát sinh ra thông đi p đ ph n ng l i m t sư ộ ệ ố ệ ể ả ứ ạ ộ ự thay đ i c a h th ng do m t ng d ng mang đ n, đi u này x y ra khi ng d ng làm c nổ ủ ệ ố ộ ứ ụ ế ề ả ứ ụ ạ ki t tài nguyên hay ng d ng t thay đ i kích th c c a c a s .ệ ứ ụ ự ổ ướ ủ ử ổ M t ng d ng có th phát sinh ra thông đi p khi c n yêu c u các c a s c a nó th cộ ứ ụ ể ệ ầ ầ ử ổ ủ ự hi n m t nhi m v nào đó hay dùng đ thông tin gi a các c a s .ệ ộ ệ ụ ể ữ ử ổ H th ng g i thông đi p vào th t c x lý c a s v i b n tham s : đ nh danh c a c aệ ố ở ệ ủ ụ ử ử ổ ớ ố ố ị ủ ử s , đ nh danh c a thông đi p, và hai tham s còn l i đ c g i là tham s c a thông đi pổ ị ủ ệ ố ạ ượ ọ ố ủ ệ (message parameters). Đ nh danh c a c a s xác đ nh c a s mà thông đi p đ c ch đ nh. Hị ủ ử ổ ị ử ổ ệ ượ ỉ ị ệ th ng s dùng đ nh danh này đ xác đ nh c n ph i g i thông đi p đ n th t c x lý c a c aố ẽ ị ể ị ầ ả ở ệ ế ủ ụ ử ủ ử s .ổ Đ nh danh thông đi p là m t h ng s th hi n m c đích c a thông đi p. Khi th t cị ệ ộ ằ ố ể ệ ụ ủ ệ ủ ụ x lý c a s nh n thông đi p thì nó s dùng đ nh danh này đ bi t hình th c c n th c hi n.ử ử ổ ậ ệ ẽ ị ể ế ứ ầ ự ệ Ví d , khi m t thông đi p đ c truy n đ n th t c c a s có đ nh danh là ụ ộ ệ ượ ề ế ủ ụ ử ổ ị WM_PAINT thì có ý nghĩa r ng c a s vùng làm vi c thay đ i và c n ph i v l i vùng này.ằ ử ổ ệ ổ ầ ả ẽ ạ Tham s thông đi p l u giá tr hay v trí c a d li u, đ c dùng b i th t c c a s khiố ệ ư ị ị ủ ữ ệ ượ ở ủ ụ ử ổ x lý thông đi p. Tham s này ph thu c vào lo i thông đi p đ c truy n đ n, nó có th làử ệ ố ụ ộ ạ ệ ượ ề ế ể s nguyên, m t t p các bit dùng làm c hi u, hay m t con tr đ n m t c u trúc d li u nàoố ộ ậ ờ ệ ộ ỏ ế ộ ấ ữ ệ đó,… Khi m t thông đi p không c n dùng đ n tham s thì h th ng s thi t l p các tham sộ ệ ầ ế ố ệ ố ẽ ế ậ ố này có giá tr NULL. M t th t c c a s ph i ki m tra xem v i lo i thông đi p nào c n dùngị ộ ủ ụ ử ổ ả ể ớ ạ ệ ầ tham s đ quy t đ nh cách s d ng các tham s này.ố ể ế ị ử ụ ố Có hai lo i thông đi p :ạ ệ Thông đi p đ c đ nh nghĩa b i h th ng (ệ ượ ị ở ệ ố system-defined messages) : D ng thông đi p này đ c h th ng đ nh nghĩa cho các c a s , các đi u khi n, và cácạ ệ ượ ệ ố ị ử ổ ề ể tài nguyên khác trong h th ng. Th ng đ c b t đ u v i các ti n t sau : ệ ố ườ ượ ắ ầ ớ ề ố WM_xxx, LB_xxx, CB_xxx,… Thông đi p đ c đ nh nghĩa b i ng d ng (ệ ượ ị ở ứ ụ application-defined message) : M t ng d ng có th t o riêng các thông đi p đ s d ng b i nh ng c a s c a nóộ ứ ụ ể ạ ệ ể ử ụ ở ữ ử ổ ủ hay truy n thông tin gi a các c a s trong ng d ng.ề ữ ử ổ ứ ụ N u m t ng d ng đ nh nghĩa các thông đi p riêng thì th t c c a s nh n đ cế ộ ứ ụ ị ệ ủ ụ ử ổ ậ ượ thông đi p này ph i cung c p các hàm x lý t ng ng.ệ ả ấ ử ươ ứ Đ i v i thông đi p h th ng, thì đ c cung c p giá tr đ nh danh t ố ớ ệ ệ ố ượ ấ ị ị ừ 0x0000 đ nế 0x03FF, nh ng ng d ng không đ c đ nh nghĩa thông đi p có giá tr trong kho ng này.ữ ứ ụ ượ ị ệ ị ả Trang 7 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS Thông đi p đ c ng d ng đ nh nghĩa có giá tr đ nh danh t ệ ượ ứ ụ ị ị ị ừ 0x0400 đ n ế 0x7FFF. L trình c a thông đi p t lúc g i đi đ n lúc x lý có hai d ng sau:ộ ủ ệ ừ ở ế ử ạ Thông đi p đ c g i vào hàng đ i thông đi p đ ch x lý (ệ ượ ở ợ ệ ể ờ ử queue message): bao g mồ các ki u thông đi p đ c phát sinh t bàn phím, chu t nh thông đi p :ể ệ ượ ừ ộ ư ệ WM_MOUSEMOVE, WM_LBUTTONDOWN, WM_KEYDOWN, và WM_CHAR. Thông đi p đ c g i tr c ti p đ n th t c x lý không qua hàng đ i (ệ ượ ở ự ế ế ủ ụ ử ợ nonqueue message), bao g m các thông đi p th i gian, thông đi p v , và thông đi p thoát nhồ ệ ờ ệ ẽ ệ ư WM_TIMER, WM_PAINT, và WM_QUIT. X lý thông đi p ử ệ : M t ng d ng ph i xóa và x lý nh ng thông đi p đ c g i t iộ ứ ụ ả ử ữ ệ ượ ở ớ hàng đ i c a ng d ng đó. Đ i v i m t ng d ng đ n ti u trình thì s d ng m t vòng l pợ ủ ứ ụ ố ớ ộ ứ ụ ơ ể ử ụ ộ ặ thông đi p (ệ message loop) trong hàm WinMain đ nh n thông đi p t hàng đ i và g i t i thể ậ ệ ừ ợ ở ớ ủ t c x lý c a s t ng ng. V i nh ng ng d ng nhi u ti u trình thì m i m t ti u trình cóụ ử ử ổ ươ ứ ớ ữ ứ ụ ề ể ỗ ộ ể t o c a s thì s có m t vòng l p thông đi p đ x lý thông đi p c a nh ng c a s trongạ ử ổ ẽ ộ ặ ệ ể ử ệ ủ ữ ử ổ ti u trình đó.ể 1.4. CÁCH VI T M T NG D NG TRÊN MICROSOFT WINDOWSẾ Ộ Ứ Ụ 1.4.1. Các thành ph n c b n t o nên m t ng d ngầ ơ ả ạ ộ ứ ụ 1.4.1.1. C a s ử ổ Trong m t ng d ng đ h a 32-bit, c a s (ộ ứ ụ ồ ọ ử ổ window) là m t vùng hình ch nh t trênộ ữ ậ màn hình, n i mà ng d ng có th hi n th thông tin ra và nh n thông tin vào t ng i sơ ứ ụ ể ể ị ậ ừ ườ ử d ng. Do v y, nhi m v đ u tiên c a m t ng d ng đ h a 32-bit là t o m t c a s .ụ ậ ệ ụ ầ ủ ộ ứ ụ ồ ọ ạ ộ ử ổ M t c a s s chia s màn hình v i các c a s khác trong cùng m t ng d ng hay cácộ ử ổ ẽ ẻ ớ ử ổ ộ ứ ụ ng d ng khác. Ch m t c a s trong m t th i đi m nh n đ c thông tin nh p t ng iứ ụ ỉ ộ ử ổ ộ ờ ể ậ ượ ậ ừ ườ dùng. Ng i s d ng có th dùng bàn phím, thi t b chu t hay các thi t b nh p li u khác đườ ử ụ ể ế ị ộ ế ị ậ ệ ể t ng tác v i c a s và ng d ng.ươ ớ ử ổ ứ ụ T t c các c a s đ u đ c t o t m t c u trúc đ c cung c p s n g i là l p c a sấ ả ử ổ ề ượ ạ ừ ộ ấ ượ ấ ẵ ọ ớ ử ổ (window class). C u trúc này là m t t p mô t các thu c tính mà h th ng dùng nh khuônấ ộ ậ ả ộ ệ ố ư m u đ t o nên các c a s . M i m t c a s ph i là thành viên c a m t l p c a s . T t cẫ ể ạ ử ổ ỗ ộ ử ổ ả ủ ộ ớ ử ổ ấ ả các l p c a s này đ u đ c x lý riêng bi t. ớ ử ổ ề ượ ử ệ 1.4.1.2. H p tho i và các đi u khi nộ ạ ề ể H p tho i (ộ ạ Dialog) dùng đ t ng tác v i ng i dùng trong m t ch ng trình ngể ươ ớ ườ ộ ươ ứ d ng. M t h p tho i th ng ch a nhi u các đ u khi n nh ô nh p văn b n (ụ ộ ộ ạ ườ ứ ề ề ể ư ậ ả edit text), nút b m (ấ button), ghi chú (static control), h p danh sách (ộ list box)… Trang 8 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS  Nút b m ấ (button): g m có ồ Push Button dùng kích ho t m t thao tác, ạ ộ Check Box dùng đ ch n m t trong hai tr ng thái (TRUE hay FALSE), ể ọ ộ ạ Radio Button cũng gi ngố nh Check Box nh ng m t nhóm các Radio Button ph i đ c ch n lo i tr nhau.ư ư ộ ả ượ ọ ạ ừ  Chú thích (static): dùng đ ch a các ghi chú trong h p tho i, ngoài ra n i dungể ứ ộ ạ ộ có th thay đ i trong quá trình s d ng h p tho i.ể ổ ử ụ ộ ạ  H p li t kê ộ ệ (list box): Ch n m t hay nhi u d li u đ c li t kê trong danhọ ộ ề ữ ệ ượ ệ sách, n u h p ch a nhi u dòng và h p không hi n th h t các m u thông tin thì ph i kèmế ộ ứ ề ộ ể ị ế ẫ ả theo m t thanh cu n (ộ ộ scroll bar).  Ô nh p văn b n ậ ả (edit text): Dùng nh p văn b n, n u ô có nhi u dòng thìậ ả ế ề th ng kèm theo thanh cu n.ườ ộ  Thanh cu n ộ (scroll bar): ngoài vi c dùng kèm v i list box hay edit box thìệ ớ thanh cu n còn có th s d ng đ c l p nh m t o các th c đo…ộ ể ử ụ ộ ậ ằ ạ ướ  Th c đ n ự ơ (menu): là m t danh sách ch a các thao tác v i m t đ nh danh màộ ứ ớ ộ ị ng i dùng có th ch n. H u h t các ng d ng có c a s thì không th thi u th c đ n.ườ ể ọ ầ ế ứ ụ ử ổ ể ế ự ơ  Thanh công c ụ (toolbar): đây là m t d ng menu nh ng ch ch a các thao tácộ ạ ư ỉ ứ c n thi t d i d ng các bi u t ng đ c tr ng.ầ ế ướ ạ ể ượ ặ ư Ngoài ra còn r t nhi u các đi u khi n mà các công c l p trình cung c p cho ng iấ ề ề ể ụ ậ ấ ườ l p trình hay t h t o ra d a trên nh ng thành ph n đ c cung c p s n.ậ ự ọ ạ ự ữ ầ ượ ấ ẵ 1.4.1.3. ng d ng đi n hình trên WindowsỨ ụ ể 1.4.1.4. Các ki u t p tin đ xây d ng m t ng d ng trên Windowsể ậ ể ự ộ ứ ụ Ch ng trình ngu n ươ ồ T ng t nh các ch ng trình C chu n, bao g m các t p tin tiêu đ (ươ ự ư ươ ẩ ồ ậ ề header) ch aứ trong t p tin ậ *.h, *.hpp. Còn mã ngu n (ồ source code) ch a trong t p tin ứ ậ *.c hay *.cpp. T p tin đ nh nghĩa ậ ị T p tin này có ph n m r ng là ậ ầ ở ộ *.def, dùng đ nh nghĩa các đi u khi n do ch ng trìnhị ề ể ươ t o ra khi vi t ng d ng t o ạ ế ứ ụ ạ DLL, ngoài ra còn dùng đ khai báo vùng nh heap khi ch yể ớ ạ ch ng trình. Lúc tr c do v n đ t ng thích v i Windows 3.1 nên t p tin này th ng đ cươ ướ ấ ề ươ ớ ậ ườ ượ dùng, còn ngày nay chúng ít đ c dùng đ n.ượ ế Các file ch a tài nguyên c a ng d ng ứ ủ ứ ụ • Các file *.ico là các bi u t ng (ể ượ icon) đ c dùng trong ch ng trình. Thôngượ ươ th ng các công c l p trình trên Windows đ u có các tool đ t o các nh này.ườ ụ ậ ề ể ạ ả • Con tr chu t c a ng d ng có th đ c v l i d i d ng các bi u t ng vàỏ ộ ủ ứ ụ ể ượ ẽ ạ ướ ạ ể ượ l u trên đĩa v i d ng file ư ớ ạ *.cur. • Các file d ng nh bitmap dùng đ minh h a đ c l u d ng file ạ ả ể ọ ượ ư ạ *.bmp. • T p tin tài nguyên ậ *.rc là ph n khai báo các tài nguyên nh th c đ n, h pầ ư ự ơ ộ tho i, và các đ nh danh ch đ n các t p tin d ng ạ ị ỉ ế ậ ạ *.ico, *.cur, *.bmp,... 1.4.1.5. Các ki u d li u m iể ữ ệ ớ Trang 9 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS Các ki u d li u trên Windows th ng đ c đ nh nghĩa nh toán t ể ữ ệ ườ ượ ị ờ ử typedef trong t pậ tin windows.h hay các t p tin khác. Thông th ng các t p tin đ nh nghĩa này do Microsoft vi tậ ườ ậ ị ế ra ho c các công ty vi t trình biên d ch C t o ra, nh t thi t nó ph i t ng thích v i h đi uặ ế ị ạ ấ ế ả ươ ớ ệ ề hành Windows 98, hay NT d a trên ki n trúc 32-bit.ự ế M t vài ki u d li u m i có tên vi t t t r t d hi u nh ộ ể ữ ệ ớ ế ắ ấ ễ ể ư UINT là m t d li u th ngộ ữ ệ ườ đ c dùng mà đ n gi n là ki u ượ ơ ả ể unsigned int, trong Windows 9x ki u này có kích th c là 32-ể ướ bit. Đ i v i ki u chu i thì có ki u ố ớ ể ỗ ể PSTR ki u này là m t con tr đ n m t chu i t ng tể ộ ỏ ế ộ ỗ ươ ự nh ư char*. Tuy nhiên, cũng có m t s ki u đ c khái báo tên thi u rõ ràng nh ộ ố ể ượ ế ưWPARAM và LPARAM. Tên này đ c đ t vì có ngu n ng c l ch s sâu xa. Khi còn h đi u hành Windowsượ ặ ồ ố ị ử ệ ề 16-bit thì tham s th 3 c a hàm ố ứ ủ WndProc đ c khai báo là ki u ượ ể WORD, v i kích th c 16-ớ ướ bit , còn tham s th 4 có ki u ố ứ ể LONG là 32-bit. Đây là lý do ng i ta thêm ti n t "ườ ế ố W", "L" vào t "ừ PARAM". Tuy nhiên, trong phiên b n Windows 32-bit, thì ả WPARAM đ c đ nhượ ị nghĩa nh là ư UINT và LPARAM thì đ c đ nh nghĩa nh m t ki u ượ ị ư ộ ể LONG, do đó c hai thamả s này đ u có giá tr là 32-bit. Đi u này là m t s nh m l n vì ố ề ị ề ộ ự ầ ẫ WORD v n là giá tr 16-bitẫ ị trong Window 98. Trong th t c x lý c a s ủ ụ ử ử ổWndProc giá tr tr v là ki u ị ả ề ể LRESULT. Ki u này đ nể ơ gi n đ c đ nh nghĩa nh là ki u ả ượ ị ư ể LONG. Ngoài ra, có m t ki u th ng xuyên dùng là ki u ộ ể ườ ể HANDLE là m t s nguyên 32-bitộ ố đ c s d ng nh m t ki u đ nh danh. Có nhi u ki u đ nh danh nh ng nh t thi t t t c ph iượ ử ụ ư ộ ể ị ề ể ị ư ấ ế ấ ả ả có cùng kích th c v i ướ ớ HANDLE. B ng sau mô t m t s ki u d li u m i:ả ả ộ ố ể ữ ệ ớ Ki uể Ý nghĩa HANDLE S nguyên 32-bit, đ nh danh. ố ị HWND S nguyên 32-bit, đ nh danh.ố ị BYTE Giá tr 8-bit không d u.ị ấ WORD S nguyên 16-bit không d u.ố ấ DWORD S nguyên 32-bit không d u.ố ấ UINT S nguyên không d u 32-bit.ố ấ LONG long 32-bit. BOOL Bool. LPSTR Con tr chu i.ỏ ỗ Trang 10 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS LPCSTR H ng con tr chu i.ằ ỏ ỗ WPARAM 32-bit. LPARAM 32-bit. BSTR Giá tr 32-bit tr đ n kí t .ị ỏ ế ự LPVOID Con tr 32-bit đ n m t ki u không xác đ nh.ỏ ế ộ ể ị LPTSTR Gi ng nh LPSTR nh ng có th chuy n sang d ngố ư ư ể ể ạ Unicode và DBCS. LPCTSTR Gi ng nh LPCTSTR nh ng có th chuy n sang d ngố ư ư ể ể ạ Unicode và DBCS. B ng 1.1 ả Mô t các ki u d li u m iả ể ữ ệ ớ 1.4.2. Khuôn m u chung t o m t ng d ngẫ ạ ộ ứ ụ M t ng d ng đ n gi n nh t c a Windows bao g m có hai hàm là ộ ứ ụ ơ ả ấ ủ ồ WinMain và x lýử c a s ử ổWinProc. Do đó hai hàm này là quan tr ng và không th thi u trong các ng d ngọ ể ế ứ ụ Windows. Hàm WinMain th c hi n các ch c năng sau :ự ệ ứ • Đ nh nghĩa l p c a s ng d ng.ị ớ ử ổ ứ ụ • Đăng ký l p c a s v a đ nh nghĩa.ớ ử ổ ừ ị • T o ra th hi n c a s c a l p đã cho.ạ ể ệ ử ổ ủ ớ • Hi n th c a s .ể ị ử ổ • Kh i đ ng chu trình x lý thông đi p.ở ộ ử ệ Hàm x lý ử WinProc có ch c năng x lý t t c các thông đi p có liên quan đ n c a s .ứ ử ấ ả ệ ế ử ổ 1.4.3. Hàm WinMain Hàm chính c a m t ng d ng ch y trên Windows là hàm ủ ộ ứ ụ ạ WinMain, đ c khai báoượ nh sau:ư int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow); Chúng ta s tìm hi u m t hàm ẽ ể ộ WinMain m u sau đây.ẫ Trang 11 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { static TCHAR szAppName[] = TEXT("HelloWin"); // tên ng d ngứ ụ HWND hwnd; MSG msg; WNDCLASS wndclass; // bi n đ đ nh nghĩa m t c a sế ể ị ộ ử ổ /* Đ nh nghĩa ki u c a s */ị ể ử ổ wndclass.style = SC_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; // Hàm th t c c a sủ ụ ử ổ wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; // Đ nh danh ng d ngị ứ ụ wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION); wndclass.hCursor = LoadCusor (NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = NULL; // Không có menu wndclass.lpszClassName = szAppName; // tên ng d ngứ ụ /* Đăng ký l p c a s */ớ ử ổ if (!RegisterClass(&wndclass)) return 0; /* T o l p c a s */ạ ậ ử ổ hwnd = CreateWindow (szAppName, // Tên c a sử ổ "Hello Program", // Tiêu đề WS_OVERLAPPEDWINDOW, // Ki u c a sể ử ổ Trang 12 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS CW_USEDEFAULT, // T a đ xọ ộ CW_USEDEFAULT, // T a đ yọ ộ CW_USEDEFAULT, // Chi u r ngề ộ CW_USEDEFAULT, // Chi u dàiề NULL, // C a s chaử ổ NULL, // Không có menu hInstacne, // Đ nh danh ng d ngị ứ ụ NULL); // Tham s b sungố ổ /* Hi n th c a s */ể ị ử ổ ShowWindow (hwnd, iCmdShow); UpdateWindow (hwnd); /* Chu trình x lý các thông đi p*/ử ệ while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg); DispatchMessage (&msg); } return msg.wParam; } Đ nh nghĩa m t l p c a s :ị ộ ớ ử ổ Đ u tiên c a viêc xây d ng m t ng d ng Windows là ph i đ nh nghĩa m t l p c a sầ ủ ự ộ ứ ụ ả ị ộ ớ ử ổ cho ng d ng. Windows cung c p m t c u trúc ứ ụ ấ ộ ấ WNDCLASS g i là l p c a s , l p này ch aọ ớ ử ổ ớ ứ nh ng thu c tính t o thành m t c a s . ữ ộ ạ ộ ử ổ typedef struct _WNDCLASS { Trang 13 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS UINT style; WNDPROC lpfnWndProc; int cbClsExtra; HINSTANCE hInstance; HICON hIcon; HCURSOR hCursor; HBRUSH hbrBackground; LPCSTR lpszMenuName; LPCSTR lpszClassName; } WNDCLASS, *PWNDCLASS; Ý nghĩa thu c tính c a c u trúc ộ ủ ấ WNDCLASS đ c mô t trong b ng sau :ượ ả ả Thu c tínhộ Ý nghĩa ghi chú style Ki u l pể ớ K t h p nhi u ki u giá tr khác nhauế ợ ề ể ị b ng toán t OR.ằ ử lpfnWndProc Con tr đ n th t c windowỏ ế ủ ụ cbClsExtra S byte đ c c p phát thêm sauố ượ ấ c u trúc window-classấ M c đ nhặ ị cbWndExtra S byte đ c c p phát thêm sauố ượ ấ m t instance c a windowộ ủ M c đ nhặ ị hInstance Đ nh danh ch a th t c c a sị ứ ủ ụ ử ổ c a l p windowủ ớ hIcon Đ nh danh c a bi u t ngị ủ ể ượ Dùng hàm LoadIcon hCursor Đ nh danh c a con tr chu tị ủ ỏ ộ Dùng hàm LoadCursor hbrBackground Đ nh danh c a ch i tô n nị ủ ổ ề Dùng hàm GetStockObject lpszMenuName Tên th c đ nự ơ Tên th c đ n g n v i c a s , th cự ơ ắ ớ ử ổ ự d n này đ c khai báo trong t p tinơ ượ ậ tài nguyên. Trang 14 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS lpszClassName Tên l pớ B ng 1.2 ả Mô t thu c tính c a l p c a sả ộ ủ ớ ử ổ Đăng ký l p c a s :ớ ử ổ Sau khi đ nh nghĩa m t l p c a s , ph i đăng ký l p c a s đó b ng hàmị ộ ớ ử ổ ả ớ ử ổ ằ RegisterClass : ATOM RegisterClass( CONST WNDCLASS * lpWndClass ); T o c a s :ạ ử ổ L p c a s đ nh nghĩa nh ng đ c tính chung c a c a s , cho phép t o ra nhi u c a sớ ử ổ ị ữ ặ ủ ử ổ ạ ề ử ổ d a trên m t l p. Khi t o ra m t c a s c a hàm ự ộ ớ ạ ộ ử ổ ủ CreateWindow, ta ch đ nh các đ c tínhỉ ị ặ riêng c a c a s này, và phân bi t nó v i các c a s khác t o ra cùng m t l p.ủ ử ổ ệ ớ ử ổ ạ ộ ớ Khai báo hàm t o c a s :ạ ử ổ HWND CreateWindow( LPCSTR lpClassName, // Tên l p c a s đã đăng kýớ ử ổ LPCSTR lpwindowName, // Tên c a c a sủ ử ổ DWORD dwStyle, // Ki u c a c a sể ủ ử ổ int x, // V trí ngang ban đ uị ầ int y, // V trí d c ban đ uị ọ ầ int nWidth, // Đ r ng ban đ uộ ộ ầ int nHeight, // Đ cao ban đ uộ ầ HWND hWndParent, // Đ nh danh c a c a s chaị ủ ử ổ MENU hMenu, // Đ nh dang c a th c đ nị ủ ự ơ INSTANCE hInstance, // Đ nh danh th hi n ng d ngị ể ệ ứ ụ PVOID lpParam // Các tham s ban đ uố ầ ); Hi n th c a s :ể ị ử ổ Trang 15 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS Sau khi g i hàm ọ CreateWindow, m t c a s đ c t o ra bên trong Windows, đi u nàyộ ử ổ ượ ạ ề có ý nghĩa là Windows đã cáp phát m t vùng nh đ l u gi t t c các thông tin v c a s đãộ ớ ể ư ữ ấ ả ề ử ổ đ c ch đ nh trong hàm ượ ỉ ị CreateWindow. Nh ng thông s này s đ c Windows tìm l i khiữ ố ẽ ượ ạ c n thi t d a vào đ nh danh mà hàm t o c a s tr v . Tuy nhiên, lúc này c a s ch a xu tầ ế ự ị ạ ử ổ ả ề ử ổ ư ấ hi n trên màn hình Windows, đ xu t hi n c n ph i g i hàm ệ ể ấ ệ ầ ả ọ ShowWindow. Hàm ShowWindow có khai báo nh sau:ư BOOL ShowWindow( HWND hWnd, // Đ nh danh c a c a s c n th hi nị ủ ử ổ ầ ể ệ int nCmdShow // Tr ng thái hi n thạ ể ị ); M t s tr ng thái c a tham s nCmdShow:ộ ố ạ ủ ố • SW_HIDE : n c a s .Ẩ ử ổ • SW_MAXIMIZE : Phóng c a s ra toàn b màn hình.ử ổ ộ • SW_MINIMIZE : thu nh thành bi u t ng trên màn hình.ỏ ể ượ • SW_RESTORE : Hi n th d i d ng chu n.ể ị ướ ạ ẩ 1.4.4. Hàm x lý c a s WndProcử ử ổ M t ch ng trình Windows có th ch a nhi u h n m t hàm x lý c a s . M t hàmộ ươ ể ứ ề ơ ộ ử ử ổ ộ x lý c a s luôn k t h p v i m t l p c a s đ c thù. Hàm x lý c a s th ng đ c đ t tênử ử ổ ế ợ ớ ộ ớ ử ổ ặ ử ử ổ ườ ượ ặ WndProc. Hàm WndProc có ch c năng giao ti p v i bên ngoài, t c là v i Windows, toàn b cácứ ế ớ ứ ớ ộ thông đi p g i đ n c a s đi u đ c x lý qua hàm này.ệ ở ế ử ổ ề ượ ử Hàm này th ng đ c khai báo nh sau :ườ ượ ư LRESULT CALLBACK WndProc ( HWND, UINT, WPARAM, LPARAM ); Trong đó tham s đ u tiên là đ nh danh c a c a s , tham s th 2 là đ nh danh thôngố ầ ị ủ ử ổ ố ứ ị đi p, và cu i cùng là 2 tham s ệ ố ốWPARAM và LPARAM b sung thông tin kèm theo thôngổ đi p.ệ Chúng ta s tìm hi u m t hàm x lý c a s ẽ ề ộ ử ử ổWndProc sau: LRESULT CALLBACK WndProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) Trang 16 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS { HDC hdc; PAINTSTRUCT ps; RECT rect; /*X lý các thông đi p c n thi t v i ng d ng*/ử ệ ầ ế ớ ứ ụ switch (msg) { case WM_CREATE: /*Vi t đo n mã khi t o c a s */ế ạ ạ ử ổ return 0; case WM_PAINT: /*Vi t đo n mã khi tô v l i c a s */ế ạ ẽ ạ ử ổ hdc = BeginPaint ( hwnd, &ps); GetClientRect (hwnd, &rect); DrawText(hdc, "Hello", -1, &rect, DT_SINGLELINE| DT_CENTER| DT_VCENTER); EndPaint ( hwnd, &ps); return 0; case WM_SIZE: /*Vi t đo n mã khi kích th c c a s thay đ i*/ế ạ ướ ử ổ ổ return 0; case WM_DESTROY: /*C a s b đóng*/ử ổ ị PostQuitMessage (0); return 0; Trang 17 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS } return DefWindowProc ( hwnd, msg, wParam, lParam); } Thông th ng chúng ta ch ch n đ x lý các thông đi p c n thi t có liên quan đ nườ ỉ ặ ể ử ệ ầ ế ế ch c năng c a ng d ng. Các thông đi p khác thì giao cho hàm x lý m c đ nh làm vi c (hàmứ ủ ứ ụ ệ ử ặ ị ệ DefWindowProc). 1.4.5. X lý thông đi pử ệ Sau khi c a s đ c hi n th trên màn hình, thì ch ng trình ph i đ c các thông tinử ổ ượ ể ị ươ ả ọ nh p c a ng i dùng t bàn phím hay thi t b chu t. Windows s duy trì m t hàng đ i thôngậ ủ ườ ừ ế ị ộ ẽ ộ ợ đi p cho m i ch ng trình ch y trên nó. Khi m t s ki n nh p thông tin xu t hi n, Windowsệ ỗ ươ ạ ộ ự ệ ậ ấ ệ s d ch s ki n này thành d ng thông đi p và đ a nó vào hàng đ i thông đi p c a ng d ngẽ ị ự ệ ạ ệ ư ợ ệ ủ ứ ụ t ng ng.ươ ứ M t ng d ng nh n các thông đi p t hàng đ i thông đi p b ng cách th c thi m tộ ứ ụ ậ ệ ừ ợ ệ ằ ự ộ đo n mã sau:ạ while ( GetMessage(&msg, NULL, 0 ,0) ) { TranslateMessage (&msg); DispatchMessage (&msg); } Trong đó msg là m t bi n c u trúc ki u ộ ế ấ ể MSG đ c đ nh nghĩa trong t p tin tiêu đượ ị ậ ề WINUSER.H. typedef struct tagMSG { HWND hwnd; UINT message; WPARAM wParam; LPARAM lParam; DWORD time; Trang 18 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS POINT pt; } MSG, *PMSG; Ki u d li u ể ữ ệ POINT là m t ki u c u trúc khác, đ c đ nh nghĩa trong t p tin tiêu độ ể ấ ượ ị ậ ề WINDEF.H, và có mô t :ả typedef struct tagPOINT { LONG x; LONG y; } POINT, *PPOINT; Ý nghĩa c a các tr ng trong c u trúc ủ ườ ấ MSG  hwnd : Đ nh danh c a c a s mà thông đi p phát sinh.ị ủ ử ỗ ệ  message : Đ nh danh c a thông đi p, ví d nh thông đi p phát sinh khi b mị ủ ệ ụ ư ệ ấ nút chu t trái là WM_LBUTTONDOWN có giá tr 0x0201.ộ ị  wParam : Tham s 32-bit ch a các thông tin ph thu c vào t ng thông đi p cố ứ ụ ộ ừ ệ ụ th .ể  lParam : Tham s 32-bit ph thu c vào thông đi p.ố ụ ộ ệ  time : Th i gian đ t thông đi p trong hàng đ i.ờ ặ ệ ợ  pt : T a đ c a chu t khi đ t thông đi p vào hàng đ iọ ộ ủ ộ ặ ệ ợ Hàm GetMessage s tr v 0 n u msg ch a thông đi p có đ nh danh WM_QUITẽ ả ề ế ứ ệ ị (0x0012), khi đó vòng l p thông đi p ng ng và ng d ng k t thúc. Ng c l i thì hàm s trặ ệ ư ứ ụ ế ượ ạ ẽ ả v m t giá tr khác 0 v i các thông đi p khác.ề ộ ị ớ ệ 1.4.6. Xây d ng m t ng d ng đ u tiênự ộ ứ ụ ầ M t ng d ng th ng có giao di n n n t ng là m t khung c a s , đ t o đ c c aộ ứ ụ ườ ệ ề ả ộ ử ổ ể ạ ượ ử s này chúng ta th c hi n b ng cách khai báo m t l p c a s và đăng ký l p c a s đó. Đổ ự ệ ằ ộ ớ ử ổ ớ ử ổ ể c a s t ng tác đ c thì chúng ta ph i vi t hàm x lý c a s ử ổ ươ ượ ả ế ử ử ổWndProc khi đó t t c cácấ ả thông đi p liên quan đ n c a s s đ c truy n vào cho hàm này. Đo n ch ng trình sau làệ ế ử ổ ẽ ượ ề ạ ươ khung s n cho các ch ng trình vi t trên Windows, bao g m 2 hàm chính là :ườ ươ ế ồ WinMain : hàm chính c a ch ng trình th c hi n các ch c năng :ủ ươ ự ệ ứ • Khai báo l p c a s .ớ ử ổ • Đăng ký l p c a s v a khai báo.ớ ử ổ ừ • T o và hi n th l p c a s trên.ạ ể ị ớ ử ổ • Vòng l p nh n thông đi p.ặ ậ ệ Trang 19 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS WndProc : Hàm x lý thông đi p g i đ n c a s .ử ệ ở ế ử ổ /* HELLOWORLD.C */ #include LRESULT CALLBACK WndProc ( HWND, UINT, WPARAM, LPARAM ); int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow ) { static TCHAR szAppName [] = TEXT ("HelloWorld"); HWND hwnd; MSG msg; WNDCLASS wndclass; wndclass.style = CS_HREDRAW|CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon ( NULL, IDI_APPLICATION ); wndclass.hCursor = LoadCursor ( NULL, IDC_ARROW ); wndclass.hbrBackground = ( HBRUSH ) GetStockObject ( WHITE_BRUSH ); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szAppName; if ( !RegisterClass ( &wndclass ) ) { MessageBox(NULL, TEXT (" The program requires Windows"), szAppName, MB_ICONERROR ); Trang 20 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS return 0; } hwnd = CreateWindow ( szAppName, // Tên l p c a sớ ử ổ TEXT (" The Hello World Program"), // Tiêu đ c a sề ử ổ WS_OVERLAPPEDWINDOW, // Ki u c a sể ử ổ CW_USEDEFAULT, // T a đ xọ ộ CW_USEDEFAULT, // T a đ yọ ộ CW_USEDEFAULT, // Chi u ngangề CW_USEDEFAULT, // Chi u d cề ọ NULL, // C a s chaử ổ NULL, // Th c đ nự ơ hInstance, // Đ nh danh ị NULL ); // Tham số ShowWindow ( hwnd, iCmdShow ); UpdateWindow ( hwnd ); while ( GetMessage ( &msg, NULL, 0, 0) ) { TranslateMessage (&msg); DispatchMessage (&msg) ; } return msg.wParam; } // End WinMain LRESULT CALLBACK WndProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { HDC hdc; Trang 21 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS PAINTSTRUCT ps; RECT rect; switch ( msg ) { case WM_CREATE: return 0; case WM_PAINT: hdc = BeginPaint ( hwnd, &ps); GetClientRect ( hwnd, &rect ); DrawText( hdc, TEXT("Hello World"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER ); EndPaint ( hwnd, &ps); return 0; case WM_DESTROY: PostQuitMessage (0); return 0; } // End switch return DefWindowProc ( hwnd, msg, wParam, lParam); } B ng d i đây li t kê ý nghĩa c a các hàm đ c s d ng trong 2 hàm ả ướ ệ ủ ượ ử ụ WinMain và WndProc c a ch ng trình HELLOWORLD.C.ủ ươ Tên hàm Ý nghĩa LoadIcon N p m t bi u t ng đ s d ng trong ch ngạ ộ ể ượ ể ử ụ ươ trình. LoadCursor Nap m t con tr chu t cho ch ng trình.ộ ỏ ộ ươ Trang 22 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS GetStockObject Nh n m t đ i t ng đ h a, trong tr ng h pậ ộ ố ượ ồ ọ ườ ợ c a ch ng trình thì l y m t ch i tô đ tô l i n n c aủ ươ ấ ộ ổ ể ạ ề ủ c a s . ử ổ RegisterClass Đăng ký m t l p c a s cho c a s ng d ngộ ớ ử ổ ử ổ ứ ụ trong ch ng trình.ươ MessageBox Hi n th m t thông đi p.ể ị ộ ệ CreateWindow T o m t c a s d a trên m t l p c a s .ạ ộ ử ổ ự ộ ớ ử ổ ShowWindow Hi n th c a s lên màn hình.ể ị ử ổ UpdateWindow Yêu c u c a s v l i chính b n thân nó.ầ ử ổ ẽ ạ ả GetMesssage Nh n m t thông đi p t hàng đ i thông đi p.ậ ộ ệ ừ ợ ệ TranslateMessage D ch thông đi p bàn phím.ị ệ DispatchMessage G i thông đi p đ n hàm x lý c a s .ở ệ ế ứ ử ổ BeginPaint Kh i t o ch c năng v c a c a s .ở ạ ứ ẽ ủ ử ổ GetClientRect L y hình ch nh t l u vùng làm vi c.ấ ữ ậ ư ệ DrawText Hi n th m t chu i văn b n.ể ị ộ ỗ ả EndPaint K t thúc vi c v c a s .ế ệ ẽ ử ổ PostQuitMessage Đ a thông đi p thoát vào hàng đ i thông đi p.ư ệ ợ ệ DefWindowProc Th c hi n vi c x lý m c đ nh các thông đi p.ự ệ ệ ử ặ ị ệ B ng 1.3 ả Mô t các hàm đ c s d ng trong ch ng trình minh h aả ượ ử ụ ươ ọ 1.4.7. M t s qui c đ t tên bi nộ ố ướ ặ ế Khi vi t m t ch ng trình ng d ng l n v i nhi u ki u khai báo bi n khác nhau, n uế ộ ươ ứ ụ ớ ớ ề ể ế ế vi c khai báo các tên bi n không thích h p s làm cho ch ng trình ph c t p thêm, đôi khiệ ế ợ ẽ ươ ứ ạ làm khó ngay c ng i vi t ra các mã ngu n đó. Vì v y các l p trình viên th ng qui c saoả ườ ế ồ ậ ậ ườ ướ cho m t tên bi n v a g i đ c ch c năng c a nó v a xác đ nh đ c ki u lo i. Có r t nhi uộ ế ừ ợ ượ ứ ủ ừ ị ượ ể ạ ấ ề phong cách đ đ t tên, trong s đó thì có phong cách đ t tên theo ể ặ ố ặ cú pháp Hungary (Hungarian Notation) là đ c dùng nhi u nh t. Qui c r t đ n gi n là b t đ u tên bi n thìượ ề ấ ướ ấ ơ ả ắ ầ ế vi t ch th ng và các ch đ u th hi n ki u d li u c a bi n, và đ c g i là các ti n t .ế ữ ườ ữ ầ ể ệ ể ữ ệ ủ ế ượ ọ ề ố Ví d nh bi n ụ ư ế szCmdLine là m t bi n l u chu i nh p t dòng l nh, ộ ế ư ỗ ậ ừ ệ sz là th hi n cho bi nể ệ ế ki u chu i k t thúc ký t 0, ngoài ra ta hay th y ể ỗ ế ự ấ hInstance và hPrevInstance, trong đó h vi tế t t cho ki u handle, ki u d li u nguyên th ng đ c khai báo d ng ti n t là ch i.ắ ể ể ữ ệ ườ ượ ạ ế ố ữ Trang 23 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS Cú pháp Hungary này giúp cho ng i l p trình r t nhi u trong khâu ki m tra l i c aườ ậ ấ ề ể ỗ ủ ch ng trình, vì khi nhìn vào hai bi n ta có th d dàng nh n bi t đ c s không t ng thíchươ ế ể ễ ậ ế ựơ ự ươ gi a hai ki u d li u th hi n trong tên c a hai bi n. ữ ể ữ ệ ể ệ ủ ế B ng mô t m t s ti n t khi đ t tên bi n c a các ki u d li u :ả ả ộ ố ề ố ặ ế ủ ể ữ ệ Ti n tề ố Ki u d li uể ữ ệ c char, WCHAR, TCHAR by BYTE n short i int x,y bi n l u t a đ ế ư ọ ộ x, y b BOOL w WORD l long dw DWORD s string sz chu i k t thúc b i kí t 0ỗ ế ở ự h handle p pointer Lpsz con tr dài chu i ký t k t thúc kí t 0ỏ ỗ ự ế ự B ng 1.4 ả Mô t ki u đ t tên bi nả ể ặ ế Trang 24 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS Ch ng 2ươ H P THO I VÀ THANH TRÌNH Đ N Ộ Ạ Ơ 2.1. M Đ UỞ Ầ H p tho i (dộ ạ ialog) và thanh trình đ n (ơ menu) là các thành ph n không th thi u trongầ ể ế vi c t ch c giao ti p gi a ng i s d ng và ch ng trình. H p tho i đ c xem nh là m tệ ổ ứ ế ữ ườ ử ụ ươ ộ ạ ượ ư ộ lo i c a s đ c bi t, là công c m m d o, linh ho t đ đ a thông tin vào ch ng trình m tạ ử ổ ặ ệ ụ ề ẻ ạ ể ư ươ ộ cách d dàng. Trong khi menu là công c giúp ng i dùng th c hi n các thao tác đ n gi nễ ụ ườ ự ệ ơ ả h n, thông qua các nhóm ch c năng th ng s d ng. ơ ứ ườ ử ụ 2.2. H P THO IỘ Ạ H p tho i ph i h p gi a ng i s d ng v i ch ng trình b ng m t s ph n t đi uộ ạ ố ợ ữ ườ ử ụ ớ ươ ằ ộ ố ầ ử ề khi n mà các ph n t này nh n nhi m v thu nh n thông tin t ng i dùng và cung c p thôngể ầ ử ậ ệ ụ ậ ừ ườ ấ tin đ n ng i dùng khi ng i dùng tác đ ng đ n các ph n t đi u khi n. Các ph n t đi uế ườ ườ ộ ế ầ ử ề ể ầ ử ề khi n này nh n c a s cha là m t h p tho i. Các ph n t đi u khi n th ng là các ể ậ ử ổ ộ ộ ạ ầ ử ề ể ườ Button, List Box, Combo Box, Check Box, Radio Button, Edit Box, Scroll Bar, Static. T ng t nh các thông đi p g i đ n th t c ươ ự ư ệ ở ế ủ ụ WndProc c a c a s chính.Windows sủ ử ổ ẽ g i các thông đi p x lý h p tho i đ n th t c x lý h p tho i ở ệ ử ộ ạ ế ủ ụ ử ộ ạ DlgProc. Hai th t củ ụ WndProc và th t c ủ ụ DlgProc tuy cách làm vi c gi ng nhau nh ng gi a chúng có nh ng đi mệ ố ư ữ ữ ể khác bi t c n l u ý. Bên trong th t c x lý h p tho i b n c n kh i t o các ph n t đi uệ ầ ư ủ ụ ử ộ ạ ạ ầ ở ạ ầ ử ề khi n bên trong h p tho i b ng thông đi p ể ộ ạ ằ ệ WM_INITDIALOG, cu i cùng là đóng h p tho i,ố ộ ạ Trang 25 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS còn th t c x lý ủ ụ ử WndProc thì không có. Có ba lo i h p tho i c b n. H p tho i tr ng tháiạ ộ ạ ơ ả ộ ạ ạ (modal), h p tho i không tr ng thái (ộ ạ ạ modeless) và h p tho i thông d ng (ộ ạ ụ common dialog) mà chúng ta s đ c p c th trong các ph n d i.ẽ ề ậ ụ ể ầ ướ 2.2.1. H p tho i tr ng thái ộ ạ ạ H p tho i tr ng thái (modal) là lo i h p tho i th ng dùng trong các ng d ng c aộ ạ ạ ạ ộ ạ ườ ứ ụ ủ chúng ta. Khi h p tho i tr ng thái đ c hi n th thì b n không th chuy n đi u khi n đ n cácộ ạ ạ ượ ể ị ạ ể ể ề ể ế c a s khác, đi u này có nghĩa b n ph i đóng h p tho i hi n hành tr c khi mu n chuy nử ổ ề ạ ả ộ ạ ệ ướ ố ể đi u khi n đ n các c a s khác.ề ể ế ử ổ 2.2.1.1. Cách t o h p tho i đ n gi nạ ộ ạ ơ ả Sau đây là ch ng trình t o ra m t h p tho i đ n gi n. H p tho i đ c t o ra có n iươ ạ ộ ộ ạ ơ ả ộ ạ ượ ạ ộ dung nh sau. ư Khi h p tho i hi n lên có xu t hi n dòng ch "HELLO WORLD", bên trên h p tho iộ ạ ệ ấ ệ ữ ộ ạ có m t bi u t ng c a h p tho i đó là m t ộ ể ượ ủ ộ ạ ộ icon, và phía d i h p tho i là m t nút b mướ ộ ạ ộ ấ (Button) có tên là OK, khi nh p chu t vào nút ấ ộ OK thì h p tho i "HELLO WORLD" đ cộ ạ ượ đóng l i.ạ Hình 2.1 H p tho i đ n gi nộ ạ ơ ả Đo n code ch ng trình nh sau (ạ ươ ư Ví d 2.1ụ ): DIALOG.CPP (trích d n)ẫ LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK DialogProc (HWND, UINT, WPARAM, LPARAM) ; LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static HINSTANCE hInstance ; Trang 26 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS switch (message) { case WM_CREATE : hInstance = ((LPCREATESTRUCT) lParam)->hInstance ; return 0 ; case WM_COMMAND : switch (LOWORD (wParam)) { case IDC_SHOW : DialogBox (hInstance, TEXT ("DIALOG1"), hwnd, DialogProc) ; break; } return 0 ; case WM_DESTROY : PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ; } /*----------------------hàm x lý thông đi p h p tho i-------------------------------*/ử ệ ộ ạ BOOL CALLBACK DialogProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG : Trang 27 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS return TRUE ; case WM_COMMAND : switch (LOWORD (wParam)) { case IDOK : EndDialog (hDlg, 0) ; return TRUE ; } break ; } return FALSE ; } DIALOG1.RC (trích d n) ẫ /*---------------------------------------dialog--------------------------------------------*/ DIALOG1 DIALOG DISCARDABLE 40, 20, 164, 89 STYLE DS_MODALFRAME | WS_POPUP FONT 9, "MS Sans Serif" BEGIN DEFPUSHBUTTON "OK",IDOK,54,65,50,14 CTEXT "HELLO WORLD ",IDC_STATIC,53,38,72,10 ICON IDI_ICON1,IDC_STATIC,68,9,20,20 END /* -----------------------------------------Menu------------------------------------------*/ MENU1 MENU DISCARDABLE BEGIN POPUP "Dialog1" Trang 28 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS BEGIN MENUITEM "&Show", IDC_SHOW END END 2.2.1.2. H p tho i và t o m u template cho h p tho iộ ạ ạ ẫ ộ ạ Trong ví d 2.1 trên, ta đã t o h p tho i b ng cách dùng các câu l nh ch a trong fileụ ở ạ ộ ạ ằ ệ ứ tài nguyên DIALOG1.RC. Cách làm này giúp ta hi u c u trúc l nh c a Windows, tuy nhiênể ấ ệ ủ công c ự Visual C++ Developer Studio, ta có th thi t l p m t h p tho i tr c quan h n nhể ế ậ ộ ộ ạ ự ơ ư sau : Ch n ọ Insert t th c đ n ừ ự ơ Resource View đ thêm m t h p tho i, màn hình đ c thể ộ ộ ạ ượ ể hi n nh trong hình 2.2.ệ ư Miscrosoft s hi n th h p tho i tr c quan cùng v i thanh công c đ b n có th thêmẽ ể ị ộ ạ ự ớ ụ ể ạ ể các thành ph n đi u khi n vào h p tho i. Chúng ta có th đi u ch nh các thu c tính c a h pầ ể ể ộ ạ ể ề ỉ ộ ủ ộ tho i nh tên h p tho i, ID h p tho i, ví trí hi n th c a h p tho i trên c a s chính, kíchạ ư ộ ạ ộ ạ ể ị ủ ộ ạ ử ổ th c ch và ki u ch th hi n trên h p tho i...vv b ng cách nh n chu t ph i trên h p tho iướ ữ ể ữ ể ệ ộ ạ ằ ấ ộ ả ộ ạ thì c a s ử ổ Properties c a h p tho i đ c hi n th (hình 2.3).ủ ộ ạ ượ ể ị Hình 2.2 Thêm m t Dialog trong Resource Viewộ Hình 2.3 H p tho i Properties c a Dialogộ ạ ủ Trang 29 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS Trong c a s ử ổ Properties này ch n tab ọ Styles, b m c ch n ỏ ụ ọ Title Bar và không c n t oầ ạ tiêu đ cho c a s . Sau đó đóng c a s ề ử ổ ử ổ Properties c a h p tho i l i.ủ ộ ạ ạ Bây gi b t đ u thi t k di n m o cho h p tho i. Xóa nút ờ ắ ầ ế ế ệ ạ ộ ạ Cancel vì không c n đ nầ ế nút này. Đ thêm m t bi u t ng vào h p tho i ta nh n nút ể ộ ể ượ ộ ạ ấ Picture lên thanh công c và kíchụ chu t vào h p tho i r i kéo khung ch nh t theo kích th c mong mu n. Đây là n i mà bi uộ ộ ạ ồ ữ ậ ướ ố ơ ể t ng đ c hi n th . Nh n chu t ph i vào khung ch nh t v a t o, ch n ượ ượ ể ị ấ ộ ả ữ ậ ừ ạ ọ Properties t trìnhừ đ n xu t hi n và đ nguyên đ nh danh c a bi u t ng là IDC_STATIC. Đ nh danh này sơ ấ ệ ể ị ủ ể ượ ị ẽ đ c Windowns t khai báo trong file Resource.h v i giá tr -1. Giá tr -1 là giá tr c a t t cượ ự ớ ị ị ị ủ ấ ả các đ nh danh mà ch ng trình không c n tham chi u đ n. Ti p đ n là ch n đ i t ng ị ươ ầ ế ế ế ế ọ ố ượ Icon trong trong m c ụ Type, r i gõ đ nh danh c a Icon c n thêm vào trong m c ồ ị ủ ầ ụ Image. N u đã t oế ạ ra bi u t ng Icon tr c thì ch vi c ch n Icon t danh sách các Icon trong m c Image.ể ượ ướ ỉ ệ ọ ừ ụ Đ thêm dòng ch "HELLO WORLD" vào h p tho i, ch n ể ữ ộ ạ ọ Static Text t b ng côngừ ả c và đ t đ i t ng vào h p tho i. Nh n chu t ph i đ hi n th ụ ặ ố ượ ộ ạ ấ ộ ả ể ệ ị Properties c a Static Text,ủ sau đó vào m c caption đánh dòng ch "HELLO WORD" vào đây.ụ ữ D ch và ch y ch ng trình sau đó xem file DIALOG1.RC d i d ng text, n i dung h pị ạ ươ ướ ạ ộ ộ tho i đ c Windows phát sinh nh sau :ạ ượ ư DIALOG1 DIALOG DISCARDABLE 40, 20, 164, 90 STYLE DS_MODALFRAME | WS_POPUP FONT 9, "MS Sans Serif" BEGIN DEFPUSHBUTTON "OK",IDOK,54,65,50,14 CTEXT "HELLO WORLD ",IDC_STATIC,53,38,72,10 ICON IDI_ICON1,IDC_STATIC,68,9,21,20 END Dòng đ u tiên là tên c a h p tho i "DIALOG1" k ti p là t khóa ầ ủ ộ ạ ế ế ừ DIALOG, DISCARDABLE và ti p sau đó là 4 s nguyên. Hai s nguyên đ u tiên ch v trí dòng, c t c aế ố ố ầ ỉ ị ộ ủ h p tho i s đ c hi n th trên c a s chính. Hai s nguyên ti p theo xác đ nh kích th c c aộ ạ ẽ ượ ể ị ử ổ ố ế ị ướ ủ h p tho i theo th t c t và dòng.ộ ạ ứ ự ộ L u ýư : Các thông s đ nh t a đ và kích th c c a h p tho i không tính theo đ n vố ị ọ ộ ướ ủ ộ ạ ơ ị Pixel mà tính theo kích c c a ở ủ Font ch . S đo c a t a đ x và chi u r ng d a trên 1/4 đ n vữ ố ủ ọ ộ ề ộ ự ơ ị r ng trung bình c a Font ch . S đo c a t a đ y và chi u cao d a trên 1/8 đ n v cao trungộ ủ ữ ố ủ ọ ộ ề ự ơ ị bình c a Font ch .ủ ữ Theo sau l nh ệ STYLE là các thu c tính c a h p tho i mà b n c n thêm vào. Thôngộ ủ ộ ạ ạ ầ th ng h p tho i modal s d ng các h ng ườ ộ ạ ử ụ ằ WS_POPUP và DS_MODALFRAME ngoài ra Trang 30 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS còn có các h ng ằ WS_CAPTION, WS_MAXIMIZEBOX, WS_MINIMIZEBOX, WS_POPUP, WS_VSCROLL, WS_HSCROLL, WS_SYSMENU, .... L nh ệ BEGIN và l nhệ END có th đ c thay b ng ể ượ ằ { và }. Trong ví d trên, h p tho i s d ng 3 ki u đi u khi n làụ ộ ạ ử ụ ể ề ể DEFPUSHBUTTON (ki u nút b m m c đ nh), ể ấ ặ ị ICON (bi u t ng), và ki u ể ượ ể CTEXT (văn b n đ c canh gi a). M t ki u đi u khi n đ c khai báo t ng quát nh sau.ả ượ ữ ộ ể ề ể ượ ổ ư Control-type "text", id , xPos, yPos, xWidth, yHeight, iStyle. Control-type là các t khóa khai báo ki u đi u khi n nh ừ ể ề ể ư DEFPUSHBUTTON, ICON, CTEXT, …. id là đ nh danh c a các đi u khi n, thông th ng m t đi u khi n có m tị ủ ề ể ườ ộ ề ể ộ đ nh danh riêng đ c g i cùng v i thông đi p ị ượ ở ớ ệ WM_COMMAND đ n các th t c x lý thôngế ủ ụ ử đi p c a c a s cha. ệ ủ ử ổ xPos, yPos là v trí c t, dòng hi m th c a đi u khi n đó trên c a s cha.ị ộ ể ị ủ ề ể ử ổ xWidth, yHeight là chi u r ng và chi u cao c a đi u khi n đó. Đ i s cu i cùng là ề ộ ề ủ ề ể ố ố ố iStyle, đ i s này tùy ch n dùng đ đ nh nghĩa thêm các ki u c a s mà đi u khi n c n th hi nố ố ọ ể ị ể ử ổ ề ể ầ ể ệ chúng th ng là các h ng ườ ằ WS_ đ c khai báo trong t p tin “ượ ậ .h" c a Windows.ủ 2.2.1.3. Th t c x lý thông đi p c a h p tho iủ ụ ử ệ ủ ộ ạ Th t c x lý thông đi p c a h p tho i dùng đ x lý t t c các thông đi p t bủ ụ ử ệ ủ ộ ạ ể ử ấ ả ệ ừ ộ qu n lý h p tho i c a Windows g i đ n hôp tho i. Th t c này đ c Windows g i khi có sả ộ ạ ủ ở ế ạ ủ ụ ượ ọ ự tác đ ng lên các ph n t đi u khi n n m trong h p tho i. ộ ầ ử ể ể ằ ộ ạ Xét th t c x lý h p tho i ủ ụ ử ộ ạ DialogProc trong ví d 2.1. Th t c này có 4 tham s nhụ ủ ụ ố ư th t c ủ ụ WndProc, và th t c này đ c đ nh nghĩa ki u tr v là ủ ụ ượ ị ể ả ề CALLBACK.Tuy hai thủ t c này t ng t gi ng nhau nh ng th c s gi a chúng có m t vài s khác bi t đáng chú ý.ụ ươ ự ố ư ự ự ữ ộ ự ệ  Th t c ủ ụ DialogProc tr v giá tr ki u ả ề ị ể BOOL, trong khi th t c ủ ụ WindProc thì tr v giá tr ả ề ị LRESULT.  Th t c ủ ụ DialogProc tr v giá tr ả ề ị TRUE (giá tr khác 0) n u nó x lý thôngị ế ử đi p và ng c l i n u không x lý các thông đi p thì th t c tr v giá th là ệ ượ ạ ế ử ệ ủ ụ ả ề ị FALSE (tr 0).ị Còn th t c ủ ụ WindProc thì g i hàm ọ DefWindowProc v i các thông đi p không c n x lý.ớ ệ ầ ử  Th t c ủ ụ DialogProc không c n x lý thông đi p ầ ử ệ WM_DESTROY, cũng không c n x lý thông đi p ầ ử ệ WM_PAINT và cũng không nh n đ c thông đi p ậ ượ ệ WM_CREATE mà là thông đi p ệ WM_INITDIALOG dùng đ kh i t o h p tho i.ể ở ạ ộ ạ Ngoài x lý thông đi p ử ệ WM_INITDIALOG, th t c x lý thông đi p h p tho i chủ ụ ử ệ ộ ạ ỉ x lý m t thông đi p duy nh t khác là ử ộ ệ ấ WM_COMMAND. Đây cũng là thông đi p đ c g iệ ượ ở đ n c a s cha khi ta kích ho t (nút nh n đang nh n đ c focus) lên các thành ph n đi uế ử ổ ạ ấ ậ ượ ầ ể khi n. Ch danh ID c a nút “ể ỉ ủ OK" là IDOK s đ c ch a trong word th p c a đ i sẽ ượ ứ ấ ủ ố ố wParam. Khi nút này đ c nh n, th t c ượ ấ ủ ụ DialogProc g i hàm ọ EndDialog đ k t thúc x lýể ế ử và đóng h p tho i.ộ ạ Các thông đi p g i đ n h p tho i không đi qua hàng đ i mà nó đ c Windows g iệ ử ế ộ ạ ợ ượ ọ tr c ti p hàm ự ế DialogProc đ truy n các thông đi p vào cho th t c x lý h p tho i.Vì v y,ể ề ệ ủ ụ ử ộ ạ ậ không ph i b n tâm v hi u ng c a các phím t t đ c quy đ nh trong ch ng trình chính. ả ậ ề ệ ứ ủ ắ ượ ị ươ 2.2.1.4. G i hi n th h p tho i và các v n đ liên quanọ ể ị ộ ạ ấ ề Trang 31 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS Trong th t c ủ ụ WndProc khi x lý thông đi p ử ệ WM_CREATE Windows l y v đ nhấ ề ị danh hInstance c a ch ng trình và l u nó trong bi n tĩnh hInstance nh sau.ủ ươ ư ế ư hInstance = ((LPCREATESTRUCT) lParam)->hInstance; Dialog1 ki m tra thông đi p ể ệ WM_COMMAND xem word th p c a đ i s wParam cóấ ủ ố ố b ng giá tr ằ ị IDC_SHOW (ch danh c a thành ph n ỉ ủ ầ Show trong th c đ n). N u ph i, t c đãự ơ ế ả ứ ch n m c ọ ụ Show trên trình đ n c a c a s chính và yêu c u hi n th h p tho i, lúc nàyơ ủ ử ổ ầ ể ị ộ ạ ch ng trình g i hi n th h p tho i b ng cách g i hàm. ươ ọ ể ị ộ ạ ằ ọ DialogBox (hInstance, TEXT ("DIALOG1"), hwnd, DialogProc) Đ i s đ u tiên c a hàm này ph i là hInstance c a ch ng trình g i, đ i s th hai làố ố ầ ủ ả ủ ươ ọ ố ố ứ tên c a h p tho i c n hi n th , đ i s th 3 là c a s cha mà h p tho i thu c v , cu i cùng làủ ộ ạ ầ ể ị ố ố ứ ử ổ ộ ạ ộ ề ố đ a ch c a th t c x lý các thông đi p c a h p tho i.ị ỉ ủ ủ ụ ử ệ ủ ộ ạ Ch ng trình không th tr đi u khi n v hàm ươ ể ả ề ể ề WndProc cho đ n khi h p tho i đ cế ộ ạ ượ đóng l i. Giá tr tr v c a hàm ạ ị ả ề ủ DialogBox là giá tr c a đ i s th hai trong hàm ị ủ ố ố ứ EndDialog n m bên trong th t c x lý thông đi p h p tho i. Tuy nhiên chúng ta cũng có th g i thôngằ ủ ụ ử ệ ộ ạ ể ở đi p đ n hàm ệ ế WndProc yêu c u x lý ngay c khi h p tho i đang m nh hàm ầ ử ả ộ ạ ở ờ SendMessage nh sau :ư SendMessage(GetParent(hDlg), message, wParam, lParam) Tuy Visual C++ Developer đã cung c p cho chúng ta b so n th o h p tho i tr c quanấ ộ ạ ả ộ ạ ự mà ta không c n ph i quan tâm đ n n i dung trong t p tin ầ ả ế ộ ậ .RC. Tuy nhiên v i cách thi t kớ ế ế m t h p tho i b ng các câu l nh giúp chúng ta hi u chi ti t h n c u trúc l nh c a Windowsộ ộ ạ ằ ệ ể ế ơ ấ ệ ủ h n th n a t p l nh dùng đ thi t k h p tho i phong phú và đa d ng h n r t nhi u so v iơ ế ữ ậ ệ ể ế ế ộ ạ ạ ơ ấ ề ớ nh ng gì mà ta tr c quan đ c trên b so n th o c a Developer. B ng cách s d ng các l nhữ ự ượ ộ ạ ả ủ ằ ử ụ ệ đ c bi t trong t p tin Resource editor c a Visual C++ ta có th t o ra nhi u đ i t ng màặ ệ ậ ủ ể ạ ề ố ượ trong b so n th o không có.ộ ạ ả Thêm h ng ằ WS_THINKFRAME vào m c ụ STYLE đ co gi n h p tho i (t ngể ả ộ ạ ươ đ ng v i trong boder ta ch n m c ươ ớ ọ ụ Resizing). Đ đ t n i dung tiêu đ cho h p tho i ta ch vi c thêm h ng ể ặ ộ ề ộ ạ ỉ ệ ằ WS_CAPTION trong STYLE. STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION CAPTION "Hello Dialog1" Có th dùng cách khác đ thêm tiêu đ cho h p tho i, b ng cách trong khi x lý thôngể ể ề ộ ạ ằ ử đi p ệ WM_INITDIALOG thêm vào dòng l nh:ệ SetWindowText(hDlg,TEXT("Hello Dialog")); Trang 32 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS Khi h p tho i có tiêu đ r i, có th thêm các ch c năng phóng to và thu nh h p tho iộ ạ ề ồ ể ứ ỏ ộ ạ b ng h ng ằ ằ WS_MINIMIZEBOX, WS_MAXIMIZEBOX. Có th thêm trình đ n vào h p tho i n u mu n b ng đo n l nh.ể ơ ộ ạ ế ố ằ ạ ệ DIALOG1 DIALOG DISCARDABLE 40, 20, 164, 90 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION CAPTION "Hello Dialog1" MENU MENU1 Trong đó MENU1 là tên c a trình đ n ta đã t o. Trong Visual C++ Developer ta chủ ơ ạ ỉ c n ch n tên th c đ n trong m c Menu nh hình sau.ầ ọ ự ơ ụ ư Hình 2.4 Ch n menu trong Dialog Propertierọ T c a s ừ ử ổ Properties trên th ch n m c "ể ọ ụ Font" đ đ nh Font ch cho h p tho i. ể ị ữ ộ ạ G i hàm ọ DialogBoxIndirect đ t o ra m t h p tho i mà không c n dùng resourceể ạ ộ ộ ạ ầ script. H p tho i t o ra b ng hàm này trong khi ch ng trình đang th c hi n đ c g i là h pộ ạ ạ ằ ươ ự ệ ượ ọ ộ tho i t o t đ ng.ạ ạ ự ộ Trong ví d 3-1 ta ch dùng 3 ki u đi u khi n đó là các ki u ‘ụ ỉ ể ề ể ể ICON’, ‘CTEXT’, ‘DEFPUSHBUTTON’. Ngoài ra còn có các ki u đi u khi n đ c li t kê trong b ng sau.ể ề ể ượ ệ ả Ki u đi u khi nể ề ể L p c a sớ ử ổ Ki u c a sể ử ổ PUSHBUTTON Button BS_BUSHBUTTON DEFPUSHBUTTON Button BS_DEFBUSHBUTTON | WS_TABSTOP CHECKBOX Button BS_CHECKBOX | WS_TABSTOP RADIOBUTTON Button BS_RADIOBUTTON | WS_TABSTOP GROUPBOX Button BS_GROUPBOX | WS_TABSTOP Trang 33 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS LTEXT Static SS_LEFT | WS_GROUP CTEXT Static SS_CENTER | WS_GROUP RTEXT Static SS_RIGHT | WS_GROUP ICON Static SS_ICON EDITTEXT Edit ES_LEFT | WS_BORDER | WS_STABSTOP SCROLLBAR Scrollbar SBS_HORZ LISTBOX Listbox LBS_NOTIFY | WS_BORDER | WS_VSCROLL COMBOBOX Combobox CBS_SIMPLE | WS_TABSTOP B ng 2.1 ả Các ki u đi u khi nể ề ể Các ki u đi u khi n đ c khai báo trong resource script có d ng nh sau, ngo i trể ề ể ượ ạ ư ạ ừ ki u đi u khi n ể ề ể LISTBOX, COMBOBOX, SCROLLBAR, EDITTEXT. Control-type "text", id, xPos, yPos, xWidth, yHeight, iStyle Các ki u đi u khi n ể ề ể LISTBOX, COMBOBOX, SCROLLBAR, EDITTEXT đ cượ khai báo trong resource script v i c u trúc nh trên nh ng không có tr ng "ớ ấ ư ư ườ text". Thêm thu c tính cho các ki u đi u khi n b ng cách thay đ i tham s iStyle. Ví d taộ ể ề ể ằ ổ ố ụ mu n t o ố ạ radio button v i chu i di n đ t n m bên trái c a nút thì ta gán tr ng iStyleớ ỗ ễ ạ ằ ở ủ ườ b ng ằ BS_LEFTTEXT c th nh sau.ụ ể ư RADIOBUTTON Radio1",IDC_RADIO1,106,10,53,15,BS_LEFTTEXT Trong resource script ta cũng có th t o m t ki u đi u khi n b ng l nh t ng quát sau.ể ạ ộ ể ể ể ằ ệ ổ CONTROL "text", id, "class", iStyle, xPos, yPos, xWidth, yHeight Trong đó class là tên l p mu n t o ví d thay vì t o m t ớ ố ạ ụ ạ ộ radio button b ng câu l nh.ằ ệ RADIOBUTTON "Radio1",IDC_RADIO1,106,10,53,15,BS_LEFTTEXT Thay b ng đo n l nh sau:ằ ạ ệ CONTROL"Radio1",IDC_RADIO1,"button",106,10,53,15,BS_LEFTTEXT 2.2.1.5. Ví d ch ng trình v h p tho i.ụ ươ ề ộ ạ Trang 34 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS Đ minh h a cho vi c trao đ i thông đi p gi a các thành ph n đi u khi n bên trongể ọ ệ ổ ệ ữ ầ ề ể h p tho i (đóng vai trò là m t c a s cha) v i các thành ph n đi u khi n con n m bên trongộ ạ ộ ử ồ ớ ầ ề ể ằ h p tho i, và c ch qu n lý h p tho i c a Windows. Chúng ta ti n hành xem xét ví d 2-2.ộ ạ ơ ế ả ộ ạ ủ ế ụ K t qu th c hi n c a ch ng trình nh trong hình 2.5.ế ả ự ệ ủ ươ ư C a s h p tho i g m có ba nhóm nút ch n radio.Nhóm th nh t dùng đ ch n đ iử ổ ộ ạ ồ ọ ứ ấ ể ọ ố t ng v là hình ch nh t hay hình ellipse, nhóm th hai dùng đ ch n màu tô cho hình v ,ượ ẽ ữ ậ ứ ể ọ ẽ nhóm th 3 dùng đ ch n ki u tô cho hình v . Khi thay đ i vi c ch n màu tô, ki u tô thì màuứ ể ọ ể ẽ ổ ệ ọ ể tô và ki u tô c a hình v c nh bên s thay đ i theo màu tô, và ki u tô v a m i ch n. Khiể ủ ẽ ạ ẽ ổ ể ừ ớ ọ nh n nút ấ OK thì h p tho i đóng l i và màu tô, ki u tô cùng hình v v a m i v s đ c hi nộ ạ ạ ể ẽ ừ ớ ẽ ẽ ượ ể th lên c a s chính. N u nh n nút ị ử ổ ế ấ Cancel ho c nh n phím ặ ấ Esc thì h p tho i đ c đóng l iộ ạ ượ ạ nh ng hình v , màu tô và ki u tô không đ c hi n th lên c a s chính. Trong ví d này nútư ẽ ể ượ ể ị ử ổ ụ OK và nút Cancel có ch danh ID l n l t là ỉ ầ ượ IDOK và IDCANCEL.Thông th ng đ t chườ ặ ỉ danh cho các ph n t đi u khi n n m trong h p tho i đ c b t đ u b ng ch ID. Bi uầ ử ề ể ằ ộ ạ ượ ắ ầ ằ ữ ể t ng chi c xe đ p trên h p tho i đó là m t icon. Trên thanh tiêu đ c a c a s chính có m tượ ế ạ ộ ạ ộ ề ủ ử ổ ộ bi u t ng, bi u t ng đó cũng là m t ể ượ ể ượ ộ icon (đó là m t ly trà). Khi đ t các nút ộ ặ radio vào h pộ tho i b ng công c Developer studio nh ph i đ t các nút đó theo th t nh hình 2-5. Thì khiạ ằ ụ ớ ả ặ ứ ự ư đó Windows m i phát sinh mã cho các nút đó theo th t tăng d n, đi u này giúp chúng ta dớ ứ ự ầ ề ễ dàng ki m soát các thao tác trên t p các nút radio. B n nh b luôn m c ch n ể ậ ạ ớ ỏ ụ ọ Auto trong ph n thi t l p ầ ế ậ Properties c a các nút ch n radio. B i vì các nút radio mang thu c tính ủ ọ ở ộ Auto yêu c u vi t ít mã l nh h n ng ng chúng th ng khó hi u so v i các nút không có thu c tínhầ ế ệ ơ ư ườ ể ớ ộ Auto. Ch n thu c tính ọ ộ Group, Tab stop trong ph n thi t k ầ ế ế Properties c a nút ủ OK, nút Cancel, và hai nút radio đ u tiên trong ba nhóm radio đ có th chuy n focus (ầ ể ể ể ch nọ ) b ngằ phím Tab trên bàn phím. Hình 2.5 Minh h a trao đ i thông đi p qua các đi u khi nọ ổ ệ ề ể Ch ng trình minh h a (ươ ọ Ví d 2.2ụ ) : DIALOG2.CPP (trích d n) ẫ #include #include "resource.h" LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); Trang 35 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS BOOL CALLBACK DialogProc (HWND, UINT, WPARAM, LPARAM); int iCurrentColor = IDC_BLACK, iCurrentFigure = IDC_RECT; int iCurrenBrush = IDC_HS_BDIAGONAL; void PaintWindow(HWND hwnd, int iColor, int iFigure, int iBrush) { static COLORREF crColor[8] = { RGB(0, 0, 0), RGB(0, 0, 255), RGB(0, 255, 0), RGB(0, 255, 255), RGB(255, 0, 0), RGB(255, 0, 255), RGB(255, 255, 0), RGB(255, 255, 255) } ; HBRUSH hBrush,hbrush; HDC hdc ; RECT rect ; hdc = GetDC (hwnd) ; GetClientRect (hwnd, &rect) ; if(iBrush==IDC_HS_BDIAGONAL) hbrush=CreateHatchBrush(HS_BDIAGONAL, crColor[iColor-IDC_BLACK]); if(iBrush == IDC_HS_CROSS) hbrush=CreateHatchBrush(HS_CROSS, crColor[iColor - IDC_BLACK]); if(iBrush == IDC_HS_DIAGCROSS) hbrush=CreateHatchBrush(HS_DIAGCROSS, crColor[iColor - IDC_BLACK]); if(iBrush == IDC_HS_FDIAGONAL) hbrush=CreateHatchBrush(HS_FDIAGONAL, crColor[iColor - IDC_BLACK]); if(iBrush == IDC_HS_HORIZONTAL) hbrush=CreateHatchBrush(HS_HORIZONTAL, Trang 36 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS crColor[iColor - IDC_BLACK]); if(iBrush == IDC_HS_VERTICAL) hbrush=CreateHatchBrush(HS_BDIAGONAL, crColor[iColor - IDC_BLACK]); hBrush = (HBRUSH) SelectObject (hdc, hbrush) ; if (iFigure == IDC_RECT) Rectangle (hdc, rect.left, rect.top, rect.right, rect.bottom) ; else Ellipse(hdc, rect.left, rect.top, rect.right, rect.bottom) ; DeleteObject (SelectObject (hdc, hBrush)) ; ReleaseDC (hwnd, hdc) ; } void PaintTheBlock(HWND hCtrl, int iColor, int iFigure, int iBrush) { InvalidateRect (hCtrl, NULL, TRUE) ; UpdateWindow (hCtrl) ; PaintWindow (hCtrl, iColor, iFigure,iBrush) ; } LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static HINSTANCE hInstance ; PAINTSTRUCT ps ; switch (message) { case WM_CREATE: Trang 37 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS hInstance = ((LPCREATESTRUCT) lParam)->hInstance ; return 0 ; case WM_COMMAND: switch (LOWORD (wParam)) { case IDC_SHOW: if (DialogBox (hInstance, TEXT ("DIALOG"), hwnd, DialogProc)) InvalidateRect (hwnd, NULL, TRUE) ; return 0 ; } break; case WM_PAINT: BeginPaint (hwnd, &ps) ; EndPaint (hwnd, &ps) ; PaintWindow (hwnd, iCurrentColor, iCurrentFigure, iCurrenBrush) ; return 0 ; case WM_DESTROY: PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ; } BOOL CALLBACK DialogProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { static HWND hCtrlBlock ; Trang 38 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS static int iColor, iFigure,iBrush; switch (message) { case WM_INITDIALOG: iColor = iCurrentColor ; iFigure = iCurrentFigure ; iBrush = iCurrenBrush; CheckRadioButton(hDlg,IDC_BLACK,IDC_WHITE, iColor); CheckRadioButton(hDlg,IDC_RECT,IDC_ELLIPSE,iFigure);CheckRadioButton (hDlg, IDC_HS_BDIAGONAL, IDC_HS_VERTICAL, iBrush); hCtrlBlock = GetDlgItem (hDlg, IDC_PAINT) ; SetFocus (GetDlgItem (hDlg, iColor)) ; return FALSE ; case WM_COMMAND: switch (LOWORD (wParam)) { case IDOK: iCurrentColor = iColor ; iCurrentFigure = iFigure ; iCurrenBrush = iBrush; EndDialog (hDlg, TRUE) ; return TRUE ; case IDCANCEL: EndDialog (hDlg, FALSE) ; return TRUE ; case IDC_BLACK: Trang 39 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS case IDC_RED: case IDC_GREEN: case IDC_YELLOW: case IDC_BLUE: case IDC_MAGENTA: case IDC_CYAN: case IDC_WHITE: iColor = LOWORD (wParam) ; CheckRadioButton (hDlg, IDC_BLACK, IDC_WHITE, LOWORD (wParam)) ; PaintTheBlock (hCtrlBlock, iColor, iFigure,iBrush) ; return TRUE ; case IDC_RECT: case IDC_ELLIPSE: iFigure = LOWORD (wParam) ; CheckRadioButton (hDlg, IDC_RECT, IDC_ELLIPSE, LOWORD (wParam)) ; PaintTheBlock (hCtrlBlock, iColor, iFigure,iBrush) ; return TRUE ; case IDC_HS_BDIAGONAL: case IDC_HS_CROSS: case IDC_HS_DIAGCROSS: case IDC_HS_FDIAGONAL: case IDC_HS_HORIZONTAL: case IDC_HS_VERTICAL: iBrush = LOWORD (wParam) CheckRadioButton(hDlg,IDC_HS_BDIAGONAL,IDC_HS_VERTICAL, LOWORD (wParam)) ; Trang 40 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS PaintTheBlock (hCtrlBlock, iColor, iFigure,iBrush) ; return TRUE ; } break; case WM_PAINT: PaintTheBlock (hCtrlBlock, iColor, iFigure,iBrush) ; break ; } return FALSE ; } 2.2.1.6. Làm vi c v i các thành ph n đi u khi n trong h p tho iệ ớ ầ ề ể ộ ạ Các thành ph n đi u khi n con đ u g i thông đi p ầ ề ể ề ở ệ WM_COMMAND đ n c a s chaế ử ổ c a nó và c a s cha có th thay đ i tr ng thái c a các thành ph n đi u khi n con nh kíchủ ử ổ ể ổ ạ ủ ầ ề ể ư ho t, đánh d u (ạ ấ check), b d u check (ỏ ấ uncheck) b ng cách g i các thông đi p đ n các thànhằ ở ệ ế ph n đi u khi n con n m trong nó. Tuy nhiên trong Windows đã cung c p c ch trao đ iầ ề ể ằ ấ ơ ế ổ thông đi p gi a các thành ph n đi u khi n con v i c a s cha. Chúng ta b t đ u tìm hi u cácệ ữ ầ ề ể ớ ử ổ ắ ầ ể c ch trao đ i thông đi p đó.ơ ế ổ ệ Trong ví d 2.2 m u template c a h p tho i Dialog2 đ c th hi n trong t p tin tàiụ ẫ ủ ộ ạ ượ ể ệ ậ nguyên DIALOG2.RC g m có các thành ph n. Thành ph n ồ ầ ầ GROUPBOX có tiêu đ do chúngề ta gõ vào, thành ph n này ch đ n gi n là m t khung vi n bao quanh hai nhóm nút ch n radio,ầ ỉ ơ ả ộ ề ọ và hai nhóm này hoàn toàn đ c l p v i nhau trong m i nhóm.ộ ậ ớ ỗ Khi m t trong nh ng nút radio đ c kích ho t thì c a s đi u khi n con g i thôngộ ữ ượ ạ ử ổ ề ể ở đi p ệ WM_COMMAND đ n c a s cha ( đây là h p tho i) v i word th p c a đ i sế ử ổ ở ộ ạ ớ ấ ủ ố ố wParam ch a thành ph n ID c a đi u khi n con, word cao c a đ i s wParam cho bi t mãứ ầ ủ ề ể ủ ố ố ế thông báo. Sau cùng là đ i s lParam mang handle c a c a s đi u khi n con. Mã thông báoố ố ủ ử ổ ề ể c a nút ch n radio luôn luôn là ủ ọ BN_CLICKED (mang giá tr 0). Windows s chuy n thôngị ẽ ể đi p ệ WM_COMMAND cùng v i các đ i s wParam và lParam đ n th t c x lý thông đi pớ ố ố ế ủ ụ ử ệ c a h p tho i (ủ ộ ạ DialogProc). Khi h p tho i nh n đ c thông đi p ộ ạ ậ ượ ệ WM_COMMAND cùng v i các đ i s lParam và wParam, h p tho i ki m tra tr ng thái c a t t c các thành ph nớ ố ố ộ ạ ể ạ ủ ấ ả ầ đi u khi n con n m trong nó và thi t l p các tr ng thái cho các thành ph n đi u khi n conề ể ằ ế ậ ạ ầ ề ể này. Có th đánh d u m t nút ch n b ng cách g i thông đi p ể ấ ộ ọ ằ ở ệ SendMessage (hwndCtrl ,MB_SETCHECK, 1, 0); Trang 41 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS Và ng c l i mu n b ch n m t nút nào đó thì dùng hàm.ượ ạ ố ỏ ọ ộ SendMessage (hwndCtrl, MB_SETCHECK, 0, 0); Trong đó đ i s hwndCtrl là handle c a c a s đi u khi n con.ố ố ủ ử ổ ề ể Chúng ta có th g p r c r i khi mu n s d ng hai hàm trên b i vì không bi t handleể ặ ắ ố ố ử ụ ở ế c a các thành ph n đi u khi n con. Chúng ta ch bi t handle c a các thành ph n đi u khi nủ ầ ề ể ỉ ế ủ ầ ề ể con khi nh n đ c thông đi p ậ ượ ệ WM_COMMAND. Đ gi i quy t đ c v ng m c trên,ể ả ế ượ ướ ắ trong Windows cung c p m t hàm đ l y handle c a c a s con khi bi t đ c đ nh danh IDấ ộ ể ấ ủ ử ổ ế ượ ị c a nó b ng hàm.ủ ằ hwndCtrl = GetDlgItem (hDlg, id); // hDlg là handle c a h p tho i ủ ộ ạ Có th l y đ c ch danh ID c a thành ph n đi u khi n con khi bi t đ c handle c aể ấ ượ ỉ ủ ầ ề ể ế ượ ủ nó b ng hàm sau.ằ id = GetWindowLong (hwndCtrl, GWL_ID); Tuy nhiên, chúng ta có th qu n lý ID c a các thành ph n đi u khi n con, còn handleể ả ủ ầ ề ể là do Windows c p ng u nhiên, do đó vi c dùng handle đ nh n v ID c a các thành ph nấ ẫ ệ ể ậ ề ủ ầ đi u khi n con là ít dùng đ n.ề ể ế Khi h p tho i nh n đ c thông đi p ộ ạ ậ ượ ệ WM_COMAND thì chúng ta ph i ki m tra nútả ể radio nào đ c ch n (xác đ nh màu c n ch n), và ti n hành b ch n các nút khác b ng đo nượ ọ ị ầ ọ ế ỏ ọ ằ ạ l nh sau. ệ case WM_COMMAND: switch (LOWORD (wParam)) { case IDC_BLACK: case IDC_RED: case IDC_GREEN: case IDC_YELLOW: case IDC_BLUE: case IDC_MAGENTA: case IDC_CYAN: case IDC_WHITE: Trang 42 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS iColor = LOWORD (wParam) ; for( i = IDC_BLACK, i < IDC_WHITE,i++) SendMessage(GetDlgItem(hDlg, i),MB_SETCHECK, i == LOWORD( wParam), 0). return TRUE ; } Trong đó iColor dùng đ l u giá tr màu hi n hành đ c ch n. Vòng l p for dùng để ư ị ệ ượ ọ ặ ể ki m tra tr ng thái c a t t c các nút radio thông qua ID c a chúng. Hàm ể ạ ủ ấ ả ủ GetDlgItem dùng để l y handle c a nút đ c ch n và l u vào bi n i. Hàm ấ ủ ượ ọ ư ế SendMessage dùng đ g i thông đi pể ở ệ MB_SETCHECK t i các nút radio. N u word th p c a đ i s wParam b ng ch danh ID c aớ ế ấ ủ ố ố ằ ỉ ủ nút đ c ch n thì nút đó đ c đánh d u và các nút khác s không đ c ch n.ượ ọ ượ ấ ẽ ượ ọ Chú ý :Trong các ví d trên th ng dùng hai nút ụ ườ OK và nút Cancel, hai nút này đ cượ Windows đ t đ nh danh m c đ nh theo th t là ặ ị ặ ị ứ ự IDOK và IDCANCEL. Thông th ng đóngườ h p tho i b ng cách nh n chu t vào m t trong hai nút ộ ạ ằ ấ ộ ộ OK ho c ặ Cancel. Trong Windows, khi nh n nút Enter thì Windows luôn phát sinh thông đi p ấ ệ WM_COMMAND, b t kỳ đ i t ngấ ố ượ nào đang nh n focus. ậ LOWORD c a đ i s wParam mang giá tr ID c a nút nh n m c đ nhủ ố ố ị ủ ấ ặ ị (nút OK), ngoài tr có m t nút đang nh n focus (trong tr ng h p này thì ừ ộ ậ ườ ợ LOWORD c a đ iủ ố s wParam mang ch danh c a nút đang nh n focus). N u nh n nút ố ỉ ủ ậ ế ấ Esc hay nh n ấ Ctrl+Break, thì Windows g i thông đi p ở ệ WM_COMMAND v i thành ph n ớ ầ LOWORD c a đ i sủ ố ố wParam có giá tr ị IDCANCEL (đ nh danh m c đ nh c a nút ị ặ ị ủ Cancel). Do đó không c n ph iầ ả x lý thêm các phím gõ đ đóng h p tho i.ử ể ộ ạ Trong ví d 2.2 đ x lý hai tr ng h p khi nh n nút ụ ể ử ườ ợ ấ Cancel và nút OK ta dùng đo nạ ch ng trình sau.ươ switch (LOWORD (wParam)) { case IDOK: iCurrentColor = iColor ; iCurrentFigure = iFigure ; EndDialog (hDlg, TRUE) ; return TRUE ; case IDCANCEL: EndDialog (hDlg, FALSE) ; return TRUE ; Trang 43 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS … } Hàm EndDialog dùng đ k t thúc và đóng h p tho i.Trong tr ng h p nh n nút ể ế ộ ạ ườ ợ ấ OK thì hai giá tr iCurrentColor và giá tr iCurrentFigure đ c l u l i cho c a s cha (c hai bi nị ị ượ ư ạ ử ổ ả ế trên đ u là bi n toàn c c). Chú ý r ng, hai giá tr khác bi t (TRUE, FALSE) c a đ i s th haiề ế ụ ằ ị ệ ủ ố ố ứ trong l i g i hàm ờ ọ EndDialog. Giá tr này s đ c tr ng c v t l i g i hàm ị ẽ ượ ả ượ ề ừ ờ ọ DialogBox trong th t c ủ ụ WndProc. case WM_COMMAND: switch (LOWORD(wParam)) { case IDC_SHOW: if(DialogBox(hInstance, TEXT("DIALOG"), hwnd, DialogProc)) InvalidateRect (hwnd, NULL, TRUE) ; return 0 ; } break; Có nghĩa n u hàm ế DialogBox tr v giá tr TRUE, t c nút ả ề ị ứ OK đ c nh n. Lúc đó thượ ấ ủ t c ụ WndProc s c p nh t l i n i dung c a c a s chính, b ng cách ghi l i s thay đ i giá trẽ ậ ậ ạ ộ ủ ử ổ ằ ạ ự ổ ị c a hai bi n toàn c c iCurrentColor và giá tr iCurrentFigure dùng đ v l i hình ch nh t hayủ ế ụ ị ể ẽ ạ ữ ậ hình ellipse v i màu đ c ch n là iCurrentColor.ớ ượ ọ Và ng c l i n u nh n nút ượ ạ ế ấ Cancel thì giá tr iCurrentColor và giá tr iCurrentFigure sị ị ẽ không thay đ i, t c th t c ổ ứ ủ ụ WndProc s d ng l i giá tr cũ.ử ụ ạ ị Giá tr TRUE hay FALSE thông báo cho c a s chính bi t r ng ng i dùng t ch i hayị ử ổ ế ằ ườ ừ ố ch p thu n tùy ch n trong h p tho i. Vì TRUE và FALSE có ki u s nguyên (1,0) nên đ i sấ ậ ọ ộ ạ ể ố ố ố th hai trong l i g i hàm ứ ờ ọ EndDialog có ki u s nguyên (ể ố int). Do đó k t qu tr v c a hàmế ả ả ề ủ này cũng có ki u là s nguyên. Ví d n u b n b m nút ể ố ụ ế ạ ấ OK thì tr tr v c a hàm b ng 1. N uị ả ề ủ ằ ế b n b m nút ạ ấ Cancel thì tr tr v c a hàm b ng 0, và n u trong ch ng trình có s d ng nútị ả ề ủ ằ ế ươ ử ụ b m m c đ nh ấ ặ ị Inoge thì khi b m nút này tr tr c a hàm s là 2.ấ ị ả ủ ẽ 2.2.1.7. V trong h p tho iẽ ộ ạ Trong ví d 2.2 chúng ta đã dùng ph ng pháp v trên h p tho i đây là công vi c khácụ ươ ẽ ộ ạ ệ th ng. Bây gi ta tìm hi u công vi c đó ti n hành nh th nào.ườ ờ ể ệ ế ư ế Trong file RESOURCE.RC có thành ph n đi u khi n là.ầ ề ể Trang 44 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS LTEXT "",IDC_PAINT, 5, 22, 92, 93 Khi chúng ta ch n nút radio đ thay đ i màu, hình v hay nh n đ c thông đi pọ ể ổ ẽ ậ ượ ệ WM_PAINT thì th t c ủ ụ DialogProc th c hi n thao tác v vào thành ph n đi u khi n c aự ệ ẽ ầ ề ể ủ h p tho i b ng hàm ộ ạ ằ PaintTheBlock. Hàm này đ c khai báo nh sau.ượ ư PaintTheBlock(hCtrBlock, iColor, iFigure); Trong đó hCtrBlock là handle c a thành ph n đi u khi n có đ nh danh là ủ ầ ề ể ị IDC_PAINT. Handle c a thành ph n đi u khi n này đ c l y v b i hàm.ủ ầ ề ể ượ ấ ề ở hCtrBlock=GetDlgItem(hDlg, IDC_PAINT); N i dung c a hàm ộ ủ PaintTheBlock nh sau.ư void PaintTheBlock(HWND hCtrl, int iColor, int iFigure) { InvalidateRect(hCtrl, NULL, TRUE); UpdateWinDow(hCtrl); PaintWinDow(hCtrl, iColor, iFigure); } Hàm InvalidateRect(hCtrl, NULL, TRUE) và UpdateWindow(hCtrl) có nhi m v làmệ ụ cho c a s con c n ph i v l i. Hàm PaintWindow dùng đ v ra màn hình ellipse hay chử ổ ầ ả ẽ ạ ể ẽ ữ nh t. Đ u tiên hàm này l y ậ ầ ấ DC (device context) c a thi t b có handle là hCtrl, và v lên thi tủ ế ị ẽ ế b này d ng hình nh cùng v i màu tô đ c ch n. Kích th c c a c a s con c n v đ cị ạ ả ớ ượ ọ ướ ủ ử ổ ầ ẽ ượ l y b ng hàm ấ ằ GetClientRect.Hàm này tr v kích th c c a vùng client c n v theo đ n vả ề ướ ủ ầ ẽ ơ ị tính là pixel. Chúng ta v trên vùng client c a các đi u khi n con ch không v tr c ti p lên vùngẽ ủ ề ể ứ ẽ ự ế client c a h p tho i. Khi h p tho i nh n đ c thông đi p ủ ộ ạ ộ ạ ậ ượ ệ WM_PAINT thì thành ph n đi uầ ề khi n có đ nh danh ể ị IDC_PAINT đ c v l i. Cách x lý thông đi p ượ ẽ ạ ử ệ WM_PAINT gi ng nhố ư th t c x lý ủ ụ ử WndProc c a c a s chính, nh ng th t c x lý h p tho i không g i hàmủ ử ổ ư ủ ụ ử ộ ạ ọ BeginPaint và hàm EndPaint b i vì nó không t v lên c a s c a chính nó. ở ự ẽ ử ổ ủ N u mu n vô hi u hóa m t ph n t đi u ki n, t c bi n đ i nút sang tr ng thái vôế ố ệ ộ ầ ử ề ể ứ ế ổ ạ hi u hóa thì dùng hàm.ệ EnableWindow(hwndCtrl, bEnable); Đ i s hwndCtrl là ch danh c a thành ph n đi u khi n mu n vô hi u hóa, thành ph nố ố ỉ ủ ầ ề ể ố ệ ầ th hai là bEnable mang hai giá tr TRUE hay FALSE, n u thành ph n này mang giá tr FALSEứ ị ế ầ ị Trang 45 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS thì đi u khi n này đ c vô hi u hóa, còn ng c l i n u thành ph n này mang giá tr TRUEề ể ượ ệ ượ ạ ế ầ ị thì đi u khi n đó có hi u hóa tr l i.ề ể ệ ở ạ 2.2.2. H p tho i không tr ng thái ộ ạ ạ Trong ph n trên đã th o lu n lo i h p tho i, th nh t đó là h p tho i tr ng thái, vàầ ả ậ ạ ộ ạ ứ ấ ộ ạ ạ bây gi ti p t c th o lu n đ n lo i h p tho i th hai, h p tho i không tr ng thái (modeless).ờ ế ụ ả ậ ế ạ ộ ạ ứ ộ ạ ạ Đ hi u rõ cách s d ng cũng nh nh ng thao tác trên h p tho i không tr ng thái, chúng taể ể ử ụ ư ữ ộ ạ ạ th t tìm hi u qua các m c sau.ứ ự ể ụ 2.2.2.1. S khác nhau gi a h p tho i tr ng thái và h p tho i không tr ng thái ự ữ ộ ạ ạ ộ ạ ạ H p tho i không tr ng thái khác v i h p tho i tr ng thái ch . Sau khi hi n th h pộ ạ ạ ớ ộ ạ ạ ở ỗ ể ị ộ tho i không tr ng thái chúng ta có th chuy n thao tác đ n các c a s khác mà không c nạ ạ ể ể ế ử ổ ầ đóng h p tho i d ng này l i. Đi u này thu n ti n đ i v i ng i dùng khi ng i dùng mu nộ ạ ạ ạ ề ậ ệ ố ớ ườ ườ ố tr c quan các s thao tác cùng m t lúc. Ví d nh trình so n th o Studio Deverloper b n cóự ổ ộ ụ ư ở ạ ả ạ th thao tác qua l i gi a hai h p tho i, đó là h p tho i b n c n thi t k và m t h p tho iể ạ ữ ộ ạ ộ ạ ạ ầ ế ế ộ ộ ạ ch a các lo i đi u khi n mà b n dùng đ thi t k . V i cách làm này giúp ng i dùng tr cứ ạ ề ể ạ ể ế ế ớ ườ ự quan h n so v i cách ch cho phép ng i dùng ch thao tác trên m t c a s .ơ ớ ỉ ườ ỉ ộ ử ổ S d ng hàm ử ụ DialogBox đ g i h p tho i tr ng thái và ch nh n đ c k t qu tr vể ọ ộ ạ ạ ỉ ậ ượ ế ả ả ề khi h p tho i này b đóng cùng v i hàm ộ ạ ị ớ DialogBox k t thúc. Giá tr tr v c a hàm này do đ iế ị ả ề ủ ố s th hai c a hàm k t thúc h p tho i (ố ứ ủ ế ộ ạ EndDialog) quy đ nh. Còn đ i v i h p tho i khôngị ố ớ ộ ạ tr ng thái thì đ c t o ra b ng hàm.ạ ượ ạ ằ hDlgModeless=CreateDialog(hInstance, szTemplate, hwndParent, DialogProc); Nh ng hàm này tr quy n đi u khi n v cho n i g i ngay l p t c và giá tr trà v làư ả ề ề ể ề ơ ọ ậ ứ ị ề handle c a c a h p tho i hi n hành. Vì có th có nhi u c a s thao tác cùng m t lúc nên b nủ ủ ộ ạ ệ ể ề ử ổ ộ ạ l c handle này đ d dàng truy c p khi b n c n.ư ể ễ ậ ạ ầ Ph i đ t ch đ ả ặ ế ộWS_VISIBLE cho h p tho i không tr ng thái, b ng cách ch n m cộ ạ ạ ằ ọ ụ More Styles trong c a s Properties c a h p tho i. N u nh không b t ch đ ử ổ ủ ộ ạ ế ư ậ ế ộ VISIBLE lên thì ch ng trình ph i có câu l nh ươ ả ệ ShowWindow sau l i g i hàm ờ ọ CreateDialog khi mu n hi nố ể th h p tho i d ng này lên màn hình. ị ộ ạ ạ hDlgModeless=CreateDialog(hInstance, szTemplate, hwndParent, DialogProc); ShowWindow(hDlgModeless,SW_SHOW); Các thông đi p g i đ n h p tho i d ng modal do trình qu n lý Windows đi u khi nệ ở ế ộ ạ ạ ả ề ể cũng khác v i các thông đi p g i đ n h p tho i d ng modeless ph i đi qua h ng đ i c aớ ệ ở ế ộ ạ ạ ả ằ ợ ủ ch ng trình chính. B i vì các thông đi p c a h p tho i d ng modeless dùng chung v i cácươ ở ệ ủ ộ ạ ạ ớ thông đi p c a c a s ch ng trình chính. Nh v y chúng ta ph i l c ra thông đi p nào làệ ủ ử ổ ươ ư ậ ả ọ ệ thông đi p g i đ n h p tho i khi thao tác trên h p tho i t trong vòng l p nh n thông đi p.ệ ở ế ộ ạ ộ ạ ừ ặ ậ ệ Trang 46 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS Đ làm đ c đi u này chúng ta dùng handle c a h p tho i (l u trong bi n toàn c c) đ c trể ượ ề ủ ộ ạ ư ế ụ ượ ả v t l i g i hàm ề ừ ờ ọ CreateDialog và chuy n h ng chúng b ng đo n l nh nh sau.ể ướ ằ ạ ệ ư while(GetMessage(&msg, NULL, 0, 0)) { if (hDlgModeless==0 || !IsDialogMessage (hDlgModeless, &msg); { TranslateMessage(&msg); DispatchMessage(&msg); } } N u thông đi p l y ra t h ng đ i dành cho h p tho i thì hàm ế ệ ấ ừ ằ ợ ộ ạ IsDialogMessage ki mể tra và g i đ n các th t c x lý h p tho i. Và lúc này hàm tr v giá tr TRUE, còn ng c l iở ế ủ ụ ử ộ ạ ả ề ị ượ ạ thì hàm tr v giá tr FALSE. N u dùng thêm ch c năng phím tăng t c thì đo n ch ng ả ề ị ế ứ ố ạ ươ trình trên đ c vi t l i nh sau.ượ ế ạ ư while(GetMessage(&msg, NULL, 0, 0)) { if (hDlgModeless==0 || !IsDialogMessage(hDlgModeless, &msg); { if(TranslateAccelerator (hwnd, hAccel, &msg) { TranslateMessage(&msg); DispatchMessage(&msg); } } } Nên chú ý r ng bi n hDlgModeless luôn mang giá tr 0 cho đ n lúc có m t h p tho iằ ế ị ế ộ ộ ạ đ c kh i t o b ng câu l nh ượ ở ạ ằ ệ CreateDialog thì giá tr c a nó m i đ c thay đ i. Khi c a sị ủ ớ ượ ổ ử ổ h p tho i b h y nh đ t hDlgModeless v giá tr 0. Đi u này giúp Windows không g i nh mộ ạ ị ủ ớ ặ ề ị ề ở ầ thông đi p x lý đ n các c a s khác. Đ k t thúc và đóng h p tho i d ng Modeless b nệ ử ế ử ổ ể ế ộ ạ ạ ạ dùng hàm DestroyWindow ch không ph i dùng hàm ứ ả EndDialog nh h p tho i d ng Modal.ư ộ ạ ạ Trang 47 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS 2.2.2.2. Ví d v h p tho i không không tr ng tháiụ ề ộ ạ ạ Đ minh h a cách dùng h p tho i không tr ng thái (ể ọ ộ ạ ạ modeless) ta xét ví d 2.3. Ch ngụ ươ trình ví d 2.3 sau khi ch y có k t qu nh sau.ụ ạ ế ả ư Hình 2.6 Minh h a h p tho i không tr ng tháiọ ộ ạ ạ Khi dùng chu t đ ch n lo i hình v trên radio button, lo i hình v đ c ch n s vộ ể ọ ạ ẽ ạ ẽ ượ ọ ẽ ẽ cùng lúc lên control tĩnh c a h p tho i và c a s chính. Dùng chu t đ ch n màu tô cho hìnhủ ộ ạ ử ổ ộ ể ọ v đ c ch n, b ng cách rê chu t lên 3 thanh cu n ẽ ượ ọ ằ ộ ộ Scrollbar. Ch ng trình minh h a ươ ọ (Ví d 2.3)ụ : *: MODELESS.CPP (trích d n) ẫ void PaintWindow (HWND hwnd, int iColor[], int iFigure) { HBRUSH hBrush ; HDC hdc ; RECT rect ; hdc = GetDC(hwnd) ; GetClientRect (hwnd, &rect) ; hBrush = CreateSolidBrush(RGB(iColor[0], iColor[1], iColor[2])); hBrush = (HBRUSH) SelectObject (hdc, hBrush) ; if (iFigure == IDC_RECT) Rectangle (hdc, rect.left, rect.top, rect.right, rect.bottom) ; Trang 48 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS else Ellipse(hdc, rect.left, rect.top, rect.right, rect.bottom) ; DeleteObject (SelectObject (hdc, hBrush)) ; ReleaseDC (hwnd, hdc) ; } LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_PAINT: PaintTheBlock(hwnd, iColor, iFigure) ; return 0 ; case WM_DESTROY : DeleteObject((HGDIOBJ)SetClassLong(hwnd, GCL_HBRBACKGROUND,(LONG)GetStockObject (WHITE_BRUSH))) ; PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ; } void PaintTheBlock (HWND hCtrl, int iColor[], int iFigure) { InvalidateRect (hCtrl, NULL, TRUE); UpdateWindow (hCtrl) ; PaintWindow (hCtrl, iColor, iFigure) ; } Trang 49 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS BOOL CALLBACK ColorScrDlg (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { HWND hwndParent, hCtrl ; static HWND hCtrlBlock ; int iCtrlID, iIndex ; switch (message) { case WM_INITDIALOG : hCtrlBlock = GetDlgItem (hDlg, IDC_PAINT) ; for (iCtrlID = 10 ; iCtrlID < 13 ; iCtrlID++) { hCtrl = GetDlgItem (hDlg, iCtrlID) ; PaintTheBlock (hCtrlBlock, iColor, iFigure) ; PaintTheBlock (hwndParent, iColor, iFigure) ; SetScrollRange (hCtrl, SB_CTL, 0, 255, FALSE) ; SetScrollPos(hCtrl, SB_CTL, 0, FALSE) ; } return TRUE ; case WM_COMMAND: { switch( LOWORD(wParam)) { case IDC_RECT: case IDC_ELLIPSE: iFigure = LOWORD(wParam) ; hwndParent = GetParent (hDlg) ; Trang 50 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS CheckRadioButton(hDlg, IDC_RECT, IDC_ELLIPSE, LOWORD (wParam)) ; PaintTheBlock(hCtrlBlock, iColor, iFigure) ; PaintTheBlock (hwndParent, iColor, iFigure) ; return TRUE ; } break; } case WM_VSCROLL : hCtrl = (HWND) lParam ; iCtrlID = GetWindowLong (hCtrl, GWL_ID) ; iIndex = iCtrlID - 10 ; hwndParent = GetParent (hDlg) ; PaintTheBlock (hCtrlBlock, iColor, iFigure) ; PaintTheBlock (hwndParent, iColor, iFigure) ; switch (LOWORD (wParam)) { case SB_PAGEDOWN : iColor[iIndex] += 15 ; case SB_LINEDOWN : iColor[iIndex] = min (255, iColor[iIndex] + 1) ; break; case SB_PAGEUP : iColor[iIndex] -= 15 ; case SB_LINEUP : iColor[iIndex] = max (0, iColor[iIndex] - 1); break; Trang 51 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS case SB_TOP : iColor[iIndex] = 0 ; break; case SB_BOTTOM : iColor[iIndex] = 255 ; break; case SB_THUMBPOSITION : case SB_THUMBTRACK : iColor[iIndex] = HIWORD (wParam) ; break; default : return FALSE ; } SetScrollPos(hCtrl, SB_CTL, iColor[iIndex], TRUE) ; SetDlgItemInt (hDlg, iCtrlID + 3, iColor[iIndex], FALSE) ; InvalidateRect(hwndParent,NULL,TRUE); DeleteObject ( (HGDIOBJ)SetClassLong( hwndParent, GCL_HBRBACKGROUND, (LONG) CreateSolidBrush( RGB(iColor[0], iColor[1], iColor[2]) ) ) ) ; return TRUE ; case WM_PAINT: PaintTheBlock(hCtrlBlock, iColor, iFigure) ; break; } return FALSE ; } Trang 52 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS 2.3. MENU Trong giao di n ng d ng Windows, thành ph n quan tr ng th ng không th thi u làệ ứ ụ ầ ọ ườ ể ế menu c a ch ng trình. Menu xu t hi n ngay d i thanh tiêu đ c a ch ng trình ng d ng.ủ ươ ấ ệ ướ ề ủ ươ ứ ụ Ngoài ra trong m t s ng d ng thanh menu có th di chuy n đ c.ộ ố ứ ụ ể ể ượ Th t ra menu cũng khá đ n gi n, vì chúng đ c t ch c thành các nhóm trên thanhậ ơ ả ượ ổ ứ chính (File, Edit, View,…), m i m c li t kê trong menu chính có th ch a m t hay nhi u m cỗ ụ ệ ể ứ ộ ề ụ li t kê g i là ệ ọ menu popup hay dropdown, và v i m i m c li t kê trong menu popup này cóớ ỗ ụ ệ th có các m c con c a nó,….ể ụ ủ Các m c li t kê trên menu có th dùng đ kích ho t m t l nh, hay ch n tr ng tháiụ ệ ể ể ạ ộ ệ ọ ạ (check, uncheck). Các m c li t kê trên menu có 3 d ng: có hi u l c (ụ ệ ạ ệ ự enabled), không có hi uệ l c (ự disabled), và màu xám (grayed). V i quan đi m l p trình thì ta ch c n hai tr ng thái là cóớ ể ậ ỉ ầ ạ hi u l c và không có hi u l c mà thôi, do đó tr ng thái màu xám s ch cho ng i dùng bi t làệ ự ệ ự ạ ẽ ỉ ườ ế tr ng thái c a m c li t kê có hi u l c hay không. Vì v y khi vi t ch ng trình nh ng m cạ ủ ụ ệ ệ ự ậ ế ươ ữ ụ nào không có hi u l c thì ta thi t l p tr ng thái màu xám, khi đó ng i dùng s bi t r ng m cệ ự ế ậ ạ ườ ẽ ế ằ ụ li t kê đó không có hi u l c.ệ ệ ự 2.3.1. Thi t l p Menuế ậ Đ t o m t menu và đ a vào ch ng trình bao g m các b c sau:ể ạ ộ ư ươ ồ ướ *T o menu trong t p tin tài nguyên ạ ậ *.RC: Đ t o menu trong t p tin tài nguyên,ể ạ ậ th ng có 2 cách chính là: dùng m t trình so n th o đ m t p tin tài nguyên và so n th oườ ộ ạ ả ể ở ậ ạ ả theo c u trúc t p tin RC cung c p cho tài nguyên menu. Thông th ng, cách này ít s d ng, vìấ ậ ấ ườ ử ụ các môi tr ng phát tri n C trên Windows (ườ ể Borland C for Windows, Visual C) đ u cung c pề ấ các công c cho phép t o menu m t cách d dàng.ụ ạ ộ ễ *Cài đ t ặ menu vào c a s c a ch ng trình ng d ng: ph n này đ n gi n là khi đ nhử ổ ủ ươ ứ ụ ầ ơ ả ị nghĩa l p c a s ta thi t l p thu c tính lpszMenuName c a c u trúc l p ớ ử ổ ế ậ ộ ủ ấ ớ WNDCLASS b ngằ tên menu đ c khai báo trong t p tin tài nguyên. ượ ậ Ví d : wndclass.lpszMenuName = "MENU1";ụ Ngoài ra, có th cài đ t menu vào c a s b ng cách dùng l nh :ể ặ ử ổ ằ ệ hMenu = LoadMenu ( hInstance, TEXT("MENU1") ); L nh này s tr v m t đ nh danh c a menu đ c n p, khi có đ c đ nh danh menuệ ẽ ả ề ộ ị ủ ượ ạ ượ ị này thì khi đ a vào c a s có 2 cách sau:ư ử ổ *Trong hàm t o c a s ạ ử ổ CreateWindow, tham s th 9 c a hàm là đ nh danh cho menu,ố ứ ủ ị thi t l p tham s này là đ nh danh c a ế ậ ố ị ủ menu v a t o. ừ ạ Trang 53 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS hwnd = CreateWindow ( TEXT("MyClass"), TEXT("Window Caption"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, hMenu, hInstance, NULL ); *Khi g i hàm t o c a s ọ ạ ử ổ CreateWindow, tham s th 9 đ c thi t l p NULL, sau đóố ứ ượ ế ậ trong ch ng trình dùng l nh: ươ ệ SetMenu(hWnd, hMenu); đ thi t l p menu cho c a s .ể ế ậ ử ổ *Thêm các đo n ch ng trình x lý menu: Windows phát sinh thông đi pạ ươ ử ệ WM_COMMAND và g i đ n ch ng trình khi ng i dùng ch n m t m c li t kê có hi u l cở ế ươ ườ ọ ộ ụ ệ ệ ự trên thanh menu. Khi đó ch c n x lý thông đi p ỉ ầ ử ệ WM_COMMAND b ng cách ki m tra 16ằ ể bit th p c a tham s wParam là xác đ nh đ c ID c a m c li t kê nào trên menu đ c ch n.ấ ủ ố ị ượ ủ ụ ệ ượ ọ 2.3.2. Ví d minh h a Menuụ ọ *T p tin tài nguyên ch a khai báo menu : ậ ứ MENUDEMO.RC MENUDEMO MENU DISCARDABLE BEGIN POPUP "&File" BEGIN MENUITEM "&New", IDM_FILE_NEW MENUITEM "&Open", IDM_FILE_OPEN MENUITEM "&Save", IDM_FILE_SAVE MENUITEM "Save &As...", IDM_FILE_SAVE_AS MENUITEM SEPARATOR MENUITEM "E&xit", IDM_APP_EXIT END POPUP "&Edit" BEGIN MENUITEM "&Undo", IDM_EDIT_UNDO MENUITEM SEPARATOR MENUITEM "C&ut", IDM_EDIT_CUT MENUITEM "&Copy", IDM_EDIT_COPY Trang 54 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS MENUITEM "&Paste", IDM_EDIT_PASTE MENUITEM "De&lete", IDM_EDIT_CLEAR END POPUP "&Background" BEGIN MENUITEM "&White", IDM_BKGND_WHITE, CHECKED MENUITEM "&Light Gray", IDM_BKGND_LTGRAY MENUITEM "&Gray", IDM_BKGND_GRAY MENUITEM "&Dark Gray", IDM_BKGND_DKGRAY MENUITEM "&Black", IDM_BKGND_BLACK END POPUP "&Help" BEGIN MENUITEM "&Help...", IDM_APP_HELP MENUITEM "&About ...", IDM_APP_ABOUT END END *T p tin tiêu đ ch a các đ nh nghĩa : ậ ề ứ ị MENUDEMO.H #define IDM_FILE_NEW 40001 #define IDM_FILE_OPEN 40002 #define IDM_FILE_SAVE 40003 #define IDM_FILE_SAVE_AS 40004 #define IDM_APP_EXIT 40005 #define IDM_EDIT_UNDO 40006 #define IDM_EDIT_CUT 40007 #define IDM_EDIT_COPY 40008 Trang 55 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS #define IDM_EDIT_PASTE 40009 #define IDM_EDIT_CLEAR 40010 #define IDM_BKGND_WHITE 40011 #define IDM_BKGND_LTGRAY 40012 #define IDM_BKGND_GRAY 40013 #define IDM_BKGND_DKGRAY 40014 #define IDM_BKGND_BLACK 40015 #define IDM_APP_HELP 40018 #define IDM_APP_ABOUT 40019 *T p tin ch a mã ngu n : ậ ứ ồ MENUDEMO.C #include #include "menudemo.h" LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); /* Khai báo tên dùng chung cho cáctài nguyên trong ch ng trình.*/ươ TCHAR szAppName[] = TEXT ("MenuDemo") ; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { HWND hwnd; MSG msg; WNDCLASS wndclass; wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = hInstance ; wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); Trang 56 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH) ; wndclass.lpszMenuName = szAppName ; wndclass.lpszClassName = szAppName ; if (!RegisterClass (&wndclass)) { MessageBox(NULL, TEXT("This program requires Windows "), szAppName, MB_ICONERROR) ; return 0 ; } hwnd = CreateWindow (szAppName, TEXT("Menu Demonstration"), WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL) ; ShowWindow (hwnd, iCmdShow) ; UpdateWindow (hwnd) ; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } return msg.wParam ; } LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { /* Khao báo danh sách các màu ch i tô, các h ng này đ c đ nh nghĩa trong file WINGDI.H */ ỗ ằ ượ ị static int idColor[5] = { WHITE_BRUSH, LTGRAY_BRUSH, GRAY_BRUSH, DKGRAY_BRUSH, BLACK_BRUSH } ; Trang 57 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS static int iSelection = IDM_BKGND_WHITE ; HMENU hMenu ; switch (message) { case WM_COMMAND: hMenu = GetMenu (hwnd) ; // L y đ nh danh c a menuấ ị ủ switch (LOWORD (wParam)) // Ki m tra đ nh danh m c ch n ể ị ụ ọ { case IDM_FILE_NEW: case IDM_FILE_OPEN: case IDM_FILE_SAVE: case IDM_FILE_SAVE_AS: MessageBeep(0) ; //Phát ra ti ng kêu bípế return 0 ; case IDM_APP_EXIT: /*G i thông đi p đ đóng ng d ng l i*/ở ệ ể ứ ụ ạ SendMessage (hwnd, WM_CLOSE, 0, 0) ; return 0 ; case IDM_EDIT_UNDO: case IDM_EDIT_CUT: case IDM_EDIT_COPY: case IDM_EDIT_PASTE: case IDM_EDIT_CLEAR: MessageBeep (0) ; return 0 ; case IDM_BKGND_WHITE: Trang 58 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS case IDM_BKGND_LTGRAY: case IDM_BKGND_GRAY: case IDM_BKGND_DKGRAY: case IDM_BKGND_BLACK: /* B check c a m c ch n tr c đó*/ ỏ ủ ụ ọ ướ CheckMenuItem(hMenu,iSelection, MF_UNCHECKED); iSelection = LOWORD (wParam) ; /*L y ID m c m i*/ấ ụ ớ /* Check m c ch n m i*/ụ ọ ớ CheckMenuItem (hMenu, iSelection, MF_CHECKED) ; /* Thi t l p màu t ng ng v i m c ch n m i*/ ế ậ ươ ứ ớ ụ ọ ớ SetClassLong(hwnd,GCL_HBRBACKGROUND, (LONG) GetStockObject(idColor[iSelection- IDM_BKGND_WHITE])); InvalidateRect (hwnd, NULL, TRUE) ; return 0 ; case IDM_APP_HELP: MessageBox(hwnd, TEXT("Help not yet implemented!"), szAppName, MB_ICONEXCLAMATION | MB_OK) ; return 0 ; case IDM_APP_ABOUT: MessageBox (hwnd, TEXT ("Menu Demonstration Program\n (c) Charles Petzold, 1998"), szAppName, MB_ICONINFORMATION | MB_OK) ; return 0 ; } break; case WM_DESTROY: PostQuitMessage(0) ; return 0 ; } Trang 59 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS return DefWindowProc(hwnd, message, wParam, lParam) ; } Ch ng 3ươ CÁC Đ I T NG ĐI U KHI N Ố ƯỢ Ề Ể 3.1. M Đ UỞ Ầ Các đ i t ng đi u khi n (ố ượ ề ể control) là các thành ph n t ng tác tr c quan, th hi n rõầ ươ ự ể ệ c ch giao ti p đ h a gi a ng d ng và ng i dùng. Nh các đ i t ng này, các ch ngơ ế ế ồ ọ ữ ứ ụ ườ ờ ố ượ ươ trình ng d ng trong Windows tr nên thân thi n và d dùng. Ví th , chúng là các thành ph nứ ụ ở ệ ễ ế ầ c b n không th thi u trong h u h t các ng d ng.ơ ả ể ế ầ ế ứ ụ Trong ch ng này, chúng ta s tìm hi u các t o l p và x lý cho các đ i t ng đi uươ ẽ ể ạ ậ ử ố ượ ề khi n thông qua các l p (ể ớ class) sau : • L p Button (nút b m).ớ ấ Trang 60 NGÔN NG L P TRÌNH Ữ Ậ L P TRÌNH C TRÊNẬ WINDOWS • L p Static (tĩnh).ớ • L p Edit Box (so n th o).ớ ạ ả • L p List Box (danhớ sách). • L p Combo Box.ớ • L p Scroll Bar (thanh cu n).ớ ộ 3.2. GI I THI U T NG QUANỚ Ệ Ổ M t ki u đi u khi n đ c xem nh là m t c a s con. Có th t o nhi u c a s conộ ể ề ể ượ ư ộ ử ổ ể ạ ề ử ổ trong cùng m t c a s cha. Các c a s con xác đ nh handle c a s c a cha b ng cách g iộ ử ổ ử ổ ị ử ổ ủ ằ ọ hàm : hwndParent = GetParent (hwnd); hwnd là handle c a c a s con c n l y handle c a c a s cha. Và khi đã l y đ củ ử ổ ầ ấ ủ ử ổ ấ ượ handle c a c a s cha, c a s con có quy n g i các thông đi p đ n c a s cha thông qua hàm.ủ ử ổ ử ổ ề ở ệ ế ử ổ SendMessage(hwndParent, message, wParam, lParam); message là thông đi p c n g i đ n th t c x lý c a c a s cha. wParam là ch danhệ ầ ở ế ủ ụ ử ủ ử ổ ỉ ID c a c a s con, còn lParam ghi l i tr ng thái c a c a s con.ủ ử ổ ạ ạ ủ ử ổ V y chúng ta có th t o m t thành ph n đi u khi n d ng c a s con hay còn g i làậ ể ạ ộ ầ ề ể ạ ử ổ ọ "child window control". C a s con có nhi m v x lý các thông đi p nh bàn phím, thôngử ổ ệ ụ ử ệ ư đi p chu t và thông báo cho c a s cha khi tr ng thái c a c a s con thay đ i. Nh v y c aệ ộ ử ổ ạ ủ ử ổ ổ ư ậ ử s con tr thành công c giao ti p (cho phép nh p và xu t) gi a ng i dùng v i ch ng trình.ổ ở ụ ế ậ ấ ữ ườ ớ ươ Tuy chúng ta có th t o ra m t c a s con cho chính mình, nh ng chúng ta nên t nể ạ ộ ử ổ ư ậ d ng các l p c a s con đã đ c Windows đ nh nghĩa s n hay còn g i là nh ng ki u đi uụ ớ ử ổ ượ ị ẵ ọ ữ ể ề khi n chu n. Nh ng ki u đi u khi n chu n này th ng là các nút b m (ể ẩ ữ ể ề ể ẩ ườ ấ button), h p ki mộ ể tra (check box), h p so n th o (ộ ạ ả edit box), h p danh sách (ộ list box), combo box, các thanh cu n và chu i ch . Ví d mu n t o ra m t nút b m trên màn hình ch c n g i hàmộ ỗ ữ ụ ố ạ ộ ấ ở ỉ ầ ọ CreateWindows, mà ch ng c n ph i quan tâm đ n cách v , cách nh n chu t hay là ch p khiẳ ầ ả ế ẽ ậ ộ ớ b kích ho t. T t c đi u này đ u do Windows x lý. Đi u quan tr ng làph i ch n thông đi pị ạ ấ ả ề ề ử ề ọ ả ặ ệ WM_COMMAND c a các đi u khi n đ x lý thông đi p này theo nh ng m c đích khácủ ề ể ể ử ệ ữ ụ nhau. Các ki u đi u khi n con th ng đ c dùng trong h p tho i. Nh đã minh h a trongể ề ể ườ ượ ộ ạ ư ọ ch ng 2, đó các đi u khi n nh n h p tho i làm c a s cha. Tuy nhiên, cũng có th t o cácươ ở ề ể ậ ộ ạ ử ổ ể ạ ki u đi u khi n con tr c ti p trên vùng c a s chính, b ng cách g i hàm ể ề ể ự ế ử ổ ằ ọ CreateWindow và đi u ch nh v trí cùng v i kích th c c a nó cho thích h p b ng hàm ề ỉ ị ớ ướ ủ ợ ằ MoveWindow. Th t củ ụ x lý thông đi p c a c a s cha g i các thông đi p đ n

Các file đính kèm theo tài liệu này:

  • pdfLaptrinhCtrenWindow.pdf