拆分窗口通信问题?

时间:2021-10-17 21:31:10
我用VC++6.0 MFC建了一个以CTest为名字的单文档工程,然后进行了窗口拆分,我的窗口拆分是这样的,用

IDD_LEFT_DIALOG和IDD_RIGHT_DIALOG两个Dialog将窗口分为一左一右两个视图。这两个Dialog对应的类为如下所示:

 class CLView : public CFormView //左Dialog
 class CRView : public CFormView //右Dialog

 CTestView 类仍然保留,那么我要怎么样才能实现CLView和CRView窗口之间互相通信呢?

 举个例子,我在CLView定义了变量m_QQ2010的变量,我要在CRView类中使用m_QQ2010,我是这么做的:

在CLView.h定义friend class CRView;//是CRView的友元,另外在CRView中加上两句话,就可以编译运行通过。

那么这样算不算CLView和CRView互相通信了。
  
   CMainFrame *pFrm = (CMainFrame *)AfxGetMainWnd();
   pFrm->m_QQ2010

到底怎么样才可以实现互相通信,期待高手答复。

另外左右窗口之间都是控件之间的信息交往。

10 个解决方案

#1


使用CSplitterWnd拆分的时候,可以使用CWnd* GetPane(int row, int col);函数取得你拆分窗口的句柄,然后强制转换成你对应的类型就可以了
void CMainFrame::OnTest() 
{
CSplitterWindowTutorialView* pVieL = ( CSplitterWindowTutorialView* )m_mainSplitter.GetPane( 0, 0 );
CSplitterWindowTutorialView* pVieR = ( CSplitterWindowTutorialView* )m_mainSplitter.GetPane( 0, 1 );

pVieL->GetDC( )->Rectangle( 0,0,200,200 );
}

我的代码是在http://www.codeproject.com/Articles/3509/Splitter-Window-Tutorial 例子上加的。
如果你要下载这个例子,请注意里面缺少RES文件夹,你只需要拷贝另外一个单文档的RES文件夹后,将里面的文件改名就可以了。

为了能够随时找到窗口,你可以建立MainFrame下的两个成员变量,在MainFrame的适当地方,例如OnShow中添加上面类似的取得窗口句柄的方法,以后,在其他地方可以同个AfxGetMainWnd()找到。

#2


文件不能下载啊,我这个窗口是已经拆分好了的。
C/C++ code
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT /*lpcs*/,
CCreateContext* pContext)
{
VERIFY(m_wndSplitter.CreateStatic(this,1, 2));
VERIFY(m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CLView), CSize(1080, 900), pContext));
VERIFY(m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CRView), CSize(100, 370), pContext));
return true;
}
网上听了很多办法都无法奏效,程序可以运行,但是运行过程中还是会出错。因为我的左边窗口的是厂家的摄像机ocx控件和其他另外一个厂家的OCX控件,右边是对应的常规操作控件。所以运行程序的时候,就会报错。
估计是和串口什么的搞上了,归根到底是两个窗口没有很好的互相通信。
  
   Debug Assertion Failed   !
   Program: C:\Test\Debug\Test.exe
   File: strcore.cpp
   Line: 519
   For information on how your program can cause an assertion
   failure, see the Visual C++ documentation on asserts.
   (Press Retry to debug the application)

#3


两个窗口通信可以通过发消息
共享数据可通过它们的父窗口

#4


楼主可以这样做,
在CMainFrame的头文件中定义CLView和CRView的指针:
CLView *m_pLView ;
CRView *m_pRView ; 


在CMainFrame的.cpp文件中:
...

VERIFY(m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CLView), CSize(1080, 900), pContext));

m_pLView = (CLView *)m_wndSplitter.GetPane(0, 0);

VERIFY(m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CRView), CSize(100, 370), pContext));

m_pRView = (CRView *)m_wndSplitter.GetPane(0, 1);
...



这样你在其他地方要使用这两个句柄的话,
 CMainFrame *pFrm = (CMainFrame *)AfxGetMainWnd();
 pFrm->m_pLView;
pFrm->m_pRView ;
就可以了



#5


两个视图相互访问,可以通过文档类
CMyDoc *pDoc = GetDocument();
CLView *pLView = NULL;
POSITION posi = pDoc->GetFirstViewPosition();
while(posi!=NULL)
{
   CView *pView = pDoc->GetNextView(posi);
   if(pView->IsKindOf(RUNTIME_CLASS(CLView)) )
   {
       pLView = (CLView*)pView;//在右侧视类中获取左侧视类CLView指针
       break;
   }
}

#6


在CRView类中需要调用m_QQ2010的地方添加:
CMainFrame    *pMain=(CMainFrame  *)AfxGetMainWnd(); 
CLView        *pLView=(CTestView *)pMain->m_wndSplitter.GetPane(0,0);

这样就可以调用:pLView->m_QQ2010

另外需要添加头文件#include "MainFrm.h"
                #include "LView.h"

#7


4#和6#的朋友,我按照你们的方法先创建拆分窗口,这个可以实现。但是,编译是通过了,运行的时候报错。
   错误信息
   Debug Assertion Failed   !
   Program:  C:\Test\Debug\Test.exe
   File: winsplit.cpp
   Line: 2329

  For information on how your program can cause an assertion
   failure, see the Visual C++ documentation on asserts.

   (Press Retry to debug the application)

4#的朋友的调用方案
在其他地方要使用这两个句柄的话,
 CMainFrame *pFrm = (CMainFrame *)AfxGetMainWnd();
 pFrm->m_pLView;
 pFrm->m_pRView ;
就可以了

6#的朋友的调用方案

在CRView类中需要调用m_QQ2010的地方添加:  
CMainFrame *pMain=(CMainFrame *)AfxGetMainWnd();  
CLView *pLView=(CTestView *)pMain->m_wndSplitter.GetPane(0,0);

这样就可以调用:pLView->m_QQ2010

怎么办啊?



#8


把Debug文件夹下的文件全部删除,重新Rebulid一下工程看一下。

#9


这个问题搞了我两天,到现在还没有结果。我将要去跳楼了。

#10


请问您这个问题解决好了吗?我最近也碰到累死的问题:
VS2010,MFC程序中添加了这段代码就报 Debug Assertion Failed! .........winsplit.cpp Line:367 ......
求大神帮忙解决:
CSplitterWnd   m_wndSplitter;
    CSplitterWnd wndSplitter1;
    //1,创建2行1列的窗口
    if ( m_wndSplitter.CreateStatic(this, 2, 1 ) == NULL)
        return FALSE;
    //2,将CAboutWidow放在1行0列处
    m_wndSplitter.CreateView(0,0,RUNTIME_CLASS(CAboutWidow),CSize(700, 100)/*size3*/,pContext);

    //创建一个1行2列长度窗口
    if(wndSplitter1.CreateStatic(&m_wndSplitter,1,2,WS_CHILD|WS_VISIBLE | WS_BORDER,m_wndSplitter.IdFromRowCol(0, 0))==NULL)
        return FALSE;     
    wndSplitter1.CreateView(0,0,RUNTIME_CLASS(CTcfConfigView),CSize(200, 300)/*size1*/,pContext);
    wndSplitter1.CreateView(0,1,RUNTIME_CLASS(CEntryView),CSize(500, 300)/*size2*/,pContext);

#1


使用CSplitterWnd拆分的时候,可以使用CWnd* GetPane(int row, int col);函数取得你拆分窗口的句柄,然后强制转换成你对应的类型就可以了
void CMainFrame::OnTest() 
{
CSplitterWindowTutorialView* pVieL = ( CSplitterWindowTutorialView* )m_mainSplitter.GetPane( 0, 0 );
CSplitterWindowTutorialView* pVieR = ( CSplitterWindowTutorialView* )m_mainSplitter.GetPane( 0, 1 );

pVieL->GetDC( )->Rectangle( 0,0,200,200 );
}

我的代码是在http://www.codeproject.com/Articles/3509/Splitter-Window-Tutorial 例子上加的。
如果你要下载这个例子,请注意里面缺少RES文件夹,你只需要拷贝另外一个单文档的RES文件夹后,将里面的文件改名就可以了。

为了能够随时找到窗口,你可以建立MainFrame下的两个成员变量,在MainFrame的适当地方,例如OnShow中添加上面类似的取得窗口句柄的方法,以后,在其他地方可以同个AfxGetMainWnd()找到。

#2


文件不能下载啊,我这个窗口是已经拆分好了的。
C/C++ code
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT /*lpcs*/,
CCreateContext* pContext)
{
VERIFY(m_wndSplitter.CreateStatic(this,1, 2));
VERIFY(m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CLView), CSize(1080, 900), pContext));
VERIFY(m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CRView), CSize(100, 370), pContext));
return true;
}
网上听了很多办法都无法奏效,程序可以运行,但是运行过程中还是会出错。因为我的左边窗口的是厂家的摄像机ocx控件和其他另外一个厂家的OCX控件,右边是对应的常规操作控件。所以运行程序的时候,就会报错。
估计是和串口什么的搞上了,归根到底是两个窗口没有很好的互相通信。
  
   Debug Assertion Failed   !
   Program: C:\Test\Debug\Test.exe
   File: strcore.cpp
   Line: 519
   For information on how your program can cause an assertion
   failure, see the Visual C++ documentation on asserts.
   (Press Retry to debug the application)

#3


两个窗口通信可以通过发消息
共享数据可通过它们的父窗口

#4


楼主可以这样做,
在CMainFrame的头文件中定义CLView和CRView的指针:
CLView *m_pLView ;
CRView *m_pRView ; 


在CMainFrame的.cpp文件中:
...

VERIFY(m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CLView), CSize(1080, 900), pContext));

m_pLView = (CLView *)m_wndSplitter.GetPane(0, 0);

VERIFY(m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CRView), CSize(100, 370), pContext));

m_pRView = (CRView *)m_wndSplitter.GetPane(0, 1);
...



这样你在其他地方要使用这两个句柄的话,
 CMainFrame *pFrm = (CMainFrame *)AfxGetMainWnd();
 pFrm->m_pLView;
pFrm->m_pRView ;
就可以了



#5


两个视图相互访问,可以通过文档类
CMyDoc *pDoc = GetDocument();
CLView *pLView = NULL;
POSITION posi = pDoc->GetFirstViewPosition();
while(posi!=NULL)
{
   CView *pView = pDoc->GetNextView(posi);
   if(pView->IsKindOf(RUNTIME_CLASS(CLView)) )
   {
       pLView = (CLView*)pView;//在右侧视类中获取左侧视类CLView指针
       break;
   }
}

#6


在CRView类中需要调用m_QQ2010的地方添加:
CMainFrame    *pMain=(CMainFrame  *)AfxGetMainWnd(); 
CLView        *pLView=(CTestView *)pMain->m_wndSplitter.GetPane(0,0);

这样就可以调用:pLView->m_QQ2010

另外需要添加头文件#include "MainFrm.h"
                #include "LView.h"

#7


4#和6#的朋友,我按照你们的方法先创建拆分窗口,这个可以实现。但是,编译是通过了,运行的时候报错。
   错误信息
   Debug Assertion Failed   !
   Program:  C:\Test\Debug\Test.exe
   File: winsplit.cpp
   Line: 2329

  For information on how your program can cause an assertion
   failure, see the Visual C++ documentation on asserts.

   (Press Retry to debug the application)

4#的朋友的调用方案
在其他地方要使用这两个句柄的话,
 CMainFrame *pFrm = (CMainFrame *)AfxGetMainWnd();
 pFrm->m_pLView;
 pFrm->m_pRView ;
就可以了

6#的朋友的调用方案

在CRView类中需要调用m_QQ2010的地方添加:  
CMainFrame *pMain=(CMainFrame *)AfxGetMainWnd();  
CLView *pLView=(CTestView *)pMain->m_wndSplitter.GetPane(0,0);

这样就可以调用:pLView->m_QQ2010

怎么办啊?



#8


把Debug文件夹下的文件全部删除,重新Rebulid一下工程看一下。

#9


这个问题搞了我两天,到现在还没有结果。我将要去跳楼了。

#10


请问您这个问题解决好了吗?我最近也碰到累死的问题:
VS2010,MFC程序中添加了这段代码就报 Debug Assertion Failed! .........winsplit.cpp Line:367 ......
求大神帮忙解决:
CSplitterWnd   m_wndSplitter;
    CSplitterWnd wndSplitter1;
    //1,创建2行1列的窗口
    if ( m_wndSplitter.CreateStatic(this, 2, 1 ) == NULL)
        return FALSE;
    //2,将CAboutWidow放在1行0列处
    m_wndSplitter.CreateView(0,0,RUNTIME_CLASS(CAboutWidow),CSize(700, 100)/*size3*/,pContext);

    //创建一个1行2列长度窗口
    if(wndSplitter1.CreateStatic(&m_wndSplitter,1,2,WS_CHILD|WS_VISIBLE | WS_BORDER,m_wndSplitter.IdFromRowCol(0, 0))==NULL)
        return FALSE;     
    wndSplitter1.CreateView(0,0,RUNTIME_CLASS(CTcfConfigView),CSize(200, 300)/*size1*/,pContext);
    wndSplitter1.CreateView(0,1,RUNTIME_CLASS(CEntryView),CSize(500, 300)/*size2*/,pContext);