在SDI中做多视转换

    技术2022-05-11  55

     一. 参考的做法1  首先利用资源编辑器新建4个对话框,在对话框中添加需要的控件,各个对话框的ID分别为IDD_MULTIVIEW_FORM,IDD_MULTIVIEW_FORM2,IDD_MULTIVIEW_FORM3,IDD_MULTIVIEW_FORM42  为每一个对话框创建一个CFormView类的派生类,分别为:CView1,CView2,CView3,CView43  在应用程序的初始化文件中用CView1替换原先的视图,这样程序启动后的缺省显示视图是CView1,修改后的部分代码如下:CSingleDocTemplate* pDocTemplate;pDocTemplate = new CSingleDocTemplate(IDR_MAINFRAME,RUNTIME_CLASS(CMultiViewDoc),RUNTIME_CLASS(CMainFrame),       // main SDI frame windowRUNTIME_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,我看见过有个前辈是这么做的,而且是可行的,我没有实践过,所以不发表评论。


    最新回复(0)