vc中怎麼使用SendMessage自定義訊息函式
最近在用VC2008做開發,後來由於要用到訊息的傳送,而且需要自定義訊息,在網上查找了很多例子,根據他們所說的,雖然大致都差不多,但是基本上沒有一個能完全做出來的。要知道VC程式設計有一個小地方出錯,都可能是個讓你頭暈腦脹的事情。經過我後來不但探索,經過改進之後,一點錯誤都沒有,現在貼出來供大家參考。
1. 先來個基本知識介紹
SendMessage的基本結構如下:
SendMessage(
HWND hWnd, //訊息傳遞的目標視窗或執行緒的控制代碼。
UINT Msg, //訊息類別(這裡可以是一些系統訊息,也可以是自己定義,下文具體介紹,)
WPARAM wParam, //引數1 (WPARAM 其實是與UINT是同種型別的,
//在vc編譯器中右鍵有個“轉到WPARAM的定義”的選項可以檢視。
LPARAM lParam); //引數2
其中一些引數的由來如下:
//typedef unsigned int UINT;
//typedef UINT WPARAM;
//typedef LONG LPARAM;
//typedef LONG LRESULT;
2. SendMessage用法例項
例如可以用以下語句:
void CTScrollWinView::OnLButtonDblClk(UINT nFlags, CPoint point)
{
// TODO: 在此新增訊息處理程式程式碼和/或呼叫預設值
::SendMessage(AfxGetMainWnd()->m_hWnd,WM_CHILDFRAMEDBCLK ,0,0);
CScrollView::OnLButtonDblClk(nFlags, point);
}
這是我用VC2008下建立的一個多文件選項卡式工程裡面的一段程式碼,是為了實現在子視窗雙擊後傳送一個不帶引數的訊息(其ID為WM_USER+1)給主視窗, 如上為部分程式碼, 其中WM_CHILDFRAMEDBCLK是自定義的訊息ID, AfxGetMainWnd()->m_hWnd是獲得主視窗(這裡不能使用GetParent()->m_hWnd或者GetParentFrame()->m_hWnd, 因為這是獲得父視窗,但父視窗不一定是主視窗,一定要注意,不然訊息就會發錯導致接收不到,我這裡卡了半天,後來在QQ群裡一位大俠告訴我的,在此再感謝一下那位大俠);
3. 在接收訊息的窗體以及執行緒所在的標頭檔案裡定義:
#define WM_CHILDFRAMEDBCLK WM_USER+1 // do something
4. 然後接下來定義一個訊息需要對映的函式,如下:
afx_msg LRESULT OnChlidFrameDBClick(WPARAM wParam, LPARAM lParam);
注意格式必須是:兩個引數必不可少,返回型別一定為LRESULT,網上很多文章都忽略了這兩點,這也是網上文章普遍錯誤的地方。
5. 新增訊息函式對映
ON_MESSAGE(WM_CHILDFRAMEDBCLK,OnChlidFrameDBClick)
注意這裡必須是ON_MESSAGE, 不能使用ON_COMMAND, 前者主要針對使用者自定義訊息,後者針對
WM_COMMAND命令,比如選單、工具欄等.
6. 實現訊息函式:
我們在接收窗體裡定義一個這樣的事情(過程),
LRESULT CMainFrame::OnChlidFrameDBClick(WPARAM wParam, LPARAM lParam)
{
CancelFullScreenWin(); // 這裡呼叫了一個使子視窗全屏的自寫函式,我就不貼出來了,以後專題將的時候會提到
return 0;
}
7. 下面是部分程式碼,要想搞清楚自定義訊息傳送只看這部分程式碼就足夠了
在MainFrm.h標頭檔案裡定義了訊息如下:
#define WM_CHILDFRAMEDBCLK WM_USER+1
然後在MainFrm.cpp中宣告需要對映的訊息函式如下:
afx_msg LRESULT OnChlidFrameDBClick(WPARAM wParam, LPARAM lParam);
再在MainFrm.cpp中新增對映如下:
BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWndEx)
ON_WM_CREATE()
ON_COMMAND(ID_FullScreen, OnViewFullscreen)
ON_MESSAGE(WM_CHILDFRAMEDBCLK,OnChlidFrameDBClick) // 對映新增到這裡
END_MESSAGE_MAP()
然後在MainFrm.cpp中實現OnChlidFrameDBClick()方法,如下:
LRESULT CMainFrame::OnChlidFrameDBClick(WPARAM wParam, LPARAM lParam)
{
CancelFullScreenWin();//自己定義的函式,你們可以在這裡完成自己需要的業務
return true;
}
最後就可以傳送訊息給主視窗了,如下:
void CTScrollWinView::OnLButtonDblClk(UINT nFlags, CPoint point)
{
// TODO: 在此新增訊息處理程式程式碼和/或呼叫預設值
::SendMessage(AfxGetMainWnd()->m_hWnd,WM_USER+1,0,0);
CScrollView::OnLButtonDblClk(nFlags, point);
}
總結一下:①注意定義訊息的ID不能重複,要用WM_USER+n;
②注意定義的訊息函式的返回值一定是LRESULT, 並且有兩個引數分別必須為WPARAM和LPARAM ;
③注意對映用ON_MESSAGE, 而不是ON_COMMAND;
④注意傳給主視窗的訊息在CXXXXView類中要用AfxGetMainWnd()->m_hWnd獲得主視窗。
至此就講完了,希望對大家找不對資源的有所幫助