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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > c/c++ >内容正文

c/c++

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

發(fā)布時(shí)間:2025/4/14 c/c++ 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 VC++ 自定义消息学习总结 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

VC添加自定義消息

http://blog.csdn.net/jinnee_cumtb/article/details/4524375
?
? VC的ClassWizard不允許增加用戶自定義消息,所以你必須手工進(jìn)行添加。當(dāng)你添加了自定義的消息以后,ClassWizard就可以像處理其它消息一樣處理你定義的消息了。
一、VC6添加自定義消息
? ? 1、定義消息。在Windows中,所有的消息都用一個(gè)特定的整數(shù)值來(lái)表示,為了避免自定義消息與已存在的其他消息發(fā)生沖突,應(yīng)該利用Windows提供 的一個(gè)常量:WM_USER,小于這個(gè)常量的是系統(tǒng)保留的。即用戶自定義的消息至少為WM_USER+1,注意最后表示的消息的數(shù)值不要超過(guò) 0x7FFF。在開(kāi)發(fā)Windows95應(yīng)用程序時(shí),Microsoft推薦用戶自定義消息至少是WM_USER+100,因?yàn)楹芏嘈驴丶惨褂?WM_USER消息。
? ? #define UM_PROGRESS WM_USER + 100
? ? 2、在類頭文件的AFX_MSG塊中聲明消息處理函數(shù):
? ? 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、在類的實(shí)現(xiàn)文件中,使用ON_MESSAGE宏指令將消息映射到消息處理表中。
? ? BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
? ? //{{AFX_MSG_MAP(CMainFrame)
? ? ? ? ON_WM_CREATE()
? ? ? ? ON_WM_TIMER()
? ? ? ? ON_MESSAGE(UM_PROGRESS, OnProgress)//注意這條語(yǔ)句的后面沒(méi)有分號(hào)
? ? //}}AFX_MSG_MAP
? ? END_MESSAGE_MAP()?
? ? 4、實(shí)現(xiàn)消息處理函數(shù)。該函數(shù)使用WPRAM和LPARAM參數(shù)并返回LPESULT。
? ? LPESULT CMainFrame::OnProgress(WPARAM wParam,LPARAM lParam){
? ? ? ?CRect rect;
? ? ? ?m_wndStatusBar.GetItemRect(2,&rect); //獲得窗格區(qū)域
? ? ? ?//創(chuàng)建進(jìn)度欄,注意第三個(gè)參數(shù)為CWnd* pParentWnd,根據(jù)情況選擇父窗體
? ? ? ?m_progress.Create(WS_CHILD|WS_VISIBLE|PBS_VERTICAL,rect,this,123);
? ? ? ?m_progress.SetPos(50);
? ? ? ?return 0;
? ? }
? ? 5、在適當(dāng)?shù)臅r(shí)候發(fā)送自定義消息,進(jìn)行消息處理。需要注意使用SendMessage還是PostMessage進(jìn)行處理:SendMessage是消息處理完畢后再返回;而PostMessage則是把消息放到消息隊(duì)列后立即返回。
? ? SendMessage(UM_PROGRESS);?
? ? PostMessage(UM_PROGRESS); ? ?
? ? 如果用戶需要整個(gè)系統(tǒng)唯一的消息,可以調(diào)用SDK函數(shù)RegisterWindowMessage并使用ON_REGISTER_MESSAGE宏指令取代ON_MESSAGE宏指令,其余步驟同上。
二、VC2003添加自定義消息
? ? 在VC2003中添加自定義消息和VC6基本一致。需要注意的是VC6處理的消息可以沒(méi)有參數(shù),但VC2003消息處理的函數(shù)必須帶有兩個(gè)參數(shù) wParam和lParam,并且其返回值類型為L(zhǎng)RESULT。這里,還有另一種方法可以實(shí)現(xiàn)地定義消息的處理(VC6和VC2003均適用):
? ? 1、定義消息:#define UM_PROGRESS WM_USER + 100
? ? 2、重載CMainFrame的DefWindowProc函數(shù),然后添加對(duì)用戶自定義消息處理:
? ? LRESULT CMainFrame::DefWindowProc(UINT message, WPARAM wParam,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? LPARAM lParam){
? ? ? ? switch(message){
? ? ? ?case UM_PROGRESS:{
? ? ? ? ? ? //通過(guò)指定資源ID獲得相應(yīng)的索引
? ? ? ? ? ? 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
一、實(shí)現(xiàn)過(guò)程

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


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

  2. 在類聲明AFX_MSG塊中聲明消息響應(yīng)函數(shù)的原型,例如:

afx_msg void OnOcrResult(WPARAM wParam, LPARAM lParam); ? 函數(shù)可以有返回值,也可以無(wú)返回值; 函數(shù)原型可以有參數(shù),也可以無(wú)參數(shù),如果無(wú)參數(shù),經(jīng)常導(dǎo)致在debug下正常運(yùn)行,release下程序就奔潰了。
復(fù)制代碼
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宏指令將消息映射到消?
息處理函數(shù)中,格式為: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. 實(shí)現(xiàn)消息處理函數(shù)

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

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

  解決方法:

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

  原因:

    當(dāng)有自定義的消息產(chǎn)生時(shí),系統(tǒng)會(huì)調(diào)用自定義消息處理函數(shù),系統(tǒng)想當(dāng)然的認(rèn)為這個(gè)函數(shù)有兩個(gè)參數(shù),分別是WPARAM wParam和LPARAM lParam。系統(tǒng)在調(diào)用函數(shù)時(shí),會(huì)把這兩個(gè)參數(shù)壓棧。 然而函數(shù)自身并沒(méi)有參數(shù)。在release優(yōu)化的情況下,在返回上一級(jí)函數(shù)時(shí),依據(jù)的是這個(gè)函數(shù)的自動(dòng)變量,參數(shù)等信息,于是這兩個(gè)參數(shù)被系統(tǒng)留了下來(lái),也就是說(shuō)參數(shù)仍然保存在棧中,這樣就產(chǎn)生了沖突,所以程序就崩潰了。






    在debug下,每調(diào)用一個(gè)函數(shù)時(shí),系統(tǒng)會(huì)把當(dāng)前函數(shù)在堆棧中的位置保存在一個(gè)寄存器中(SP),當(dāng)函數(shù)執(zhí)行完畢后返回上一級(jí)函數(shù)時(shí),SP指針?lè)祷氐胶瘮?shù)調(diào)用前SP指針指向的位置。也就是說(shuō)保證了入棧和出棧的一致性。




========

VC/MFC中如何自定義消息


定義一個(gè)自定義消息號(hào):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 )
  {
  ...
  }

  如果該消息不需要返回值,也不需要參數(shù),那么可以使用宏ON_MESSAGE_VOID來(lái)映射

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

  復(fù)雜全面版本:

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


  第一步:定義消息。

  推薦用戶自定義消息至少是WM_USER+100,因?yàn)楹芏嘈驴丶惨褂肳M_USER消息。

  #define WM_MY_MESSAGE (WM_USER+100)

  第二步:實(shí)現(xiàn)消息處理函數(shù)。該函數(shù)使用WPRAM和LPARAM參數(shù)并返回LPESULT。

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

  第三步:在類頭文件的AFX_MSG塊中說(shuō)明消息處理函數(shù):

  class CMainFrame:public CMDIFrameWnd


  {


  ...


  // 一般消息映射函數(shù)

  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宏指令將消息映射到消息處理函數(shù)中。


  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()


  如果用戶需要一個(gè)定義整個(gè)系統(tǒng)唯一的消息,可以調(diào)用SDK函數(shù)RegisterWindowMessage定義消息:


  static UINT WM_MY_MESSAGE=RegisterWindowMessage(User);


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


  當(dāng)需要使用自定義消息時(shí),可以在相應(yīng)類中的函數(shù)中調(diào)用函數(shù)PostMessage或SendMessage發(fā)送消息PoseMessage(WM_MY_MESSAGE,O,O); 如果向其他進(jìn)程發(fā)送消息可通過(guò)如下方法發(fā)送消息:


  DWORD result;


  SendMessageTimeout(wnd->m_hWnd, // 目標(biāo)窗口


  WM_MY_MESSAGE, // 消息


  0, // WPARAM


  0, // LPARAM


  SMTO_ABORTIFHUNG |


  SMTO_NORMAL,


  TIMEOUT_INTERVAL,


  &result);


  以避免其它進(jìn)程如果被阻塞而造成系統(tǒng)死等狀態(tài)。


  可是如果需要向其它類(如主框架、子窗口、視類、對(duì)話框、狀態(tài)條、工具條或其他控件等)發(fā)送消息時(shí),上述方法顯得無(wú)能為力,而在編程過(guò)程中往往需要獲取其它類中的某個(gè)識(shí)別信號(hào),MFC框架給我們?cè)斐闪朔N種限制,但是可以通過(guò)獲取某個(gè)類的指針而向這個(gè)類發(fā)送消息,而自定義消息的各種動(dòng)作則在這個(gè)類中定義,這樣就可以自由自在的向其它類發(fā)送消息了。


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


  在主框架類中向視類發(fā)送消息:


  視類中定義消息:


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


  視類定義消息處理函數(shù):


  // 消息處理函數(shù)


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


  {


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


  ...


  return 0;


  }


  //發(fā)送消息的測(cè)試函數(shù)


  void CMainFrame::OnTest()


  {


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


  if(active != NULL)


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


  }


  在其它類中向視類發(fā)送消息:


  //發(fā)送消息的測(cè)試函數(shù)


  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);//發(fā)送消息


  }


  其余步驟同上。


  在視類中向主框架發(fā)送消息:


  首先在主框架中定義相關(guān)的消息,方法同上,然后在發(fā)送消息的函數(shù)中添加代碼如下


  //發(fā)送消息的測(cè)試函數(shù)


  void CMessageView::OnTest()


  {


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


  if(active != this)


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


  return 0;


  }


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


  下面一個(gè)例子程序?yàn)槎辔臋n程序里在一對(duì)話框中向視類發(fā)送消息,詳述了發(fā)送自定義消息的具體過(guò)程。


  實(shí)現(xiàn)步驟:


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


  第二步:在主菜單中添加測(cè)試菜單為調(diào)出對(duì)話框,在框架類中建立相應(yīng)函數(shù)OnTest()


  第三步:在資源中建立對(duì)話框,通過(guò)ClassWizard添加新類TestDialog,添加測(cè)試按鈕,


  在對(duì)話框類中建立相應(yīng)函數(shù)OnDialogTest()


  //通過(guò)對(duì)話框按鈕發(fā)送消息的函數(shù)


  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);//發(fā)送消息


  }


  在Message.h頭文件中添加如下語(yǔ)句:


  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()


  添加相應(yīng)的0消息處理函數(shù)


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


  {


  CRect rect;


  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)!);


  }


  第五步:顯示測(cè)試對(duì)話框


  在MainFrame類中包含對(duì)話框頭文件:


  #include TestDialog.h;


  OnTest()函數(shù)中添加代碼


  void CMainFrame::OnTest()


  {


  TestDialog dialog;


  dialog.DoModal();


  }


  運(yùn)行程序,在測(cè)試菜單打開(kāi)對(duì)話框,點(diǎn)擊測(cè)試按鈕即可看到結(jié)果。
========

MFC中自定義消息

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


這篇技術(shù)文章不是討論經(jīng)典的MFC中的消息工作機(jī)理的,討論消息工作原理、方式和路徑的文章在網(wǎng)上和書(shū)本中


隨處可見(jiàn)。網(wǎng)上眾多的討論都是關(guān)于如何響應(yīng)并進(jìn)行用戶自定義消息映射的;網(wǎng)上還有一些文章介紹如何在自定


義類中響應(yīng)Windows消息,在本文中都簡(jiǎn)略敘述。但是,網(wǎng)上大部分的文章沒(méi)用透徹闡述如何在用戶自定義類中


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


某個(gè)自定義消息。


首先能夠響應(yīng)消息的類必須都從CCmdTarget類中派生,因?yàn)橹挥幸赃@個(gè)類中提供了消息的框架和處理機(jī)制,而


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


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


,但是響應(yīng)消息的種類不太相同。


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


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


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


應(yīng)當(dāng)?shù)捻憫?yīng)命令消息。這種命令消息無(wú)論是往已有的一些諸如CWinApp類中還是自定義的類中添加都是一件非常


容易的事情,只需用向?qū)Ъ纯?#xff0c;在此不再敘述。


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


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


是由于此類消息的處理機(jī)制決定的,這類消息沒(méi)有命令消息那條繁瑣的流動(dòng)路徑,而是消息發(fā)出者直接發(fā)給對(duì)應(yīng)


CWnd的窗體句柄,由CWnd負(fù)責(zé)消息的響應(yīng)。所以這類消息必須同一個(gè)CWnd類對(duì)應(yīng),更精確的說(shuō)必須與一個(gè)HWND類


型的窗體句柄相對(duì)應(yīng)。這樣得出一個(gè)重要的結(jié)論,就是從CCmdTarget中派生而沒(méi)有從CWnd派生的類沒(méi)有處理此類


消息的能力。


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


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


中的類中處理。


由此可見(jiàn),我們自定義的類要想響應(yīng)自定義消息就只能從CWnd中派生(當(dāng)然不響應(yīng)任何消息的類可以從CObject


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


在.h中做的工作:


第一步要聲明消息:


#define WM_MYMSG WM_USER+8


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


DECLARE_MESSAGE_MAP()


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


afx_msg LRESULT MyMsgHandler(WPARAM,LPARAM);


在.cpp中做的工作:


第四步要實(shí)現(xiàn)消息映射:


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


第五步要實(shí)現(xiàn)消息處理函數(shù)(當(dāng)然可以不實(shí)現(xiàn)):


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


在引發(fā)或發(fā)出消息的地方只用寫(xiě)上:


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


到此,自定義消息完畢,這是好多網(wǎng)上文章都寫(xiě)的東西。大家會(huì)發(fā)現(xiàn)上面代碼是在CMainFrame類中實(shí)現(xiàn)的,但是


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


CMyTestObject來(lái)代表自定義類)是不能正常工作的。原因在于在發(fā)送消息的SendMessage函數(shù)中的第一個(gè)參數(shù)是


要響應(yīng)消息對(duì)應(yīng)的HWND類型的窗體句柄,而CMyTestObject類中的m_hWnd中在沒(méi)有調(diào)用CWnd::Create之前是沒(méi)有


任何意義的,也就是沒(méi)有調(diào)用CWnd::Create或CWnd::CreateEx函數(shù)時(shí),CWnd不對(duì)應(yīng)任何窗體,消息處理不能正常


運(yùn)作。


所以,又一個(gè)重要的結(jié)論,在自定義類能夠處理任何消息之前一定要確保m_hWnd關(guān)聯(lián)到一個(gè)窗體,即便這個(gè)窗體


是不可見(jiàn)的。那么有人說(shuō),在自定義類的構(gòu)造函數(shù)中調(diào)用Create函數(shù)就行了,不錯(cuò),當(dāng)然也可以在別處調(diào)用,只


要確保在消息發(fā)送之前。但是,Create的調(diào)用很有說(shuō)法,要注意兩個(gè)地方,第一個(gè)參數(shù)是類的名稱,我建議最好


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


。還有很多人問(wèn)第六個(gè)參數(shù)的意義,這個(gè)參數(shù)關(guān)系不大,是子窗體ID,用于傳給父窗體記錄以便識(shí)別。如下是我


的自定義類的構(gòu)造函數(shù):


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);
}


不能如下調(diào)用Create,因?yàn)榇藭r(shí)CMyTestObject不關(guān)聯(lián)任何窗體,所以this中的m_hWnd無(wú)效:


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


這時(shí)上面四、五兩步修改成:


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;?
}


在類外部發(fā)出消息:


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


在類內(nèi)部某個(gè)成員函數(shù)(方法)中發(fā)出消息:


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


最后一個(gè)問(wèn)題便是容易產(chǎn)生警告錯(cuò)誤的窗體回收,自定義的類要顯式調(diào)用窗體銷毀,析構(gòu)函數(shù)如下:


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

vc中SendMessage自定義消息函數(shù)用法實(shí)例

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


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


SendMessage的基本結(jié)構(gòu)如下:




復(fù)制代碼 代碼如下:SendMessage(
? ? HWND hWnd, ?//消息傳遞的目標(biāo)窗口或線程的句柄。
? ? UINT Msg, //消息類別(這里可以是一些系統(tǒng)消息,也可以是自己定義,下文具體介紹,)
? ? WPARAM wParam, //參數(shù)1 (WPARAM 其實(shí)是與UINT是同種類型的,
? //在vc編譯器中右鍵有個(gè)“轉(zhuǎn)到WPARAM的定義”的選項(xiàng)可以查看。?
? ? LPARAM lParam); //參數(shù)2
其中一些參數(shù)的由來(lái)如下:


//typedef unsigned int UINT;
//typedef UINT WPARAM;
//typedef LONG LPARAM;
//typedef LONG LRESULT;


例如可以用以下語(yǔ)句:




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




復(fù)制代碼 代碼如下:#define WM_MY_DOSOME WM_USER+1 // do something
當(dāng)然你還可以定義更多如:


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


到這里,可能大家還是對(duì)消息類別有點(diǎn)模糊,不要擔(dān)心,下面很快就講到。
我們發(fā)了一個(gè)消息出去,那么接收方要能識(shí)別這個(gè)消息是干什么,就是通過(guò)消息類別來(lái)區(qū)分,并且開(kāi)始去做這個(gè)消息對(duì)應(yīng)要處理的事情。如下:


一、編寫(xiě)一個(gè)事情:
我們?cè)诮邮沾绑w里定義一個(gè)這樣的事情(過(guò)程),




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


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


二、讓接收方知道什么時(shí)候做這個(gè)事情:
我們?cè)?




復(fù)制代碼 代碼如下://{{AFX_MSG_MAP
//。。。這里寫(xiě)上
ON_MESSAGE(WM_MY_DOSOME,DoSomeThing)
//如果還有其他消息就再寫(xiě)一個(gè)
ON_MESSAGE(WM_DOOTHER,DoOther)
//}}AFX_MSG_MAP
到這里,當(dāng)你用SendMessage,發(fā)了一個(gè)WM_MY_DOSOME類型的消息過(guò)來(lái)的時(shí)候,接收方就會(huì)去做DoSomeThing(WPARAM iParam1,LPARAM iParam2)
發(fā)了一個(gè)WM_DOOTHER類型的消息過(guò)來(lái)的時(shí)候,接收方就會(huì)去做DoOther(WPARAM iParam1,LPARAM iParam2)當(dāng)然,這里DoOther我還沒(méi)有定義。


這樣就是一個(gè)完整的消息發(fā)送與接受過(guò)程,這里沒(méi)有詳細(xì)講參數(shù),iParam1,因?yàn)檫€沒(méi)有用到很復(fù)雜的情況,


在頭文件里:




復(fù)制代碼 代碼如下:#define WM_MYMSG ?WM_USER+5 //自定義一個(gè)消息


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


在.cpp文件里:




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


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


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


? ? SetDlgItemText(IDC_EDIT,*str);
}


按下按鈕發(fā)送消息




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


========

總結(jié)

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

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。