




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、在MFC中添加用戶自定義消息首先弄清楚兩點:(1)誰要發(fā)送這個消息(2)誰要接受這個消息。用一個簡單的例子來說明。對象A向B(也可以就是A到A)發(fā)送消息。1 發(fā)送消息首先在A的頭文件中定義這個消息:#define WM_USERMESSAGE WM_USER+30所有自定義消息都是以WM_USER消息為基礎(chǔ)加上一個任意的自然數(shù)來表示的。A是向外發(fā)送消息的對象,因此在A的某個方法(函數(shù))里就會調(diào)用用來發(fā)消 息的函數(shù)B:SendMessage()/B:PostMessage(),因為是B接受消息,因此是如上的形式。2 接受消息對象接受一個消息,應(yīng)該有三部分:在頭文件中有該消息的處理函數(shù)的原型;在實
2、現(xiàn)文件中有接受消息映射的宏; 以及該消息的處理函數(shù)的具體實現(xiàn)。2.1 頭文件中加上自定義消息的處理函數(shù)原型在DECLARE_MESSAGE_MAP()語句之前,一對AFX_MSG之間加上如下形式的函數(shù)原型:afx_msg LRESULT OnProcName( WPARAM wParam, LPARAM lParam );對Win32來說,wParam, lParam是傳遞消息最常用的手段。2.2 在實現(xiàn)文件中加上接受消息映射的宏在cpp文件里,BEGIN_MESSAGE_MAP語句之后,在一對AFX_MSG_MAP之間,增加 如下形式的代碼:ON_MESSAGE(WM_USERMESSAGE
3、, OnProcName)上面是不用分號結(jié)尾的。2.3 在實現(xiàn)文件中給出消息處理函數(shù)的具體實現(xiàn)。發(fā)信人: Amia (小羊橘子和中南海有緣), 信區(qū): VisualC標題: MFC中自由使用自定義消息發(fā)信站: 哈工大紫丁香 (2003年11月26日07:45:34 星期三), 站內(nèi)信件消息映射、循環(huán)機制是Windows程序運行的基本方式。VC+ MFC 中有許多現(xiàn)成的消息句柄,可當我們需要完成其它的任務(wù),需要自定義消息,就遇到了一些困難。在MFCClassWizard中不允許添加用戶自定義消息,所以我們必須在程序中添加相應(yīng)代碼,以便可以象處理其它消息一樣處理自定義消息。通常的做法是采取以下步驟
4、:第一步:定義消息。推薦用戶自定義消息至少是WM_USER+100,因為很多新控件也要使用WM_USER消息。#define WM_MY_MESSAGE (WM_USER+100)第二步:實現(xiàn)消息處理函數(shù)。該函數(shù)使用WPRAM和LPARAM參數(shù)并返回LPESULT。LPESULT CMainFrame:OnMyMessage(WPARAM wParam, LPARAM lParam)/ TODO: 處理用戶自定義消息.return 0;第三步:在類頭文件的AFX_MSG塊中說明消息處理函數(shù):class CMainFrame:public CMDIFrameWnd./ 一般消息映射函數(shù)prote
5、cted:/ AFX_MSG(CMainFrame)afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);afx_msg void OnTimer(UINT nIDEvent);afx_msg LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam);/AFX_MSGDECLARE_MESSAGE_MAP()第四步:在用戶類的消息塊中,使用ON_MESSAGE宏指令將消息映射到消息處理函數(shù)中。BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)/AFX_MSG_MAP(
6、CMainFrame)ON_WM_CREATE()ON_WM_TIMER()ON_MESSAGE(WM_MY_MESSAGE, OnMyMessage)/AFX_MSG_MAPEND_MESSAGE_MAP()如果用戶需要一個定義整個系統(tǒng)唯一的消息,可以調(diào)用SDK函數(shù)RegisterWindowMessage定義消息:static UINT WM_MY_MESSAGE=RegisterWindowMessage(User);并使用ON_REGISTERED_MESSAGE宏指令取代ON_MESSAGE宏指令,其余步驟同上。當需要使用自定義消息時,可以在相應(yīng)類中的函數(shù)中調(diào)用函數(shù)PostMessa
7、ge或SendMessage發(fā)送消息PoseMessage(WM_MY_MESSAGE,O,O); 如果向其他進程發(fā)送消息可通過如下方法發(fā)送消息:DWORD result;SendMessageTimeout(wnd-m_hWnd, / 目標窗口WM_MY_MESSAGE, / 消息0, / WPARAM0, / LPARAMSMTO_ABORTIFHUNG |SMTO_NORMAL,TIMEOUT_INTERVAL,&result);以避免其它進程如果被阻塞而造成系統(tǒng)死等狀態(tài)??墒侨绻枰蚱渌?如主框架、子窗口、視類、對話框、狀態(tài)條、工具條或其他控件等)發(fā)送消息時,上述方法顯得無能為力,
8、而在編程過程中往往需要獲取其它類中的某個識別信號,MFC框架給我們造成了種種限制,但是可以通過獲取某個類的指針而向這個類發(fā)送消息,而自定義消息的各種動作則在這個類中定義,這樣就可以自由自在的向其它類發(fā)送消息了。下面舉的例子敘述了向視類和框架類發(fā)送消息的方法:在主框架類中向視類發(fā)送消息:視類中定義消息:ON_REGISTERED_MESSAGE(WM_MY_MESSAGE,OnMyMessage) /定義消息映射視類定義消息處理函數(shù):/ 消息處理函數(shù)LRESULT CMessageView:OnMyMessage(WPARAM wParam, LPARAM lParam)/ TODO: 處理用戶
9、自定義消息.return 0;/發(fā)送消息的測試函數(shù)void CMainFrame:OnTest()CView * active = GetActiveView();/獲取當前視類指針if(active != NULL)active-PostMessage(WM_MY_MESSAGE,0,0);在其它類中向視類發(fā)送消息:/發(fā)送消息的測試函數(shù)void CMainFrame:OnTest()CMDIFrameWnd *pFrame;CMDIChildWnd *pChild;CView *pView;/獲取主窗口指針pFrame =(CMDIFrameWnd*)AfxGetApp()-m_pMainW
10、nd;/ 獲取子窗口指針pChild = (CMDIChildWnd *) pFrame-GetActiveFrame();/獲取視類指針pView = pChild-GetActiveView();if(pView != NULL)pView-PostMessage(WM_MY_MESSAGE,0,0);/發(fā)送消息其余步驟同上。在視類中向主框架發(fā)送消息:首先在主框架中定義相關(guān)的消息,方法同上,然后在發(fā)送消息的函數(shù)中添加代碼如下/發(fā)送消息的測試函數(shù)void CMessageView:OnTest()CFrameWnd * active = GetActiveFrame();/獲取當前主窗口框架
11、指針if(active != this)active-PostMessage(WM_MY_MESSAGE,0,0);return 0;在其它類中向不同的類發(fā)送消息可依次方法類推,這樣我們的程序就可以的不受限制向其它類和進程發(fā)送消息,而避免了種種意想不到的風險。下面一個例子程序為多文檔程序里在一對話框中向視類發(fā)送消息,詳述了發(fā)送自定義消息的具體過程。實現(xiàn)步驟:第一步:在VC+中新建工程Message,所有ClassWizard步驟選項均為缺省,完成。第二步:在主菜單中添加測試菜單為調(diào)出對話框,在框架類中建立相應(yīng)函數(shù)OnTest()第三步:在資源中建立對話框,通過ClassWizard添加新類Te
12、stDialog,添加測試按鈕,在對話框類中建立相應(yīng)函數(shù)OnDialogTest()/通過對話框按鈕發(fā)送消息的函數(shù)void TestDialog:OnDialogTest()CMDIFrameWnd *pFrame;CMDIChildWnd *pChild;CView *pView;/獲取主窗口指針pFrame =(CMDIFrameWnd*)AfxGetApp()-m_pMainWnd;/ 獲取子窗口指針pChild = (CMDIChildWnd *) pFrame-GetActiveFrame();/獲取視類指針pView = pChild-GetActiveView();if(acti
13、ve != NULL)active-PostMessage(WM_MY_MESSAGE,0,0);/發(fā)送消息在Message.h頭文件中添加如下語句:static UINT WM_MY_MESSAGE=RegisterWindowMessage(Message);第四步:在視類中添加自定義消息:在頭文件MessageView.h中添加消息映射protected:/AFX_MSG(CMessageView)/AFX_MSGafx_msg LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam); /此行為添加代碼DECLARE_MESSAGE_MAP()
14、在視類文件MessageView.cpp中的消息映射中添加自定義消息映射BEGIN_MESSAGE_MAP(CMessageView, CView)/AFX_MSG_MAP(CMessageView)/AFX_MSG_MAP/ Standard printing commandsON_REGISTERED_MESSAGE(WM_MY_MESSAGE,OnMyMessage) /此行添加代碼定義唯一消息END_MESSAGE_MAP()添加相應(yīng)的0消息處理函數(shù)LRESULT CMessageView:OnMyMessage(WPARAM wParam, LPARAM lParam)CRect r
15、ect;GetClientRect(&rect);InvalidateRect(&rect);test=!test;return 0;在MessageView.h中添加布爾變量 public:BOOL test;在視類構(gòu)造函數(shù)中初始化 test變量:test=FALSE;修改CMessageView:OnDraw()函數(shù)void CMessageView:OnDraw(CDC* pDC)CMessageDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);/ 以下程序顯示消息響應(yīng)效果if(test)pDC-TextOut(0,0,消息響應(yīng)!);第五步:顯示測
16、試對話框在MainFrame類中包含對話框頭文件:#include TestDialog.h;OnTest()函數(shù)中添加代碼void CMainFrame:OnTest()TestDialog dialog;dialog.DoModal();運行程序,在測試菜單打開對話框,點擊測試按鈕即可看到結(jié)果。關(guān)于VC+中兩種自定義消息的發(fā)送與接收的方法實現(xiàn)進行說明說明:以下用一個自創(chuàng)的對話框類(MyMessageDlg)向視圖類(MessageTestView)發(fā)送自定義消息為例,說明這兩種不同方法的自定義消息的總結(jié):消息傳遞的方法一:使用ON_MESSAGE使用ON_MESSAGE響應(yīng)消息,必須配合定
17、義消息#define WM_MY_MESSAGE (WM_USER+100)對于發(fā)送消息者-MyMessageDlg,在其MyMessageDlg.h中,定義#define WM_MY_MESSAGE (WM_USER+100)在其MyMessageDlg.cpp中要先添加:#include MainFrm.h因為使用了CMainFrame*定義對象。并且要有測試消息的函數(shù):void MyMessageDlg:OnButtonMsg() / TODO: Add your control notification handler code here CMainFrame* pMF=(CMainF
18、rame*)AfxGetApp()-m_pMainWnd; /先通過獲取當前框架指針 CView * active = pMF-GetActiveView();/才能獲取當前視類指針 if(active != NULL) /獲取了當前視類指針才能發(fā)送消息 active-PostMessage(WM_MY_MESSAGE,0,0); /使用PostMessage發(fā)送消息對于消息的接受者-MessageTestView,在其MessageTestView.h中,也要定義#define WM_MY_MESSAGE (WM_USER+100)并定義消息映射函數(shù)-OnMyMessage()protect
19、ed:/AFX_MSG(CMessageTestView)afx_msg LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam); /AFX_MSGDECLARE_MESSAGE_MAP()在其MessageTestView.cpp中,先要聲明響應(yīng)消息:BEGIN_MESSAGE_MAP(CMessageTestView, CEditView)/AFX_MSG_MAP(CMessageTestView)ON_MESSAGE(WM_MY_MESSAGE, OnMyMessage)/AFX_MSG_MAP再添加消息響應(yīng)的函數(shù)實現(xiàn):LRESULT CMes
20、sageTestView:OnMyMessage(WPARAM wParam, LPARAM lParam)MessageBox(OnMyMessage!);return 0; 消息傳遞的方法二:使用ON_REGISTERED_MESSAGE使用ON_REGISTERED_MESSAGE注冊消息,必須配合static UINT WM_MY_MESSAGE=RegisterWindowMessage(Message);對于消息的發(fā)送者-MyMessageDlg,在其MyMessageDlg.h中,只要定義static UINT WM_MY_MESSAGE=RegisterWindowMessag
21、e(Message);就可以了。在其MyMessageDlg.cpp中要先添加:#include MainFrm.h因為使用了CMainFrame*定義對象。并且要有測試消息的函數(shù):void MyMessageDlg:OnButtonMsg() / TODO: Add your control notification handler code here CMainFrame* pMF=(CMainFrame*)AfxGetApp()-m_pMainWnd; /先通過獲取當前框架指針 CView * active = pMF-GetActiveView();/才能獲取當前視類指針 if(act
22、ive != NULL) /獲取了當前視類指針才能發(fā)送消息 active-PostMessage(WM_MY_MESSAGE,0,0); /使用PostMessage發(fā)送消息對于消息的接收者-MessageTestView,在其MessageTestView.h中不要定義static UINT WM_MY_MESSAGE=RegisterWindowMessage(Message);應(yīng)該把這個定義放到MessageTestView.cpp中,要不會出現(xiàn): redefinition在其MessageTestView.h中只要定義消息映射函數(shù)protected:/AFX_MSG(CMessageT
23、estView)afx_msg LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam); /AFX_MSGDECLARE_MESSAGE_MAP()在其MessageTestView.cpp中,先定義static UINT WM_MY_MESSAGE=RegisterWindowMessage(Message);接著注冊消息:BEGIN_MESSAGE_MAP(CMessageTestView, CEditView)/AFX_MSG_MAP(CMessageTestView) ON_REGISTERED_MESSAGE(WM_MY_MESSAGE,O
24、nMyMessage)/AFX_MSG_MAP最后添加消息響應(yīng)的函數(shù)實現(xiàn):LRESULT CMessageTestView:OnMyMessage(WPARAM wParam, LPARAM lParam)MessageBox(OnMyMessage!);return 0;-比較兩種方法,只是略有不同。但也要小心謹慎,以免出現(xiàn)接收不到消息的情況。 -其他注意事項:發(fā)送消息的-MyMessageDlg.cpp前也要定義static UINT WM_MY_MESSAGE=RegisterWindowMessage(Message);接受消息的-MessageTestView.cpp前也要定義sta
25、tic UINT WM_MY_MESSAGE=RegisterWindowMessage(Message);RegisterWindowMessage(Message)中的內(nèi)容是什么不重要,寫什么都可以,單必須發(fā)送者與接受者是一樣的內(nèi)容,例如:MessageMFC 消息類型1、命令消息(WM_COMMAND) 所有派生自CCmdTarget的類都有資格接受WM_COMMAND。2、Window消息(WM_xxx) 所有派生自CWnd的類都有資格接受WM_xxx。 3、控件消息(WM_NOTIFY) 控件向其父窗口通知消息。消息處理 1、WM_xxx消息處理窗口類(自身)處理基類處理CWndDe
26、fWindowProc()處理; 其所對應(yīng)的宏一般為在消息WM_前面加上ON_。 2、命令消息處理 命令消息來自命令用戶接口對象(菜單、加速鍵或工具欄按鈕)發(fā)出的WM_COMMAND消息; 、WM_COMMAND消息 其所包含的類型和對應(yīng)的宏如下: 、ON_COMMAND(ID,pfn) 標準的命令消息; 、ON_COMMAND_EX(ID,pfn) 多個對象對同一個命令I(lǐng)D的處理; 其函數(shù)的原型如下: afx_msgBOOLpfn(UINTnID) 說明: 當返回TRUE時表示已經(jīng)處理,不用在消息處理鏈中繼續(xù)處理該命令;為FALSE時表示繼續(xù)在消息處理鏈中處理該命令。 注意: 其一:在多對象
27、處理中一定要使用該宏; 其二:pfn(UINTnID)(消息處理函數(shù))返回值將其類型void改成BOOL,而且必須為FALSE; 其三:多個對象的處理是由高層向低層的過程:即視圖類主框架窗口類應(yīng)用程序類; 、ON_COMMAND_RANGE(nID,nLastID,pfn) 多個命令I(lǐng)D提供相同的處理; 注意: 其一:確保nID、nLastID的值在Resource.h中是連續(xù)的。 其二:一般在函數(shù)pfn(UINTnID)中加入?yún)?shù),用來確定那一個按鈕點擊。 、CN_UPDATE_COMMAND_UI消息 當菜單項、工具欄按鈕等命令用戶接口對象要更新其狀態(tài)時所對應(yīng)的消息,它所包含的類型和對應(yīng)的
28、宏如下: 、ON_UPDATE_COMMAND_UI(ID,pfn) 其中函數(shù)的原型如下:afx_msgvoidpfn(CCmdUI*pCmdUI) 、ON_UPDATE_COMMAND_UI_RANGE(nID,nLastID,pfn) 該函數(shù)可以處理一組命令用戶接口對象的外觀; 其中函數(shù)的原型如下:afx_msgvoidpfn(CCmdUI*pCmdUI) 重要: CCmdUI中的m_nID成員表示不同的ID,因此可以利用它來進行區(qū)別處理。3、控件的通知消息 從控件和子窗口發(fā)送到父窗口的WM_COMMAND通知消息(即在發(fā)送命令消息中加入控件的通知碼)。 注意:在Window9x新控件中不
29、再傳送WM_COMMAND通知消息,而是發(fā)送WM_NOTIFY消息,但為了兼容,舊有的控件還是傳送WM_COMMAND消息。 例如: CEdit控件向父窗口發(fā)送EN_CHANGE通知代碼的WM_COMMAND消息。注意:框架像傳送其它WM_消息一樣傳送通知消息,但有一個例外,即由按鈕控件發(fā)送的BN_CLICKED通知消息,被作為命令消息特別處理。 、WM_COMMAND其所對應(yīng)的宏如下: 、ON_CONTROL(通知碼,nID,fn) 、ON_CONTROL_RANGE(通知碼,nFirstID,nEndID,fn) 注意: 這兩個宏的應(yīng)用和ON_COMMAND、ON_COMMAND_RANG
30、E相同,所不同的是在宏前面加入通知碼。 注意:可以根據(jù)不同的控件的通知碼派生出特定的宏,其所派生的宏一般為在通知碼前面加上ON_。 、WM_NOTIFY其所對應(yīng)的宏如下: 、ON_NOTIFY(通知碼,nID,fn) 其中函數(shù)的原型如下: afx_msgvoidfn(NMHDR*pNotifyStruct,LRESULT*result) 其中結(jié)構(gòu): typedefstructtagNMHDR HWNDhwndFrom;/發(fā)送通知消息的控件的句柄; UINTidFrom;/發(fā)送通知消息的控件的ID; UINTcode;/通知碼; NMHDR; 、ON_NOTIFY_EX(通知碼,nID,fn)
31、表示一個消息在多個對象的成員函數(shù)中進行處理。 其中函數(shù)的原型如下: afx_msgBOOLfn(UINTnID,NMHDR*pNotifyStruct,LRESULT*result) 說明: 它必須返回BOOL類型的數(shù)值,其意義和ON_COMMAND_EX相同。 、ON_NOTIFY_RANGE(通知碼,nFirstID,nEnd,fn) 表示多個控件的通知消息在同一個函數(shù)中進行處理。 其中函數(shù)的原型如下: afx_msgvoidfn(UINTnID,NMHDR*pNotifyStruct,LRESULT*result) 說明: 其意義和ON_COMMAND_RANGE相同。 4、反射消息處理
32、 父窗口在處理控件窗口的通知消息WM_CTLCOLOR、WM_COMMAND、WM_NOTIFY時,會把該消息轉(zhuǎn)化為反射消息,并轉(zhuǎn)交給控件子窗口處理,只有在控件子窗體不處理該消息時,父窗口才有機會處理。 注意:在類的屬性對話框中的消息頁面可查反射消息(前面有=標志) 、WM_CTLCOLOR_REFLECT反射消息 其所對應(yīng)的宏如下: ON_WM_CTLCOLOR_REFLECT() 反射消息函數(shù)的原型: HBRUSHclass_nameCtlColor(CDC*pDC,UINTnCtlColor) returnNULL; 該函數(shù)用來重置控件的顔色;注意:必須returnCBrush才有效。
33、5、自定義的窗口消息 自定義窗口消息的消息標志都大于WM_USER(至少是WM_USER+100,因為許多控件都使用這一范圍的WM_USER消息) 使用自定義的消息分為二步: 、在Resource.h中定義消息標記 #defineWM_MYMSG (WM_USER+1000) 、在消息映射表中加入消息映射宏 BEGIN_MESSAGE_MAP() ON_MESSAGE(WM_MYMSG,fn) END_MESSAGE_MAP() 說明: 其對應(yīng)的宏為ON_MESSAGE(),其成員函數(shù)的原型為: afx_msgLRESULTfn(WPARAM,LPARAM) 6、登記消息 、在系統(tǒng)中注冊并獲取
34、一個登記消息的消息標記 UINTRegisterWindowMessage(LPCTSTR) 說明:通過API函數(shù)來注冊消息標記,其中LPCTSTR為用戶的任意字符串。例如: UINTWM_MYMSG=RegisterWindowMessage(MYMSG);其中WM_MYMSG是自定義無符號整型的消息標記。 、在消息映射表中加入消息映射宏 BEGIN_MESSAGE_MAP() ON_REGISTERED_MESSAGE(WM_MYMSG,fn) END_MESSAGE_MAP() 說明:其對應(yīng)的宏為ON_REGISTERED_MESSAGE(),其成員函數(shù)的原型為: afx_msgLRES
35、ULTfn(WPARAM,LPARAM) 注意:登記消息可以實現(xiàn)跨進程的數(shù)據(jù)通訊。 7、線程消息 只有繼承自CWinThread類才能允許處理線程消息。 、定義線程的消息標記 有兩種方法: (1)、使用自定義的消息標記,即:WM_USER; (2)、使用登記的消息標記,即:RegisterWindowMessage; 、在CWinThread繼承類的消息映射表中添加宏 ON_THREAD_MESSAGE(消息標記,fn)/自定義的消息; ON_REGISTERED_THREAD_MESSAGE(消息標記,fn)/登記的/消息 、其函數(shù)的原型如下: afx_msgvoidfn(WPARAMwPA
36、RAM,LPARAMlParam) 、引發(fā)線程消息 線程消息的引發(fā)必須調(diào)用CWinThread類的PostThreadMessage將消息投遞到線程消息隊列中。注意:可以通過AfxGetApp()函數(shù)獲取一個全局的應(yīng)用對象。PostThreadMessage(UINT,WPARAM,LPARAM) 8、WM_COPYDATA 操作系統(tǒng)維護一塊內(nèi)存來管理WM_COPYDATA消息,該消息主要用于跨進程傳遞數(shù)據(jù),傳遞的數(shù)據(jù)量達到232。 、定義一個COPYDATASTRUCT數(shù)據(jù)結(jié)構(gòu) typedefstructtagCOPYDATASTRUCT DWORDdwData;/自定義的特殊數(shù)據(jù); DWO
37、RDcbData;/以字節(jié)為單位的lpData的大?。?PVOIDlpData;/傳送的數(shù)據(jù)內(nèi)存塊的指針; COPYDATASTRUCT; 、其所對應(yīng)的宏 ON_WM_COPYDATA() 、其所對應(yīng)的函數(shù)的原型 afx_msgBOOLOnCopyData(CWnd*,COPYDATASTRUCT*) 說明:CWnd*:發(fā)送該消息的窗口的指針; 9、投遞和發(fā)送消息 通過向一個窗體投遞或發(fā)送消息,可以間接地驅(qū)動窗體的消息過程。 投遞(PostMessage):將消息放到線程的消息隊列中,然后不等線程處理該消息就直接返回到調(diào)用方。 發(fā)送(SendMessage):當一個線程向目標線程發(fā)送消息時,該
38、線程要一直等待,直到目標線程處理了該消息為止。 、投遞消息 BOOLCWndPostMessage(UINT,WPARAM=0,LPARAM=0) 說明:CWnd:目標窗口; 該函數(shù)將一條消息放入到應(yīng)用程序的消息隊列,然后不等窗口處理就直接返回。 、發(fā)送消息 LRESULTCWndSendMessage(UINT,WPARAM=0,LPARAM=0) 說明:CWnd:目標窗口; 該函數(shù)將一條消息放入到應(yīng)用程序的消息隊列,等待窗口處理后才返回。 為了避免線程陷入永久等待狀態(tài),可以用SendMessageTimeout代替SendMessage: LRESULTSendMessageTimeout
39、(HWND,UINT,WPARAM,LPARAM,UINT,UINT,PDWORD_PTR) 說明:HWND:窗口句柄; UINT:消息發(fā)送的選項,為SMTO_BLOCK時,可以防止線程無限等待,即根據(jù)一定的超時值返回。 UINT:超時,以毫秒為單位; PDWORD_PTR:返回值; 注意:CWnd沒有對該函數(shù)的包裝。 、投遞和發(fā)送消息 BOOLCWndSendNotifyMessage(UINT,WPARAM,LPARAM) 說明:CWnd:目標窗口; 該消息具有SendMessage和PostMessage兩種功能: 當目標窗口和發(fā)送窗口為同一個線程時,則相當于SendMessage的功能
40、;否則當不為同一個線程時,則為PostMessage的功能。 6-1、投遞和發(fā)送WM_XXX消息 在發(fā)送標準的WINDOW消息時,只要將該消息的ID、wParam、lParam參數(shù)放在SendMessage()和PostMessage()函數(shù)的相應(yīng)位置即可。 6-2、投遞和發(fā)送命令消息和控件的通知消息 在投遞和發(fā)送命令消息時,消息的ID為WM_COMMADN,而對于不同的菜單項、加速鍵、控件則wParam、lParam的取值不同。 wParam分成低、高兩部分,低部分為菜單項、加速鍵、控件的ID。高部分則: 菜單項:0;加速鍵:1;控件:通知碼 lParam:當控件時是控件的句柄,否則為NUL
41、L。 對于wParam參數(shù)可以采用自定義宏: WPARAMMAKEWPARAM(WORDwLow,WORDwHigh) 6-3、投遞和發(fā)送自定義的窗口消息 在投遞和發(fā)送自定義的窗口消息時,參數(shù)wParam、lParam沒有特別的涵義,只和普通函數(shù)的形參一樣進行數(shù)據(jù)的傳遞。 注意:PostMessage和SendMessage是不同的,前者投遞后就返回,而后者必須等到消息處理后再返回;所以在參數(shù)是局部或臨時時,使用PostMessage函數(shù)會引發(fā)錯誤(除非參數(shù)使用指針,則可避免錯誤),而必須使用SendMessage函數(shù)。 6-4、投遞和發(fā)送注冊的窗口消息 和6-3基本一樣,但它要特別注意的問題
42、是:在跨進程的處理消息時,如果將消息PostMessage、SendMessage到某個進程A,則必須在進程B中獲取進程A的窗口類名,并通過窗口類名獲取窗口的指針,最后再根據(jù)指針調(diào)用PostMessage、SendMessage函數(shù)。 注意:在獲取窗口的指針時,可以根據(jù)窗口類名或窗口的標題。 6-5、投遞和發(fā)送WM_COPYDATA消息 SendMessage(消息標記,WPARAM,LPARAM) 其中:消息標記:WM_COPYDATA; WPARAM:發(fā)送該消息的窗口句柄; LPARAM:COPYDATASTRUCT結(jié)構(gòu)的指針,先通過(LPVOID)進行轉(zhuǎn)換,再通過(LPARAM)進行轉(zhuǎn)換
43、,如下形式: (LPARAM)(LPVOID)&cdsSendMessage消息參數(shù)大全SENDMESSAGE 參數(shù):WM_CREATE = &H0001 應(yīng)用程序創(chuàng)建一個窗口 WM_DESTROY = &H0002 一個窗口被銷毀 WM_MOVE = &H0003 移動一個窗口 WM_SIZE = &H0005 改變一個窗口的大小 WM_ACTIVATE = &H0006 一個窗口被激活或失去激活狀態(tài); WM_SETFOCUS = &H0007 獲得焦點后 WM_KILLFOCUS = &H0008 失去焦點 WM_ENABLE = &H000A 改變enable狀態(tài) WM_SETREDRA
44、W = &H000B 設(shè)置窗口是否能重畫 WM_SETTEXT = &H000C 應(yīng)用程序發(fā)送此消息來設(shè)置一個窗口的文本 WM_GETTEXT = &H000D 應(yīng)用程序發(fā)送此消息來復(fù)制對應(yīng)窗口的文本到緩沖區(qū) WM_GETTEXTLENGTH = &H000E 得到與一個窗口有關(guān)的文本的長度(不包含空字符) WM_PAINT = &H000F 要求一個窗口重畫自己 WM_CLOSE = &H0010 當一個窗口或應(yīng)用程序要關(guān)閉時發(fā)送一個信號 WM_QUERYENDSESSION=&H0011 當用戶選擇結(jié)束對話框或程序自己調(diào)用ExitWindows函數(shù) WM_QUIT = &H0012 用來結(jié)
45、束程序運行或當程序調(diào)用postquitmessage函數(shù) WM_QUERYOPEN = &H0013 當用戶窗口恢復(fù)以前的大小位置時,把此消息發(fā)送給某個圖標 WM_ERASEBKGND = &H0014 當窗口背景必須被擦除時(例在窗口改變大小時) WM_SYSCOLORCHANGE = &H0015 當系統(tǒng)顏色改變時,發(fā)送此消息給所有頂級窗口 WM_ENDSESSION = &H0016 當系統(tǒng)進程發(fā)出WM_QUERYENDSESSION消息后,此消息發(fā)送給應(yīng)用程序, 通知它對話是否結(jié)束 WM_SYSTEMERROR = &H0017 WM_SHOWWINDOW = &H0018 當隱藏或顯
46、示窗口是發(fā)送此消息給這個窗口 WM_ACTIVATEAPP = &H001C 發(fā)此消息給應(yīng)用程序哪個窗口是激活的,哪個是非激活的; WM_FONTCHANGE = &H001D 當系統(tǒng)的字體資源庫變化時發(fā)送此消息給所有頂級窗口 WM_TIMECHANGE = &H001E 當系統(tǒng)的時間變化時發(fā)送此消息給所有頂級窗口 WM_CANCELMODE = &H001F 發(fā)送此消息來取消某種正在進行的摸態(tài)(操作) WM_SETCURSOR = &H0020 如果鼠標引起光標在某個窗口中移動且鼠標輸入沒有被捕獲時,就發(fā)消息給某個窗口 WM_MOUSEACTIVATE = &H0021 當光標在某個非激活的
47、窗口中而用戶正按著鼠標的某個鍵發(fā)送此消息給當前窗口 WM_CHILDACTIVATE = &H0022 發(fā)送此消息給MDI子窗口當用戶點擊此窗口的標題欄,或當窗口被激活,移動,改變大小 WM_QUEUESYNC = &H0023 此消息由基于計算機的訓(xùn)練程序發(fā)送,通過WH_JOURNALPALYBACK的hook程序 分離出用戶輸入消息 WM_GETMINMAXINFO = &H0024 此消息發(fā)送給窗口當它將要改變大小或位置; WM_PAINTICON = &H0026 發(fā)送給最小化窗口當它圖標將要被重畫 WM_ICONERASEBKGND = &H0027 此消息發(fā)送給某個最小化窗口,僅當
48、它在畫圖標前它的背景必須被重畫 WM_NEXTDLGCTL = &H0028 發(fā)送此消息給一個對話框程序去更改焦點位置 WM_SPOOLERSTATUS = &H002A 每當打印管理列隊增加或減少一條作業(yè)時發(fā)出此消息 WM_DRAWITEM = &H002B 當button,combobox,listbox,menu的可視外觀改變時發(fā)送 此消息給這些空件的所有者 WM_MEASUREITEM = &H002C 當button, combo box, list box, list view control, or menu item 被創(chuàng)建時,發(fā)送此消息給控件的所有者 WM_DELETEITE
49、M = &H002D 當the list box 或 combo box 被銷毀 或 當 某些項被刪除通過LB_DELETESTRING, LB_RESETCONTENT, CB_DELETESTRING, or CB_RESETCONTENT 消息 WM_VKEYTOITEM = &H002E 此消息有一個LBS_WANTKEYBOARDINPUT風格的發(fā)出給它的所有者來響應(yīng)WM_KEYDOWN消息 WM_CHARTOITEM = &H002F 此消息由一個LBS_WANTKEYBOARDINPUT風格的列表框發(fā)送給他的所有者來響應(yīng)WM_CHAR消息 WM_SETFONT = &H0030
50、當繪制文本時程序發(fā)送此消息得到控件要用的顏色 WM_GETFONT = &H0031 應(yīng)用程序發(fā)送此消息得到當前控件繪制文本的字體 WM_SETHOTKEY = &H0032 應(yīng)用程序發(fā)送此消息讓一個窗口與一個熱鍵相關(guān)連 WM_GETHOTKEY = &H0033 應(yīng)用程序發(fā)送此消息來判斷熱鍵與某個窗口是否有關(guān)聯(lián) WM_QUERYDRAGICON = &H0037 此消息發(fā)送給最小化窗口,當此窗口將要被拖放而它的類中沒有定義圖標,應(yīng)用程序能返回一個圖標或光標的句柄,當用戶拖放圖標時系統(tǒng)顯示這個圖標或光標 WM_COMPAREITEM = &H0039 發(fā)送此消息來判定combobox或listbox新增加的項的相對位置 WM_GETOBJECT = &H003D W
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年醫(yī)師考試真題解析試題及答案
- 水墨插畫風兒童故事繪本雙管齊下
- 典型行政法學(xué)試題與答案匯編
- 執(zhí)業(yè)醫(yī)師考試各科目重難點分析試題及答案
- 中國文化自信的時代意義試題及答案
- 護理臨床研究設(shè)計試題及答案分析
- 常見錯誤與解決方案執(zhí)業(yè)醫(yī)師考試試題及答案
- 護理技能提升策略執(zhí)業(yè)護士考試試題及答案
- 網(wǎng)絡(luò)文化對青少年心理的影響試題及答案
- 護理學(xué)實踐能力考核試題及答案
- 2024年廣東大亞灣開發(fā)區(qū)招聘公辦學(xué)校教師筆試真題
- 江蘇交控筆試試題及答案
- JJF1033-2023計量標準考核規(guī)范
- 三對三籃球賽記錄表
- 被執(zhí)行人財產(chǎn)線索提供書(模板)
- HP系列培訓(xùn)手冊
- 畢業(yè)論文-原油電脫水方法與機理的研究
- 陜西省2022年普通高中學(xué)業(yè)水平考試(真題)
- 事故池管理的有關(guān)規(guī)定
- 2021-2022學(xué)年甘肅省天水市第一中學(xué)高一下學(xué)期第二階段考物理試題(原卷版)
- GE全球供應(yīng)鏈的管理與實踐
評論
0/150
提交評論