天天看点

MFC SDI分割视图之间消息传递MFC SDI分割视图之间消息传递

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即可。