项目背景:
创建了MFC SDI 单文档视图,由于项目需要,对视图进行了分割。主要分为三部分,
1)主View 左边;--------------标记为视图A
2)操作对话框视图,右上;--------------标记为视图B
3)属性对话框视图,右下。--------------标记为视图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发送消息给对话框,原理是一致的。
这种情况处理起来有些绕,原因是普通方式无法获取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,原理也是一样的。
比如这里的在属性编辑对话框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即可。