从MSDN中看了关于单文档多视图中视图切换
http://msdn.microsoft.com/library/chs/default.asp?url=/library/CHS/vccore/html/vcconaddingmultipleviewstosingledocument.asp其中一段:
//SwitchCView* CMyWinApp::SwitchView( )
{
   CView* pActiveView =
      ((CFrameWnd*) m_pMainWnd)->GetActiveView();   CView* pNewView= NULL;
   if(pActiveView == m_pOldView)
      pNewView= m_pNewView;
   else
      pNewView= m_pOldView;   // Exchange view window IDs so RecalcLayout() works.
   #ifndef _WIN32
   UINT temp = ::GetWindowWord(pActiveView->m_hWnd, GWW_ID);
   ::SetWindowWord(pActiveView->m_hWnd, GWW_ID, ::GetWindowWord(pNewView->m_hWnd, GWW_ID));
   ::SetWindowWord(pNewView->m_hWnd, GWW_ID, temp);
   #else
   UINT temp = ::GetWindowLong(pActiveView->m_hWnd, GWL_ID);
   ::SetWindowLong(pActiveView->m_hWnd, GWL_ID, ::GetWindowLong(pNewView->m_hWnd, GWL_ID));
   ::SetWindowLong(pNewView->m_hWnd, GWL_ID, temp);
   #endif   pActiveView->ShowWindow(SW_HIDE);
   pNewView->ShowWindow(SW_SHOW);
   ((CFrameWnd*) m_pMainWnd)->SetActiveView(pNewView);
   ((CFrameWnd*) m_pMainWnd)->RecalcLayout();
   pNewView->Invalidate();
   return pActiveView;
} //Switch
当中的几个语句怎么看也不清楚它的意思..
// Exchange view window IDs so RecalcLayout() works.
UINT temp = ::GetWindowWord(pActiveView->m_hWnd, GWW_ID);
   ::SetWindowWord(pActiveView->m_hWnd, GWW_ID, ::GetWindowWord(pNewView->m_hWnd, GWW_ID));
   ::SetWindowWord(pNewView->m_hWnd, GWW_ID, temp);
///////////////////////////////交换窗口的ID,RecalcLayout()函数才起作用...?
这样的交换对视图的切换倒底有什么用??但是去掉这几句切换功能就不能实现.
郁闷中....

解决方案 »

  1.   

    时间仓促写了一个,可以实现你要要求的函数:void ChangeFrameView(CFrameWnd* pFrame, CRuntimeClass* pNewView)
    {
    ASSERT(pFrame);
    ASSERT(pNewView); // 获取当前的视图。
    CView* pCurrentView = pFrame->GetActiveView(); // 保存当前视图的位置。
    CRect rcView;
    pCurrentView->GetWindowRect(&rcView); // 获得当前视图相关的文档。
    CDocument* pDoc;
    pDoc = pCurrentView->GetDocument(); // 保存文档的状态, 防止在释放视图的时候自动释放。
    BOOL bSaveDocument  = pDoc->m_bAutoDelete;
    pDoc->m_bAutoDelete = FALSE;

    // 释放当前视图。
    pCurrentView->DestroyWindow(); // 恢复文档状态。
    pDoc->m_bAutoDelete = bSaveDocument; // 创建新的上下文。
    CCreateContext context;
    context.m_pCurrentFrame   = NULL;
    context.m_pLastView       = NULL;
    context.m_pNewDocTemplate = NULL; context.m_pCurrentDoc     = pDoc;
    context.m_pNewViewClass   = pNewView;  // 创建视图。
    CView* pNewCreateView = static_cast<CView*>(pFrame->CreateView(&context)); // 移动新视图到原来视图的位置。
    pFrame->ScreenToClient(&rcView);
    pNewCreateView->MoveWindow(&rcView); // 更新。

    pFrame->InitialUpdateFrame(pDoc, TRUE);
    }调用方法:
    假如在SDI的框架窗口类中:
    ChangeFrameView(this, RUNTIME_CLASS(视图类名));
      

  2.   


             // 获取当前的视图。
    CView* pCurrentView = pFrame->GetActiveView();
    的后面在写上如下的代码,如果要转化的视图和当前视图为同一类型,就直接退出。
    if (pCurrentView->IsKindOf(pNewView))
    {
         return;
    }
      

  3.   

    谢谢ks_gq的回复!你写的函数是动态切换视图,功能是可以实现,我也有类似实现,
    但是动态实现每次都要重新创建一个VIEW;如果是静态创建,那下次显示的时候,只要调用一下指针就可.
    //
    对于我提出来的问题:为什么要调换窗口ID,我还是不明白.
      

  4.   

    交换视图的窗口ID,使RecalcLayout()可以工作