在SDI中做多视转换

来源:互联网 发布:四人网络防诈骗小剧本 编辑:程序博客网 时间:2024/05/18 20:35

 一. 参考的做法

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<CEcmUIDoc *>(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,我看见过有个前辈是这么做的,而且是可行的,我没有实践过,所以不发表评论。


原创粉丝点击