关于VC中两种自定义消息的发送与接收的方法实现进行说明精.docx

上传人:b****7 文档编号:23751454 上传时间:2023-05-20 格式:DOCX 页数:38 大小:32.64KB
下载 相关 举报
关于VC中两种自定义消息的发送与接收的方法实现进行说明精.docx_第1页
第1页 / 共38页
关于VC中两种自定义消息的发送与接收的方法实现进行说明精.docx_第2页
第2页 / 共38页
关于VC中两种自定义消息的发送与接收的方法实现进行说明精.docx_第3页
第3页 / 共38页
关于VC中两种自定义消息的发送与接收的方法实现进行说明精.docx_第4页
第4页 / 共38页
关于VC中两种自定义消息的发送与接收的方法实现进行说明精.docx_第5页
第5页 / 共38页
点击查看更多>>
下载资源
资源描述

关于VC中两种自定义消息的发送与接收的方法实现进行说明精.docx

《关于VC中两种自定义消息的发送与接收的方法实现进行说明精.docx》由会员分享,可在线阅读,更多相关《关于VC中两种自定义消息的发送与接收的方法实现进行说明精.docx(38页珍藏版)》请在冰豆网上搜索。

关于VC中两种自定义消息的发送与接收的方法实现进行说明精.docx

关于VC中两种自定义消息的发送与接收的方法实现进行说明精

在MFC中添加用户自定义消息

首先弄清楚两点:

  

(1)谁要发送这个消息

(2)谁要接受这个消息。

  用一个简单的例子来说明。

对象A向B(也可以就是A到A)发送消息。

  1发送消息

  首先在A的头文件中定义这个消息:

  #defineWM_USERMESSAGEWM_USER+30

  所有自定义消息都是以WM_USER消息为基础加上一个任意的自然数来表示的。

A是向外发送消息的对象,因此在A的某个方法(函数)里就会调用用来发消息的函数B:

:

SendMessage()/B:

:

PostMessage(),因为是B接受消息,因此是如上的形式。

  2接受消息

  对象接受一个消息,应该有三部分:

在头文件中有该消息的处理函数的原型;在实现文件中有接受消息映射的宏;以及该消息的处理函数的具体实现。

  2.1头文件中加上自定义消息的处理函数原型

  在DECLARE_MESSAGE_MAP()语句之前,一对AFX_MSG之间加上如下形式的函数原型:

  afx_msgLRESULTOnProcName(WPARAMwParam,LPARAMlParam);

  对Win32来说,wParam,lParam是传递消息最常用的手段。

  2.2在实现文件中加上接受消息映射的宏

  在cpp文件里,BEGIN_MESSAGE_MAP语句之后,在一对AFX_MSG_MAP之间,增加如下形式的代码:

  ON_MESSAGE(WM_USERMESSAGE,OnProcName)

  上面是不用分号结尾的。

  2.3在实现文件中给出消息处理函数的具体实现。

  发信人:

Amia(小羊·橘子·和中南海有缘),信区:

VisualC

  标题:

MFC中自由使用自定义消息

  发信站:

哈工大紫丁香(2003年11月26日07:

45:

34星期三),站内信件

  消息映射、循环机制是Windows程序运行的基本方式。

VC++MFC中有许多现成的消息句柄,可当我们需要完成其它的任务,需要自定义消息,就遇到了一些困难。

在MFC  ClassWizard中不允许添加用户自定义消息,所以我们必须在程序中添加相应代码,以便可

  以象处理其它消息一样处理自定义消息。

通常的做法是采取以下步骤:

  第一步:

定义消息。

  推荐用户自定义消息至少是WM_USER+100,因为很多新控件也要使用WM_USER消息。

  #defineWM_MY_MESSAGE(WM_USER+100)

  第二步:

实现消息处理函数。

该函数使用WPRAM和LPARAM参数并返回LPESULT。

  LPESULTCMainFrame:

:

OnMyMessage(WPARAMwParam,LPARAMlParam)

  {

  //TODO:

处理用户自定义消息

  ...

  return0;

  }

  第三步:

在类头文件的AFX_MSG块中说明消息处理函数:

  classCMainFrame:

publicCMDIFrameWnd

  {

  ...

  //一般消息映射函数

  protected:

  //{{AFX_MSG(CMainFrame)

  afx_msgintOnCreate(LPCREATESTRUCTlpCreateStruct);

  afx_msgvoidOnTimer(UINTnIDEvent);

  afx_msgLRESULTOnMyMessage(WPARAMwParam,LPARAMlParam);

  //}}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定义

  消息:

  staticUINTWM_MY_MESSAGE=RegisterWindowMessage("User");

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

  当需要使用自定义消息时,可以在相应类中的函数中调用函数PostMessage或SendMessa

  ge发送消息PoseMessage(WM_MY_MESSAGE,O,O);如果向其他进程发送消息可通过如下方法

  发送消息:

  DWORDresult;

  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)//定义消息映射

  视类定义消息处理函数:

  //消息处理函数

  LRESULTCMessageView:

:

OnMyMessage(WPARAMwParam,LPARAMlParam)

  {

  //TODO:

处理用户自定义消息

  ...

  return0;

  }

  //发送消息的测试函数

  voidCMainFrame:

:

OnTest()

  {

  CView*active=GetActiveView();//获取当前视类指针

  if(active!

=NULL)

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

  }

在其它类中向视类发送消息:

  //发送消息的测试函数

  voidCMainFrame:

:

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);//发送消息

  }

  其余步骤同上。

  在视类中向主框架发送消息:

  首先在主框架中定义相关的消息,方法同上,然后在发送消息的函数中添加代码如下

  //发送消息的测试函数

  voidCMessageView:

:

OnTest()

  {

  CFrameWnd*active=GetActiveFrame();//获取当前主窗口框架指针

  if(active!

=this)

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

  return0;

  }

  在其它类中向不同的类发送消息可依次方法类推,这样我们的程序就可以的不受限制

  向其它类和进程发送消息,而避免了种种意想不到的风险。

  下面一个例子程序为多文档程序里在一对话框中向视类发送消息,详述了发送自定义消

  息的具体过程。

  实现步骤:

  第一步:

在VC++中新建工程Message,所有ClassWizard步骤选项均为缺省,完成。

  第二步:

在主菜单中添加测试菜单为调出对话框,在框架类中建立相应函数OnTest()

  第三步:

在资源中建立对话框,通过ClassWizard添加新类TestDialog,添加测试按钮,

  在对话框类中建立相应函数OnDialogTest()

  //通过对话框按钮发送消息的函数

  voidTestDialog:

:

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头文件中添加如下语句:

  staticUINTWM_MY_MESSAGE=RegisterWindowMessage("Message");

  第四步:

在视类中添加自定义消息:

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

  protected:

  //{{AFX_MSG(CMessageView)

  //}}AFX_MSG

  afx_msgLRESULTOnMyMessage(WPARAMwParam,LPARAMlParam);//此行为添加代码

  DECLARE_MESSAGE_MAP()

  在视类文件MessageView.cpp中的消息映射中添加自定义消息映射

  BEGIN_MESSAGE_MAP(CMessageView,CView)

  //{{AFX_MSG_MAP(CMessageView)

  //}}AFX_MSG_MAP

  //Standardprintingcommands

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

  END_MESSAGE_MAP()

  添加相应的0消息处理函数

  LRESULTCMessageView:

:

OnMyMessage(WPARAMwParam,LPARAMlParam)

  {

  CRectrect;

  GetClientRect(&rect);

  InvalidateRect(&rect);

  test=!

test;

  return0;

  }

  在MessageView.h中添加布尔变量public:

BOOLtest;

  在视类构造函数中初始化test变量:

test=FALSE;

  修改CMessageView:

:

OnDraw()函数

  voidCMessageView:

:

OnDraw(CDC*pDC)

  {

  CMessageDoc*pDoc=GetDocument();

  ASSERT_VALID(pDoc);

  //以下程序显示消息响应效果

  if(test)

  pDC->TextOut(0,0,"消息响应!

");

  }

  第五步:

显示测试对话框

  在MainFrame类中包含对话框头文件:

  #include"TestDialog.h";

  OnTest()函数中添加代码

  voidCMainFrame:

:

OnTest()

  {

  TestDialogdialog;

  dialog.DoModal();

  }

  运行程序,在测试菜单打开对话框,点击测试按钮即可看到结果。

关于VC++中两种自定义消息的发送与接收的方法实现进行说明

说明:

以下用一个自创的对话框类(MyMessageDlg)向视图类(MessageTestView)

发送自定义消息为例,说明这两种不同方法的自定义消息的

总结:

消息传递的方法一:

使用ON_MESSAGE

使用ON_MESSAGE响应消息,必须配合定义消息#defineWM_MY_MESSAGE(WM_USER+100)

对于发送消息者-MyMessageDlg,

在其MyMessageDlg.h中,定义#defineWM_MY_MESSAGE(WM_USER+100)

在其MyMessageDlg.cpp中要先添加:

#include"MainFrm.h"

因为使用了CMainFrame*定义对象。

并且要有测试消息的函数:

voidMyMessageDlg:

:

OnButtonMsg()

{

   //TODO:

Addyourcontrolnotificationhandlercodehere

   CMainFrame*pMF=(CMainFrame*)AfxGetApp()->m_pMainWnd; //先通过获取当前框架指针

   CView*active=pMF->GetActiveView();//才能获取当前视类指针

   if(active!

=NULL) //获取了当前视类指针才能发送消息

   active->PostMessage(WM_MY_MESSAGE,0,0);  //使用PostMessage发送消息

}

对于消息的接受者-MessageTestView,

在其MessageTestView.h中,也要定义#defineWM_MY_MESSAGE(WM_USER+100)

并定义消息映射函数-OnMyMessage()

protected:

 //{{AFX_MSG(CMessageTestView)

 afx_msgLRESULTOnMyMessage(WPARAMwParam,LPARAMlParam);

 //}}AFX_MSG

 DECLARE_MESSAGE_MAP()

在其MessageTestView.cpp中,

先要声明响应消息:

BEGIN_MESSAGE_MAP(CMessageTestView,CEditView)

 //{{AFX_MSG_MAP(CMessageTestView)

 ON_MESSAGE(WM_MY_MESSAGE,OnMyMessage)

 //}}AFX_MSG_MAP

再添加消息响应的函数实现:

LRESULTCMessageTestView:

:

OnMyMessage(WPARAMwParam,LPARAMlParam)

{

 MessageBox("OnMyMessage!

");

 return0;

}

消息传递的方法二:

使用ON_REGISTERED_MESSAGE

使用ON_REGISTERED_MESSAGE注册消息,必须配合

staticUINTWM_MY_MESSAGE=RegisterWindowMessage("Message");

对于消息的发送者-MyMessageDlg,

在其MyMessageDlg.h中,只要

定义staticUINTWM_MY_MESSAGE=RegisterWindowMessage("Message");

就可以了。

在其MyMessageDlg.cpp中要先添加:

#include"MainFrm.h"

因为使用了CMainFrame*定义对象。

并且要有测试消息的函数:

voidMyMessageDlg:

:

OnButtonMsg()

{

   //TODO:

Addyourcontrolnotificationhandlercodehere

   CMainFrame*pMF=(CMainFrame*)AfxGetApp()->m_pMainWnd; //先通过获取当前框架指针

   CView*active=pMF->GetActiveView();//才能获取当前视类指针

   if(active!

=NULL) //获取了当前视类指针才能发送消息

   active->PostMessage(WM_MY_MESSAGE,0,0);  //使用PostMessage发送消息

}

对于消息的接收者-MessageTestView,

在其MessageTestView.h中不要定义

staticUINTWM_MY_MESSAGE=RegisterWindowMessage("Message");

应该把这个定义放到MessageTestView.cpp中,要不会出现:

redefinition

在其MessageTestView.h中只要定义消息映射函数

protected:

 //{{AFX_MSG(CMessageTestView)

 afx_msgLRESULTOnMyMessage(WPARAMwParam,LPARAMlParam);

 //}}AFX_MSG

 DECLARE_MESSAGE_MAP()

在其MessageTestView.cpp中,先定义

staticUINTWM_MY_MESSAGE=RegisterWindowMessage("Message");

接着注册消息:

BEGIN_MESSAGE_MAP(CMessageTestView,CEditView)

 //{{AFX_MSG_MAP(CMessageTestView)

       ON_REGISTERED_MESSAGE(WM_MY_MESSAGE,OnMyMessage)

 //}}AFX_MSG_MAP

最后添加消息响应的函数实现:

LRESULTCMessageTestView:

:

OnMyMessage(WPARAMwParam,LPARAMlParam)

{

 MessageBox("OnMyMessage!

");

 return0;

}

----------------------------------------------------------------

比较两种方法,只是略有不同。

但也要小心谨慎,以免出现接收不到消息的情况。

-------------------------------------------------------------------

其他注意事项:

发送消息的-MyMessageDlg.cpp前也要定义

staticUINTWM_MY_MESSAGE=RegisterWindowMessage("Message");

接受消息的-MessageTestView.cpp前也要定义

staticUINTWM_MY_MESSAGE=RegisterWindowMessage("Message");

RegisterWindowMessage("Message")中""的内容是什么不重要,写什么都可以,单必须

发送者与接受者是一样的内容,例如:

"Message"

 

MFC消息类型

1、命令消息(WM_COMMAND)所有派生自 CCmdTarget 的类都有资格接受WM_COMMAND。

2、Window消息(WM_xxx)所有派生自 CWnd 的类都有资格接受 WM_xxx。

3、控件消息(WM_NOTIFY)控件向其父窗口通知消息。

消息处理

1、WM_xxx 消息处理

窗口类(自身)处理→基类处理→CWnd∷DefWindowProc()处理;

其所对应的宏一般为在消息 WM_ 前面加上 ON_。

2、命令消息处理

命令消息来自命令用户接口对象(菜单、加速键或工具栏按钮)发出的WM_COMMAND消息;

㈠、WM_COMMAND消息

其所包含的类型和对应的宏如下:

①、ON_COMMAND(ID,pfn)标准的命令消息;

②、ON_COMMAND_EX(ID,pfn)多个对象对同一个命令 ID 的处理;

其函数的原型如下:

afx_msg BOOL pfn(UINT nID)

说明:

当返回 TRUE 时表示已经处理,不用在消息处理链中继续处理该命令;为 FALSE 时表示继续在消息处理链中处理该命令。

注意:

其一:

在多对象处理中一定要使用该宏;

其二:

pfn(UINT nID)(消息处理函数)返回值将其类型void改成BOOL,而且必须为FALSE;

其三:

多个对象的处理是由高层向低层的过程:

即视图类→主框架窗口类→应用程序类;

③、ON_COMMAND_RANGE(nID,nLastID,pfn)多个命令 ID 提供相同的处理;

注意:

其一:

确保nID、nLastID的值在 Resource.h 中是连续的。

其二:

一般在函数 pfn(UINT nID) 中加入参数,用来确定那一个按钮点击。

㈡、CN_UPDATE_COMMAND_UI消息

当菜单项、工具栏按钮等[命令用户接口对象]要更新其状态时所对应的消息,它所包含的类型和对应的宏如下:

①、ON_UPDATE_COMMAND_UI(ID,pfn)

其中函数的原型如下:

afx_msg void pfn(CCmdUI* pCmdUI)

②、ON_UPDATE_COMMAND_UI_RANGE(nID,nLastID,pfn)该函数可以处理一组[命令用户接口对象]的外观;

其中函数的原型如下:

afx_msg void pfn(CCmdUI* pCmdUI)

重要:

CCmdUI 中的 m_nID 成员表示不同的 ID,因此可以利用它来进行区别处理。

3、控件的通知消息

从控件和子窗口发送到父窗口的WM_COMMAND通知消息(即在发送命令消息中加入控件的通知码)。

注意:

在 Window9x 新控件中不再传送WM_COMMAND通知消息,而是发送 WM_NOTIFY 消息,但为了兼容,旧有的控件还是传送WM_COMMAND消息。

例如:

CEdit控件向父窗口发送 EN_CHANGE 通知代码的WM_COMMAND消息。

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 考试认证 > 其它考试

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1