程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> (MFC)Vs2010制作Visual Studio風格的停靠側欄窗口(CDockablePane裡嵌套FormView

(MFC)Vs2010制作Visual Studio風格的停靠側欄窗口(CDockablePane裡嵌套FormView

編輯:C++入門知識

[cpp] view plaincopyprint?關鍵字:CDockablePane,  Visual Studio風格的Gui界面,,CDoackable裡嵌套FormView表單視圖步驟  www.2cto.com   關鍵字:CDockablePane,  Visual Studio風格的Gui界面,,CDoackable裡嵌套FormView表單視圖步驟[cpp] view plaincopyprint?轉載注意作者原創:K_Linux_Man     轉載注意作者原創:K_Linux_Man 一直比較喜歡Visual Studio兩側的窗口,可以來回滑動,並且和點擊圖釘,釘住懸浮的窗口。那就嘗試著如何去做出來。   VC++6.0如果要去實現的話,不是不可以,但是得借助第三方的類庫,比如說,ToolKit,但是非常的麻煩。。。   Visual Studio裡面的新建Demo就可以實現這一功能,何樂而不為呢!!!   那停靠窗口裡面用什麼填充呢? 樹形控件??新建的Demo裡有了。更直觀一點的話,還是用FormView吧。。。好的。。。開始   要不先來個最終的效果圖..... 自己添加的解決方案停靠窗口,裡面嵌套FormView視圖窗口.而文件視圖,類視圖,還有屬性,Demo裡面默認生成的。只有解決方案那個是自己添加的。   \     新建兩個文件,SolutionWnd.h SolutionWnd.cpp   在資源窗口裡新建一個FormView的Dialog,修改ID為IDD_FORMVIEW,建立一個與FormView相關聯的的類, 利用類向導,添加一個名為CMfcFormView,選擇基類為CFormView. 生成在SolutionWnd.h和SolutionWnd.cpp文件裡。   SoulutionWnd.h     [cpp]  #pragma once    #include "Resource.h"          // CMfcFormView 窗體視圖       class CMfcFormView : public CFormView   {       <SPAN style="COLOR: rgb(255,0,0)">DECLARE_DYNCREATE</SPAN>(CMfcFormView)//<SPAN style="BACKGROUND-COLOR: rgb(255,0,0)">具有動態創建對象的能力</SPAN>       public:       CMfcFormView(): CFormView(CMfcFormView::IDD)       {}// 動態創建所使用的受保護的構造函數        ~CMfcFormView()       {}   public:             public:       enum { IDD = IDD_FORMVIEW };   #ifdef _DEBUG        virtual void AssertValid() const;   #ifndef _WIN32_WCE        virtual void Dump(CDumpContext& dc) const;   #endif    #endif       protected:       virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持           DECLARE_MESSAGE_MAP()     #pragma once #include "Resource.h"     // CMfcFormView 窗體視圖   class CMfcFormView : public CFormView { DECLARE_DYNCREATE(CMfcFormView)//具有動態創建對象的能力   public: CMfcFormView(): CFormView(CMfcFormView::IDD) {}// 動態創建所使用的受保護的構造函數 ~CMfcFormView() {} public:     public: enum { IDD = IDD_FORMVIEW }; #ifdef _DEBUG virtual void AssertValid() const; #ifndef _WIN32_WCE virtual void Dump(CDumpContext& dc) const; #endif #endif   protected: virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持   DECLARE_MESSAGE_MAP()[cpp] view plaincopyprint?};     }; SolutionWnd.cpp      [cpp] #include "stdafx.h"    #include "SolutionWnd.h"          // CMfcFormView          <SPAN style="COLOR: #ff0000">IMPLEMENT_DYNCREATE</SPAN>(CMfcFormView, CFormView)         void CMfcFormView::DoDataExchange(CDataExchange* pDX)   {       CFormView::DoDataExchange(pDX);   }            BEGIN_MESSAGE_MAP(CMfcFormView, CFormView)         END_MESSAGE_MAP()               // CMfcFormView 診斷          #ifdef _DEBUG    void CMfcFormView::AssertValid() const   {       CFormView::AssertValid();   }         #ifndef _WIN32_WCE    void CMfcFormView::Dump(CDumpContext& dc) const   {       CFormView::Dump(dc);   }   #endif    #endif //_DEBUG          // CMfcFormView 消息處理程序     #include "stdafx.h" #include "SolutionWnd.h"     // CMfcFormView     IMPLEMENT_DYNCREATE(CMfcFormView, CFormView)     void CMfcFormView::DoDataExchange(CDataExchange* pDX) { CFormView::DoDataExchange(pDX); }       BEGIN_MESSAGE_MAP(CMfcFormView, CFormView)     END_MESSAGE_MAP()         // CMfcFormView 診斷     #ifdef _DEBUG void CMfcFormView::AssertValid() const { CFormView::AssertValid(); }     #ifndef _WIN32_WCE void CMfcFormView::Dump(CDumpContext& dc) const { CFormView::Dump(dc); } #endif #endif //_DEBUG     // CMfcFormView 消息處理程序       至此我們已經把FormView派生出的CMfcFormView類建好了。   我們需要建立一個CDockablePane的派生類,予以容納FormView,建立派生出的CDockablePane類為CSolutionWnd   利用類向導,添加名為CSolutionWnd,基類為CDockablePane...生成文件SolutionWnd.h和SolutionWnd.cpp   SolutionWnd.h裡又添加了如下代碼     [cpp]  class CSolutionWnd : public CDockablePane   {        DECLARE_DYNAMIC(CSolutionWnd)       //構造函數    public:       CSolutionWnd();       //析構函數        ~CSolutionWnd();             //特性    public:         protected:       CMfcFormView*   m_pformView;         public:             DECLARE_MESSAGE_MAP()   };     class CSolutionWnd : public CDockablePane { DECLARE_DYNAMIC(CSolutionWnd) //構造函數 public: CSolutionWnd(); //析構函數 ~CSolutionWnd();     //特性 public:     protected: CMfcFormView*   m_pformView;     public:     DECLARE_MESSAGE_MAP() }; SolutionWnd.cpp    新添加的代碼     [cpp]  BEGIN_MESSAGE_MAP(CSolutionWnd, CDockablePane)      END_MESSAGE_MAP()            IMPLEMENT_DYNAMIC(CSolutionWnd, CDockablePane)      CSolutionWnd::CSolutionWnd()   {       m_pformView = (CMfcFormView*) (RUNTIME_CLASS(CMfcFormView)->CreateObject());   }      CSolutionWnd::~CSolutionWnd()   {      }     BEGIN_MESSAGE_MAP(CSolutionWnd, CDockablePane)   END_MESSAGE_MAP()       IMPLEMENT_DYNAMIC(CSolutionWnd, CDockablePane)   CSolutionWnd::CSolutionWnd() { m_pformView = (CMfcFormView*) (RUNTIME_CLASS(CMfcFormView)->CreateObject()); }   CSolutionWnd::~CSolutionWnd() {   } 接著    1.在MainFrm.cpp裡添加m_wndSolution變量,類型為CSolutionWnd   2.在MainFrm.cpp裡的CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)函數裡添加代碼     [cpp]  // 創建停靠窗口    if (!CreateDockingWindows())                                                                                                                                        _   {   TRACE0("未能創建停靠窗口\n");         return -1;           }                           m_wndFileView.EnableDocking(CBRS_ALIGN_ANY);               m_wndClassView.EnableDocking(CBRS_ALIGN_ANY);                  DockPane(&m_wndFileView);                                                                                                                                         |   CDockablePane* pTabbedBar = NULL;                                                                                                                        |   m_wndClassView.AttachToTabWnd(&m_wndFileView, DM_SHOW, TRUE, &pTabbedBar);                          m_wndOutput.EnableDocking(CBRS_ALIGN_ANY);   DockPane(&m_wndOutput);   m_wndProperties.EnableDocking(CBRS_ALIGN_ANY);   DockPane(&m_wndProperties);_   <SPAN style="COLOR: #ff0000">m_wndSolution.EnableDocking(CBRS_ALIGN_ANY);   m_wndSolution.AttachToTabWnd(&m_wndProperties, DM_SHOW, TRUE, &pTabbedBar);</SPAN><PRE class=cpp name="code"> //  紅色為自己添加</PRE><P></P>    <PRE></PRE>   <BR>   <BR>   <P></P>   <P>3.在MainFrm.cpp裡的CMainFrame::CreateDockingWindows()中添加代碼</P>   <P></P>   <PRE class=cpp name="code"><SPAN style="COLOR: #ff0000">//創建解決方案窗口        CString strSolutionWnd;       bNameValid = strSolutionWnd.LoadString(IDS_SOLUTION_WND);       ASSERT(bNameValid);       if(!</SPAN><SPAN style="COLOR: #3333ff">m_wndSolution.Create</SPAN><SPAN style="COLOR: #ff0000">(strSolutionWnd,this,CRect(0,0,200,200),TRUE,1234,WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CBRS_RIGHT | CBRS_FLOAT_MULTI))       {           TRACE0("未能創建“解決方案窗口\n");           return FALSE;       }</SPAN></PRE>既然我們要創建CDockablePane那必然需要改寫OnCreate函數和OnSize函數,原因是,通過CDockablePane的創建必然會調用OnCreate函數,在OnCreate函數裡創建FormView,在OnSize裡面調整FormView的大小,覆蓋整個CDockablePane。   <P></P>   <P>利用類向導在CSolution聲明裡添加消息映射函數</P>   <P></P>   <PRE class=cpp name="code">public:          DECLARE_MESSAGE_MAP()       afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);       afx_msg void OnSize(UINT nType, int cx, int cy);</PRE><BR>   <PRE class=cpp name="code">int CSolutionWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)   {       if (CDockablePane::OnCreate(lpCreateStruct) == -1)           return -1;          // TODO:  在此添加您專用的創建代碼           return 0;   }            void CSolutionWnd::OnSize(UINT nType, int cx, int cy)   {       CDockablePane::OnSize(nType, cx, cy);          // TODO: 在此處添加消息處理程序代碼           }   </PRE><BR>   利用類向導在CMfcFormView裡添加消息映射函數OnCreate以及改寫虛函數Create   <P></P>   <P></P>   <PRE class=cpp name="code">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);</PRE><BR>   <PRE class=cpp name="code">// 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);   }</PRE>   <P></P>   <P>在CSolution.h裡聲明CMfcFormView*類型的指針變量 </P>   <P></P>   <PRE class=cpp name="code">protected:       CMfcFormView*   m_pformView;</PRE><BR>   在CSolution的構造函數裡創建CMfcFormView對象   <P></P>   <P></P>   <PRE class=cpp name="code">CSolutionWnd::CSolutionWnd()   {       m_pformView = (CMfcFormView*) (RUNTIME_CLASS(CMfcFormView)->CreateObject());   }   </PRE><BR>   在CSolution的OnCreate函數裡創建FormView   <P></P>   <P></P>   <PRE class=cpp name="code">int CSolutionWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)   {       if (CDockablePane::OnCreate(lpCreateStruct) == -1)           return -1;          // TODO:  在此添加您專用的創建代碼           <SPAN style="COLOR: #ff0000">RECT rect;       GetClientRect(&rect);          m_pformView->Create(NULL, NULL,  WS_CHILD|WS_VISIBLE, rect, this, 123, NULL);</SPAN>                return 0;   }</PRE><BR>   在CSolution的OnSize函數裡調整FormView填充整個DockablePane區域   <P></P>   <P></P>   <PRE class=cpp name="code">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);       }   }</PRE><BR>   <BR>   <P></P>   <P>至此結束。。。回答一些疑問。</P>   <P>為什麼要改寫CMfcFormView的Create虛函數呢?</P>   <P>因為我們要用到這句函數。</P>   <P><SPAN style="COLOR: rgb(255,0,0)">m_pformView->Create(NULL, NULL, WS_CHILD|WS_VISIBLE, rect, this, 123, NULL);</SPAN></P>   <P></P>   <P>調用到FormView::Create函數。由於FormView的Create函數是protected類型的.所以我們必須改寫FormView::Create函數為Publc類型。雖然我們在Create函數裡什麼也沒有做什麼。如果不重寫Create函數的話,那麼會出現編譯錯誤。</P>   <P><BR>   </P>   <P><BR>   </P>     // 創建停靠窗口 if (!CreateDockingWindows())                                                                                                                                        _ { TRACE0("未能創建停靠窗口\n");       return -1;         }                       m_wndFileView.EnableDocking(CBRS_ALIGN_ANY);             m_wndClassView.EnableDocking(CBRS_ALIGN_ANY);                DockPane(&m_wndFileView);                                                                                                                                         | CDockablePane* pTabbedBar = NULL;                                                                                                                        | m_wndClassView.AttachToTabWnd(&m_wndFileView, DM_SHOW, TRUE, &pTabbedBar);                        m_wndOutput.EnableDocking(CBRS_ALIGN_ANY); DockPane(&m_wndOutput); m_wndProperties.EnableDocking(CBRS_ALIGN_ANY); DockPane(&m_wndProperties);_ m_wndSolution.EnableDocking(CBRS_ALIGN_ANY); m_wndSolution.AttachToTabWnd(&m_wndProperties, DM_SHOW, TRUE, &pTabbedBar);[cpp] view plaincopyprint?//  紅色為自己添加   //  紅色為自己添加         3.在MainFrm.cpp裡的CMainFrame::CreateDockingWindows()中添加代碼   [cpp]  <SPAN style="COLOR: #ff0000">//創建解決方案窗口       CString strSolutionWnd;      bNameValid = strSolutionWnd.LoadString(IDS_SOLUTION_WND);      ASSERT(bNameValid);      if(!</SPAN><SPAN style="COLOR: #3333ff">m_wndSolution.Create</SPAN><SPAN style="COLOR: #ff0000">(strSolutionWnd,this,CRect(0,0,200,200),TRUE,1234,WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CBRS_RIGHT | CBRS_FLOAT_MULTI))      {          TRACE0("未能創建“解決方案窗口\n");          return FALSE;      }</SPAN>  //創建解決方案窗口 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("未能創建“解決方案窗口\n"); return FALSE; }既然我們要創建CDockablePane那必然需要改寫OnCreate函數和OnSize函數,原因是,通過CDockablePane的創建必然會調用OnCreate函數,在OnCreate函數裡創建FormView,在OnSize裡面調整FormView的大小,覆蓋整個CDockablePane。   利用類向導在CSolution聲明裡添加消息映射函數   [cpp]  public:        DECLARE_MESSAGE_MAP()      afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);      afx_msg void OnSize(UINT nType, int cx, int cy);  public:   DECLARE_MESSAGE_MAP() afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); afx_msg void OnSize(UINT nType, int cx, int cy); [cpp]  int CSolutionWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)  {      if (CDockablePane::OnCreate(lpCreateStruct) == -1)          return -1;        // TODO:  在此添加您專用的創建代碼         return 0;  }        void CSolutionWnd::OnSize(UINT nType, int cx, int cy)  {      CDockablePane::OnSize(nType, cx, cy);        // TODO: 在此處添加消息處理程序代碼         }  int CSolutionWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CDockablePane::OnCreate(lpCreateStruct) == -1) return -1;   // TODO:  在此添加您專用的創建代碼   return 0; }       void CSolutionWnd::OnSize(UINT nType, int cx, int cy) { CDockablePane::OnSize(nType, cx, cy);   // TODO: 在此處添加消息處理程序代碼   }   利用類向導在CMfcFormView裡添加消息映射函數OnCreate以及改寫虛函數Create     [cpp]  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);  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); [cpp]  // 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);  }  // 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); }   在CSolution.h裡聲明CMfcFormView*類型的指針變量    [cpp]  protected:      CMfcFormView*   m_pformView;  protected: CMfcFormView*   m_pformView; 在CSolution的構造函數裡創建CMfcFormView對象     [cpp] CSolutionWnd::CSolutionWnd()  {      m_pformView = (CMfcFormView*) (RUNTIME_CLASS(CMfcFormView)->CreateObject());  }  CSolutionWnd::CSolutionWnd() { m_pformView = (CMfcFormView*) (RUNTIME_CLASS(CMfcFormView)->CreateObject()); }   在CSolution的OnCreate函數裡創建FormView     [cpp]  int CSolutionWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)  {      if (CDockablePane::OnCreate(lpCreateStruct) == -1)          return -1;        // TODO:  在此添加您專用的創建代碼         <SPAN style="COLOR: #ff0000">RECT rect;      GetClientRect(&rect);        m_pformView->Create(NULL, NULL,  WS_CHILD|WS_VISIBLE, rect, this, 123, NULL);</SPAN>            return 0;  }  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區域     [cpp]  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);      }  }  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); } }     至此結束。。。回答一些疑問。 為什麼要改寫CMfcFormView的Create虛函數呢? 因為我們要用到這句函數。 m_pformView->Create(NULL, NULL, WS_CHILD|WS_VISIBLE, rect, this, 123, NULL);   調用到FormView::Create函數。由於FormView的Create函數是protected類型的.所以我們必須改寫FormView::Create函數為Publc類型。雖然我們在Create函數裡什麼也沒有做什麼。如果不重寫Create函數的話,那麼會出現編譯錯誤。           分享到: 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved