此例向导为使用Visual Studio 6.0 应用程序向导制作具有可停靠面板的MDI程序. 对于最新版本的 Visual Studio . NET这种技巧同样生效.
使用MFC AppWizard制作简单的MDI程序:
- Visual Studio中选择文件(File) |新建(New) 选择项目(Projects) tab.
- 选择 项目类型为MFC Appwizard(exe) ,输入 ‘MDISample’ 作为项目名称.
Visual Studio 新建工程对话框...
- 第一步, 确定多文档(Multiple documents) 被选中,单击'完成(Finish)’ 按钮.
添加空白停靠面板:
- 在
StdAfx.h
文件中加入下面一行:Xtreme Toolkit Pro:
- #define _XTP_STATICLINK //此处为译者修改 using mfc in static link lib
- #include <XTToolkitPro.h>
- //在rc2文件中添加
- #include "xttoolkitpro.rc"
#define _XTP_STATICLINK //此处为译者修改 using mfc in static link lib #include <XTToolkitPro.h> //在rc2文件中添加 #include "xttoolkitpro.rc"
- 给CMainFrame class添加成员变量 CXTPDockingPaneManager :
// Attributes public: CXTPDockingPaneManager m_paneManager;
- 给将要使用的面板标题添加字符串资源:
IDR_PANE_OPTIONS 61446 Options IDR_PANE_PROPERTIES 61447 Properties
此图为译者所加
- 在CMainFrame::OnCreate中添加如下代码:
- // 只有在所有控制栏对象被创建和停靠以后,初始化停靠面板管理器并设置面板的初始值.
- m_paneManager.InstallDockingPanes(this);
- m_paneManager.SetTheme(xtpPaneThemeOffice);
- //CXTPDockingPane* pwndPane1 = m_paneManager.CreatePane(
- // IDR_PANE_OPTIONS, CRect(0, 0,200, 120), dockLeftOf);
- //CXTPDockingPane* pwndPane2 = m_paneManager.CreatePane(
- // IDR_PANE_PROPERTIES, CRect(0, 0,200, 120), dockBottomOf, pwndPane1)
- <U>// 创建停靠面板,注意dockLeftOf改为xtpPaneDockLeft xtpPaneDockBottom 译者修改
- CXTPDockingPane* pwndPane1 = m_paneManager.CreatePane(
- IDR_PANE_OPTIONS, CRect(0, 0,200, 120), xtpPaneDockLeft);
- CXTPDockingPane* pwndPane2 = m_paneManager.CreatePane(
- IDR_PANE_PROPERTIES, CRect(0, 0,200, 120), xtpPaneDockBottom, pwndPane1);
- </U>
- return 0;
// 只有在所有控制栏对象被创建和停靠以后,初始化停靠面板管理器并设置面板的初始值. m_paneManager.InstallDockingPanes(this); m_paneManager.SetTheme(xtpPaneThemeOffice); //CXTPDockingPane* pwndPane1 = m_paneManager.CreatePane( // IDR_PANE_OPTIONS, CRect(0, 0,200, 120), dockLeftOf); //CXTPDockingPane* pwndPane2 = m_paneManager.CreatePane( // IDR_PANE_PROPERTIES, CRect(0, 0,200, 120), dockBottomOf, pwndPane1) // 创建停靠面板,注意dockLeftOf改为xtpPaneDockLeft xtpPaneDockBottom 译者修改 CXTPDockingPane* pwndPane1 = m_paneManager.CreatePane( IDR_PANE_OPTIONS, CRect(0, 0,200, 120), xtpPaneDockLeft); CXTPDockingPane* pwndPane2 = m_paneManager.CreatePane( IDR_PANE_PROPERTIES, CRect(0, 0,200, 120), xtpPaneDockBottom, pwndPane1); return 0;
带有停靠面板的MDI 示例程序...
由 CWnd 类派生面板:
- 为CMainFrame添加CWnd 派生类成员变量
- // Attributes
- public:
- CStatic m_wndOptions;
- CEdit m_wndProperties;
// Attributes public: CStatic m_wndOptions; CEdit m_wndProperties;
- MainFrm.cpp添加
OnDockingPaneNotify
面板停靠通知消息句柄.- <PRE class=cpp name="code">BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
- //{{AFX_MSG_MAP(CMainFrame)
- ON_WM_CREATE()
- //}}AFX_MSG_MAP
- ON_MESSAGE(XTPWM_DOCKINGPANE_NOTIFY, OnDockingPaneNotify)
- END_MESSAGE_MAP()
- //{{AFX_MSG(CMainFrame)
- afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
- // NOTE - the ClassWizard will add and remove member functions here.
- // DO NOT EDIT what you see in these blocks of generated code!
- //}}AFX_MSG
- afx_msg LRESULT OnDockingPaneNotify(WPARAM wParam,LPARAM lParam);
- DECLARE_MESSAGE_MAP()
- LRESULT CMainFrame::OnDockingPaneNotify(WPARAM wParam,LPARAM lParam)
- {
- //wParam消息 LPARAM 对象
- if (wParam ==XTP_DPN_SHOWWINDOW)
- {
- CXTPDockingPane* pPane=(CXTPDockingPane*)lParam;
- if (!pPane->IsValid())
- {
- switch(pPane->GetID())
- {
- case IDR_PANE_PROPERTIES:
- {
- if (m_wndProperties.GetSafeHwnd()==0)
- {
- //子窗口,垂直滚动,多行编辑
- m_wndProperties.Create(WS_CHILD|
- ES_AUTOVSCROLL|ES_MULTILINE,
- CRect(0,0,0,0),this,0);
- }
- pPane->Attach((&m_wndProperties));
- break;
- }
- case IDR_PANE_OPTIONS:
- {
- if (m_wndOptions.GetSafeHwnd()==0)
- {
- m_wndOptions.Create(_T("\n\nOptions"),
- WS_CHILD|WS_CLIPCHILDREN|
- WS_CLIPSIBLINGS|SS_CENTER,
- CRect(0,0,0,0),this,0);
- }
- pPane->Attach(&m_wndOptions);
- break;
- }
- }
- }
- return TRUE;
- }
- return FALSE;
- }
- </PRE>
- BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
- //{{AFX_MSG_MAP(CMainFrame)
- ON_WM_CREATE()
- //}}AFX_MSG_MAP
- ON_MESSAGE(XTPWM_DOCKINGPANE_NOTIFY, OnDockingPaneNotify)
- END_MESSAGE_MAP()
- //{{AFX_MSG(CMainFrame)
- afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
- // NOTE - the ClassWizard will add and remove member functions here.
- // DO NOT EDIT what you see in these blocks of generated code!
- //}}AFX_MSG
- afx_msg LRESULT OnDockingPaneNotify(WPARAM wParam,LPARAM lParam);
- DECLARE_MESSAGE_MAP()
- LRESULT CMainFrame::OnDockingPaneNotify(WPARAM wParam,LPARAM lParam)
- {
- //wParam消息 LPARAM 对象
- if (wParam ==XTP_DPN_SHOWWINDOW)
- {
- CXTPDockingPane* pPane=(CXTPDockingPane*)lParam;
- if (!pPane->IsValid())
- {
- switch(pPane->GetID())
- {
- case IDR_PANE_PROPERTIES:
- {
- if (m_wndProperties.GetSafeHwnd()==0)
- {
- //子窗口,垂直滚动,多行编辑
- m_wndProperties.Create(WS_CHILD|
- ES_AUTOVSCROLL|ES_MULTILINE,
- CRect(0,0,0,0),this,0);
- }
- pPane->Attach((&m_wndProperties));
- break;
- }
- case IDR_PANE_OPTIONS:
- {
- if (m_wndOptions.GetSafeHwnd()==0)
- {
- m_wndOptions.Create(_T("\n\nOptions"),
- WS_CHILD|WS_CLIPCHILDREN|
- WS_CLIPSIBLINGS|SS_CENTER,
- CRect(0,0,0,0),this,0);
- }
- pPane->Attach(&m_wndOptions);
- break;
- }
- }
- }
- return TRUE;
- }
- return FALSE;
- }
BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd) //{{AFX_MSG_MAP(CMainFrame) ON_WM_CREATE() //}}AFX_MSG_MAP ON_MESSAGE(XTPWM_DOCKINGPANE_NOTIFY, OnDockingPaneNotify) END_MESSAGE_MAP() //{{AFX_MSG(CMainFrame) afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); // NOTE - the ClassWizard will add and remove member functions here. // DO NOT EDIT what you see in these blocks of generated code! //}}AFX_MSG afx_msg LRESULT OnDockingPaneNotify(WPARAM wParam,LPARAM lParam); DECLARE_MESSAGE_MAP() LRESULT CMainFrame::OnDockingPaneNotify(WPARAM wParam,LPARAM lParam) { //wParam消息 LPARAM 对象 if (wParam ==XTP_DPN_SHOWWINDOW) { CXTPDockingPane* pPane=(CXTPDockingPane*)lParam; if (!pPane->IsValid()) { switch(pPane->GetID()) { case IDR_PANE_PROPERTIES: { if (m_wndProperties.GetSafeHwnd()==0) { //子窗口,垂直滚动,多行编辑 m_wndProperties.Create(WS_CHILD| ES_AUTOVSCROLL|ES_MULTILINE, CRect(0,0,0,0),this,0); } pPane->Attach((&m_wndProperties)); break; } case IDR_PANE_OPTIONS: { if (m_wndOptions.GetSafeHwnd()==0) { m_wndOptions.Create(_T("\n\nOptions"), WS_CHILD|WS_CLIPCHILDREN| WS_CLIPSIBLINGS|SS_CENTER, CRect(0,0,0,0),this,0); } pPane->Attach(&m_wndOptions); break; } } } return TRUE; } return FALSE; }
MDI Sample Application With CWnd Objects Attached to Docking Panes...
给停靠面板选项页添加图像:
- 为创建好的面板制作Bitmap 图标
Visual Studio 资源编辑器...
- 在
CMainFrame::OnCreate 中添加如下代码
- int nIDIcons[] = {IDR_PANE_OPTIONS, IDR_PANE_PROPERTIES};
- m_paneManager.SetIcons(IDB_BITMAP_ICONS, nIDIcons,
- _countof(nIDIcons), RGB(0, 255, 0));
- return 0;
int nIDIcons[] = {IDR_PANE_OPTIONS, IDR_PANE_PROPERTIES}; m_paneManager.SetIcons(IDB_BITMAP_ICONS, nIDIcons, _countof(nIDIcons), RGB(0, 255, 0)); return 0;
Visual Studio 资源编辑器... (图标仅为示例,与原文并不一致)
添加保存和装载状态句柄:
- CMainFrame中添加如下代码在
OnCreate
函数. 恢复先前停靠栏状态:int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { ... // 加载先前停靠栏状态. CXTPDockingPaneLayout layoutNormal(&m_paneManager); if (layoutNormal.Load(_T("NormalLayout"))) { m_paneManager.SetLayout(&layoutNormal); } return 0; }
- 在CMainFrame 类添加
OnClose
消息句柄,调用基类前添加如下代码. 将保存最近停靠栏状态:- void CMainFrame::OnClose()
- {
- // TODO: Add your message handler code here and/or call default
- CXTPDockingPaneLayout layoutNormal(&m_paneManager);
- m_paneManager.GetLayout(&layoutNormal);
- layoutNormal.Save(_T("NormalLayout"));
- CMDIFrameWnd::OnClose();
- }
void CMainFrame::OnClose() { // TODO: Add your message handler code here and/or call default CXTPDockingPaneLayout layoutNormal(&m_paneManager); m_paneManager.GetLayout(&layoutNormal); layoutNormal.Save(_T("NormalLayout")); CMDIFrameWnd::OnClose(); }
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
原文
Chapter 4: Tutorials for Using Xtreme Toolkit Pro v13.2 |
How to Add a Docking Pane to Your Application
The following is a tutorial on how to create an MDI application with Docking Panes using the Visual Studio 6.0 Application Wizard. The same technique can be used for later versions of Visual Studio . NET as well.
Create a simple MDI application using the MFC AppWizard:
- From Visual Studio select File thenNew and select theProjects tab.
- Choose MFC Appwizard(exe) as your project type and enter ‘MDISample’ as the project name.
Visual Studio New Project Dialog...
- For the first step, make sure that Multiple documents is selected then press the ‘Finish’ button.
Add Empty Docking Panes:
- Add the following line to your
StdAfx.h
file:Xtreme Toolkit Pro:
#include <XTToolkitPro.h> // Xtreme Toolkit Pro component library
- Add CXTPDockingPaneManager member to CMainFrame class:
// Attributes public: CXTPDockingPaneManager m_paneManager;
- Add string resources for the titles of the future panes:
IDR_PANE_OPTIONS 61446 Options IDR_PANE_PROPERTIES 61447 Properties
- Add following to CMainFrame::OnCreate:
// Initialize the docking pane manager and set the // initial them for the docking panes. Do this only after all // control bars objects have been created and docked. m_paneManager.InstallDockingPanes(this); m_paneManager.SetTheme(xtpPaneThemeOffice); // Create docking panes. CXTPDockingPane* pwndPane1 = m_paneManager.CreatePane( IDR_PANE_OPTIONS, CRect(0, 0,200, 120), dockLeftOf); CXTPDockingPane* pwndPane2 = m_paneManager.CreatePane( IDR_PANE_PROPERTIES, CRect(0, 0,200, 120), dockBottomOf, pwndPane1)
MDI Sample Application With Docking Panes...
Attach CWnd derived class to the panes:
- Add a CWnd derived class as member ofCMainFrame:
// Attributes public: CStatic m_wndOptions; CEdit m_wndProperties;
- Add
OnDockingPaneNotify
handler.BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd) //{{AFX_MSG_MAP(CMainFrame) ON_WM_CREATE() //}}AFX_MSG_MAP ON_MESSAGE(XTPWM_DOCKINGPANE_NOTIFY, OnDockingPaneNotify) END_MESSAGE_MAP() LRESULT CMainFrame::OnDockingPaneNotify(WPARAM wParam, LPARAM lParam) { if (wParam == XTP_DPN_SHOWWINDOW) { CXTPDockingPane* pPane = (CXTPDockingPane*)lParam; if (!pPane->IsValid()) { switch (pPane->GetID()) { case IDR_PANE_PROPERTIES: { if (m_wndProperties.GetSafeHwnd() == 0) { m_wndProperties.Create(WS_CHILD| ES_AUTOVSCROLL|ES_MULTILINE, CRect(0, 0, 0, 0), this, 0); } pPane->Attach(&m_wndProperties); break; } case IDR_PANE_OPTIONS: { if (m_wndOptions.GetSafeHwnd() == 0) { m_wndOptions.Create(_T("\n\nOptions"), WS_CHILD|WS_CLIPCHILDREN| WS_CLIPSIBLINGS|SS_CENTER, CRect(0, 0, 0, 0), this, 0); } pPane->Attach(&m_wndOptions); break; } } } return TRUE; } return FALSE; }
MDI Sample Application With CWnd Objects Attached to Docking Panes...
- Create Bitmap with icons for created panes
Visual Studio Resource Editor...
- Add to
CMainFrame::OnCreate
int nIDIcons[] = {IDR_PANE_OPTIONS, IDR_PANE_PROPERTIES}; m_paneManager.SetIcons(IDB_BITMAP_ICONS, nIDIcons, _countof(nIDIcons), RGB(0, 255, 0));
Visual Studio Resource Editor...
Add Save and Load State Handlers:
- Add following to the
OnCreate
function forCMainFrame. This will restore the previous state of docking panes:int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { ... // Load the previous state for docking panes. CXTPDockingPaneLayout layoutNormal(&m_paneManager); if (layoutNormal.Load(_T("NormalLayout"))) { m_paneManager.SetLayout(&layoutNormal); } return 0; }
- Add the
OnClose
message handler to CMainFrame and the following before the call to the base class. This will save the current state of your docking pane:void CMainFrame::OnClose() { // Save the current state for docking panes. CXTPDockingPaneLayout layoutNormal(&m_paneManager); m_paneManager.GetLayout(&layoutNormal); layoutNormal.Save(_T("NormalLayout")); CMDIFrameWnd::OnClose(); }