1、小心的使用消息传送-传送给多个 View 类时需要引起注意的一个问题我的前一篇文章里说的是关于 两种自定义消息的发送与接收的方法实现可当我在一次使用消息传送的时候也遇到一个让人迷惑的问题,好在最后解决了。-原来我对于一个消息的传送也做过,使用的是CMainFrame* pMF=(CMainFrame*)AfxGetApp()-m_pMainWnd; / 通过获取当前框架指针CView * active = pMF-GetActiveView();/ 获取当前视类指针if(active != NULL) active-PostMessage(WM_MY_MESSAGE,0,0); / 使用 Po
2、stMessage 发送消息来发送我定义的消息的。很顺利的,我就在要接收的 View 类里接收到了该消息。可是当一个类中定义了 2 个自定义的消息,并要分别发送给两个不同的 View 视图类的时候,如果还般照上面的代码,就要出一些问题了。为什么说是照搬就会出现问题呢?请注意一个地方:上面的代码中,是如何得到 View 类的指针的。对,就是使用的函数 GetActiveView(),这个函数的作用是获得“ 当前“视图指针。我之所以出问题,使得其中的一个 View 类不能接收到消息也就是这个原因。-下面详细说明我出错的过程和解决过程。来源:一个 SDI 被我用静态切分的方式,且分成左右大小相等的两
3、个部分,并使这两个部分分别指向自行创建的两个新类:CMyLeftView 和 CMyRightView,它们的基类都是CEditView。所以说这两个准备接收消息的视图类除了名字,其他并没有什么不太一样的地方。一个对话框(CMyFindDialog 类),其上有 2 个 RADIO BUTTON 控件,和一个确定按钮,这两个 RADIO BUTTON 控件在选择的时候,使其只能进行单选,他们也就分别对应于前面所说的左右两个部分,选择后,点击确定按钮,便表示向 哪个视图发送消息。做好了发送和接收部分,运行发现只能有一个消息被接收到,void CMyFindDialog:OnButtonFind(
4、) MainFrame* pMF=(CMainFrame*)AfxGetApp()-m_pMainWnd;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,
5、0,0); elseMessageBox(“MUST CHOOSE ONE!“); 通过 GetActiveView()得到的当前视类指针,那么如果你打开对话框之前,焦点(光标) 在左边,那么就是左边能接收到消息,右边怎么也接收不到。如果你打开对话框之前,焦点(光标) 在右边,那么就是右边能接收到消息,左边怎么也接收不到。程序运行后,焦点(光标)默认的是在左边,这也就导致我总一为是右边的接收消息的部分有问题。其实,如果在程序运行后,先把焦点(光标) 改换到右边,再打开对话框测试发送与接收,就成了左边收不到消息,右边可以收到消息。(这还是在论坛中,别人的话提醒了,才找到了错误的所在。要不然还在考
6、虑是不是接收部分出了问题。)对于这样一个向 2 个 View 类发送消息问题,就是要注意你所执行发送(PostMessage)的对象是谁!正确的代码如下:void CMyFindDialog:OnButtonFind() CMainFrame* pMF=(CMainFrame*)AfxGetApp()-m_pMainWnd;CMyLeftView* pLV=(CMyLeftView*)pMF-m_wndSplitter.GetPane(0,0);CMyRightView* pRV=(CMyRightView*)pMF-m_wndSplitter.GetPane(0,1);/ 对于我这个题,是通
7、过切分对象 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); elseMessageBox(“MUST CHOOSE ONE!“); 总结:当你需要发送消息给多个视图对象的时候,要考虑你是向什么样的视图对象发送消息。如果你就是向多个视图对象中当前的视图对象发送消息,那么我原本“出错” 的那个方法对于你来说就是正确的。但如果你不是向当前视图对象发消息,而是有个明确的目标,那么千万要注意,通过某种方法一定要得到确定的视图指针,那么用 (View*)-PostMessage( , , )发送消息的时候,接收方才能接收的到你的消息。