日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

VC++ 自定义消息学习总结

發布時間:2025/4/14 c/c++ 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 VC++ 自定义消息学习总结 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

VC添加自定義消息

http://blog.csdn.net/jinnee_cumtb/article/details/4524375
?
? VC的ClassWizard不允許增加用戶自定義消息,所以你必須手工進行添加。當你添加了自定義的消息以后,ClassWizard就可以像處理其它消息一樣處理你定義的消息了。
一、VC6添加自定義消息
? ? 1、定義消息。在Windows中,所有的消息都用一個特定的整數值來表示,為了避免自定義消息與已存在的其他消息發生沖突,應該利用Windows提供 的一個常量:WM_USER,小于這個常量的是系統保留的。即用戶自定義的消息至少為WM_USER+1,注意最后表示的消息的數值不要超過 0x7FFF。在開發Windows95應用程序時,Microsoft推薦用戶自定義消息至少是WM_USER+100,因為很多新控件也要使用 WM_USER消息。
? ? #define UM_PROGRESS WM_USER + 100
? ? 2、在類頭文件的AFX_MSG塊中聲明消息處理函數:
? ? class CMainFrame:public CFrameWnd{
? ? protected:
? ? //{{AFX_MSG(CMainFrame)
? ? afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
? ? afx_msg void OnTimer(UINT nIDEvent);
? ? afx_msg LRESULT OnProgress(WPARAM wParam, LPARAM lParam);
? ? //}}AFX_MSG
? ? DECLARE_MESSAGE_MAP()
? ? 3、在類的實現文件中,使用ON_MESSAGE宏指令將消息映射到消息處理表中。
? ? BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
? ? //{{AFX_MSG_MAP(CMainFrame)
? ? ? ? ON_WM_CREATE()
? ? ? ? ON_WM_TIMER()
? ? ? ? ON_MESSAGE(UM_PROGRESS, OnProgress)//注意這條語句的后面沒有分號
? ? //}}AFX_MSG_MAP
? ? END_MESSAGE_MAP()?
? ? 4、實現消息處理函數。該函數使用WPRAM和LPARAM參數并返回LPESULT。
? ? LPESULT CMainFrame::OnProgress(WPARAM wParam,LPARAM lParam){
? ? ? ?CRect rect;
? ? ? ?m_wndStatusBar.GetItemRect(2,&rect); //獲得窗格區域
? ? ? ?//創建進度欄,注意第三個參數為CWnd* pParentWnd,根據情況選擇父窗體
? ? ? ?m_progress.Create(WS_CHILD|WS_VISIBLE|PBS_VERTICAL,rect,this,123);
? ? ? ?m_progress.SetPos(50);
? ? ? ?return 0;
? ? }
? ? 5、在適當的時候發送自定義消息,進行消息處理。需要注意使用SendMessage還是PostMessage進行處理:SendMessage是消息處理完畢后再返回;而PostMessage則是把消息放到消息隊列后立即返回。
? ? SendMessage(UM_PROGRESS);?
? ? PostMessage(UM_PROGRESS); ? ?
? ? 如果用戶需要整個系統唯一的消息,可以調用SDK函數RegisterWindowMessage并使用ON_REGISTER_MESSAGE宏指令取代ON_MESSAGE宏指令,其余步驟同上。
二、VC2003添加自定義消息
? ? 在VC2003中添加自定義消息和VC6基本一致。需要注意的是VC6處理的消息可以沒有參數,但VC2003消息處理的函數必須帶有兩個參數 wParam和lParam,并且其返回值類型為LRESULT。這里,還有另一種方法可以實現地定義消息的處理(VC6和VC2003均適用):
? ? 1、定義消息:#define UM_PROGRESS WM_USER + 100
? ? 2、重載CMainFrame的DefWindowProc函數,然后添加對用戶自定義消息處理:
? ? LRESULT CMainFrame::DefWindowProc(UINT message, WPARAM wParam,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? LPARAM lParam){
? ? ? ? switch(message){
? ? ? ?case UM_PROGRESS:{
? ? ? ? ? ? //通過指定資源ID獲得相應的索引
? ? ? ? ? ? int index = m_wndStatusBar.CommandToIndex(IDS_PROGRESS);?
? ? ? ? ? ?CRect rect;
? ? ? ? ? m_wndStatusBar.GetItemRect(index,&rect);
? ? ? ? ? ?m_progress.Create(WS_CHILD|WS_VISIBLE,rect, &m_wndStatusBar
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ,123);
? ? ? ? ? ?m_progress.SetPos(50);
? ? ? ? ? ?break;
? ? ? ? }
? ? ? ? default:
? ? ? ? ? ? break;
? ? ?}
? ? ?return CFrameWnd::DefWindowProc(message, wParam, lParam);
? ? }
========

自定義消息

http://www.cnblogs.com/xydblog/archive/2014/02/25/3566266.html
一、實現過程

  1. 使用宏定義消息ID,例如:


#define ?  WM_OCRRESULT  (WM_USER+101)
   其中WM_USER為系統消息和用戶自定義消息的分界線,小于WM_USER的消息被系統所占用,如:WM_LBUTTONDOWN消息,大于WM_USER的消息為用戶自定義消息;

  2. 在類聲明AFX_MSG塊中聲明消息響應函數的原型,例如:

afx_msg void OnOcrResult(WPARAM wParam, LPARAM lParam); ? 函數可以有返回值,也可以無返回值; 函數原型可以有參數,也可以無參數,如果無參數,經常導致在debug下正常運行,release下程序就奔潰了。
復制代碼
class CDlgOCRMain : public CDialog
{
protected:?
? ? // Generated message map functions
? ? //{{AFX_MSG(CDlgOCRMain)
? ? virtual BOOL OnInitDialog();
? ? afx_msg void OnDestroy();
? ? afx_msg void OnSize(UINT nType, int cx, int cy);
? ? afx_msg BOOL OnEraseBkgnd(CDC *pDC);
? ? afx_msg void OnPaint();
? ? afx_msg void OnOcrResult(WPARAM wParam, LPARAM lParam);
? ? //}}AFX_MSG?
? ? DECLARE_MESSAGE_MAP()
}

  3. 在用戶類的消息塊中,使用ON_MESSAGE宏指令將消息映射到消?
息處理函數中,格式為:ON_MESSAGE(MsgID,MsgFun)

    注意:ON_MESSAGE一定要放到AFX_MSG_MAP之后,END_MESSAGE_MAP()之前

BEGIN_MESSAGE_MAP(CDlgOCRMain, CDialog)
? ? //{{AFX_MSG_MAP(CDlgOCRMain)
? ? ON_WM_DESTROY()
? ? ON_WM_SIZE()
? ? ON_WM_ERASEBKGND()
? ? ON_WM_PAINT()
? ? //}}AFX_MSG_MAP?

? ? ON_MESSAGE(WM_OCRRESULT, OnOcrResult)?
END_MESSAGE_MAP()

?  4. 實現消息處理函數

void CDlgOCRMain::OnOcrResult(WPARAM wParam, LPARAM lParam)
{
? //........................ ? ? ? ? ? ? ??
}
?二、自定義消息出錯

  如果我們消息響應函數原型為: afx_msg void OnXXXX(); 則在經常導致在debug下正常運行,release下程序就奔潰了。

  解決方法:

      將afx_msg void OnXXXX()改為afx_msg void OnXXXX(WPARAM wParam, LPARAM lParam);

  原因:

    當有自定義的消息產生時,系統會調用自定義消息處理函數,系統想當然的認為這個函數有兩個參數,分別是WPARAM wParam和LPARAM lParam。系統在調用函數時,會把這兩個參數壓棧。 然而函數自身并沒有參數。在release優化的情況下,在返回上一級函數時,依據的是這個函數的自動變量,參數等信息,于是這兩個參數被系統留了下來,也就是說參數仍然保存在棧中,這樣就產生了沖突,所以程序就崩潰了。






    在debug下,每調用一個函數時,系統會把當前函數在堆棧中的位置保存在一個寄存器中(SP),當函數執行完畢后返回上一級函數時,SP指針返回到函數調用前SP指針指向的位置。也就是說保證了入棧和出棧的一致性。




========

VC/MFC中如何自定義消息


定義一個自定義消息號:const UINT WM_MYMESSAGE = WM_USER + n; // 自定義消息一般大于WM_USER,然后就可以為該消息添加映射了。

  afx_msg LRESULT OnMyMessage ( WPARAM wParam, LPARAM lParam );

  ON_MESSAGE ( WM_MYMESSAGE, OnMyMessage )

  LRESULT cxx::OnMyMessage ( WPARAM wParma, LPARAM lParam )
  {
  ...
  }

  如果該消息不需要返回值,也不需要參數,那么可以使用宏ON_MESSAGE_VOID來映射

  afx_msg void OnMyMessage ();
  ON_MESSAGE_VOID ( WM_MYMESSAGE, OnMyMessage )
  void cxx::OnMyMessage ()
  {
  ...
  }

  復雜全面版本:

  消息映射、循環機制是Windows程序運行的基本方式。VC++ MFC 中有許多現成的消息句柄,可當我們需要完成其它的任務,需要自定義消息,就遇到了一些困難。在MFC ClassWizard中不允許添加用戶自定義消息,所以我們必須在程序中添加相應代碼,以便可以象處理其它消息一樣處理自定義消息。通常的做法是采取以下步驟:


  第一步:定義消息。

  推薦用戶自定義消息至少是WM_USER+100,因為很多新控件也要使用WM_USER消息。

  #define WM_MY_MESSAGE (WM_USER+100)

  第二步:實現消息處理函數。該函數使用WPRAM和LPARAM參數并返回LPESULT。

  LPESULT CMainFrame::OnMyMessage(WPARAM wParam, LPARAM lParam)
  {
  // TODO: 處理用戶自定義消息
  ...
  return 0;
  }

  第三步:在類頭文件的AFX_MSG塊中說明消息處理函數:

  class CMainFrame:public CMDIFrameWnd


  {


  ...


  // 一般消息映射函數

  protected:

  // {{AFX_MSG(CMainFrame)

  afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);

  afx_msg void OnTimer(UINT nIDEvent);

  afx_msg LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam);

  //}}AFX_MSG

  DECLARE_MESSAGE_MAP()
  }

  第四步:在用戶類的消息塊中,使用ON_MESSAGE宏指令將消息映射到消息處理函數中。


  BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)


  //{{AFX_MSG_MAP(CMainFrame)


  ON_WM_CREATE()


  ON_WM_TIMER()


  ON_MESSAGE(WM_MY_MESSAGE, OnMyMessage)


  //}}AFX_MSG_MAP


  END_MESSAGE_MAP()


  如果用戶需要一個定義整個系統唯一的消息,可以調用SDK函數RegisterWindowMessage定義消息:


  static UINT WM_MY_MESSAGE=RegisterWindowMessage(User);


  并使用ON_REGISTERED_MESSAGE宏指令取代ON_MESSAGE宏指令,其余步驟同上。


  當需要使用自定義消息時,可以在相應類中的函數中調用函數PostMessage或SendMessage發送消息PoseMessage(WM_MY_MESSAGE,O,O); 如果向其他進程發送消息可通過如下方法發送消息:


  DWORD result;


  SendMessageTimeout(wnd->m_hWnd, // 目標窗口


  WM_MY_MESSAGE, // 消息


  0, // WPARAM


  0, // LPARAM


  SMTO_ABORTIFHUNG |


  SMTO_NORMAL,


  TIMEOUT_INTERVAL,


  &result);


  以避免其它進程如果被阻塞而造成系統死等狀態。


  可是如果需要向其它類(如主框架、子窗口、視類、對話框、狀態條、工具條或其他控件等)發送消息時,上述方法顯得無能為力,而在編程過程中往往需要獲取其它類中的某個識別信號,MFC框架給我們造成了種種限制,但是可以通過獲取某個類的指針而向這個類發送消息,而自定義消息的各種動作則在這個類中定義,這樣就可以自由自在的向其它類發送消息了。


  下面舉的例子敘述了向視類和框架類發送消息的方法:


  在主框架類中向視類發送消息:


  視類中定義消息:


  ON_REGISTERED_MESSAGE(WM_MY_MESSAGE,OnMyMessage) //定義消息映射


  視類定義消息處理函數:


  // 消息處理函數


  LRESULT CMessageView::OnMyMessage(WPARAM wParam, LPARAM lParam)


  {


  // TODO: 處理用戶自定義消息


  ...


  return 0;


  }


  //發送消息的測試函數


  void CMainFrame::OnTest()


  {


  CView * active = GetActiveView();//獲取當前視類指針


  if(active != NULL)


  active->PostMessage(WM_MY_MESSAGE,0,0);


  }


  在其它類中向視類發送消息:


  //發送消息的測試函數


  void CMainFrame::OnTest()


  {


  CMDIFrameWnd *pFrame;


  CMDIChildWnd *pChild;


  CView *pView;


  //獲取主窗口指針


  pFrame =(CMDIFrameWnd*)AfxGetApp()->m_pMainWnd;


  // 獲取子窗口指針


  pChild = (CMDIChildWnd *) pFrame->GetActiveFrame();


  //獲取視類指針


  pView = pChild->GetActiveView();


  if(pView != NULL)


  pView->PostMessage(WM_MY_MESSAGE,0,0);//發送消息


  }


  其余步驟同上。


  在視類中向主框架發送消息:


  首先在主框架中定義相關的消息,方法同上,然后在發送消息的函數中添加代碼如下


  //發送消息的測試函數


  void CMessageView::OnTest()


  {


  CFrameWnd * active = GetActiveFrame();//獲取當前主窗口框架指針


  if(active != this)


  active->PostMessage(WM_MY_MESSAGE,0,0);


  return 0;


  }


  在其它類中向不同的類發送消息可依次方法類推,這樣我們的程序就可以的不受限制向其它類和進程發送消息,而避免了種種意想不到的風險。


  下面一個例子程序為多文檔程序里在一對話框中向視類發送消息,詳述了發送自定義消息的具體過程。


  實現步驟:


  第一步:在VC++中新建工程Message,所有ClassWizard步驟選項均為缺省,完成。


  第二步:在主菜單中添加測試菜單為調出對話框,在框架類中建立相應函數OnTest()


  第三步:在資源中建立對話框,通過ClassWizard添加新類TestDialog,添加測試按鈕,


  在對話框類中建立相應函數OnDialogTest()


  //通過對話框按鈕發送消息的函數


  void TestDialog::OnDialogTest()


  {


  CMDIFrameWnd *pFrame;


  CMDIChildWnd *pChild;


  CView *pView;


  //獲取主窗口指針


  pFrame =(CMDIFrameWnd*)AfxGetApp()->m_pMainWnd;


  // 獲取子窗口指針


  pChild = (CMDIChildWnd *) pFrame->GetActiveFrame();


  //獲取視類指針


  pView = pChild->GetActiveView();


  if(active != NULL)


  active->PostMessage(WM_MY_MESSAGE,0,0);//發送消息


  }


  在Message.h頭文件中添加如下語句:


  static UINT WM_MY_MESSAGE=RegisterWindowMessage(Message);


  第四步:在視類中添加自定義消息:


  在頭文件MessageView.h中添加消息映射


  protected:


  //{{AFX_MSG(CMessageView)


  //}}AFX_MSG


  afx_msg LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam); //此行為添加代碼


  DECLARE_MESSAGE_MAP()


  在視類文件MessageView.cpp中的消息映射中添加自定義消息映射


  BEGIN_MESSAGE_MAP(CMessageView, CView)


  //{{AFX_MSG_MAP(CMessageView)


  //}}AFX_MSG_MAP


  // Standard printing commands


  ON_REGISTERED_MESSAGE(WM_MY_MESSAGE,OnMyMessage) //此行添加代碼定義唯一消息


  END_MESSAGE_MAP()


  添加相應的0消息處理函數


  LRESULT CMessageView::OnMyMessage(WPARAM wParam, LPARAM lParam)


  {


  CRect rect;


  GetClientRect(&rect);


  InvalidateRect(&rect);


  test=!test;


  return 0;


  }


  在MessageView.h中添加布爾變量 public:BOOL test;


  在視類構造函數中初始化 test變量:test=FALSE;


  修改CMessageView::OnDraw()函數


  void CMessageView::OnDraw(CDC* pDC)


  {


  CMessageDoc* pDoc = GetDocument();


  ASSERT_VALID(pDoc);


  // 以下程序顯示消息響應效果


  if(test)


  pDC->TextOut(0,0,消息響應!);


  }


  第五步:顯示測試對話框


  在MainFrame類中包含對話框頭文件:


  #include TestDialog.h;


  OnTest()函數中添加代碼


  void CMainFrame::OnTest()


  {


  TestDialog dialog;


  dialog.DoModal();


  }


  運行程序,在測試菜單打開對話框,點擊測試按鈕即可看到結果。
========

MFC中自定義消息

http://blog.csdn.net/qihailong123456/article/details/6777112


這篇技術文章不是討論經典的MFC中的消息工作機理的,討論消息工作原理、方式和路徑的文章在網上和書本中


隨處可見。網上眾多的討論都是關于如何響應并進行用戶自定義消息映射的;網上還有一些文章介紹如何在自定


義類中響應Windows消息,在本文中都簡略敘述。但是,網上大部分的文章沒用透徹闡述如何在用戶自定義類中


響應自定義消息這一通用方法。?
問題定義如下:用戶自定義一個類,這個類不一定要有界面(完全可以是不可視的),要求自定義的類可以響應


某個自定義消息。


首先能夠響應消息的類必須都從CCmdTarget類中派生,因為只有以這個類中提供了消息的框架和處理機制,而


CWnd類也派生與此類。CWinApp類、CDocument類、CDocTemplate類等都是CCmdTarget的派生類,即子類;而


CFrameWnd類、CView類、CDialog類等都是從CWnd中派生的,其實也是CCmdTarget的子孫,所以都能夠響應消息


,但是響應消息的種類不太相同。


那么,如果自己定義的類要求響應命令消息(就是WM_COMMAND,也就是一些菜單、工具欄中的消息,包括快捷鍵


,這類消息處理的機制與其他以WM_開頭的消息處理機制不同,它具有一條層次明確的消息流動路徑),那么自


定義的類可以從CCmdTarget中派生。由于CWnd窗體類派生于CCmdTarget父類,那么從CWnd中派生的類也可以理所


應當的響應命令消息。這種命令消息無論是往已有的一些諸如CWinApp類中還是自定義的類中添加都是一件非常


容易的事情,只需用向導即可,在此不再敘述。


如果用戶自定義的類要求響應普通的Windows消息(也就是以WM_開頭,除了WM_COMMAND以外的消息,這類消息在


WM_USER以下的是系統消息,WM_USER以上的可以由用戶自己定義),那就要求自定義的類必須從CWnd中派生。這


是由于此類消息的處理機制決定的,這類消息沒有命令消息那條繁瑣的流動路徑,而是消息發出者直接發給對應


CWnd的窗體句柄,由CWnd負責消息的響應。所以這類消息必須同一個CWnd類對應,更精確的說必須與一個HWND類


型的窗體句柄相對應。這樣得出一個重要的結論,就是從CCmdTarget中派生而沒有從CWnd派生的類沒有處理此類


消息的能力。


綜上所述,就是為什么命令消息可以放到大部分類中處理,包括CWinThread、CWinApp、CDocument、CView、


CFrameWnd或是自定義的類中,而普通Windows消息和用戶自定義的消息只能放到CFrameWnd和CView等派生與CWnd


中的類中處理。


由此可見,我們自定義的類要想響應自定義消息就只能從CWnd中派生(當然不響應任何消息的類可以從CObject


中派生)。先來看看如何自定義消息:


在.h中做的工作:


第一步要聲明消息:


#define WM_MYMSG WM_USER+8


第二步要在類聲明中聲明消息映射:


DECLARE_MESSAGE_MAP()


第三步要在類聲明中定義消息處理函數:


afx_msg LRESULT MyMsgHandler(WPARAM,LPARAM);


在.cpp中做的工作:


第四步要實現消息映射:


BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
ON_MESSAGE(WM_MYMSG,OnMyMsgHandler)
END_MESSAGE_MAP()


第五步要實現消息處理函數(當然可以不實現):


LRESULT CMainFrame::OnMyMsgHandler(WPARAM w,LPARAM l)
{
AfxMessageBox("Hello,World!");
return 0;?
}


在引發或發出消息的地方只用寫上:


::SendMessge(::AfxGetMainWnd()->m_hWnd,WM_MYMSG,0,0);


到此,自定義消息完畢,這是好多網上文章都寫的東西。大家會發現上面代碼是在CMainFrame類中實現的,但是


如果要用自定義類,就沒有那么簡單了。顯然把第四步與第五步的CMainFrame換成自定義的類名(這里我用


CMyTestObject來代表自定義類)是不能正常工作的。原因在于在發送消息的SendMessage函數中的第一個參數是


要響應消息對應的HWND類型的窗體句柄,而CMyTestObject類中的m_hWnd中在沒有調用CWnd::Create之前是沒有


任何意義的,也就是沒有調用CWnd::Create或CWnd::CreateEx函數時,CWnd不對應任何窗體,消息處理不能正常


運作。


所以,又一個重要的結論,在自定義類能夠處理任何消息之前一定要確保m_hWnd關聯到一個窗體,即便這個窗體


是不可見的。那么有人說,在自定義類的構造函數中調用Create函數就行了,不錯,當然也可以在別處調用,只


要確保在消息發送之前。但是,Create的調用很有說法,要注意兩個地方,第一個參數是類的名稱,我建議最好


設為NULL;第五個參數是父窗體對象的指針,這個函數指定的對象一定要存在,我建議最好為整個程序的主窗體


。還有很多人問第六個參數的意義,這個參數關系不大,是子窗體ID,用于傳給父窗體記錄以便識別。如下是我


的自定義類的構造函數:


CMyTestObject::CMyTestObject()
{
CWnd::Create(NULL,"MyTestObject",WS_CHILD,CRect(0,0,0,0),::AfxGetMainWnd(),1234);
} ? ?//一定要在生成主窗體后使用,在主窗體完成OnCreate消息的處理后


CMyTestObject::CMyTestObject(CWnd *pParent)
{
CWnd::Create(NULL,"MyTestObject",WS_CHILD,CRect(0,0,0,0),pParent,1234);
}


不能如下調用Create,因為此時CMyTestObject不關聯任何窗體,所以this中的m_hWnd無效:


CWnd::Create(NULL,"MyTestObject",WS_CHILD,CRect(0,0,0,0),this,1234);


這時上面四、五兩步修改成:


BEGIN_MESSAGE_MAP(CMyTestObject, CWnd)
ON_MESSAGE(WM_MYMSG,OnMyMsgHandler)
END_MESSAGE_MAP()


LRESULT CMyTestObject::OnMyMsgHandler(WPARAM w,LPARAM l)
{
AfxMessageBox("My Messge Handler in My Self-Custom Class!");
return 0;?
}


在類外部發出消息:


CMyTestObject *test=new CMyTestObject();
::SendMessage(test->m_hWnd,WM_MYMSG,0,0);


在類內部某個成員函數(方法)中發出消息:


::SendMessage(m_hWnd,WM_MYMSG,0,0);


最后一個問題便是容易產生警告錯誤的窗體回收,自定義的類要顯式調用窗體銷毀,析構函數如下:


CMyTestObject::~CMyTestObject()
{
CWnd::DestroyWindow();
}
?
========

vc中SendMessage自定義消息函數用法實例

http://www.jb51.net/article/56565.htm


這篇文章主要介紹了vc中SendMessage自定義消息函數用法,以實例實行詳細講述了SendMessage的定義、原理與用法,具有一定的實用價值,需要的朋友可以參考下
..本文實例講述了vc中SendMessage自定義消息函數用法,分享給大家供大家參考。具體如下:


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;


例如可以用以下語句:




復制代碼 代碼如下:::SendMessage(this->m_hWnd, WM_MY_DOSOME, (WPARAM) 0, (LPARAM) 0);
這里我發送的消息是本窗體接收的,所以句柄用:this->m_hWnd
這里的消息類別WM_MY_DOSOME就是我自定義的,
在接收消息的窗體或線程所在的頭文件里:




復制代碼 代碼如下:#define WM_MY_DOSOME WM_USER+1 // do something
當然你還可以定義更多如:


復制代碼 代碼如下:#define WM_DOOTHER WM_USER+2 // do other
表示要做一些事情。


到這里,可能大家還是對消息類別有點模糊,不要擔心,下面很快就講到。
我們發了一個消息出去,那么接收方要能識別這個消息是干什么,就是通過消息類別來區分,并且開始去做這個消息對應要處理的事情。如下:


一、編寫一個事情:
我們在接收窗體里定義一個這樣的事情(過程),




復制代碼 代碼如下:afx_msg LRESULT DoSomeThing(WPARAM iParam1,LPARAM iParam2)
{
?MessageBox("收到消息了,我要開始做一些事情了。","收到",MB_OK);
?//可以運用iParam1,iParam2 來做一些事情。
?return 0;
}
這個事情有3點大家要注意,非常重要:


1. 使用了afx_msg,并且要將afx_msg LRESULT DoSomeThing(WPARAM iParam1,LPARAM iParam2)
改寫到頭文件的?
//{{AFX_MSG?
//。。。改寫到這里,顏色會變成灰的。這一點非常重要。
//}}AFX_MSG
2. 參數有2個,WPARAM iParam1,LPARAM iParam2,哪怕沒有東西傳進來也要寫,不然會吃苦頭的,vc里不會提醒你少寫了一個,
但一些莫名奇妙的事情會發生。
3. 類型用 LRESULT,完了要return 0;


二、讓接收方知道什么時候做這個事情:
我們在




復制代碼 代碼如下://{{AFX_MSG_MAP
//。。。這里寫上
ON_MESSAGE(WM_MY_DOSOME,DoSomeThing)
//如果還有其他消息就再寫一個
ON_MESSAGE(WM_DOOTHER,DoOther)
//}}AFX_MSG_MAP
到這里,當你用SendMessage,發了一個WM_MY_DOSOME類型的消息過來的時候,接收方就會去做DoSomeThing(WPARAM iParam1,LPARAM iParam2)
發了一個WM_DOOTHER類型的消息過來的時候,接收方就會去做DoOther(WPARAM iParam1,LPARAM iParam2)當然,這里DoOther我還沒有定義。


這樣就是一個完整的消息發送與接受過程,這里沒有詳細講參數,iParam1,因為還沒有用到很復雜的情況,


在頭文件里:




復制代碼 代碼如下:#define WM_MYMSG ?WM_USER+5 //自定義一個消息


afx_msg void OnMyMessage(WPARAM wParam, LPARAM lParam); //自定義消息的處理函數聲明


在.cpp文件里:




復制代碼 代碼如下:ON_MESSAGE(WM_MYMSG, OnMyMessage)
//利用ON_MESSAGE()宏在自定義消息與其處理函數間建立映射關系


void CModelessDlg::OnMyMessage(WPARAM wParam, LPARAM lParam)
//從lParam中取出CString對象的指針,并將字符串內容在IDC_MSGEDIT中顯示出來
{


? ? CString *str;
? ? str=(CString *)lParam;


? ? SetDlgItemText(IDC_EDIT,*str);
}


按下按鈕發送消息




復制代碼 代碼如下:void CModelessDlg::OnMsgBTN()?
{
?CString str= "自定義消息被觸發了!";
?SendMessage(WM_MYMSG, 0, (LPARAM) &str);
?//給ModelessDlg自己發一個自定義的消息
}
希望本文所述對大家的VC程序設計有所幫助。


========

總結

以上是生活随笔為你收集整理的VC++ 自定义消息学习总结的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。