zoukankan      html  css  js  c++  java
  • VS2010 MFC中制作Visual Studio风格的停靠侧栏窗口(CDockablePane里嵌套FormView表单视图)

    VS2010 MFC中制作Visual Studio风格的停靠侧栏窗口(CDockablePane里嵌套FormView表单视图)

    1. 在资源窗口里新建一个FormView的Dialog,修改ID为IDD_FORMVIEW。在此Dialog上点击右键添加类,建立一个基类为CFormView的类,这里取名为CMfcFormView。则生成了MfcFormView.h和MfcFormView.cpp文件。

    2. 建立一个CDockablePane的派生类,予以容纳FormView,建立派生出的CDockablePane类为CSolutionWnd

        即利用类向导,添加类名为CSolutionWnd,基类为CDockablePane,生成文件为SolutionWnd.h和SolutionWnd.cpp。

    3. 在SolutionWnd.h中添加:

         头文件:#include "MfcFormView.h"

         代码:

          protected:  

                   CMfcFormView*   m_pformView;  

        在SolutionWnd.cpp中的构造函数中创建CMfcFormView对象,即添加代码:

                   m_pformView = (CMfcFormView*) (RUNTIME_CLASS(CMfcFormView)->CreateObject());

    4. 既然创建了CDockablePane,那必然需要改写OnCreate函数和OnSize函数。因为通过CDockablePane的创建必然会调用OnCreate函数,在OnCreate函数里创建

       FormView,在OnSize里面调整FormView的大小,覆盖整个CDockablePane。 

       利用类向导在CSolution声明里添加消息映射函数:

       DECLARE_MESSAGE_MAP()  

          afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);  

          afx_msg void OnSize(UINT nType, int cx, int cy);

       在OnCreate函数里创建FormView

     int CSolutionWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)  

     {  

       if (CDockablePane::OnCreate(lpCreateStruct) == -1)  

            return -1;  

       // TODO:  在此添加您专用的创建代码  

        RECT rect;   

        GetClientRect(&rect);     

        m_pformView->Create(NULL, NULL,  WS_CHILD|WS_VISIBLE, rect, this, 123, NULL);

        return 0;  

     }  

      在CSolution的OnSize函数里调整FormView填充整个DockablePane区域 

     void CSolutionWnd::OnSize(UINT nType, int cx, int cy)  

     {  

      CDockablePane::OnSize(nType, cx, cy);

        // TODO: 在此处添加消息处理程序代码  

       if (GetSafeHwnd() == NULL)
       {
                 return;
       }
       if(m_pformView->GetSafeHwnd()!=NULL)
       {
                CRect rect;
                GetClientRect(rect);
                 m_pformView->SetWindowPos(NULL, rect.left, rect.top, rect.Width(), rect.Height(), SWP_NOACTIVATE | SWP_NOZORDER);
       }

    4. 在MainFrm.h里添加头文件:#include "SolutionWnd.h",添加m_wndSolution变量(类型为CSolutionWnd)

        在MainFrm.cpp里的CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)函数里找到代码:

                     m_wndProperties.EnableDocking(CBRS_ALIGN_ANY);  

                     DockPane(&m_wndProperties);

              在其后添加:

                     m_wndSolution.EnableDocking(CBRS_ALIGN_ANY);  

                     m_wndSolution.AttachToTabWnd(&m_wndProperties, DM_SHOW, TRUE, &pTabbedBar);

        在MainFrm.cpp里的CMainFrame::CreateDockingWindows()中添加代码:

                           CString strSolutionWnd;  

                           bNameValid = strSolutionWnd.LoadString(IDS_SOLUTION_WND);  

                           ASSERT(bNameValid);  

                           if(!m_wndSolution.Create(strSolutionWnd,this,CRect(0,0,200,200),TRUE,1234,WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS

                             | WS_CLIPCHILDREN | CBRS_RIGHT | CBRS_FLOAT_MULTI))  

                         {

                             TRACE0("未能创建“解决方案窗口 ");  

                             return FALSE;  

                         }

    5. 利用类向导在CMfcFormView里添加消息映射函数OnCreate以及改写虚函数Create:

    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);  

    virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL);

    // CMfcFormView 消息处理程序  

    int CMfcFormView::OnCreate(LPCREATESTRUCT lpCreateStruct)

    {  

        if (CFormView::OnCreate(lpCreateStruct) == -1)  

            return -1;  

        // TODO:  在此添加您专用的创建代码  

        return 0;  

    }      

    BOOL CMfcFormView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext)  

    {  

        // TODO: 在此添加专用代码和/或调用基类  

        return CFormView::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext);  

    }

     Bingo~

    注意几点:

       1. FormView的Create函数是protected类型的,通过改写FormView::Create函数为Public类型,才能调用到FormView::Create函数。尽管我们在Create函数里什么也没有做,但是如果不重写Create函数的话,就会出现编译错误。

       2. 报错:error C2065: “IDD_FORMVIEW”: 未声明的标识符

           解决办法:在MfcFormView.h中添加头文件:#include "Resource.h"

       3. 编译通过了,但运行出错。通过调试发现

           每次运行到:
    BOOL CFormView::Create(LPCTSTR /*lpszClassName*/, LPCTSTR /*lpszWindowName*/,
     DWORD dwRequestedStyle, const RECT& rect, CWnd* pParentWnd, UINT nID,
     CCreateContext* pContext)
    {
     ASSERT(pParentWnd != NULL);
     ASSERT(m_lpszTemplateName != NULL);

     m_pCreateContext = pContext;    // save state for later OnCreate

    #ifdef _DEBUG
     // dialog template must exist and be invisible with WS_CHILD set  <——请注意此处
     if (!_AfxCheckDialogTemplate(m_lpszTemplateName, TRUE))
     {
      ASSERT(FALSE);          // invalid dialog template name    
      PostNcDestroy();        // cleanup if Create fails too soon     
      return FALSE;
     }
    #endif //_DEBUG

          中的ASSERT时就报错。

          解决办法:检查Dialog的属性:Visible属性应设置为FALSE

                                                Style属性应设置为Child

                                                 SystemMenu和TitleBar属性最好都设为False

                     因为 根据上面代码的要求是:对话框模板必须存在,属性要设置成不可见和子窗口风格。

     

  • 相关阅读:
    文档API
    vi编辑器常用方法
    storm实战入门一
    redis教程
    为redis分配一个新的端口
    Lucene分页查询
    Lucene搜索方式大合集
    HBase Scan类用法
    java.util.Queue用法
    Makefile中预定义变量
  • 原文地址:https://www.cnblogs.com/lxt287994374/p/3381734.html
Copyright © 2011-2022 走看看