第3章 MFC的消息與命令_第1頁
第3章 MFC的消息與命令_第2頁
第3章 MFC的消息與命令_第3頁
第3章 MFC的消息與命令_第4頁
第3章 MFC的消息與命令_第5頁
已閱讀5頁,還剩66頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、第3章 MFC的消息和命令3.1 Windows操作系統(tǒng)的消息用戶通過窗口界面的各種操作最后轉(zhuǎn)化為發(fā)送到程序中的對象的各種消息,然后由Windows系統(tǒng)交由相應(yīng)的函數(shù)處理3.1.1 Windows消息的發(fā)送和接收消息: 消息號(hào):一條消息的標(biāo)識(shí),同時(shí)表達(dá)了消息的意義和來源 字參數(shù):wParam參數(shù) 長整型參數(shù):lParam參數(shù)消息被發(fā)送到其對應(yīng)的窗口,對于MFC來說,只有主框架CMainFrame和視圖類CView及其派生類才能接收消息用戶可以發(fā)送和接收消息,Windows提供兩個(gè)發(fā)送消息的函數(shù): PostMessage(),不理會(huì)消息是否已被處理 SendMessage(),等待消息處理完畢才

2、返回3.1.2 MFC的消息處理機(jī)制Windows消息處理機(jī)制: 事件發(fā)生格式化信息處理窗口消息映射: 將一條消息翻譯并交由相應(yīng)函數(shù)去處理的過程消息映射包括兩方面的內(nèi)容:1)在類的定義中(MyHelloView.h)有一行宏調(diào)用 DECLARE_MESSAGE_MAP() 用來聲明在該類中將使用消息映射來向函數(shù)映射消息。/ MyHelloView.h : interface of the CMyHelloView classclass CMyHelloView : public CView/ Attributespublic:CMyHelloDoc* GetDocument();/ Opera

3、tionsprotected:/AFX_MSG(CMyHelloView)/ NOTE - the ClassWizard will add and remove member functions here./ DO NOT EDIT what you see in these blocks of generated code !/AFX_MSGDECLARE_MESSAGE_MAP();2)在類的實(shí)現(xiàn)文件(MyHelloView.cpp)中加上消息映射表BEGIN_MESSAGE_MAP(CMyHelloView, CView)/AFX_MSG_MAP(CMyHelloView)/AFX_M

4、SG_MAP/ Standard printing commandsON_COMMAND(ID_FILE_PRINT, CView:OnFilePrint)ON_COMMAND(ID_FILE_PRINT_DIRECT, CView:OnFilePrint)ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView:OnFilePrintPreview)END_MESSAGE_MAP()宏,開始消息映射宏,具體實(shí)現(xiàn)所需要的消息映射。ID消息處理函數(shù)的名稱宏,結(jié)束消息映射表3.1 幾種常見的消息映射宏消息映射宏說 明ON_COMMAND指出由哪個(gè)函數(shù)處理指定的命令消息ON_C

5、ONTROL指出由哪個(gè)函數(shù)處理指定的控制消息ON_MESSAGE指出由哪個(gè)函數(shù)處理指定的用戶自定義消息ON_REGISTERED_MESSAGE指出由哪個(gè)函數(shù)處理指定的已登記用戶定義消息ON_UPDATE_COMMAND_UI指出由哪個(gè)函數(shù)處理指定的用戶接口更新命令消息應(yīng)用程序應(yīng)用程序操作系統(tǒng)應(yīng)用程序操作系統(tǒng)用戶Windows消息處理機(jī)制通過操作系統(tǒng)發(fā)送消息消息響應(yīng)函數(shù)包括:w在類的定義中,加入消息處理成員函數(shù)的函數(shù)原型(函數(shù)聲明)w在類的消息映射表中加入相應(yīng)的消息映射入口項(xiàng)w在類的實(shí)現(xiàn)中加入該消息處理成員函數(shù)的函數(shù)體消息處理函數(shù)的原型前面要以afx_msg開頭;ClassWizard會(huì)自動(dòng)加

6、入這3部分內(nèi)容,用戶只需添加代碼3.1.3 Windows的消息分類w標(biāo)準(zhǔn)Windows消息由窗口和視圖來處理,通常包括WM前綴,最常用的是鼠標(biāo)、鍵盤和窗口消息三類。消息類型消息標(biāo)識(shí)()ID說明(產(chǎn)生消息的事件)鼠標(biāo)消息WM_MOUSEMOVE鼠標(biāo)移動(dòng)時(shí)發(fā)送該消息WM_LBUTTONDOWN 鼠標(biāo)左鍵被按下時(shí)發(fā)送該消息WM_LBUTTONUP鼠標(biāo)左鍵被釋放時(shí)發(fā)送該消息WM_LBUTTONDBCLK 鼠標(biāo)左鍵被雙擊時(shí)發(fā)送該消息WM_RBUTONDOWN鼠標(biāo)右鍵被按下時(shí)發(fā)送該消息WM_RBUTTONUP鼠標(biāo)右鍵被釋放時(shí)發(fā)送該消息WM_RBUTTONDBCLK 鼠標(biāo)右鍵被雙擊時(shí)發(fā)送該消息鍵盤消息WM

7、_CHAR將一次單擊鍵翻譯成一個(gè)非系統(tǒng)字符時(shí),發(fā)送該消息WM_KEYDOWN按下一個(gè)非系統(tǒng)鍵時(shí),發(fā)送該消息WM_KEYUP釋放一個(gè)非系統(tǒng)鍵時(shí),發(fā)送該消息窗口消息WM_CREATE生成一個(gè)窗口時(shí)發(fā)送該消息WM_DESTROY銷毀一個(gè)窗口時(shí)發(fā)送該消息WM_CLOSE關(guān)閉一個(gè)窗口時(shí)發(fā)送該消息WM_SIZE改變窗口大小時(shí)發(fā)送該消息WM_MOVE移動(dòng)一個(gè)窗口時(shí)發(fā)送該消息WM_PAINT重畫窗口工作區(qū)時(shí)發(fā)送該消息w控件通告消息包括按下按鈕或輸入字符等事件的消息由窗口和視圖來處理例如,當(dāng)用戶對編輯控件中的文本作出修改后,編輯控件向其父窗口發(fā)送的WM_COMMAND消息中包含EN_CHANGE控件通告碼。w命

8、令消息n也以WM_COMMAND為消息名n包含命令的標(biāo)示符(ID),以區(qū)分具體的命令n來源是以下3種用戶接口對象:n菜單:選擇某菜單n工具欄:按下工具欄按鈕n加速鍵:在鍵盤上按下了定義的加速鍵n可以被更廣泛的對象(如文檔、文檔模板、應(yīng)用程序模板等)處理w自定義消息n用戶可以自定義消息,在應(yīng)用程序中主動(dòng)發(fā)出n一般用于應(yīng)用程序的某一部分內(nèi)部處理命令消息的傳遞路徑如果某個(gè)命令在多個(gè)對象中都有消息處理函數(shù),那么是不是所有對象的消息處理函數(shù)都要被調(diào)用呢?答案是否定的,只有其中之一被調(diào)用。這就是命令消息的傳遞路徑。當(dāng)某個(gè)命令消息產(chǎn)生時(shí),它就被應(yīng)用框架按命令消息傳遞路徑傳送,一旦傳遞過程中遇到了某個(gè)對象有該

9、消息的處理函數(shù),則處理該消息,中斷傳遞過程,不再搜索后續(xù)的對象。例:一個(gè)MDI應(yīng)用程序,“編輯”菜單下的“復(fù)制”菜單項(xiàng),當(dāng)用戶選擇時(shí),對應(yīng)的命令消息按如下所述到達(dá)其處理函數(shù):1) MDI主邊框窗口首先收到此命令消息;2) 主邊框窗口將處理命令的機(jī)會(huì)先讓給其當(dāng)前活動(dòng)的MDI子邊框窗口;3) 子邊框窗口在搜索自己的消息映射之前又將處理命令的機(jī)會(huì)先讓給其活動(dòng)的視圖;4) 視圖先搜索自己的消息映射,查找對應(yīng)的處理函數(shù),沒有,則將消息傳遞給與其關(guān)聯(lián)的文檔;5) 文檔搜索自己的消息映射,發(fā)現(xiàn)有該命令消息的處理函數(shù),則該處理函數(shù)就被應(yīng)用框架調(diào)用,完成復(fù)制功能,而命令傳遞終止,不再繼續(xù);6) 如果文檔也沒有處

10、理函數(shù),則命令又被傳遞給文檔模板,若還沒有,則命令又回到子邊框窗口,子邊框窗口現(xiàn)在才搜索自己的消息映射。如果同樣沒有處理函數(shù),命令就被傳回給主邊框窗口;最終是傳遞到應(yīng)用對象,由它來收拾未被處理的命令消息。3.2 Windows程序框架主事件標(biāo)準(zhǔn)Windows消息循環(huán)while(GetMessage(&msg,.) TranslateMessage(&msg); DispatchMessage(&msg);從時(shí)間序列中獲得下一個(gè)消息,將消息存儲(chǔ)在msg結(jié)構(gòu)中翻譯標(biāo)準(zhǔn)消息分派標(biāo)準(zhǔn)消息GetMesssage( )TranslateMesssage( )DispatchMesssage( )WinMa

11、in( )事 件 句 柄WindowProc( )wm-Create:wm-Paint:.wm-Destroy:屏幕窗口消息隊(duì)列msg1.msgn用戶輸入PostMessage( )3.3 鼠標(biāo)消息處理實(shí)例在MFC編程中,伴隨鼠標(biāo)輸入,Windows將會(huì)產(chǎn)生相應(yīng)的消息如:鼠標(biāo)左鍵按下時(shí),產(chǎn)生WM_LBUTTONDOMN消息如:鼠標(biāo)左鍵釋放時(shí),產(chǎn)生WM_LBUTTONUP消息對大部分的鼠標(biāo)消息Windows系統(tǒng)均有默認(rèn)的處理3.3.1 鼠標(biāo)消息處理程序3.3.2 聲明視圖類的數(shù)據(jù)成員視圖類中添加一數(shù)據(jù)成員:/ MyHelloView.h : interface of the CMyHelloVi

12、ew classclass CMyHelloView : public CVtected: CString m_MousePoint; /存儲(chǔ)鼠標(biāo)的方式和位置/ Generated message map functions.視圖類的構(gòu)造函數(shù)中初始化/ MyHelloView.cpp : implementation of the CMyHelloView classCMyHelloView:CMyHelloView()/ TODO: add construction code herem_MousePoint=;/初始化為空串3.3.3 修改屏幕重畫函數(shù)OnDraw( )voi

13、d CMyHelloView:OnDraw(CDC* pDC)CMyHelloDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);/ TODO: add draw code for native data here/pDC-TextOut(100,80,Hello, 我們開始VC+編程了!);pDC-TextOut(100,100,m_MousePoint); /在坐標(biāo)(100,100)處顯示字符串3.3.4 添加鼠標(biāo)消息WM_LBUTTONDOWN響應(yīng)函數(shù)在上述操作中,ClassWizard(類向?qū)?自動(dòng)為應(yīng)用程序作了以下三件事:1)添加了3個(gè)響應(yīng)函數(shù)的

14、原型說明:/ MyHelloView.hclass CMyHelloView : public CView./ Generated message map functionsprotected:/AFX_MSG(CMyHelloView)afx_msg void OnLButtonDown(UINT nFlags, CPoint point);afx_msg void OnLButtonUp(UINT nFlags, CPoint point);afx_msg void OnMouseMove(UINT nFlags, CPoint point);/AFX_MSGDECLARE_MESSAGE

15、_MAP();2)添加了3個(gè)消息映射:/ MyHelloView.cppBEGIN_MESSAGE_MAP(CMyHelloView, CView)/AFX_MSG_MAP(CMyHelloView)ON_WM_LBUTTONDOWN()ON_WM_LBUTTONUP()ON_WM_MOUSEMOVE()/AFX_MSG_MAP/ Standard printing commandsON_COMMAND(ID_FILE_PRINT, CView:OnFilePrint)ON_COMMAND(ID_FILE_PRINT_DIRECT, CView:OnFilePrint)ON_COMMAND(I

16、D_FILE_PRINT_PREVIEW, CView:OnFilePrintPreview)END_MESSAGE_MAP()3)添加了3個(gè)響應(yīng)函數(shù)的空函數(shù)體:/ MyHelloView.cppvoid CMyHelloView:OnLButtonDown(UINT nFlags, CPoint point) / TODO: Add your message handler code here and/or call defaultCView:OnLButtonDown(nFlags, point);void CMyHelloView:OnLButtonUp(UINT nFlags, CPo

17、int point) / TODO: Add your message handler code here and/or call defaultCView:OnLButtonUp(nFlags, point);void CMyHelloView:OnMouseMove(UINT nFlags, CPoint point) / TODO: Add your message handler code here and/or call defaultCView:OnMouseMove(nFlags, point);3.3.5 編寫信息響應(yīng)函數(shù)代碼void CMyHelloView:OnLButto

18、nDown(UINT nFlags, CPoint point) / TODO: Add your message handler code here and/or call defaultm_MousePoint.Format(鼠標(biāo)左鍵在點(diǎn)(%d,%d)按下,point.x,point.y);Invalidate(); CView:OnLButtonDown(nFlags, point);void CMyHelloView:OnLButtonUp(UINT nFlags, CPoint point) m_MousePoint.Format(鼠標(biāo)左鍵被釋放);Invalidate(); CVi

19、ew:OnLButtonUp(nFlags, point);void CMyHelloView:OnMouseMove(UINT nFlags, CPoint point) m_MousePoint.Format(鼠標(biāo)位于點(diǎn)(%d,%d),point.x,point.y);Invalidate(); CView:OnMouseMove(nFlags, point);3.3.6 查看結(jié)果3.3.7 技術(shù)要點(diǎn)Invalidate(); 作用是讓用戶區(qū)無效,從而調(diào)用重畫函數(shù)OnDraw()3.4 鍵盤消息處理實(shí)例鍵盤的輸入將產(chǎn)生相應(yīng)的Windows鍵盤消息如:用戶按下鍵盤鍵時(shí)產(chǎn)生WM_KEYDOWN

20、消息如:用戶釋放鍵盤鍵時(shí)產(chǎn)生 WM_KEYUP消息對大部分的鍵盤消息,Windows系統(tǒng)均有默認(rèn)的處理方法3.4.1 鍵盤消息處理程序3.4.2 聲明視圖類的數(shù)據(jù)成員添加數(shù)據(jù)成員class CMyHelloView : public CVtected: CString m_MousePoint; /存儲(chǔ)鼠標(biāo)的方式和位置 int m_nLine; /存儲(chǔ)回車次數(shù) CString m_strDisplay; /存儲(chǔ)當(dāng)前輸入的字符.;初始化CMyHelloView:CMyHelloView()/ TODO: add construction code herem_MousePoint=

21、;/初始化為空串m_nLine=0; /回車次數(shù)初始化為0次3.4.3 添加鍵盤消息響應(yīng)函數(shù)在上述操作中,ClassWizard(類向?qū)?自動(dòng)為應(yīng)用程序作了以下三件事:1)添加了1個(gè)響應(yīng)函數(shù)的原型說明:/ MyHelloView.hclass CMyHelloView : public CView./ Generated message map functionsprotected:/AFX_MSG(CMyHelloView)afx_msg void OnLButtonDown(UINT nFlags, CPoint point);afx_msg void OnLButtonUp(UINT n

22、Flags, CPoint point);afx_msg void OnMouseMove(UINT nFlags, CPoint point);afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);/AFX_MSGDECLARE_MESSAGE_MAP();2)添加了1個(gè)消息映射:/ MyHelloView.cppBEGIN_MESSAGE_MAP(CMyHelloView, CView)/AFX_MSG_MAP(CMyHelloView)ON_WM_LBUTTONDOWN()ON_WM_LBUTTONUP()ON_WM_MOU

23、SEMOVE()ON_WM_CHAR()/AFX_MSG_MAP/ Standard printing commandsON_COMMAND(ID_FILE_PRINT, CView:OnFilePrint)ON_COMMAND(ID_FILE_PRINT_DIRECT, CView:OnFilePrint)ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView:OnFilePrintPreview)END_MESSAGE_MAP()3)添加了1個(gè)響應(yīng)函數(shù)的空函數(shù)體:/ MyHelloView.cppvoid CMyHelloView:OnChar(UINT nChar

24、, UINT nRepCnt, UINT nFlags) / TODO: Add your message handler code here and/or call defaultCView:OnChar(nChar, nRepCnt, nFlags);3.4.4 編輯消息響應(yīng)函數(shù)void CMyHelloView:OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) / TODO: Add your message handler code here and/or call defaultif(nChar=VK_RETURN) /如按下回車鍵m_str

25、Display.Empty(); /清空變量m_nLine+; /行數(shù)加一elsem_strDisplay+=nChar; /將輸入的字符添加到變量m_strDisplay的尾端CClientDC dc(this);dc.TextOut(0,m_nLine*20,m_strDisplay);CView:OnChar(nChar, nRepCnt, nFlags);3.4.5 查看結(jié)果3.5 定時(shí)器消息處理實(shí)例定時(shí)器能夠以固定的時(shí)間間隔產(chǎn)生WM_TIMER事件,它是用軟件實(shí)現(xiàn)的3.5.1 定時(shí)器程序程序運(yùn)行每隔一定的時(shí)間間隔,發(fā)出“滴答”聲1)創(chuàng)建一個(gè)定時(shí)器,使之在規(guī)定的時(shí)間間隔,發(fā)送特定的消息

26、;2)在消息響應(yīng)函數(shù)中,編寫發(fā)“滴答”聲音的代碼。3.5.2 安裝定時(shí)器void CMyHelloView:OnInitialUpdate() CView:OnInitialUpdate();/ TODO: Add your specialized code here and/or call the base classSetTimer(1,500,NULL); /安裝定時(shí)器3.5.3 清除定時(shí)器void CMyHelloView:OnDestroy() CView:OnDestroy();/ TODO: Add your message handler code hereKillTimer(

27、1); /清除定時(shí)器3.5.4 添加定時(shí)器消息WM_TIMER響應(yīng)函數(shù)void CMyHelloView:OnTimer(UINT nIDEvent) / TODO: Add your message handler code here and/or call defaultMessageBeep(-1);CView:OnTimer(nIDEvent);3.5.5 查看結(jié)果程序運(yùn)行每隔一定的時(shí)間間隔,發(fā)出“滴答”聲3.5.6 技術(shù)要點(diǎn)1. SetTimer()函數(shù)UINT SetTimer(UINT nIDEvent, UINT nElapse, void(CALLBACK EXPORT *l

28、pfnTimer(HWND,UINT,UINT,DWORD); nIDEvent: 定時(shí)器的ID; nElapse: 指定定時(shí)器時(shí)間間隔; lpfnTimer: 處理函數(shù)的地址,如設(shè)置為NULL,則WM_TIMER消息放在消息隊(duì)列中,由窗口對象處理如果安裝成功,返回非零2. KillTimer()函數(shù)BOOL KillTimer(int nIDEvent);nnIDEvent: 定時(shí)器的ID;程序退出時(shí),必須清除定時(shí)器3.6 自定義消息處理實(shí)例用戶可以自定義消息,在應(yīng)用程序中主動(dòng)發(fā)出,這種消息一般用于應(yīng)用程序的某一部分內(nèi)部處理3.6.1 基本知識(shí)1. 定義用戶消息的IDconst WM_USE

29、RMSG = WM_USER + nWindows定義的第一個(gè)有效的用戶消息新的用戶消息標(biāo)示符整數(shù)2. 用戶消息的發(fā)送wPostMessage()函數(shù):將消息插入消息隊(duì)列并返回,由處理線程處理;wGetMessage(),PeekMessage()函數(shù):獲取消息BOOL PostMessage(HWND hWnd, /接收消息的窗口的句柄UINT Msg, /消息的IDWPARAM wParam, /消息參數(shù)1LPARAM lParam, /消息參數(shù)2);3.6.2 定義用戶消息和消息響應(yīng)函數(shù)1. 定義用戶消息/ MyHelloView.hconst WM_USERMSG = WM_USER

30、+ 100;class CMyHelloView : public CView加入到MyHelloView.h中CMyHelloView類聲明的上面2. 聲明用戶消息響應(yīng)函數(shù)/ MyHelloView.hconst WM_USERMSG = WM_USER + 100;class CMyHelloView : public CView/ Operationspublic:void OnMyFunction(); /用戶消息響應(yīng)函數(shù)聲明在MyHelloView.h中加上該函數(shù)的聲明3. 定義用戶消息響應(yīng)函數(shù)/ MyHelloView.cppvoid CMyHelloView:OnMyFunction()MessageBox(消息發(fā)送成功!:);3.6.3 添加消息映射/ MyHelloView.cppBEGIN_MESSAGE_MAP(CMyHelloView, CView)/AFX_MSG_MAP(CMyHelloView)ON_WM_LBUTTONDOWN()O

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論