MFC SDI单文档多视图的实现及自由切换(2种实现方式简析)

来源:互联网 发布:国家统计局统计局数据 编辑:程序博客网 时间:2024/05/24 06:14

原文地址 http://blog.csdn.net/teleinfor/article/details/1858976


class CMultiViewApp : public CWinApp

{

public:

       CView* m_pFirstView;

       CView* m_pOtherView;

       int m_currentView;

       CView* m_pView2;

       CView* m_pView1;

       CMultiViewApp();

 

// Overrides

       // ClassWizard generated virtual function overrides

       //{{AFX_VIRTUAL(CMultiViewApp)

       public:

       virtual BOOL InitInstance();

       //}}AFX_VIRTUAL

 

// Implementation

       //{{AFX_MSG(CMultiViewApp)

       afx_msg void OnAppAbout();

       afx_msg void OnViewOtherview();

       afx_msg void OnViewFirstview();

       //}}AFX_MSG

       afx_msg void OnViewChange(UINT nCmdID);

       DECLARE_MESSAGE_MAP()

};

 

其次,在CPP文件有如下消息MAP

/////////////////////////////////////////////////////////////////////////////

// CMultiViewApp

 

BEGIN_MESSAGE_MAP(CMultiViewAppCWinApp)

       //{{AFX_MSG_MAP(CMultiViewApp)

       ON_COMMAND(ID_APP_ABOUTOnAppAbout)

       ON_COMMAND(ID_VIEW_OTHERVIEW, OnViewOtherview)

       ON_COMMAND(ID_VIEW_FIRSTVIEW, OnViewFirstview)

       //}}AFX_MSG_MAP

       // Standard file based document commands

       ON_COMMAND(ID_FILE_NEWCWinApp::OnFileNew)

       ON_COMMAND(ID_FILE_OPENCWinApp::OnFileOpen)

       // Standard print setup command

       ON_COMMAND(ID_FILE_PRINT_SETUPCWinApp::OnFilePrintSetup)

       ON_COMMAND_RANGE( ID_VIEW_VIEW1, ID_VIEW_VIEW2, OnViewChange)   

END_MESSAGE_MAP()

 

说明:SDI程序在CMyApp::InitInstance()已经通过DocTemplate创建一个关联的视图/文档实例,切显示出来.具体实现如下:

BOOL CMultiViewApp::InitInstance()

{

       AfxEnableControlContainer();

 

       // Standard initialization

       // If you are not using these features and wish to reduce the size

       //  of your final executable, you should remove from the following

       //  the specific initialization routines you do not need.

 

#ifdef _AFXDLL

       Enable3dControls();                 // Call this when using MFC in a shared DLL

#else

       Enable3dControlsStatic();       // Call this when linking to MFC statically

#endif

 

       // Change the registry key under which our settings are stored.

       // TODO: You should modify this string to be something appropriate

       // such as the name of your company or organization.

       SetRegistryKey(_T("Local AppWizard-Generated Applications"));

 

       LoadStdProfileSettings();  // Load standard INI file options (including MRU)

 

       // Register the application's document templates.  Document templates

       //  serve as the connection between documents, frame windows and views.

 

       CSingleDocTemplatepDocTemplate;

       pDocTemplate = new CSingleDocTemplate(

              IDR_MAINFRAME,

              RUNTIME_CLASS(CMultiViewDoc),

              RUNTIME_CLASS(CMainFrame),       // main SDI frame window

              RUNTIME_CLASS(CMultiViewView));

       AddDocTemplate(pDocTemplate);

 

       // Parse command line for standard shell commands, DDE, file open

       CCommandLineInfo cmdInfo;

       ParseCommandLine(cmdInfo);

 

       // Dispatch commands specified on the command line

       if (!ProcessShellCommand(cmdInfo))

              return FALSE;

 

       CViewpActiveView = ((CFrameWnd*) m_pMainWnd)->GetActiveView();

       m_pFirstView = pActiveView;

       m_pOtherView = (CView*) new COtherView;

 

       CDocumentpDoc = ((CFrameWnd*)m_pMainWnd)->GetActiveDocument();

       //通过CCreateContext实现第二视图和文档的关联

       CCreateContext context;

       context.m_pCurrentDoc = pDoc;

 

       UINT m_ID = AFX_IDW_PANE_FIRST + 1;

       CRect rect;

       //为了演示第一种多视图是实现方法,Vew的实例创建放在了这里

       m_pOtherView->Create(NULLNULLWS_CHILDrectm_pMainWndm_ID, &context);

 

       // The one and only window has been initialized, so show and update it.

       m_pMainWnd->ShowWindow(SW_SHOWMAXIMIZED);

       m_pMainWnd->UpdateWindow();

       m_currentView=1;

       return TRUE;

}

1.     SDI单文档多视图实现方法1

void CMultiViewApp::OnViewOtherview()

{

       // TODO: Add your command handler code here

       UINT temp = ::GetWindowLong(m_pOtherView->m_hWndGWL_ID);

    ::SetWindowLong(m_pOtherView->m_hWndGWL_ID, ::GetWindowLong(m_pFirstView->m_hWndGWL_ID));

    ::SetWindowLong(m_pFirstView->m_hWndGWL_IDtemp);

 

       m_pFirstView->ShowWindow(SW_HIDE);

       m_pOtherView->ShowWindow(SW_SHOW);      

 

       ((CFrameWnd*)m_pMainWnd)->SetActiveView(m_pOtherView); 

       ((CFrameWnd*) m_pMainWnd)->RecalcLayout();

    m_pOtherView->Invalidate();

      

}

 

void CMultiViewApp::OnViewFirstview()

{

      // TODO: Add your command handler code here

   

    UINT temp = ::GetWindowLong(m_pOtherView->m_hWndGWL_ID); //GetWindowWord()

    ::SetWindowLong(m_pOtherView->m_hWndGWL_ID, ::GetWindowLong(m_pFirstView->m_hWnd,GWL_ID));//SetWindowWord()

    ::SetWindowLong(m_pFirstView->m_hWndGWL_IDtemp);//SetWindowWord()

 

      m_pOtherView->ShowWindow(SW_HIDE);

      m_pFirstView->ShowWindow(SW_SHOW);        

     

      ((CFrameWnd*)m_pMainWnd)->SetActiveView(m_pFirstView); 

      ((CFrameWnd*)m_pMainWnd)->RecalcLayout();

    m_pFirstView->Invalidate();

}

2.     SDI单文档多视图实现方法2

void CMultiViewApp::OnViewChange(UINT nCmdID)

{

       //另外一种方法实现SDI的多视图切换

       CViewpViewAdd;

       CViewpViewRemove;

       CMainFramepMainFrame=(CMainFrame*)AfxGetMainWnd();

       CDocumentpDoc = pMainFrame->GetActiveDocument();

      

       if((nCmdID == ID_VIEW_VIEW1) && (m_currentView == 1))

              return;

       if((nCmdID == ID_VIEW_VIEW2) && (m_currentView == 2))

              return;

      

       if (nCmdID == ID_VIEW_VIEW2)

       {

              if (m_pView2 == NULL)

              {

                     m_pView1 = pMainFrame->GetActiveView();

                     m_pView2 = new COtherView();

                    

                     //Note that if OnSize has been overridden in CMyView2

                     //and GetDocument() is used in this override it can

                     //cause assertions and, if the assertions are ignored,

                     //cause access violation.

                     //使用CCreateContext structure实现viewdocument的关联

                     CCreateContext context;

                     context.m_pCurrentDoc=pDoc;//m_pView1->GetDocument();

                    

                     m_pView2->Create(NULLNULLAFX_WS_DEFAULT_VIEW,

                            CFrameWnd::rectDefaultAfxGetMainWnd(), AFX_IDW_PANE_FIRST + 1, &context/*NULL*/);

              }

              pViewAdd = m_pView2;

              pViewRemove = m_pView1;

              m_currentView= 2;

       }

       else

       {

              pViewAdd = m_pView1;

              pViewRemove = m_pView2;

              m_currentView= 1;

       }

      

       // Set the child i.d. of the active view to AFX_IDW_PANE_FIRST,

       // so that CFrameWnd::RecalcLayout will allocate to this

       // "first pane" that portion of   the frame window's client area

       // not allocated to control   bars.  Set the child i.d. of the

       // other view to anything other than AFX_IDW_PANE_FIRST; this

       // examples switches the child id's of the two views.

      

       int nSwitchChildID = pViewAdd->GetDlgCtrlID();

       pViewAdd->SetDlgCtrlID(AFX_IDW_PANE_FIRST);

       pViewRemove->SetDlgCtrlID(nSwitchChildID);

      

       // Show the newly active view and hide the inactive view.

      

       pViewAdd->ShowWindow(SW_SHOW);

       pViewRemove->ShowWindow(SW_HIDE);

      

       // Connect the newly active view to the document, and

       // disconnect the inactive view.

       //通过CCreateContext实现视图View和文档Document的关联

       //就没有必要手动AddView(),如果需要可以进行手动RemoveView()

       //AddView()会在CView::OnCreate()MFC调用,RemoveView()会在CView::~CView()被调用

       //当然可以根据需要手动调用它们,在本例当中,View都是被创建一次,没有被销毁,所以不会自动

       //调用RemoveView()

       //pDoc->AddView(pViewAdd);

       //pDoc->RemoveView(pViewRemove);

      

       pMainFrame->SetActiveView(pViewAdd);

       pMainFrame->RecalcLayout();

      

       return ;

}


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 苹果手机四位数密码忘记了怎么办 锡山教育app登陆密码忘了怎么办 新商盟手机订烟登录忘记密码怎么办 在qq上修改支付密码忘记怎么办 微信红包支付密码忘了怎么办 qq钱包绑定了别人的银行卡怎么办 用支付宝充手机话费怎么退款怎么办 我有个qq号丢了怎么办 微信红包密码输错了怎么办 qq钱包支付限额付不了款怎么办 电信手机没开流量被扣流量钱怎么办 运动鞋子买大了一码怎么办 淘宝直播间粉丝福利购优惠券怎么办 微信卡包的券不小心删了怎么办 0pp0手机官网手机总跳屏怎么办 很想买一部手机但是舍不得钱怎么办 自己没钱了还想贷款买手机怎么办 4g手机锁屏密码忘了怎么办 oppo手机锁屏密码忘了怎么办 三星手机锁屏密码忘了怎么办 网上买的手机想退了怎么办 沙棘排湿排毒后皮肤痒怎么办 做了沙棘排毒两次上上痒怎么办? 微信支付打款认证超时怎么办 微信上买东西钱付款了货没发怎么办 掌上道聚城王者轮回分解错了怎么办 鞋子脱胶了怎么办别傻傻用胶水粘 斗鱼主播积分太低无法收礼物怎么办 信誉积分没有了什么也玩不了怎么办 忘记自己电信卡号的密码怎么办 淘宝卖出去东西的钱被冻结了怎么办 手机店铺搞抽奖活动上当了怎么办 网易云音乐上传作品编辑失败怎么办 手机连了wifi后自动扣费怎么办 店铺被低价拍了一部分商品该怎么办 淘宝买家退货快递单号填错了怎么办 卖家同意退款了买家不退货怎么办 淘宝代购衣服有破损不给退怎么办 网上购飞机票身份证号写错了怎么办 交易猫买家把我号清了怎么办 光大普卡额度4万封顶了怎么办