- 关键字:CDockablePane, Visual Studio风格的Gui界面,,CDoackable里嵌套FormView表单视图步骤
关键字:CDockablePane, Visual Studio风格的Gui界面,,CDoackable里嵌套FormView表单视图步骤
- 转载注意作者原创: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
- #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()
- };
};
SolutionWnd.cpp
- #include "stdafx.h"
- #include "SolutionWnd.h"
- // CMfcFormView
- <span style="color: rgb(255, 0, 0);">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里又添加了如下代码
- 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
新添加的代码
- 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)函数里添加代码
- // 创建停靠窗口
- 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: rgb(255, 0, 0);">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: rgb(255, 0, 0);">//创建解决方案窗口
- CString strSolutionWnd;
- bNameValid = strSolutionWnd.LoadString(IDS_SOLUTION_WND);
- ASSERT(bNameValid);
- 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))
- {
- 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: rgb(255, 0, 0);">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>