各位编程高手,大家好。我遇到一个棘手问题,假如我要执行下面的On12()函数,需要调用CMainFrame::OnCreateClient函数,但是我想把OnCreateClient函数里面的CView2字符替换替换成CView3再执行,我该怎么做。void CMainFrame::On12() 
{
  bool OnCreateClient();//调用的函数
}
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) 
{
  VERIFY(m_wndSplitter.CreateStatic(this,1, 2));
  VERIFY(m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CView1), CSize(1050, 0), pContext));
  VERIFY(m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CView2), CSize(800,  0), pContext));
  return true;
}

解决方案 »

  1.   

    为什么不用m_wndSplitter的CreateView而是用CMainFrame::OnCreateClient?如果执行的功能和CMainFrame::OnCreateClient相同或者相似,也可以将:
    VERIFY(m_wndSplitter.CreateStatic(this,1, 2));
    VERIFY(m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CView1), CSize(1050, 0), pContext));
    VERIFY(m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CView2), CSize(800, 0), pContext));
    代码直接拷贝到你要用的地方,或者稍做修改就可以了啊。
      

  2.   

    我的意思,你们可能都没有明白。我问的是怎么按照我说调用呢。因为我要处理下面这个效果。三个窗口对应的类为CView1 CView2 CView3分别是第一,第二,第三个窗口。
    程序运行的时候是这样的点击切换窗口上的窗口切换如下图所示,菜单下 窗口切换项的响应函数即为On12(),所以我是为了达到这个效果的。
      

  3.   

    我的意思,你们可能都没有明白。我问的是怎么按照我说调用呢。因为我要处理下面这个效果。三个窗口对应的类为CView1 CView2 CView3分别是第一,第二,第三个窗口。
    程序运行的时候是这样的点击切换窗口上的窗口切换如下图所示,菜单下 窗口切换项的响应函数即为On12(),所以我是为了达到这个效果的。
      

  4.   

    给CMainFrame加个变量,如:m_iCurrentState;
    初始化为0
    BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)  
    {
      VERIFY(m_wndSplitter.CreateStatic(this,1, 2));
      VERIFY(m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CView1), CSize(1050, 0), pContext));
    if(m_iCurrentState == 0)
    {
      VERIFY(m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CView3), CSize(800, 0), pContext));
    iCurrentState = 1;
    }else
    {
      VERIFY(m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CView2), CSize(800, 0), pContext));
    iCurrentState  = 0;
    }
     return true;
    }
      

  5.   

    楼上的朋友,能否麻烦你的明白点。m_iCurrentState变量定义为什么类型的。还有On12()函数,直接调用CMainFrame::OnCreateClient函数无任何反应啊。
      

  6.   

    ...............无语,唉int型
    那就不要调用,
    void CMainFrame::On12()  
    {
    VERIFY(m_wndSplitter.CreateStatic(this,1, 2));
    VERIFY(m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CView1), CSize(1050, 0), pContext));
    if(m_iCurrentState == 0)
    {
    VERIFY(m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CView3), CSize(800, 0), pContext));
    m_iCurrentState = 1;
    }
    else
    {
    VERIFY(m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CView2), CSize(800, 0), pContext));
    m_iCurrentState = 0;
    }
    }
      

  7.   

    不需要那么麻烦  你可以只用两个View  然后在右边那个View中使用两个对话框 使其覆盖View 通过设置对话框的显隐来控制窗口的变换
      

  8.   

    没有那么容易,
    (m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CView2), CSize(800, 0), pContext));
    这个东西是不能放在其他地方的,因为有pContext变量,他放到其他地方是会报错的,我不知道你们有没有自己去实验过。如果可以的话。那就很好办,也就是1楼所说的方法,我发帖之前就想过了。不行。
      

  9.   

    将pContext设置为NULL也是不行,运行的时候会报错
      

  10.   

    9# 的朋友 heksn  越说越麻烦了,
    我这个思路比较好的,具体能不能实现,我就不好说了,至少我这个只需要控制一个量啊。
      

  11.   

    用m_wndSplitter.CreateStatic(this,1, 3));创建3个分割窗口
    每次只显示两个噻
      

  12.   

    //网上摘抄的一段代码,可以参考一下
    void SwitchViewInSplitter( CSplitterWnd * pSplitter, int row, int col, CRuntimeClass * pViewClass )
    {
        ///////////////////////////////////////////////////////////   
        //   Replace   the   current   view   in   the   splitter   pSplitter   
        //   at   pane   (row,   col)   by   a   new   view   of   class   pViewClass   
        ASSERT_VALID( pSplitter );
        ASSERT( pViewClass != NULL );    ASSERT( pViewClass->IsDerivedFrom( RUNTIME_CLASS( CView ) ) );    //   1   -   Find   the   view   to   be   replaced   
        CWnd *pPaneWnd = pSplitter->GetPane( row, col );
        if( !pPaneWnd->IsKindOf( RUNTIME_CLASS( CView ) ) )   
        {   
            TRACE2( "Unable   to   switch:   pane   (%d,%d)   is   not   a   view\n", row, col );
            return;
        }       CView*   pCurrentView   =   static_cast<CView*>( pPaneWnd );
        ASSERT_VALID(   pCurrentView   );
        ASSERT_KINDOF(   CView,   pCurrentView   );    if(   pCurrentView->IsKindOf(   pViewClass   )   )   
        {   
            //   No   need   to   switch   for   same   view   class   
            return;
        }       //   2   -   Store   current   view   position   and   activation   state   
        CRect   rcView;
        pCurrentView->GetWindowRect(   &rcView   );    CView*   pActiveView   =   pSplitter->GetParentFrame()->GetActiveView();
        BOOL   bSaveActive   =   (   pActiveView   ==   NULL   )    ||   (   pActiveView   ==   pCurrentView   );    //   3   -   Find   the   associated   document   
        CDocument*   pDoc   =   pCurrentView->GetDocument();
        ASSERT_VALID(   pDoc   );    //   4   -   Make   sure   the   document   won't   self-destruct   
        //   when   current   view   is   destroyed   
        BOOL   bSaveAutoDelete   =   pDoc->m_bAutoDelete;
        pDoc->m_bAutoDelete   =   FALSE;    //   5   -   Destroy   the   current   view   
        pCurrentView->DestroyWindow();    //   6   -   Restore   document   to   initial   state   
        pDoc->m_bAutoDelete   =   bSaveAutoDelete;    //   7   -   Initialize   creation   context   used   by   CreateView()   
        CCreateContext   context;
        context.m_pNewDocTemplate   =   NULL;
        context.m_pLastView   =   NULL;
        context.m_pCurrentFrame   =   NULL;    context.m_pNewViewClass   =   pViewClass;
        context.m_pCurrentDoc   =   pDoc;    //   8   -   Create   the   new   view   
        pSplitter->CreateView( row,   col,   pViewClass,   
        rcView.Size(),   &context   );    CView*   pNewView   =   static_cast<CView*>(   pSplitter->GetPane(   row,   col   )   );
        ASSERT_VALID(   pNewView   );
        ASSERT_KINDOF(   CView,   pNewView   );    //   9   -   Position   the   new   view   like   the   old   one   and
        //   activate   it   if   needed
        pSplitter->ScreenToClient(   &rcView   );
        pNewView->MoveWindow(   &rcView,   TRUE   );
        if(   bSaveActive   )
        {
            pSplitter->GetParentFrame()->SetActiveView(   pNewView   );
        }    //   10   -   Send   WM_INITIALUPDATE   to   the   view   
        pNewView->GetParentFrame()->InitialUpdateFrame(   pDoc,   TRUE   );
    }// 使用方法
    SwitchViewInSplitter( &m_wndSplitter_v, 0, 1, RUNTIME_CLASS( CView3 ) );
      

  13.   

    恩,我这个CView1 CView2 CView3是三个对话框。不简单啊,麻烦啊。
      

  14.   

    很简单的问题啊。你只需要有两个View,一个CLeftView,一个CRightView
    然后CRightView里面有子View,比如CView2,CView3。
    在需要的时候创建或者显示/隐藏CView2,CView3即可。
      

  15.   

    CView1,CView2,CView3是三个对话框对应的类,为什么要搞三个对话框呢,而不在一个对话框上进行分割呢。因为我右边CView2,CView3两个对话框上面要分别放几十个控件的。而CView1也是要放几个ocx控件的。控件太多了,所以我分别用一个对话框放他们对应控件。现在其实是相当于我要把有两张纸,第一张纸是CView1,CView2将纸分成左右两半,第二张纸是CView1,CView3将纸分成左右两半。
    我现在头痛的是,我这个两张纸张需要切换,这个切换的开关我设置在菜单项的一个子项下。点击这个子项目可以进行两张纸张的切换。注意,我不是单纯的要分成上面那个效果,我还要求分别在各自的界面上都可以独立的放空间比如button等,不仅仅是为了显示而已。现在的问题还是跑回来了,不知道怎么讲菜单项下的切换子菜单项目和我两张纸张对应起来,所以我想了是不是将菜单的状态设置为一个开关量呢,这样在CMainFrame::OnCreateClient函数下面不就可以用swich或者if语句判断。菜单项目的状态比如默认设置为0,再次点击一下变为1.将某个值赋给这个菜单项的状态。但是不知道怎么实现。楼上几位都说分割为三个,要的时候显示他们,问题是我连怎么显示他们我都不会操作,所以对我来说那就更麻烦了。
      

  16.   

    我看了网上的一些做法。
    第一种方法:移动对话框,将左对话框移动为整个屏幕大。但是右边对话框原来里面放了一些按钮控件还在屏幕上。而且移动后的屏幕都把工具条覆盖了。如果左边对话框上放的是厂家提供的OCX视频类开发控件,那么根本就没法移动。
    CWnd* m_pWndRight = m_wndSplitter.GetPane(0, 0);
    CRect rect;
    GetClientRect( &rect );
    m_pWndRight->MoveWindow(&rect);
    第二种方法:隐藏右对话框,当全屏的时候没有任何变化,点击“还原”,然后再点击“最大化”右边出现整块都是白色的。
    CWnd* pWnd = m_wndSplitter.GetPane(0, 1);
    CRView* pFrm = DYNAMIC_DOWNCAST(CRView,pWnd);
    pFrm->ShowWindow(SW_HIDE);
    怎么办呢。
      

  17.   

    1、把窗口分割为左右两半,左边CView1用CFormView,CFormView可以像对话框一样使用。
    2、为右边视图建立两个对话框的子窗口,根据需要显示或隐臧相应的对话框子窗口。