Lập trình windows với MFC Micrisoft visual C++6.0- P4
lượt xem 30
download
Ðang chuyển nút bằng chuột . nPos được sử dụng trong các tác vụ định vị nút tuyệt đối ( ). Dùng hành vi GetDlgCtrlID của đối tượng chỉ bởi pScrollBar để xác định số hiệu của mục phát sinh message WM_HSCROLL.
Bình luận(0) Đăng nhập để gửi bình luận!
Nội dung Text: Lập trình windows với MFC Micrisoft visual C++6.0- P4
- • Ðặt điểm chỉ (hotpot) của cursor: Trong màn hình thiết kế SB_PAGERIGHT : Tăng nút một đoạn SB_RIGHT : Tăng nút đến vị trí cao nhất cursor: SB_THUMBPOSITION : Chuyển nút bằng chuột - Click chọn biểu tượng trên thanh công cụ. SB_THUMBTRACK : Ðang chuyển nút bằng chuột . - Click tại vị trí hotpot của cursor trên màn hình thiết kế. nPos được sử dụng trong các tác vụ định vị nút tuyệt đối ( ). Dùng đối tượng CWnd làm cửa sổ giao diện chính của ứng dụng: Dùng hành vi GetDlgCtrlID của đối tượng chỉ bởi pScrollBar để Ðược thực hiện bởi hành vi InitInstance (xem 2.4) của đối tượng xác định số hiệu của mục phát sinh message WM_HSCROLL. CEmpApp quản lý tiểu trình chính. Kế thừa hành vi này từ Ðây là cơ sở giúp phân biệt mục này với các mục khác trong CWinApp cho lớp CEmpApp (xem 2.7). Nội dung cài đặt của hành cùng cửa sổ giao diện nhằm lựa chọn xử lý thích hợp cho vi như sau: WM_HSCROLL. afx_msg void OnVScroll ( CWnd* main = new CWnd(); // Con trỏ đối tượng CWnd. UINT nSBCode, // Số hiệu ghi nhận đặc điểm tác động HICON myIcon; // Khai báo biến quản lý UINT nPos, // Vị trí nút cuộn / nút trượt trên mục HCURSOR myCursor; // handle của cursor và icon CScrollBar* pScrollBar // Con trỏ đối tượng quản lý mục CBrush myBrush; ); Hành vi xử lý WM_VSCROLL, message do windows gửi đến cửa sổ khi có một mục là thanh cuộn hay thanh trượt đặt thẳng đứng // Nạp cursor và icon từ resource vào bộ nhớ. (vertical scrollbar hoặc vertical sliderCtrl) trong cửa sổ bị tác động. myIcon = LoadIcon ( IDR_MAINFRAME ); myCursor = LoadCursor ( IDR_MAINFRAME ); Xử lý của hành vi này được cài đặt tương tự hành vi OnHScroll. // Tạo brush tô nền cửa sổ với màu RGB(190, 190, 0) afx_msg BOOL OnSetCursor ( myBrush. CreateSolidBrush (RGB(190, 190, 0) ); CWnd* pWnd, // Con trỏ đến đối tượng cửa sổ chứa cursor UINT nHitTest, // Thông tin về vị trí cursor // Khởi tạo thông số cho đối tượng cửa sổ main UINT message // Chứa các số hiệu message có liên quan đến main->CreateEx( WS_EX_TOPMOST, // trạng thái hiện thời của các nút con chuột AfxRegisterWndClass( ); Hành vi xử lý WM_SETCURSOR, message do windows gửi đến CS_HREDRAW|CS_VREDRAW, cửa sổ khi windows cần ấn định lại hình dạng cursor cho phù hợp myCursor, myBrush, myIcon), với vị trí hiện thời của nó trên cửa sổ. "Emp.Example 2", nHitTest chứa thông tin vị trí hiện thời của cursor: WS_SYSMENU | WS_VISIBLE | WS_MINIMIZEBOX, HTBORDER : Cursor hiện nằm trên biên cửa sổ 100, 100, 300, 200, NULL, NULL ); HTCLIENT : Cursor hiện nằm trong vùng client // Dùng main làm cửa sổ giao diện chính HTCAPTION : Cursor hiện nằm trên tiêu đề của cửa sổ m_pMainWnd = main; virtual LRESULT WindowProc( UINT message, main->ShowWindow ( SW_SHOW ); // Kích hoạt cửa sổ main WPARAM wParam, LPARAM lParam ); Khi đối tượng cửa sổ main ngừng hoạt động thì ứng dụng cũng kết Hành vi xử lý các message gửi đến cửa sổ. Mặc nhiên, hành vi này thúc. dựa vào bảng MessageMap để chuyển message đến hành vi xử lý Xem VD02: Cửa sổ main với ExStyle là WS_EX_TOPMOST có thể nổi message tương ứng của đối tượng quản lý cửa sổ. trên mọi cửa sổ khác ngay cả khi nó không phải là cửa sổ kích hoạt. Với ExStyle là WS_EX_TOOLWINDOW, cửa sổ sẽ không hiển thị trên 4.3 SỬ DỤNG ÐỐI TƯỢNG CWnd: taskbar. 4.3.1 Sử dụng CWnd làm giao diện chính của ứng dụng: Tạo dự án VD02 như dự án VD01. Thực hiện các bổ sung sau: 4.3.2 Ứng dụng chỉ chạy một bản (instance) tại mỗi thời điểm: Tạo icon có số hiệu là IDC_MAINFRAME. Tham khảo (2.8). Ðể ứng dụng chỉ được thực hiện với 1 bản duy nhất, ta cài đặt cơ chế Tạo cursor có số hiệu là IDC_MAINFRAME: đánh dấu và kiểm tra. Trong chương trình của ứng dụng, ta qui ước đăng • Tạo mới cursor: Thực hiện tương tự như tạo mới icon, (2.8). Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com Cöûa soå giao dieän vaø lôùp CWnd 48 49
- ký và sử dụng một tên duy nhất cho cửa sổ chính. Khi chương trình được thực hiện, nó kiểm tra xem tên đó đã được đăng ký chưa thông qua hàm sau: HANDLE CreateMutex( NULL, FALSE, LPCTSTR Tên ); Hàm trả về giá trị ERROR_ALREADY_EXISTS nếu Tên đã được đăng ký. Trong trường hợp này ta có thể khẳng định một instance của ứng dụng đã được thực hiện, chương trình kết thúc để chỉ cho phép một instance duy nhất. Hãy cài đặt cơ chế này cho ứng dụng VD02 (Tham khảo VD03). THỰC HÀNH: 1. Viết ứng dụng windows chỉ cho phép thực hiện tối đa hai bản (instance). 2. Cài đặt hành vi PreCreateWindow cho lớp kế thừa CWnd của ứng dụng để cửa sổ giao diện luôn có kích thước 100100 và tiêu đề là "Hello !" bất chấp giá trị kích thước và tiêu đề dùng cho khởi tạo thông số của đối tượng cửa sổ. Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com 50
- UINT nID, CHÖÔNG 5: // Soá hieäu command message int nCode, void* pExtra, Xử lý message AFX_CMDHANDLERINFO* pHandlerInfo ); Ñieàu phoái command message. Neáu baûn thaân ñoái töôïng laø cöûa soå giao 5.1 LÔÙP XÖÛ LYÙ MESSAGE CCmdTarget: dieän chính thì caùc WM_COMMAND ñöôïc öu tieân gôûi ñeán cho ñoái Windows laø moâi tröôøng maø phaàn lôùn giao taùc giöõa caùc boä phaän döïa treân cô töôïng. Thoâng qua haønh vi naøy, ñoái töôïng coù theå ñieàu phoái command cheá göûi-nhaän message. Vieäc taïo ra ñoái töôïng coù khaû naêng xöû lyù vaø ñieàu phoái message cho caùc ñoái töôïng khaùc (öùng duïng, caùc control, view…). Löu yù messages laø raát caàn thieát khoâng chæ ñoái vôùi heä thoáng maø vôùi caû öùng duïng. laø ñoái töôïng ñöôïc ñieàu phoái coù theå khoâng coù chöùc naêng xöû lyù command Treân quan ñieåm ñoù, MFC cung caáp lôùp ñoái töôïng CCmdTarget phuïc vuï xöû lyù message göûi ñeán, do ñoù caàn kieåm tra keát quaû cuûa haønh vi OnCmdMsg vaø ñieàu phoái messages trong phaïm vi öùng duïng, giöõa öùng duïng vôùi heä thoáng treân ñoái töôïng ñöôïc ñieàu phoái. Boá cuïc xöû lyù ñieàu phoái nhö sau: vaø vôùi caùc öùng duïng khaùc. Caùc haønh vi ñaëc tröng cuûa lôùp nhö sau: if (Ñoái_töôïng->OnCmdMsg(...) != 0) { void BeginWaitCursor( ); Hieån thò cursor chôø xöû lyù (ñoàng hoà caùt). return; // Ñoái töôïng ñöôïc ñieàu phoái ñaõ xöû lyù message void EndWaitCursor( ); Chaám döùt hieån thò cursor chôø xöû lyù. } Ñònh höôùng xöû lyù message: Cô cheá ñònh höôùng xöû lyù message do MFC … // Chuû theå phaûi xöû lyù message cung caáp cho pheùp boå sung muïc xöû lyù message cho caùc lôùp ñoái töôïng keá thöøa lôùp CCmdTarget. Caùc macro giuùp caøi ñaët cô cheá naøy nhö sau: 5.2 KHAI BAÙO MUÏC XÖÛ LYÙ MESSAGE TRONG MESSAGE MAP: • DECLARE_MESSAGE_MAP( ): AÁn ñònh ñaëc tính xöû lyù message Muïc xöû lyù message trong baûng MessageMap cho pheùp aán ñònh moät xöû lyù cho lôùp ñoái töôïng xöû lyù message thoâng qua caùc caøi ñaët boå sung sau: duy nhaát cho moät message. Caùc loaïi message khaùc nhau coù kieåu muïc xöû lyù - Thuoäc tính private kieåu caáu truùc maûng chöùa caùc phaàn töû coù kieåu message khaùc nhau. Caùc kieåu muïc xöû lyù message phoå bieán nhö sau: AFX_MSGMAP_ENTRY. Moãi phaàn töû cuûa maûng ñöôïc duøng löu Caùc message cuûa heä thoáng, ñöôïc bieåu dieãn bôûi caùc haèng soá baét ñaàu tröõ moät muïc xöû lyù message maø lôùp keá thöøa khai baùo boå sung. baèng WM_ *, muïc xöû lyù message töông öùng coù daïng ON_WM_* (). - Thuoäc tính protected kieåu caáu truùc AFX_MSGMAP vôùi teân laø Ví duï: WM_PAINT ON_WM_PAINT() MessageMap chæ ñeán baûng caùc muïc xöû lyù message noùi treân. WM_SIZE ON_WM_SIZE() - Haønh vi protected: virtual AFX_MSGMAP GetMessageMap( ); Caùc message cuûa ngöôøi duøng: Soá hieäu message ñöôïc choïn tuøy yù trong traû veà ñòa chæ cuûa baûng MessageMap chöùa caùc muïc xöû lyù. ñoaïn WM_USER ÷ WM_USER+0×7FFF. Muïc xöû lyù message cho caùc DECLARE_MESSAGE_MAP ñöôïc ñaët cuoái phaàn khai baùo lôùp: message cuûa ngöôøi duøng coù daïng nhö sau: // Taäp tin .H cuûa lôùp class MyClass : public CCmdTarget { ON_MESSAGE( userMessageID , UserFuncName ) // Caùc noäi dung khai baùo cuûa lôùp … Trong ñoù: DECLARE_MESSAGE_MAP() - userMessageID : Soá hieäu message do ngöôøi duøng choïn tröôùc }; - UserFuncName : Haøm xöû lyù message, coù khai baùo nhö sau: • BEGIN_MESSAGE_MAP( Teân_lôùp_keá thöøa, Teân_lôùp_cô_sôû ): Baét ñaàu noäi dung khai baùo caùc muïc xöû lyù cuûa baûng MessageMap. afx_msg LRESULT UserFuncName ( // Tham soá kieåu WORD vaø • END_MESSAGE_MAP( ): Keát thuùc khai baùo baûng MessageMap. WPARAM wParam, // Tham soá kieåu LONG keøm theo message Toaøn boä noäi dung khai baùo cuûa baûng MessageMap ñöôïc ñaët trong LPARAM lParam taäp tin caøi ñaët (.CPP) cuûa lôùp, neân ñaët ñaàu taäp tin ñeå tieän theo doõi. ); virtual BOOL OnCmdMsg ( Xöû lyù Message Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com 51 52
- Caùc message coù ñaêng kyù cuûa ngöôøi duøng: Ngoaøi caùc message töï ñònh void [ClassName::]PreFunctionName (CCmdUI* pCmdUI ) { pCmdUI->Enabled (FALSE ); // Caám ñoái töôïng hoaït ñoäng nghóa vaø söû duïng theo qui öôùc trong moät öùng duïng, windows cho pheùp öùng duïng ñaêng kyù message ñeå message ñoù coù theå söû duïng treân nhieàu } öùng duïng khaùc nhau. Vieäc ñaêng kyù ñöôïc thöïc hieän thoâng qua haøm sau: Caùc message do ñoái töôïng con (controls) göûi ñeán cöûa soå cha: Tham soá wParam chöùa soá hieäu control, giaù trò WORD cao cuûa tham soá lParam UINT RegisterWindowMessage (LPCSTR Chuoãi_teân_message ); chöùa thoâng tin veà traïng thaùi control ôû thôøi ñieåm göûi message ñeán cöûa soå Haøm traû veà soá hieäu ñaêng kyù ñöôïc cuûa message. Giaù trò naøy naèm trong cha (ví duï BN_CLICKED laø moät traïng thaùi cuûa button control,…). Muïc ñoaïn 0×C000÷0×FFFF. Caùc öùng duïng ñang chaïy treân moät heä thoáng coù xöû lyù message cho message göûi töø control coù daïng nhö sau: theå chia xeû message duøng rieâng vôùi ñieàu kieän chuùng phaûi thöïc hieän ON_CONTROL (Traïng_thaùi_control, Soá_hieäu_Control, Haøm_xöû_lyù ) thao taùc ñaêng kyù cuøng moät chuoãi teân message ñeå laáy soá hieäu message. Muïc xöû lyù message cho caùc message coù ñaêng kyù cuûa ngöôøi coù daïng: Ví duï: Ta coù ví duï minh hoïa ñònh höôùng xöû lyù message nhö sau: ON_REGISTERED_MESSAGE(UserRegMessageID, UserFuncName) * Khai baùo lôùp (teâp tin .H): Sau ñaây laø moät ví duï: class CMyClass: public CBasedWnd { // Ñaêng kyù message vôùi teân laø “MY_MESS” public: CMyClass(); void myProc(void); const UINT myMess = RegisterWindowMessage(“MY_MESS”); void mySerach(); // Khai baùo muïc xöû lyù cho message ñöôïc ñaêng kyù void myWork(); BEGIN_MESSAGE_MAP ( CMyWnd, CMyBasedWndClass ) void PremyWork(); //{{AFX_MSG_MAP ( CMyWnd ) void OnExit(void); ON_REGISTERED_MESSAGE ( myMess, myFunc ) DECLARE_MESSAGE_MAP() // ... } //}}AFX_MSG_MAP * Phaàn caøi ñaët cuûa lôùp (teâp tin .CPP): END_MESSAGE_MAP ( ) Message WM_COMMAND: Khi WM_COMMAND ñöôïc göûi ñeán ñoái #define MY_MESSAGE WM_USER + 1 töôïng xöû lyù message thì tham soá wParam keøm theo chöùa soá hieäu static UINT NEAR MY_MESS = RegisterWindowMessage(“MY_MESS”); BEGIN_MESSAGE_MAP(CMyClass, CDerivedWnd) (CommandID) cuûa ñoái töôïng phaùt sinh message. Muïc xöû lyù message //{{AFX_MSG_MAP(CMyClass) WM_COMMAND aán ñònh xöû lyù töông öùng, vaø coù daïng nhö sau: ON_WM_PAINT() // WindowsMessage ON_COMMAND ( CommandID, FunctionName ) ON_MESSAGE (MY_MESSAGE, myProc) // UserMessage ON_REGISTERED_MESSAGE(MY_MESS,OnSearch) Coù theå caøi ñaët xöû lyù ñieàu khieån ñoái vôùi ñoái töôïng laøm phaùt sinh // UserRegMessage WM_COMMAND thoâng qua muïc xöû lyù ñieàu khieån message nhö sau: ON_COMMAND(ID_DO, myWork) // CommandMessage // Command Preprocess ON_UPDATE_COMMAND_UI( CommandID, PreFunctionName ) ON_UPDATE_COMMAND_UI(ID_DO, PremyWork) PreFunctionName laø haønh vi thöïc hieän xöû lyù ñieàu khieån treân ñoái töôïng //Control IDC_EXIT ON_CONTROL(BN_CLICKED, IDC_EXIT, OnExit) phaùt sinh WM_COMMAND, tham soá nhaän ñöôïc laø giaù trò con troû ñeán //}}AFX_MSG_MAP ñoái töôïng CCmdUI*. Haønh vi Enable ( BOOL isEnabled ) cuûa ñoái END_MESSAGE_MAP() töôïng naøy ñöôïc duøng ñeå caám hoaëc cho pheùp hoaït ñoäng ñoái vôùi ñoái Caùc muïc xöû lyù message do Classwizard quaûn lyù ñaët giöõa //{{ vaø //}} töôïng phaùt sinh WM_COMMAND. Xöû lyù cuûa haønh vi naøy coù theå laø: Xöû lyù Message Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com 53 54
- 5.3 CAÙC LÔÙP KEÁ THÖØA CCmdTarget: Caùc lôùp ñoái töôïng cuûa MFC keá thöøa töø CCmdTarget coù chöùc naêng xöû lyù message laø CWnd, CWinApp, CDocument. ÖÙng duïng coù theå döïa treân nhöõng lôùp naøy ñeå xaây döïng caùc lôùp keá thöøa ñaûm nhaän chöùc naêng xöû lyù message phuø hôïp vôùi yeâu caàu cuûa öùng duïng. 5.4 MESSAGE MAP CUÛA LÔÙP KEÁ THÖØA CWnd TRONG ÖÙNG DUÏNG: 5.4.1 Cöûa soå cuûa öùng duïng coù chöùc naêng hoaït ñoäng: Trong phaàn naøy, ta thöïc hieän öùng duïng vôùi cöûa soå giao dieän chính coù tieâu ñeà chöùa noäi dung chöõ chaïy theo kieåu baûng chöõ ñieän töû. Lôùp CWnd cuûa MFC khoâng cung caáp tieän ích naøy. Chuùng ta caàn xaây döïng lôùp cöûa soå môùi vôùi nhöõng khaû naêng phuø hôïp; coù caùc chöùc naêng nhö CWnd ñeå laøm giao dieän, ñoàng thôøi coù khaû naêng töï thay ñoåi noäi dung tieâu ñeà (caption) theo thôøi gian (timer). Lôùp cöûa soå naøy keá thöøa töø lôùp CWnd, töï caøi ñaët timer (SetTimer) khi baét ñaàu (OnCreate) hoaït ñoäng, xöû lyù thay ñoåi noäi dung tieâu ñeà ôû moãi chu kyø Timer (OnTimer) vaø huûy boû Timer (KillTimer) khi chaám döùt hoaït ñoäng (OnDestroy). Sau ñaây laø caùc böôùc thöïc hieän döï aùn: Taïo döï aùn VD04 töông töï döï aùn VD03. Boå sung lôùp CEmpWnd (teân lôùp cöûa soå môùi) keá thöøa töø CWnd: Thöïc hieän nhö boå sung lôùp CEmpApp trong muïc (2.7). Löu yù trong hoäp hoäi thoaïi New Class : choïn Class Type = MFC Class ; BaseClass = CWnd. Caøi ñaët caùc haønh vi xöû lyù message caàn thieát cho lôùp CEmpWnd treân cô - Choïn WM_CREATE. Sau ñoù choïn Add and Edit. sôû keá thöøa töø lôùp CWnd cuûa MFC: - Haønh vi OnCreate vôùi tham soá thích hôïp ñöôïc boå sung vaøo lôùp • Haønh vi OnCreate thöïc hieän caùc aán ñònh caàn thieát cho CEmpWnd CEmpWnd, ñoàng thôøi muïc xöû lyù ON_WM_CREATE() ñöôïc ñaët tröôùc khi ñi vaøo hoaït ñoäng. Boå sung vaø caøi ñaët haønh vi nhö sau: vaøo baûng MessageMap. Caøi ñaët noäi dung cuûa OnCreate nhö sau: - Trong maøn hình Workspace cuûa döï aùn, choïn trang ClassView. int CEmpWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) - Right-click treân tieâu ñeà cuûa lôùp CEmpWnd: { if (CWnd::OnCreate(lpCreateStruct) == -1) return -1; // Ñaët timer soá hieäu 100, chu kyø 250 ms SetTimer(100, 250, NULL); return 0; } • Haønh vi OnTimer xöû lyù WM_TIMER, cho pheùp xöû lyù yeâu caàu ôû moãi chu kyø cuûa timer. Vieäc boå sung haønh vi naøy ñöôïc thöïc hieän töông töï OnCreate. Noäi dung caøi ñaët cuûa haønh vi nhö sau: void CEmpWnd::OnTimer( UINT nIDEvent ) - Choïn muïc Add Windows Message Handler... : { Xöû lyù Message Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com 55 56
- Ta nhaän ñöôïc hoäp hoäi thoaïi Resource Symbols chöùa danh saùch caùc giaù // Timer do chuùng ta caøi ñaët if (nIDEvent == 100) { trò ñaõ khai baùo. Coù theå thöïc hieän theâm, xoùa caùc giaù trò khai baùo naøy. char s[200], ch; // Laáy tieâu ñeà cöûa soå GetWindowText(s, 200); ch = s[0]; for (UINT i=0; i
- void Invalidate(BOOL bErase = TRUE ); Yeâu caàu caäp nhaät toaøn boä vuøng client cuûa cöûa soå. Neáu tham soá bErase = FALSE thì heä thoáng seõ khoâng töï ñoäng xoùa hoä phaàn noäi dung cuõ trong cöûa soå. void InvalidateRect ( LPCRECT lpRect, // Con troû ñeán bieán kieåu RECT chöùa // thoâng tin vuøng ñöôïc caäp nhaät BOOL bErase = TRUE // Coù yù nghóa nhö Invalidate () ); Yeâu caàu caäp nhaät moät vuøng giôùi haïn trong client cuûa cöûa soå. Haønh vi OnPaint cuûa CWnd duøng xöû lyù WM_PAINT. Vieäc söû duïng haønh vi naøy trong caùc lôùp keá thöøa CWnd nhaèm thöïc hieän caùc trang trí rieâng theo boá cuïc ôû muïc OnPaint trong (4.2). Toaøn boä thao taùc xöû lyù naøy ñöôïc MFC thöïc hieän thoâng qua lôùp CPaintDC nhö sau: CPaintDC dc(this); // Device context ñeå veõ leân // Thöïc hieän caùc taùc vuï veõ treân dc ... THÖÏC HAØNH: 1. Töông töï VD04. Khi ngöôøi duøng keát thuùc öùng duïng, chöông trình hieån thò hoäp thoâng baùo "Are you sure to exit this program ?" vôùi hai muïc YES-NO. Neáu ngöôøi duøng choïn YES thì keát thuùc: HD: Caøi ñaët haønh vi OnClose xöû lyù message WM_CLOSE cho CEmpWnd. Duøng haønh vi MessageBox cuûa CWnd ñeå hieån thò caâu thoâng baùo. Neáu ngöôøi duøng ñoàng yù thì thöïc hieän haønh vi OnClose cuûa CWnd ñeå keát thuùc, ngöôïc laïi khoâng thöïc hieän xöû lyù gì caû (xem VD05) 2. Töông töï VD04 vôùi phaàn demo laø aûnh vieân bi chaïy trong client cuûa cöûa soå. HD: Duøng timer ñeå lieân tuïc phaùt WM_PAINT baèng haønh vi Invalidate theo moãi chu kyø. Haønh vi OnPaint thöïc hieän veõ vaøo vuøng client cuûa cöûa soå chính moät doøng chöõ coù noäi dung chaïy kieåu baûng chöõ ñieän töû. (xem VD06). 3. Thöïc hieän öùng duïng cho pheùp hieån thò moät vaät theå coù hình daïng baát kyø trong vuøng client. Caùc phím ← , ↑ , → , ↓ cho pheùp dòch chuyeån vaät theå naøy. HD: Nhö baøi taäp 2 nhöng khoâng söû duïng timer. Duøng haønh vi OnKeyDown xöû lyù message WM_KEYDOWN. Haønh vi naøy kieåm tra giaù trò phím nhaän ñöôïc nChar vôùi caùc giaù trò haèng phím VK_LEFT (phím ←), VK_UP (phím ↑), VK_RIGHT (phím →), VK_DOWN (phím ↓) ñeå thay ñoåi toïa ñoä vaät theå cho phuø hôïp. Sau cuøng phaùt sinh message WM_PAINT ñeå veõ laïi vaät theå. Xöû lyù Message 59
- CHÖÔNG 6: ÖÙ ng duïng coâng cuï GDI 6.1 DC VAØ BITMAP: Vaán ñeà trang trí thieát bò ñoà hoïa ñöôïc tieán haønh thoâng qua ñoái töôïng DC quaûn lyù thieát bò, treân cô sôû khai thaùc chöùc naêng caùc coâng cuï GDI lieân quan. Keát quaû trang trí treân DC ñöôïc quaûn lyù bôûi ñoái töôïng Bitmap maø DC ñang söû duïng. Bitmap laø coâng cuï laøm neàn khoâng theå thieáu cho caùc DC. Vieäc khôûi taïo noäi dung cho ñoái töôïng bitmap trong öùng duïng coù theå ñöôïc thöïc hieän baèng caùch laáy aûnh bitmap töø resource (LoadBitmap) hay taïo môùi noäi dung cho bitmap döïa treân moät DC xaùc ñònh (CreateCompatibleBitmap). - Choïn Bitmap, Import. Sau ñoù choïn taäp tin chöùa aûnh bitmap thoâng Thoâng thöôøng, öùng duïng ñoà hoïa phaûi chuaån bò saün caùc aûnh caàn thieát trong qua hoäp hoäi thoaïi File-Folder. resource cuûa öùng duïng. ÔÛ phaàn xöû lyù, caùc resource naøy ñöôïc taûi vaøo boä nhôù - AÁn ñònh caùc thoâng soá cuûa bitmap (soá hieäu laø IDB_MYPICT). laøm noäi dung cho caùc ñoái töôïng bitmap. Töø caùc ñoái töôïng bitmap naøy, aûnh seõ Boå sung ñoái töôïng thuoäc tính m_myPict kieåu CBitmap cho CEmpWnd: ñöôïc veõ leân caùc thieát bò hieån thò ñoà hoïa thoâng qua ñoái töôïng DC töông öùng. - Choïn trang ClassView trong maøn hình Workspace cuûa döï aùn. - Right-click treân tieâu ñeà cuûa lôùp CEmpWnd: 6.2 ÖÙNG DUÏNG VÔÙI CÖÛA SOÅ CHÍNH HIEÅN THÒ AÛNH: Trong phaàn naøy ta thöïc hieän öùng duïng coù chöùc naêng hieån thò moät aûnh xaùc ñònh trong vuøng client cuûa cöûa soå chính. Caùc böôùc tieán haønh döï aùn nhö sau: Taïo döï aùn VD07 töông töï döï aùn VD06. Taïo moät aûnh bitmap trong resource vôùi soá hieäu laø IDB_MYPICT: Noäi dung aûnh naøy coù theå ñöôïc taïo môùi hoaøn toaøn hoaëc laáy töø noäi dung cuûa moät taäp tin bitmap (.bmp) ñaõ coù. Choïn moät trong hai caùch sau: - Choïn Add Member Variable… : • Caùch 1 – aûnh bitmap ñöôïc taïo môùi: Töông töï taïo môùi icon (2.8). • Caùch 2 – aûnh bitmap ñöôïc laáy töø noäi dung taäp tin bitmap (.bmp): - Choïn trang ResourceView trong maøn hình Workspace. - Right-click treân Project Resource: - Nhaäp caùc thoâng tin veà kieåu, teân vaø loaïi cuûa thuoäc tính. Choïn OK. Duøng haønh vi OnCreate cuûa CEmpWnd ñeå laáy aûnh bitmap töø resource - Choïn Insert: laøm noäi dung cuûa m_myPict. Xöû lyù ñöôïc caøi ñaët nhö sau: Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com ÖÙng duïng coâng cuï GDI 60 61
- Ñoái töôïng DC cho pheùp sao cheùp laïi noäi dung trang trí ñoà hoïa treân thieát bò int CEmpWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) hieån thò ñoà hoïa ñöôïc quaûn lyù bôûi moät ñoái töôïng DC khaùc leân thieát bò hieån thò { ñoà hoïa ñöôïc quaûn lyù bôûi chính noù thoâng qua moät soá haønh vi sau: if (CWnd::OnCreate(lpCreateStruct) == -1) - BitBlt : Sao cheùp vaø giöõ nguyeân tyû leä trong noäi dung aûnh. return -1; - StretchBlt : Sao cheùp vaø thay ñoåi tyû leä trong noäi dung aûnh. // Khôûi ñoäng bitmap töø bitmap resource IDB_MYPICT Trong phaàn naøy ta xaây döïng öùng duïng coù caùc ñaëc ñieåm sau: mypict.LoadBitmap( IDB_MYPICT ); - Cöûa soå chính cuûa öùng duïng coù theå thay ñoåi kích thöôùc. return 0; - Noäi dung aûnh hieån thò trong vuøng client cuûa cöûa soå töï ñoäng thay ñoåi } kích thöôùc moät caùch phuø hôïp khi kích thöôùc cöûa soå thay ñoåi. Duøng haønh vi OnPaint cuûa CEmpWnd, veõ aûnh bitmap trong m_myPict Vieäc thöïc hieän caàn löu yù caùc böôùc sau: thoâng qua haønh vi DrawState cuûa ñoái töôïng CPaintDC dc. - Cöûa soå chính cuûa öùng duïng coù thuoäc tính WS_THICKFRAME. void CEmpWnd::OnPaint() - Duøng moät DC aûo ñeå loàng aûnh bitmap thoâng qua ñoái töôïng CBitmap. Veõ { aûnh bitmap töø DC naøy leân DC hieån thò. CPaintDC dc(this); Caùc böôùc thöïc hieän nhö sau: RECT rect; Taïo döï aùn VD08 töông töï döï aùn VD07. // Kích thöôùc vuøng client GetClientRect( &rect ); Haønh vi OnPaint cuûa CEmpWnd söû duïng DC trong boä nhôù ñeå loàng aûnh // draw on client bitmap, töø ñoù veõ leân vuøng client cuûa cöûa soå. Xöû lyù caøi ñaët nhö sau: /* Goùc traùi treân cuûa aûnh */ dc.DrawState ( CPoint(0,0), void CEmpWnd::OnPaint() CSize (rect.right-rect.left, rect.bottom-rect.top), { &m_myPict, DST_BITMAP); CPaintDC dc(this); } RECT rt; Haønh vi OnDestroy cuûa CEmpWnd giaûi phoùng ñoái töôïng m_myPict. CDC memDC; void CEmpWnd::OnDestroy() CBitmap *oldBmp; { BITMAP bmpInfo; CWnd::OnDestroy(); // Kích thöôùc vuøng client m_myPict.DeleteObject(); GetClientRect(&rect); } mypict.GetBitmap(&bmpInfo); // Laáy thoâng tin cuûa aûnh bitmap Löu yù: Ñeå xöû lyù trang trí ñoà hoïa trong vuøng client cuûa cöûa soå giao dieän khoâng memDC.CreateCompatibleDC(&dc); // Loàng bitmap m_myPict vaøo memDC vaø löu laïi bitmap cuõ cuûa noù. gaây ra hieän töôïng "chôùp", ta coù theå söû duïng moät soá giaûi phaùp sau: - Khoâng söû duïng ñoái töôïng brush cho cöûa soå lieân quan: Duøng giaù trò NULL oldBmp = memDC.SelectObject(&m_myPict); // Cheùp aûnh töø memDC leân DC quaûn lyù vuøng client cuûa cöûa soå: dc cho tham soá naøy trong haønh vi khôûi taïo thoâng soá cuûa ñoái töôïng cöûa soå. dc.StretchBlt( 0, 0, rt.right-rt.left, rt.bottom-rt.top, &memDC, - Duøng tham soá FALSE cho yeâu caàu caäp nhaät vuøng client cuûa cöûa soå (5.4.2) 0, 0, bmpInfo.bmWidth, bmpInfo.bmHeight, - Duøng moät DC trong boä nhôù laøm coâng cuï trang trí trung gian. Thöïc hieän caùc SRCCOPY); noäi dung trang trí caàn thieát leân DC naøy. Sau khi hoaøn taát caùc taùc vuï trang // Phuïc hoài aûnh bitmap cuõ cuûa memDC trí caàn thieát thì chuyeån noäi dung DC coâng cuï leân DC cuûa maøn hình. memDC.SelectObject(oldBmp); memDC.DeleteDC(); 6.3 SAO CHEÙP AÛNH TÖØ DC VAØO DC, PHOÙNG TO & THU NHOÛ AÛNH: } // Xem VD08 6.4 DC TRONG BOÄ NHÔÙ (DC AÛO) - VUØNG VEÕ ÑEÄM LYÙ TÖÔÛNG: Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com ÖÙng duïng coâng cuï GDI 62 63
- Neáu vieäc trang trí goàm nhieàu thao taùc phöùc taïp thì neân thöïc hieän chuùng Vôùi caùc ñoái töôïng GDI ñöôïc söû duïng thöôøng xuyeân thì vieäc laëp ñi laëp laïi treân DC aûo, sau ñoù chuyeån keát quaû ra DC hieån thò. Chæ moät laàn duy nhaát cho caùc thao taùc taïo vaø huûy boû chuùng trong caùc haønh vi trang trí cuûa CEmpWnd seõ moãi noäi dung trang trí, nhö theá seõ caûi thieän ñaùng keå chaát löôïng ñoà hoïa. laøm laõng phí taøi nguyeân cuûa heä thoáng. Neân chuyeån taát caû caùc thao taùc ñoù veà ÖÙng vôùi moãi DC aûo taïo ra trong boä nhôù, ngoaøi ñoái töôïng CDC quaûn lyù, ta hai haønh vi OnCreate vaø OnDestroy cuûa CEmpWnd moät caùch phuø hôïp. caàn söï phoái hôïp cuûa ñoái töôïng bitmap laøm neàn thay theá ñoái töôïng bitmap Baïn haõy thöû aùp duïng ñieàu löu yù naøy cho VD09. töôïng tröng khoâng söû duïng ñöôïc maø heä thoáng gaùn cho DC khi taïo laäp. Boá cuïc 6.5 AÛNH CHUYEÅN ÑOÄNG TRONG VUØNG CLIENT: xöû lyù cuûa haønh vi OnPaint coù söû duïng ñoái töôïng DC aûo nhö sau: Ñöôïc thöïc hieän moät caùch ñôn giaûn baèng kyõ thuaät hoaït hình. Ta chuaån bò // Ñoái töôïng DC hieån thò moät soá aûnh cô baûn cuûa chuoãi hoaït ñoäng ñoù, sau ñoù thöïc hieän hieån thò vaø traùo CClientDC dc(this); aûnh theo trình töï vôùi khoaûng thôøi gian chôø hôïp lyù. RECT rect; // Ñoái töôïng DC aûo ñeå veõ trung gian Caùc aûnh trong noäi dung hoaït hình ñöôïc quaûn lyù bôûi coâng cuï GDI thích hôïp: CDC memDrawDC; CBitmap memDrawBmp; CBitmap: Moãi bitmap quaûn lyù ñöôïc moät aûnh. Ta duøng nhieàu bitmap. CBitmap *memDrawOldBmp; AÛnh veõ baèng haønh vi DrawState cuûa ñoái töôïng DC quaûn lyù thieát bò hieån GetClientRect ( &rt ); thò. Kích thöôùc aûnh hieån thò khoâng thay ñoåi. int CX = rect.right–rect.left ; int CY = rect.bottom–rect.top; CDC: Loàng taát caû caùc aûnh vaøo moät DC. Töø DC naøy ta coù theå cheùp baát memDrawBmp.CreateCompatibleBitmap( &dc, CX, CY ); kyø phaàn aûnh caàn veõ naøo sang DC hieån thò. Coù theå thay ñoåi kích thöôùc memDrawDC.CreateCompatibleDC( &dc ); aûnh tuøy yù: StretchBlt. memDrawOldBmp = memDrawDC.SelectObject( &memDrawBmp ); CImageList: Lôùp ñoái töôïng quaûn lyù taäp hôïp nhieàu aûnh coù cuøng kích ... // Trang trí memDrawDC thöôùc. Khaû naêng thao taùc treân danh saùch aûnh cuûa CImageList laø raát toát. // Chuyeån noäi dung DC aûo sang dc: Trong phaàn naøy ta xaây döïng öùng duïng vôùi hình aûnh chuù böôùm bay trong dc.StretchBlt ( 0, 0, CX,CY, &memDrawDC, CX,CY, SRCCOPY ); vuøng client cuûa cöûa soå. Taäp tin butterfly.bmp trong thö muïc BMP chöùa caùc // Huûy boû caùc ñoái töôïng GDI: aûnh chuyeån ñoäng cuûa böôùm. Ta duøng caùch thöù 2, loàng caùc aûnh vaøo DC vaø memDrawDC.SelectObject(&memDrawOldBmp); veõ leân DC hieån thò. Caùc böôùc thöïc hieän döï aùn nhö sau: memDrawBmp.DeleteObject(); Taïo döï aùn VD10 töông töï döï aùn VD09. memDrawDC.DeleteDC(); Boå sung bitmap resource vôùi soá hieäu IDB_ANIMATION maø noäi dung Phaàn tieáp theo ta thöïc hieän öùng duïng töông töï VD08, ñoàng thôøi taïo doøng ñöôïc laáy töø taäp tin chöùa caùc aûnh hoaït hình. Ghi nhôù soá aûnh trong bitmap chöõ chaïy theo kieåu baûng chöõ ñieän töû trong vuøng client cuûa cöûa soå chính. ñoù. Chaúng haïn, choïn taäp tin butterfly.bmp trong thö muïc BMP. Taäp tin Taïo döï aùn VD09 töông töï döï aùn VD08. naøy coù 4 aûnh, kích thöôùc 32x28. Xöû lyù Trang trí memDrawDC trong OnPaint cuûa CEmpWnd nhö sau: Boå sung caùc ñoái töôïng thuoäc tính protected cho lôùp CEmpWnd: BITMAP bmpInfo; - m_butterDC : Ñoái töôïng CDC, quaûn lyù DC loàng aûnh. m_myPict.GetBitmap( &bmpInfo ); - m_butterBmp : Ñoái töôïng CBitmap, quaûn lyù caùc aûnh hoaït hình. memDrawDC.StretchBlt( 0, 0, CX, CY, &memDC, - m_butterOldBmp : Ñoái töôïng CBitmap*, quaûn lyù con troû chæ ñeán 0, 0, bmpInfo.bmWidth, bmpInfo.bmHeight, ñoái töôïng bitmap cuõ cuûa m_butterDC. SRCCOPY ); - m_pictNo : Kieåu int, quaûn lyù soá thöù töï cuûa hình ñang ñöôïc memDrawDC.SetTextColor( RGB(255,0,0) ); // text color hieån thò trong caùc aûnh hoaït hình noùi treân. memDrawDC.SetBkMode( TRANSPARENT ); // transparent Haønh vi OnCreate cuûa CEmpWnd thöïc hieän caùc chuaån bò: memDrawDC.TextOut( 30, 100, Chuoãi, I ); Xem VD09. int CEmpWnd::OnCreate( LPCREATESTRUCT lpCreateStruct ) Laäp trình Windows vôùi MFC - Microsoft Visual C++ 6.0 - Leâ Ngoïc Thaïnh - lntmail@yahoo.com ÖÙng duïng coâng cuï GDI 64 65
CÓ THỂ BẠN MUỐN DOWNLOAD
-
Lập trình windows với MFC Micrisoft visual C++6.0- P1
10 p | 272 | 96
-
Lập trình windows với MFC Micrisoft visual C++6.0- P2
10 p | 216 | 69
-
Lập trình windows với MFC Micrisoft visual C++6.0- P10
10 p | 165 | 46
-
Lập trình windows với MFC Micrisoft visual C++6.0- P3
10 p | 202 | 45
-
Lập trình windows với MFC Micrisoft visual C++6.0- P13
10 p | 160 | 40
-
Lập trình windows với MFC Micrisoft visual C++6.0- P9
10 p | 138 | 33
-
Lập trình windows với MFC Micrisoft visual C++6.0- P5
10 p | 167 | 33
-
Lập trình windows với MFC Micrisoft visual C++6.0- P6
10 p | 155 | 30
-
Lập trình windows với MFC Micrisoft visual C++6.0- P11
10 p | 123 | 30
-
Lập trình windows với MFC Micrisoft visual C++6.0- P8
10 p | 108 | 25
-
Lập trình windows với MFC Micrisoft visual C++6.0- P12
10 p | 144 | 22
-
Lập trình windows với MFC Micrisoft visual C++6.0- P7
10 p | 100 | 19
Chịu trách nhiệm nội dung:
Nguyễn Công Hà - Giám đốc Công ty TNHH TÀI LIỆU TRỰC TUYẾN VI NA
LIÊN HỆ
Địa chỉ: P402, 54A Nơ Trang Long, Phường 14, Q.Bình Thạnh, TP.HCM
Hotline: 093 303 0098
Email: support@tailieu.vn