MFC中如何处理极光自定义消息息

扫一扫体验手机阅读
VC入门学习---MFC传输自定义消息并响应自定义消息
& & & & & & & & & & & & & & & & & &&
以下用一个自创的对话框类(MyMessageDlg)向视图类(MessageTestView)
发送自定义消息为例,说明这两种不同方法的自定义消息的
消息传递的方法一:使用ON_MESSAGE
使用ON_MESSAGE响应消息,必须配合定义消息#define WM_MY_MESSAGE (WM_USER+100)
对于发送消息者-MyMessageDlg,
在其MyMessageDlg.h中,定义#define WM_MY_MESSAGE (WM_USER+100)
在其MyMessageDlg.cpp中要先添加:#include &MainFrm.h&
因为使用了CMainFrame*定义对象。
并且要有测试消息的函数:
void MyMessageDlg::OnButtonMsg()&
& & // TODO: Add your control notification handler code here
& & CMainFrame* pMF=(CMainFrame*)AfxGetApp()-&m_pMainW &//先通过获取当前框架指针
& & CView * active = pMF-&GetActiveView();//才能获取当前视类指针
& & if(active != NULL) &//获取了当前视类指针才能发送消息
& & active-&PostMessage(WM_MY_MESSAGE,0,0); & //使用PostMessage发送消息
对于消息的接受者-MessageTestView,
在其MessageTestView.h中,也要定义#define WM_MY_MESSAGE (WM_USER+100)
并定义消息映射函数-OnMyMessage()
protected:
&//{{AFX_MSG(CMessageTestView)
&afx_msg LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam);&
&//}}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
再添加消息响应的函数实现:
LRESULT CMessageTestView::OnMyMessage(WPARAM wParam, LPARAM lParam)
&MessageBox(&OnMyMessage!&);
&return 0;
消息传递的方法二:使用ON_REGISTERED_MESSAGE
使用ON_REGISTERED_MESSAGE注册消息,必须配合
static UINT WM_MY_MESSAGE=RegisterWindowMessage(&Message&);
对于消息的发送者-MyMessageDlg,
在其MyMessageDlg.h中,只要
定义static UINT WM_MY_MESSAGE=RegisterWindowMessage(&Message&);
就可以了。
在其MyMessageDlg.cpp中要先添加:#include &MainFrm.h&
因为使用了CMainFrame*定义对象。
并且要有测试消息的函数:
void MyMessageDlg::OnButtonMsg()&
& & // TODO: Add your control notification handler code here
& & CMainFrame* pMF=(CMainFrame*)AfxGetApp()-&m_pMainW &//先通过获取当前框架指针
& & CView * active = pMF-&GetActiveView();//才能获取当前视类指针
& & if(active != NULL) &//获取了当前视类指针才能发送消息
& & active-&PostMessage(WM_MY_MESSAGE,0,0); & //使用PostMessage发送消息
对于消息的接收者-MessageTestView,
在其MessageTestView.h中不要定义
static UINT WM_MY_MESSAGE=RegisterWindowMessage(&Message&);
应该把这个定义放到MessageTestView.cpp中,要不会出现: redefinition
在其MessageTestView.h中只要定义消息映射函数
protected:
&//{{AFX_MSG(CMessageTestView)
&afx_msg LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam);&
&//}}AFX_MSG
&DECLARE_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,OnMyMessage)
&//}}AFX_MSG_MAP
最后添加消息响应的函数实现:
LRESULT CMessageTestView::OnMyMessage(WPARAM wParam, LPARAM lParam)
&MessageBox(&OnMyMessage!&);
&return 0;
----------------------------------------------------------------
比较两种方法,只是略有不同。但也要小心谨慎,以免出现接收不到消息的情况。
-------------------------------------------------------------------
其他注意事项:
发送消息的-MyMessageDlg.cpp前也要定义
static UINT WM_MY_MESSAGE=RegisterWindowMessage(&Message&);
接受消息的-MessageTestView.cpp前也要定义
static UINT WM_MY_MESSAGE=RegisterWindowMessage(&Message&);
RegisterWindowMessage(&Message&)中&&的内容是什么不重要,写什么都可以,单必须
发送者与接受者是一样的内容,例如:&Message&
小心的使用消息传送--传送给多个View类时需要引起注意的一个问题
我的前一篇文章里说的是关于《两种自定义消息的发送与接收的方法实现》
可当我在一次使用消息传送的时候也遇到一个让人迷惑的问题,
好在最后解决了。
-------------------------------------------------------------
原来我对于一个消息的传送也做过,使用的是
& & CMainFrame* pMF=(CMainFrame*)AfxGetApp()-&m_pMainW // 通过获取当前框架指针
& & CView * active = pMF-&GetActiveView();// 获取当前视类指针
& & if(active != NULL) &
& & active-&PostMessage(WM_MY_MESSAGE,0,0); & // 使用PostMessage发送消息
来发送我定义的消息的。
很顺利的,我就在要接收的View类里接收到了该消息。
可是当一个类中定义了2个自定义的消息,并要分别发送给两个不同的View视图类的时候,
如果还般照上面的代码,就要出一些问题了。
为什么说是照搬就会出现问题呢?
请注意一个地方:
上面的代码中,是如何得到View类的指针的。
对,就是使用的函数GetActiveView(),这个函数的作用是获得&当前&视图指针。
我之所以出问题,使得其中的一个View类不能接收到消息也就是这个原因。
------------------------------------------------------------
下面详细说明我出错的过程和解决过程。
来源:一个SDI被我用静态切分的方式,且分成左右大小相等的两个部分,并使这两个部分分别指向自行创建的两个新类:CMyLeftView和CMyRightView,它们的基类都是CEditView。所以说这两个准备接收消息的视图类除了名字,其他并没有什么不太一样的地方。
一个对话框(CMyFindDialog类),其上有2个RADIO BUTTON控件,和一个确定按钮,
这两个RADIO BUTTON控件在选择的时候,使其只能进行单选,他们也就分别对应于前面所说的左右两个部分,选择后,点击确定按钮,便表示向 哪个视图发送消息。
做好了发送和接收部分,运行发现只能有一个消息被接收到,
void CMyFindDialog::OnButtonFind()&
{ & MainFrame* pMF=(CMainFrame*)AfxGetApp()-&m_pMainW
& & CView* active = pMF-&GetActiveView();//获取当前视类指针
& & // 错就错在上一句得到的active是个 &不确定& 的对象。
& & if(m_selLeft == TRUE)
& & & &{ &if(active != NULL) &
& & & & & & & active-&PostMessage(WM_MY_MESSAGE_LEFT,0,0); &
& & &else if(m_selRight == TRUE)
& & & { &if(active != NULL) &
& & & & & & active-&PostMessage(WM_MY_MESSAGE_RIGHT,0,0);
& & & & & &MessageBox(&MUST CHOOSE ONE!&);&
通过GetActiveView()得到的当前视类指针,那么
如果你打开对话框之前,焦点(光标)在左边,那么就是左边能接收到消息,右边怎么也接收不到。
如果你打开对话框之前,焦点(光标)在右边,那么就是右边能接收到消息,左边怎么也接收不到。
程序运行后,焦点(光标)默认的是在左边,这也就导致我总一为是右边的接收消息的部分有问题。
其实,如果在程序运行后,先把焦点(光标)改换到右边,再打开对话框测试发送与接收,就成了
左边收不到消息,右边可以收到消息。(这还是在论坛中,别人的话提醒了,才找到了错误的所在。要不然还在考虑是不是接收部分出了问题。)
对于这样一个向2个View类发送消息问题,就是要注意你所执行发送(PostMessage)的对象是谁!
正确的代码如下:
void CMyFindDialog::OnButtonFind()&
{ & CMainFrame* pMF=(CMainFrame*)AfxGetApp()-&m_pMainW
& & &CMyLeftView* pLV=(CMyLeftView*)pMF-&m_wndSplitter.GetPane(0,0);
& & &CMyRightView* pRV=(CMyRightView*)pMF-&m_wndSplitter.GetPane(0,1);
& &// 对于我这个题,是通过切分对象m_wndSplitter的GetPane函数得到它实际并确定的
& &// 视图类指针的。
& &// 如果你也是多个视图类,但不是切分,而是别的,只要注意
& &// 获得的是个你确定视图对象指针。
& & if(m_selLeft == TRUE)&
& & &{ &if(pLV != NULL) &
& & & & & & &pLV-&PostMessage(WM_MY_MESSAGE_LEFT,0,0); &
& & else if(m_selRight == TRUE)
& & & &{ &if(pRV != NULL) &
& & & & & & & &pRV-&PostMessage(WM_MY_MESSAGE_RIGHT,0,0);
& & & & & &MessageBox(&MUST CHOOSE ONE!&);&
当你需要发送消息给多个视图对象的时候,要考虑你是向什么样的视图对象发送消息。
如果你就是向多个视图对象中当前的视图对象发送消息,那么我原本&出错&的那个
方法对于你来说就是正确的。
但如果你不是向当前视图对象发消息,而是有个明确的目标,那么千万要注意,通过
某种方法一定要得到确定的视图指针,
那么用 &(View*)-&PostMessage( , , )发送消息的时候,
接收方才能接收的到你的消息。
如何在自定义消息中传递字符串呢(我有一种方法)?
&发送方: &&
& CString & mystr & ; &&
& char & *buf & ; &&
& buf & = & ( & char & * & ) & new & char[ & 100 & ] & ; &&
& mystr & = & &谢谢wtzyb4446(不死鸟) & 、stonespace(stonespace) & 具体的在下面:&; &&
& strcpy( & buf, & mystr & ); &&
& ::SendMessage( & pFrame-&m_wndWorkspace.GetActiveView()-&GetSafeHwnd(), & WM_USER_QUERY & , & (WPARAM)buf,(LPARAM)mystr.GetLength()); &&
& 接收方: &&
& char & * & dd & ; &&
& dd & = & ( & char & * & )wParam & ; &&
& int & num & = & (int)lParam & ; &&
& for( & int & i & = & 0 & ; & i & & & num & ; & i & ++ & ) &&
& & & str & += & dd[ & i & ]; &&
& delete & dd & ;&
<span type="1" blog_id="940579" userid='
分享到朋友圈
关注作者,不错过每一篇精彩Posts - 98,
Articles - 0,
Comments - 338
男,程序员,关注 c++,欢迎技术探讨,平时看书,写博客。
15:12 by 捣乱小子, ... 阅读,
WIN32编程回忆
在MFC中,听得最多的莫过于&#8220;消息&#8221;这词,透彻理解MFC的消息机制对学习MFC大有裨益。
依稀记得,在纯C的win32编程中,写的最多就是WinMain和win消息处理函数, 我当时有个模板,每每建立一个win32的工程,我就把他复制进去,大概的如下:
#include&&windows.h&#define&CLSNAME&""#define&WNDNAME&""LRESULT&CALLBACK&WindowProc(HWND&hwnd,&&&&&&&&&&&&&&&&&&&&&&&&&&&&UINT&uMsg,&&&&&&&&&&&&&&&&&&&&&&&&&&&&WPARAM&wParam,&&&&&&&&&&&&&&&&&&&&&&&&&&&&LPARAM&lParam&&&&&&&&&&&&&&&&&&&&&&&&&&&&);int&WINAPI&WinMain&(HINSTANCE&hInstance,&&&&&&&&&&&&&&&&&&&&HINSTANCE&hPrevInstance,&&&&&&&&&&&&&&&&&&&&PSTR&szCmdLine,&&&&&&&&&&&&&&&&&&&&&int&iCmdShow){&&&&static&TCHAR&clsname[]&=&TEXT(CLSNAME);&&&&WNDCLASS&&&&&wndclass.style&=&CS_HREDRAW&|&CS_VREDRAW&;&&&&wndclass.lpfnWndProc&=&WindowProc&;&&&&wndclass.cbClsExtra&=&<span style="color: #&;&&&&wndclass.cbWndExtra&=&<span style="color: #&;&&&&wndclass.hInstance&=&hInstance&;&&&&wndclass.hIcon&=&LoadIcon&(NULL,&IDI_APPLICATION)&;&&&&wndclass.hCursor&=&LoadCursor&(NULL,&IDC_ARROW)&;&&&&wndclass.hbrBackground&=&(HBRUSH)&GetStockObject&(WHITE_BRUSH)&;&&&&wndclass.lpszMenuName&=&NULL&;&&&&wndclass.lpszClassName&=&clsname&;&&&&if(!::RegisterClass(&wndclass))&&&&{&&&&&&&&MessageBox&(&NULL,&&&&&&&&&&&&&TEXT&("This&program&requires&Windows&NT!"),&&&&&&&&&&&&clsname,&&&&&&&&&&&&&MB_ICONERROR)&;&&&&&&&&return&<span style="color: #&;&&&&}&&&&HWND&&&&&hwnd&=&::CreateWindow(clsname,TEXT(WNDNAME),&&&&&&&&WS_OVERLAPPEDWINDOW,&&&&&&&&CW_USEDEFAULT,CW_USEDEFAULT,&&&&&&&&CW_USEDEFAULT,CW_USEDEFAULT,&&&&&&&&NULL,NULL,hInstance,NULL);&&&&::ShowWindow(hwnd,SW_SHOW);&&&&::UpdateWindow(hwnd);&&&&MSG&&&&&while(::GetMessage(&msg,NULL,<span style="color: #,<span style="color: #)){&&&&&&&&::TranslateMessage(&msg);&&&&&&&&::DispatchMessage(&msg);&&&&}&&&&return&msg.wP}LRESULT&CALLBACK&WindowProc(HWND&hwnd,&&&&&&&&&&&&&&&&&&&&&&&&&&&&UINT&uMsg,&&&&&&&&&&&&&&&&&&&&&&&&&&&&WPARAM&wParam,&&&&&&&&&&&&&&&&&&&&&&&&&&&&LPARAM&lParam&&&&&&&&&&&&&&&&&&&&&&&&&&&&){&&&&HDC&&&&&PAINTSTRUCT&&&&&TEXTMETRIC&&&&&switch(uMsg)&&&&{&&&&case&WM_DESTROY:&&&&&&&&::PostQuitMessage(<span style="color: #);&&&&&&&&return&<span style="color: #;&&&&case&WM_PAINT:&&&&&&&&hdc&=&::BeginPaint(hwnd,&ps);&&&&&&&&::EndPaint(hwnd,&ps);&&&&&&&&return&<span style="color: #;&&&&}&&&&return&::DefWindowProc(hwnd,uMsg,wParam,lParam);}
为了偷懒,就把窗口类名CLSNAME和窗口标题WNDNAME直接在文件头部define(定义),阅读过《windows程序设计》都应该这样偷懒过。WinMain主函数里面的东西也不用怎么改,像上面原样照搬没有多大的问题,除非要修改窗口类的属性。需要大动干戈的地方,在WindowProc里,这里才是实现你编程梦想的地方。switch语法在展现的淋漓尽致,每个case都是一个windows消息,所以用一句话说明白:windows编程就是基于消息传递的,而消息的传递是有系统负责的,我们负责的是如何去响应系统发出的消息,也就是编写消息响应函数&。
MFC的思想很类似,不过MFC结合了C++,所以MFC的消息机制比起win32编程,会复杂的多,这也让一个很普遍的现象很直观:市面上的很多关于MFC教程的书籍,都对MFC的消息机制一笔带过,能减则减;他们最最擅长就是拖控件。&
MFC自定义窗口消息
在winuser.h头文件中定义了这些消息,但是总有不尽人意的地方,这些消息满足不了我们。MFC有给我们留后路,在winuser.h中WM_USER被定义为0x0400,意味着我们可以定义自己的消息。
根据以下步骤可以定义一般的消息:
定义消息的标号。就像我们经常看到的WM_PAINT等消息一样,他们实际上都有一个标号,#define赋予他们这些标号。
#define&WM_MY_MESSAGE1&WM_USER+0#define&WM_MY_MESSAGE2&WM_USER+1其中
#define&WM_USER&&&&&&&&&&&&&&&&&&&&&&&&&0x0400
添加消息映射函数。这个消息映射函数有一定的规格,MSDN上有硬性的规定:
The type of the function must be afx_msg LRESULT (CWnd::*)(WPARAM, LPARAM).也就是说你的消息响应函数也必须写成是这种形式。因此你的窗口类中必须声明下面的函数原型,函数名可以自由变通,
afx_msg&LRESULT&OnMyMessage1(WPARAM&wParam,&LPARAM&lParam);afx_msg&LRESULT&OnMyMessage2(WPARAM&wParam,&LPARAM&lParam);
&并且在这些函数的定义实现中实现响应的过程。
在消息映射表BEGIN_MESSAGE_MAP和END_MESSAGE_MAP()之间添加消息和消息处理函数的映射。用到了MFC当中的一个宏,ON_MESSAGE(message, memberFxn)&,message是定义的消息,而memberFxn就是消息响应函数,因此:
ON_MESSAGE(WM_MY_MESSAGE1,OnMyMessage1)ON_MESSAGE(WM_MY_MESSAGE2,OnMyMessage2)如此一来就自定义消息就可以实现了。
窗口与窗口之间实现通信:
::SendMessage(hWnd,WM_MY_MESSAGE1,<span style="color: #,<span style="color: #);::SendMessage(hWnd,WM_MY_MESSAGE2,<span style="color: #,<span style="color: #);
&&&&& 这种消息机制可以带来很多的好处,方便实现窗口与窗口之间的通信,特别当两个窗口是父子关系的时候,也就是说一个窗口从属于另一个窗口。子窗口可以在任意时刻通过SendMessage来向父窗口发送消息。
捣乱小子 日星期六没有更多推荐了,
不良信息举报
举报内容:
MFC程序中如何实现自定义消息
举报原因:
原文地址:
原因补充:
最多只允许输入30个字
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!没有更多推荐了,
不良信息举报
举报内容:
MFC中自定义消息的步骤
举报原因:
原文地址:
原因补充:
最多只允许输入30个字
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!

我要回帖

更多关于 微信自定义模板消息 的文章

 

随机推荐