Visual Studio 風格的可停靠、可浮動、可縮放工具視窗(Tool Window)能大幅提升專業應用的使用體驗。Cristi Posea 開發的 CSizingControlBar 類別已完美封裝所有複雜邏輯。本文示範如何整合該類別(重新命名為 CCoolBar),在 SDI 專案中建立左側與底部停靠視窗,並分別放入編輯框、樹狀圖、對話框、分頁控制項。
BarDemo。CSizingControlBar 原始碼(sizecbar.h/cpp, scbarg.h/cpp),複製到專案目錄並加入專案。stdafx.h 加入:#include "sizecbar.h"、#include "scbarg.h"。
// MainFrm.h
class CMainFrame : public CFrameWnd {
CCoolBar m_wndMyBar1; // 左側
CCoolBar m_wndMyBar2; // 底部
// 子控制項
CEdit m_wndEdit;
CTreeCtrl m_wndTree;
CCoolTabCtrl m_wndTab; // 隨附的分頁控制項
// ...
};
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1) return -1;
// 建立左側控制列
if (!m_wndMyBar1.Create(_T("左側面板"), this, 123))
return -1;
m_wndMyBar1.SetBarStyle(m_wndMyBar1.GetBarStyle() |
CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
m_wndMyBar1.EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndMyBar1, AFX_IDW_DOCKBAR_LEFT);
// 建立底部控制列
if (!m_wndMyBar2.Create(_T("底部面板"), this, CSize(100,100), TRUE, 124))
return -1;
m_wndMyBar2.SetBarStyle(m_wndMyBar2.GetBarStyle() |
CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
m_wndMyBar2.EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndMyBar2, AFX_IDW_DOCKBAR_BOTTOM);
// --- 將子控制項放入控制列 ---
// 1. 編輯框放入底部
m_wndEdit.Create(WS_VSCROLL|WS_CHILD|WS_VISIBLE|
ES_AUTOVSCROLL|ES_MULTILINE|ES_WANTRETURN,
CRect(0,0,0,0), &m_wndMyBar2, 101);
m_wndEdit.ModifyStyleEx(0, WS_EX_CLIENTEDGE);
// 2. 樹狀圖放入左側
m_wndTree.Create(WS_CHILD|WS_VISIBLE|
TVS_HASLINES|TVS_HASBUTTONS|TVS_LINESATROOT,
CRect(0,0,0,0), &m_wndMyBar1, 100);
m_wndTree.ModifyStyleEx(0, WS_EX_CLIENTEDGE);
HTREEITEM hRoot = m_wndTree.InsertItem(_T("VC 知識庫"));
m_wndTree.InsertItem(_T("電子文檔"));
m_wndTree.InsertItem(_T("線上雜誌第 1 期"), hRoot);
m_wndTree.InsertItem(_T("線上雜誌第 2 期"), hRoot);
// 3. 分頁控制項放入左側,內含樹狀圖與對話框
m_wndTab.Create(TCS_DOWN|WS_CHILD|WS_VISIBLE,
CRect(0,0,100,100), &m_wndMyBar1, 125);
// 頁 1:樹狀圖
m_wndTab.AddPage(&m_wndTree, _T("知識庫"), IDI_ICON1);
// 頁 2:對話框 (需 DECLARE_DYNCREATE/IMPLEMENT_DYNCREATE)
m_wndTab.AddPage(RUNTIME_CLASS(CVCKBASEDlg), IDD_DIALOGBAR, _T("設定"), IDI_ICON2);
// 頁 3:另一個對話框
m_wndTab.AddPage(RUNTIME_CLASS(CMyDlg), IDD_DIALOGBAR2, _T("工具"), IDI_ICON3);
m_wndTab.UpdateWindow();
return 0;
}
// VCKBASEDlg.h
class CVCKBASEDlg : public CDialog {
DECLARE_DYNCREATE(CVCKBASEDlg)
public:
CVCKBASEDlg(CWnd* pParent = NULL);
// ...
};
// VCKBASEDlg.cpp
IMPLEMENT_DYNCREATE(CVCKBASEDlg, CDialog)
// 浮動視窗使用標準工具視窗標題列(預設為迷你框架)
#ifdef _SCB_REPLACE_MINIFRAME
m_wndMyBar1.m_pFloatingFrameClass = RUNTIME_CLASS(CSCBMiniDockFrameWnd);
#endif
// 扁平化風格
#define _SCB_STYLE_FLAT
// 在 stdafx.h 定義上述宏即可啟用
// 同一列(底部)並排
DockControlBar(&m_wndMyBar1, AFX_IDW_DOCKBAR_BOTTOM);
RecalcLayout();
CRect rc; m_wndMyBar1.GetWindowRect(&rc);
rc.OffsetRect(1, 0);
DockControlBar(&m_wndMyBar2, AFX_IDW_DOCKBAR_BOTTOM, rc);
// 同一行(右側)上下
DockControlBar(&m_wndMyBar1, AFX_IDW_DOCKBAR_RIGHT);
RecalcLayout();
m_wndMyBar1.GetWindowRect(&rc);
rc.OffsetRect(0, 1);
DockControlBar(&m_wndMyBar2, AFX_IDW_DOCKBAR_RIGHT, rc);

整合 CSizingControlBar 僅需幾十行程式碼即可獲得專業級停靠視窗框架,支援任意控制項嵌入、分頁、浮動、自動隱藏等功能,極大縮短開發週期。