MFC SDI分割视图之间消息传递
项目背景:
创建了MFC SDI 单文档视图,由于项目需要,对视图进行了分割。主要分为三部分,
1)主View 左边;--------------标记为视图A
2)操作对话框视图,右上;--------------标记为视图B
3)属性对话框视图,右下。--------------标记为视图C
类型1 View视图A 发送消息给对话框视图C
A视图中 已选中当前ROI后,需将ROI信息通过消息的方式传递到对话框视图C
定义一个自定义消息ID
#define WM_PROPERTY_MESSAGE WM_USER+100
在视图A中发送消息,格式如下,
::SendMessage(m_pParent->m_formPropertyView->m_hWnd, WM_PROPERTY_MESSAGE, (WPARAM)oide, (LPARAM)(LPCTSTR)strtype.GetBuffer(0));
接收消息的是视图C,需要在C中添加自定义消息响应函数
声明:
afx_msg LRESULT OnGetROIMessage(WPARAM wParam, LPARAM lParam);
消息宏:
ON_MESSAGE(WM_PROPERTY_MESSAGE, &CPropertyView::OnGetROIMessage)
定义:
LRESULT CPropertyView::OnGetROIMessage(WPARAM wParam, LPARAM lParam)
{
CString str;
str.Format("%s", (lParam));
//CString str1 = (CString)lParam;
AOIDetectionEvent* aoide = new AOIDetectionEvent();
aoide = (AOIDetectionEvent*)wParam;
UpDateUI(*aoide);
delete aoide;
return 1;
}
说明:这里需要说明一下 消息响应函数的两个参数 WPARAM wParam, LPARAM lParam ,类型都是指针。在不同界面通过消息来传递参数时非常高效。一般习惯性的一个传递 指针类型的结构体或其他类型的指针,另外一个参数可以表示消息的类型,用于区分同一消息的不同的响应方式。
同理,View视图A 发送给对话框视图B,也是View发送消息给对话框,原理是一致的。
类型2 对话框视图C 发送消息给View视图A
这种情况处理起来有些绕,原因是普通方式无法获取View的句柄,按照网上的方法,尝试过如下方法,
CFrameWndEx *pMain = (CFrameWndEx *)AfxGetMainWnd();
CMainFrame* m_pParent = ((CMainFrame*)pMain->GetActiveFrame());
CAOIShopView* m_pView = ((CAOIShopView*)m_pParent->GetActiveView());
LRESULT AA = ::SendMessage(m_pView->m_hWnd, WM_AOISHOPVIEW_MESSAGE, (WPARAM)(&iNum), (LPARAM)(LPCTSTR)str.GetBuffer(0));
通过这种方法发现返回值为0,无法完成消息的发送。原因未知。
这里主要的问题是窗口句柄,这里提供另外一种解决方案,在MainFrm.cpp 定义一个外部的全局变量
CAOIShopView* g_shopview;
在MainFrm的OnCreateClient函数 中给分割的View赋值,
g_shopview = (CAOIShopView*)m_wndSplitter1.GetPane(0, 0);
在对话框视图C中引用这里的 全局变量 g_shopview,发送自定义消息如下,
::SendMessage(g_shopview->m_hWnd, WM_AOISHOPVIEW_MESSAGE, (WPARAM)(&iNum), (LPARAM)(LPCTSTR)str.GetBuffer(0));
参数3 指针和参数4 传数据。
以上是消息发送端的内容,接收端就是主View类中添加自定义消息函数,用于接收并处理消息
首先定义一个自定义消息ID
#define WM_PROPERTY_MESSAGE WM_USER+101
添加接收消息的函数声明,
afx_msg LRESULT OnAOIShopMessage(WPARAM wParam, LPARAM lParam);
添加消息宏映射,
ON_MESSAGE(WM_AOISHOPVIEW_MESSAGE, &CAOIShopView::OnAOIShopMessage)
最后添加消息定义
LRESULT CAOIShopView::OnAOIShopMessage(WPARAM wParam, LPARAM lParam)
{
CString str;
str.Format("%s", (lParam));
if (-1 != str.FindOneOf(_T("Del")))
{
int* iNum = (int*)wParam;
int iTmp = *iNum;
m_idirct = 5;
ChangeRectPt(m_idirct);
}
return 1;
}
同理,对话框视图B发送消息给View视图A,原理也是一样的。
类型3 对话框视图之间发送消息
比如这里的在属性编辑对话框C,发送添加或删除的消息给操作对话框B,B在收到消息后,在列表控件中完成相应更新(添加或删除数据)。
这种情况跟类型1也比较类似,唯一的区别在于获取当前窗体的句柄,这里是通过MainFrm来获取的,方法如下,
CFrameWndEx *pMain = (CFrameWndEx *)AfxGetMainWnd();
CMainFrame* m_pParent= ((CMainFrame*)pMain->GetActiveFrame());
::SendMessage(m_pParent->m_formOperationalView->m_hWnd, WM_OPERATION_MESSAGE, (WPARAM)aoide, (LPARAM)(LPCTSTR)str.GetBuffer(0));
消息接收端 实现方法参考类型1即可。