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

来源:互联网 发布:美工助理 编辑:程序博客网 时间:2024/06/06 12:54
[cpp] view plaincopyprint?
  1. 关键字:CDockablePane, Visual Studio风格的Gui界面,,CDoackable里嵌套FormView表单视图步骤
关键字:CDockablePane,  Visual Studio风格的Gui界面,,CDoackable里嵌套FormView表单视图步骤
[cpp] view plaincopyprint?
  1. 转载注意作者原创: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] view plaincopyprint?
  1. #pragma once
  2. #include "Resource.h"
  3. // CMfcFormView 窗体视图
  4. class CMfcFormView : public CFormView
  5. {
  6. <span style="color: rgb(255, 0, 0);">DECLARE_DYNCREATE</span>(CMfcFormView)//<span style="background-color: rgb(255, 0, 0);">具有动态创建对象的能力</span>
  7. public:
  8. CMfcFormView(): CFormView(CMfcFormView::IDD)
  9. {}// 动态创建所使用的受保护的构造函数
  10. ~CMfcFormView()
  11. {}
  12. public:
  13. public:
  14. enum { IDD = IDD_FORMVIEW };
  15. #ifdef _DEBUG
  16. virtual void AssertValid()const;
  17. #ifndef _WIN32_WCE
  18. virtual void Dump(CDumpContext& dc)const;
  19. #endif
  20. #endif
  21. protected:
  22. virtual void DoDataExchange(CDataExchange* pDX);// DDX/DDV 支持
  23. 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 _DEBUGvirtual void AssertValid() const;#ifndef _WIN32_WCEvirtual void Dump(CDumpContext& dc) const;#endif#endifprotected:virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持DECLARE_MESSAGE_MAP()
[cpp] view plaincopyprint?
  1. };
};

SolutionWnd.cpp

[cpp] view plaincopyprint?
  1. #include "stdafx.h"
  2. #include "SolutionWnd.h"
  3. // CMfcFormView
  4. <span style="color: rgb(255, 0, 0);">IMPLEMENT_DYNCREATE</span>(CMfcFormView, CFormView)
  5. void CMfcFormView::DoDataExchange(CDataExchange* pDX)
  6. {
  7. CFormView::DoDataExchange(pDX);
  8. }
  9. BEGIN_MESSAGE_MAP(CMfcFormView, CFormView)
  10. END_MESSAGE_MAP()
  11. // CMfcFormView 诊断
  12. #ifdef _DEBUG
  13. void CMfcFormView::AssertValid() const
  14. {
  15. CFormView::AssertValid();
  16. }
  17. #ifndef _WIN32_WCE
  18. void CMfcFormView::Dump(CDumpContext& dc)const
  19. {
  20. CFormView::Dump(dc);
  21. }
  22. #endif
  23. #endif //_DEBUG
  24. // CMfcFormView 消息处理程序
#include "stdafx.h"#include "SolutionWnd.h"// CMfcFormViewIMPLEMENT_DYNCREATE(CMfcFormView, CFormView)void CMfcFormView::DoDataExchange(CDataExchange* pDX){CFormView::DoDataExchange(pDX);}BEGIN_MESSAGE_MAP(CMfcFormView, CFormView)END_MESSAGE_MAP()// CMfcFormView 诊断#ifdef _DEBUGvoid CMfcFormView::AssertValid() const{CFormView::AssertValid();}#ifndef _WIN32_WCEvoid 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] view plaincopyprint?
  1. class CSolutionWnd : public CDockablePane
  2. {
  3. DECLARE_DYNAMIC(CSolutionWnd)
  4. //构造函数
  5. public:
  6. CSolutionWnd();
  7. //析构函数
  8. ~CSolutionWnd();
  9. //特性
  10. public:
  11. protected:
  12. CMfcFormView* m_pformView;
  13. public:
  14. DECLARE_MESSAGE_MAP()
  15. };
class CSolutionWnd : public CDockablePane{ DECLARE_DYNAMIC(CSolutionWnd)//构造函数public:CSolutionWnd();//析构函数~CSolutionWnd();//特性public:protected:CMfcFormView*   m_pformView;public:DECLARE_MESSAGE_MAP()};
SolutionWnd.cpp

新添加的代码

[cpp] view plaincopyprint?
  1. BEGIN_MESSAGE_MAP(CSolutionWnd, CDockablePane)
  2. END_MESSAGE_MAP()
  3. IMPLEMENT_DYNAMIC(CSolutionWnd, CDockablePane)
  4. CSolutionWnd::CSolutionWnd()
  5. {
  6. m_pformView = (CMfcFormView*) (RUNTIME_CLASS(CMfcFormView)->CreateObject());
  7. }
  8. CSolutionWnd::~CSolutionWnd()
  9. {
  10. }
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] view plaincopyprint?
  1. // 创建停靠窗口
  2. if (!CreateDockingWindows()) _
  3. {
  4. TRACE0("未能创建停靠窗口\n");
  5. return -1;
  6. }
  7. m_wndFileView.EnableDocking(CBRS_ALIGN_ANY);
  8. m_wndClassView.EnableDocking(CBRS_ALIGN_ANY);
  9. DockPane(&m_wndFileView); |
  10. CDockablePane* pTabbedBar = NULL; |
  11. m_wndClassView.AttachToTabWnd(&m_wndFileView, DM_SHOW, TRUE, &pTabbedBar);
  12. m_wndOutput.EnableDocking(CBRS_ALIGN_ANY);
  13. DockPane(&m_wndOutput);
  14. m_wndProperties.EnableDocking(CBRS_ALIGN_ANY);
  15. DockPane(&m_wndProperties);_
  16. <span style="color: rgb(255, 0, 0);">m_wndSolution.EnableDocking(CBRS_ALIGN_ANY);
  17. m_wndSolution.AttachToTabWnd(&m_wndProperties, DM_SHOW, TRUE, &pTabbedBar);</span><preclass="cpp" name="code">// 红色为自己添加</pre><p></p>
  18. <pre></pre>
  19. <br>
  20. <br>
  21. <p></p>
  22. <p>3.在MainFrm.cpp里的CMainFrame::CreateDockingWindows()中添加代码</p>
  23. <p></p>
  24. <pre class="cpp" name="code"><span style="color: rgb(255, 0, 0);">//创建解决方案窗口
  25. CString strSolutionWnd;
  26. bNameValid = strSolutionWnd.LoadString(IDS_SOLUTION_WND);
  27. ASSERT(bNameValid);
  28. if(!</span><span style="color: rgb(51, 51, 255);">m_wndSolution.Create</span><span style="color: rgb(255, 0, 0);">(strSolutionWnd,this,CRect(0,0,200,200),TRUE,1234,WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CBRS_RIGHT | CBRS_FLOAT_MULTI))
  29. {
  30. TRACE0("未能创建“解决方案窗口\n");
  31. return FALSE;
  32. }</span></pre>既然我们要创建CDockablePane那必然需要改写OnCreate函数和OnSize函数,原因是,通过CDockablePane的创建必然会调用OnCreate函数,在OnCreate函数里创建FormView,在OnSize里面调整FormView的大小,覆盖整个CDockablePane。
  33. <p></p>
  34. <p>利用类向导在CSolution声明里添加消息映射函数</p>
  35. <p></p>
  36. <pre class="cpp" name="code">public:
  37. DECLARE_MESSAGE_MAP()
  38. afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
  39. afx_msg void OnSize(UINT nType,int cx, int cy);</pre><br>
  40. <pre class="cpp" name="code">int CSolutionWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
  41. {
  42. if (CDockablePane::OnCreate(lpCreateStruct) == -1)
  43. return -1;
  44. // TODO: 在此添加您专用的创建代码
  45. return 0;
  46. }
  47. void CSolutionWnd::OnSize(UINT nType,int cx, int cy)
  48. {
  49. CDockablePane::OnSize(nType, cx, cy);
  50. // TODO: 在此处添加消息处理程序代码
  51. }
  52. </pre><br>
  53. 利用类向导在CMfcFormView里添加消息映射函数OnCreate以及改写虚函数Create
  54. <p></p>
  55. <p></p>
  56. <pre class="cpp" name="code">afx_msgint OnCreate(LPCREATESTRUCT lpCreateStruct);
  57. virtual BOOL Create(LPCTSTR lpszClassName,LPCTSTR lpszWindowName, DWORD dwStyle,const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL);</pre><br>
  58. <pre class="cpp" name="code">// CMfcFormView 消息处理程序
  59. int CMfcFormView::OnCreate(LPCREATESTRUCT lpCreateStruct)
  60. {
  61. if (CFormView::OnCreate(lpCreateStruct) == -1)
  62. return -1;
  63. // TODO: 在此添加您专用的创建代码
  64. return 0;
  65. }
  66. BOOL CMfcFormView::Create(LPCTSTR lpszClassName,LPCTSTR lpszWindowName, DWORD dwStyle,const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext)
  67. {
  68. // TODO: 在此添加专用代码和/或调用基类
  69. return CFormView::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext);
  70. }</pre>
  71. <p></p>
  72. <p>在CSolution.h里声明CMfcFormView*类型的指针变量 </p>
  73. <p></p>
  74. <pre class="cpp" name="code">protected:
  75. CMfcFormView* m_pformView;</pre><br>
  76. 在CSolution的构造函数里创建CMfcFormView对象
  77. <p></p>
  78. <p></p>
  79. <pre class="cpp" name="code">CSolutionWnd::CSolutionWnd()
  80. {
  81. m_pformView = (CMfcFormView*) (RUNTIME_CLASS(CMfcFormView)->CreateObject());
  82. }
  83. </pre><br>
  84. 在CSolution的OnCreate函数里创建FormView
  85. <p></p>
  86. <p></p>
  87. <pre class="cpp" name="code">int CSolutionWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
  88. {
  89. if (CDockablePane::OnCreate(lpCreateStruct) == -1)
  90. return -1;
  91. // TODO: 在此添加您专用的创建代码
  92. <span style="color: rgb(255, 0, 0);">RECT rect;
  93. GetClientRect(&rect);
  94. m_pformView->Create(NULL, NULL, WS_CHILD|WS_VISIBLE, rect, this, 123, NULL);</span>
  95. return 0;
  96. }</pre><br>
  97. 在CSolution的OnSize函数里调整FormView填充整个DockablePane区域
  98. <p></p>
  99. <p></p>
  100. <pre class="cpp" name="code">void CSolutionWnd::OnSize(UINT nType,int cx, int cy)
  101. {
  102. CDockablePane::OnSize(nType, cx, cy);
  103. // TODO: 在此处添加消息处理程序代码
  104. if (GetSafeHwnd() == NULL)
  105. {
  106. return;
  107. }
  108. if(m_pformView->GetSafeHwnd()!=NULL)
  109. {
  110. CRect rect;
  111. GetClientRect(rect);
  112. m_pformView->SetWindowPos(NULL, rect.left, rect.top, rect.Width(), rect.Height(), SWP_NOACTIVATE | SWP_NOZORDER);
  113. }
  114. }</pre><br>
  115. <br>
  116. <p></p>
  117. <p>至此结束。。。回答一些疑问。</p>
  118. <p>为什么要改写CMfcFormView的Create虚函数呢?</p>
  119. <p>因为我们要用到这句函数。</p>
  120. <p><span style="color: rgb(255, 0, 0);">m_pformView->Create(NULL, NULL, WS_CHILD|WS_VISIBLE, rect,this, 123, NULL);</span></p>
  121. <p></p>
  122. <p>调用到FormView::Create函数。由于FormView的Create函数是protected类型的.所以我们必须改写FormView::Create函数为Publc类型。虽然我们在Create函数里什么也没有做什么。如果不重写Create函数的话,那么会出现编译错误。</p>
  123. <p><br>
  124. </p>
  125. <p><br>
  126. </p>