Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1676450
  • 博文数量: 585
  • 博客积分: 14610
  • 博客等级: 上将
  • 技术积分: 7402
  • 用 户 组: 普通用户
  • 注册时间: 2008-05-15 10:52
文章存档

2013年(5)

2012年(214)

2011年(56)

2010年(66)

2009年(44)

2008年(200)

分类: C/C++

2011-08-20 10:58:49

一. 参考的做法

1  首先利用资源编辑器新建4个对话框,在对话框中添加需要的控件,各个对话框的ID分别为IDD_MULTIVIEW_FORM,IDD_MULTIVIEW_FORM2,IDD_MULTIVIEW_FORM3,IDD_MULTIVIEW_FORM4

2  为每一个对话框创建一个CFormView类的派生类,分别为:CView1,CView2,CView3,CView4

3  在应用程序的初始化文件中用CView1替换原先的视图,这样程序启动后的缺省显示视图是CView1,修改后的部分代码如下:
CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CMultiViewDoc),
RUNTIME_CLASS(CMainFrame),       // main SDI frame window
RUNTIME_CLASS(CView1));
AddDocTemplate(pDocTemplate);

4  利用资源编辑器,添加几个菜单,并添加相应的消息处理函数:
void CMainFrame::OnViewView1() 
{
SwitchToForm(IDD_MULTIVIEW_FORM);   
}

void CMainFrame::OnViewView2() 
{
SwitchToForm(IDD_MULTIVIEW_FORM2);   
}

void CMainFrame::OnViewView3() 
{
SwitchToForm(IDD_MULTIVIEW_FORM3);   
}

void CMainFrame::OnViewView4() 
{
SwitchToForm(IDD_MULTIVIEW_FORM4);   
}

在SDI 中CFrame的派生类即CMainFrame控制着所有的视图,而且它允许用户通过消息处理进行视图的切换。进行视图切换的原理很简单,只是断开和旧视 图的连接并把他删除,创建一个新视图,将文档和它相连,设置几个标志,然后显示新视图,SwitchToForm函数是进行视图切换的代码函数。

void CMainFrame::SwitchToForm(int nForm)
{
   //CDocument* pDoc = GetActiveDocument();
     CView *pOldActiveView=GetActiveView();             //保存旧视图
     CView *pNewActiveView=(CView*)GetDlgItem(nForm);   //取得新视图
     if(pNewActiveView==NULL)
     {
         switch(nForm)
             //这些ID是对话框的标志符,但也可以用其他的标志
         {
         case IDD_MULTIVIEW_FORM :
             pNewActiveView=(CView*)new CView1;
             break;
         case IDD_MULTIVIEW_FORM2 :
             pNewActiveView=(CView*)new CView2;
             break;
         case IDD_MULTIVIEW_FORM3 :
             pNewActiveView=(CView*)new CView3;
             break;
         case IDD_MULTIVIEW_FORM4 :
             pNewActiveView=(CView*)new CView4;
             break;
         }
         CCreateContext context;   //将文挡和视图相连
         context.m_pCurrentDoc=pOldActiveView->GetDocument();
pNewActiveView->Create(NULL, NULL, WS_BORDER|WS_CHILD ,
             CFrameWnd::rectDefault, this, nForm, &context);


         pNewActiveView->OnInitialUpdate();
     }
     SetActiveView(pNewActiveView);        //改变活动的视图
     pNewActiveView->ShowWindow(SW_SHOW);  //显示新的视图
     pOldActiveView->ShowWindow(SW_HIDE);  //隐藏旧的视图

     if(pOldActiveView->GetRuntimeClass() ==RUNTIME_CLASS(CView1))
pOldActiveView->SetDlgCtrlID(IDD_MULTIVIEW_FORM);

else if(pOldActiveView->GetRuntimeClass() ==RUNTIME_CLASS(CView2))
pOldActiveView->SetDlgCtrlID(IDD_MULTIVIEW_FORM2);

else if(pOldActiveView->GetRuntimeClass() ==RUNTIME_CLASS(CView3))
pOldActiveView->SetDlgCtrlID(IDD_MULTIVIEW_FORM3);

else if(pOldActiveView->GetRuntimeClass() ==RUNTIME_CLASS(CView4))
pOldActiveView->SetDlgCtrlID(IDD_MULTIVIEW_FORM4);

     pNewActiveView->SetDlgCtrlID(AFX_IDW_PANE_FIRST);
     
     

delete pOldActiveView;   //删除旧视图

RecalcLayout();          //调整框架窗口
}

二.我的做法

// 普通视图和分栏视图的转换

 CLogRcd::RecordLog("@ CMainFrame::OnViewAnalysis", MESSAGE_INVOKE);

 CView *pOldView = GetActiveView();

 // Must be switch from the record view and an opened record is available 
  if (pOldView->IsKindOf(RUNTIME_CLASS(CEcmRecordView)) == FALSE || !m_bOpendRecord)
   return;

 DWORD dwWaveWndWidth = ::GetSystemMetrics(SM_CXFULLSCREEN)/2;
  DWORD dwMapWndHeight = ::GetSystemMetrics(SM_CYFULLSCREEN)/2;
  CCreateContext cc;
  cc.m_pCurrentDoc = GetActiveDocument();
  cc.m_pLastView = pOldView;

 if (m_wndSplitter.GetColumnCount() == 0)   // splitter has not be created
  {
   if (!m_wndSplitter.CreateStatic(this, 1, 2))
   {
    TRACE("CMainFrame::OnViewAnalysis create splitter 0 static failed\n");
    return;
   }
  }

 if (!m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CEcmWaveView), CSize(dwWaveWndWidth, 0), &cc))
  {
   TRACE("CMainFrame::OnViewAnalysis create wave view failed\n");
   m_wndSplitter.DestroyWindow();
   return;
  } 

 if (m_wndSplitter1.GetRowCount() == 0)    // splitter1 has not be created
  {
   if (!m_wndSplitter1.CreateStatic(&m_wndSplitter, 2, 1, WS_CHILD|WS_VISIBLE, m_wndSplitter.IdFromRowCol(0, 1)))
   {
    TRACE("CMainFrame::OnViewAnalysis create splitter 1 static failed\n");
    return;
   }
  }

 if (!m_wndSplitter1.CreateView(0, 0, RUNTIME_CLASS(CEcmMapView), CSize(0, dwMapWndHeight), &cc))
  {
   TRACE("CMainFrame::OnViewAnalysis create map view failed\n");
   m_wndSplitter1.DestroyWindow();
   return;
  }

 if (!m_wndSplitter1.CreateView(1, 0, RUNTIME_CLASS(CEcmPropertyView), CSize(0, 0), &cc))
  {
   TRACE("CMainFrame::OnViewAnalysis create electrode view failed\n");
   m_wndSplitter1.DestroyWindow();
   return;
  }
  
  CEcmUIDoc *pDoc = (CEcmUIDoc *)GetActiveDocument();
  pDoc->m_paraData.pMapView = (CEcmMapView *)(m_wndSplitter1.GetPane(0, 0));

 pDoc->RemoveView(pOldView);
  pOldView->ShowWindow(SW_HIDE);
  pOldView->DestroyWindow();

 SetActiveView((CView *)m_wndSplitter.GetPane(0, 0));  // set wave view window as active one
  RecalcLayout();

 m_wndSplitter.RecalcLayout();  // XX
  m_wndSplitter1.RecalcLayout();  // XX
  SetWindowText("Epicardial Mapping System User Interface : Analysing ...");

 m_wndSplitter.ShowWindow(SW_NORMAL);
  m_wndSplitter1.ShowWindow(SW_NORMAL);

// 普通视和普通视的转换

 CLogRcd::RecordLog("@ CMainFrame::OnViewSample", MESSAGE_INVOKE);

 CView *pOldView = GetActiveView();
  CEcmUIDoc *pDoc = static_cast(GetActiveDocument());
  
  // Must be switch from the record view and an opened record is available
  if (pOldView->IsKindOf(RUNTIME_CLASS(CEcmRecordView)) == FALSE || !m_bOpendRecord)
   return;

 // new a new CEcmSampleView
  CEcmSampleView *pNewView = new CEcmSampleView;

    pNewView->Create(NULL, NULL, AFX_WS_DEFAULT_VIEW, rectDefault, this, AFX_IDW_PANE_FIRST+1, NULL);

 // switch view ID for further RecalcLayout
  int iNewViewID = pNewView->GetDlgCtrlID();
  pNewView->SetDlgCtrlID(AFX_IDW_PANE_FIRST);
  pOldView->SetDlgCtrlID(iNewViewID);

 // attach view to document
  pDoc->AddView(pNewView);
  pDoc->RemoveView(pOldView);
  SetActiveView(pNewView);

 pNewView->ShowWindow(SW_SHOW);
  pOldView->ShowWindow(SW_HIDE);
  
  pNewView->OnInitialUpdate();

 // redraw mainframe client area
  RecalcLayout();
  SetWindowText("Epicardial Mapping System User Interface : Sampling ...");


三.说在最后
        
     上面的方法只适用于SDI的App,对于MDI的做法是new一个DocTemplate出来,代替原来的DocTemplate,我看见过有个前辈是这么做的,而且是可行的,我没有实践过,所以不发表评论。

阅读(724) | 评论(0) | 转发(0) |
0

上一篇:VC菜单编程

下一篇:MFC工作原理

给主人留下些什么吧!~~