CSizingControlBar - 可调整大小的控件栏






4.96/5 (145投票s)
类似 DevStudio 的对接窗口
CSizingControlBar 2.43 的特性
- 可调整大小的控件栏,在停靠和浮动时都可以调整大小
- 多个可调整大小的控件栏可以停靠在同一行/列上
- 完全动态调整大小,包括停靠和浮动时的调整,浮动时包括对角线调整
- 状态持久化支持 (
SaveState
/LoadState
) - 带“隐藏栏”扁平按钮的抓手
- 内存 DC 无闪烁 NC 绘制
- 具有焦点自动感应文本标题的示例扩展类。在 Win98/Win2k 上,标题使用渐变色绘制
- 未使用自定义资源(位图、光标、字符串等),因此集成更简单,您可以完全控制最终在派生类中使用的资源
- 易于使用:直接使用
CSizingControlBar*
类之一,或派生自己的控件栏类,然后添加子控件
说明
入门
- 在您的项目中包含以下文件
sizecbar.h sizecbar.cpp scbarg.h scbarg.cpp
- 将以下行添加到您的 stdafx.h (如果文件在不同目录中,请包含路径 - 请参阅示例中的 stdafx.h 文件)
#include "sizecbar.h" #include "scbarg.h"
- 从
CSizingControlBarG
派生一个类(您在 mybar.* 文件中有示例)。 - 在 mainfrm.h 中,包含您的类的头文件
#include "mybar.h"
然后在
CMainFrame
中添加一个成员变量CMyBar m_wndMyBar;
- 在
CMainFrame::OnCreate()
中创建栏。然后设置栏样式,使其能够停靠……就像任何控件栏一样。if (!m_wndMyBar.Create(_T("My Bar"), this, 123) { TRACE0("Failed to create mybar\n"); return -1; // fail to create } m_wndMyBar.SetBarStyle(m_wndMyBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC); m_wndMyBar.EnableDocking(CBRS_ALIGN_ANY); EnableDocking(CBRS_ALIGN_ANY); DockControlBar(&m_wndMyBar, AFX_IDW_DOCKBAR_LEFT);
高级示例
上面的说明将创建一个类似 DevStudio 的抓手(带两个凸起的线条和一个隐藏按钮)的停靠栏,当浮动时没有抓手。
让我们探索一些高级功能。现在我们将使用 CSizingControlBarCF
类作为基类,并隐藏迷你框架标题,在浮动状态下也显示抓手。这是可能的,因为 CSizingControlBarCF
的抓手看起来像一个小标题。作为使用自定义迷你框架类的副作用,如果启用了“拖动时显示窗口内容”显示属性,浮动栏的调整大小将是动态的。
- 还将这些文件添加到您的项目中
scbarcf.h scbarcf.cpp
- 将 stdafx.h 文件更改为如下内容
#define _SCB_REPLACE_MINIFRAME #include "sizecbar.h" #include "scbarg.h" #include "scbarcf.h" #define baseCMyBar CSizingControlBarCF
- 在
CMainFrame::OnCreate()
中,在EnableDocking()
调用之后添加这些行#ifdef _SCB_REPLACE_MINIFRAME m_pFloatingFrameClass = RUNTIME_CLASS(CSCBMiniDockFrameWnd); #endif //_SCB_REPLACE_MINIFRAME
备注
这些类 intended to be used as base classes。不要仅仅将您的代码添加到文件中 - 而是创建一个派生自 CSizingControlBarG
或 CSizingControlBarCF
的新类,并将您需要的内容放在那里。如果您想自定义抓手,或者根本不想要抓手,可以使用 CSizingControlBar
作为基类。
窗口 ID:只有当栏未启用停靠时(即,它将固定在框架菜单的正下方)才需要使用 AFX_IDW_CONTROLBAR_FIRST + 32 .. AFX_IDW_CONTROLBAR_LAST
范围内的 ID。但在这种情况下,您将无法充分利用此类功能,因此如果您启用停靠(这是合理的猜测 :),则可以使用任何有效的窗口 ID。
ID 重要的另一个地方是栏状态的保存/加载。您必须为启用了停靠的每个控件栏使用不同的 ID,这包括其他栏。例如,如果您有两个工具栏,您可以为第一个工具栏创建默认 ID(即 AFX_IDW_TOOLBAR = AFX_IDW_CONTROLBAR_FIRST
),但第二个工具栏必须具有不同的 ID。
OnUpdateCmdUI:此成员函数在 CControlBar
(CSizingControlBar
的基类)中是纯虚拟的。它的目的是允许在空闲时更新控件(从这里调用 CCmdUI::DoUpdate()
来处理工具栏按钮、对话框栏上的控件、状态栏的窗格等)。
然而,我发现更新 CSizingControlBarG
中“x
”扁平按钮的外观以及 CSizingControlBarCF
中标题的颜色非常有用(无需定时器)。因此,如果您将使用此函数,请不要忘记调用基类的成员(参见 mybar.cpp)。
动态调整大小:此功能允许在调整大小时重绘栏。此外,所有栏都会被重新定位和重绘(如果需要)。
为此会查询 SPI_GETDRAGFULLWINDOWS
系统参数(它由显示属性中的“拖动时显示窗口内容”复选框启用)。
CBRS_SIZE_DYNAMIC:需要此栏样式。请确保将其添加到栏中,否则当用户浮动栏时应用程序将崩溃。您可以在 Create()
之后使用 SetBarStyle()
添加它,或将 Create()
的默认样式更改为类似:WS_VISIBLE|WS_CHILD|CBRS_TOP|CBRS_SIZE_DYNAMIC
。
状态持久化:通用的 MFC 控件栏停靠状态使用 CMainFrame::SaveBarState()
保存。除了此函数保存的信息外,CSizingControlBar
类还需要保存 3 个大小。这在 CSizingControlBar::SaveState()
函数中完成,因此需要调用 m_wndMyBar.SaveState()
。请注意,状态存储代码必须放在 CMainFrame
的 OnClose()
或 DestroyWindow()
中,而不是 OnDestroy()
中,因为当收到 WM_DESTROY
消息时,浮动栏已销毁。
在 CMainFrame::OnCreate()
中,必须在 LoadBarState()
之前放置 m_wndMyBar.LoadState()
调用。
或者,如果您有多个可调整大小的栏,您可以调用一次 static
成员 SizingControlBar::GlobalSaveState()
而不是调用每个栏的 SaveState()
。对于 LoadState()
也是如此 - 有一个 CSizingControlBar::GlobalLoadState()
函数。有关更多详细信息,请参阅两个示例。
预编译器标志:有两个符号可以定义,以使浮动栏具有不同的外观和功能
_SCB_REPLACE_MINIFRAME
可用于插入CSCBMiniDockFrameWnd
,这是一个自定义迷你框架类。使用此类的主要好处是浮动栏可以像所有其他窗口一样动态调整大小。另一个优点是可以关闭迷你框架标题,允许栏显示自己的抓手,以增加功能和/或自定义设计。
如果使用此标志,则必须更改主框架的m_pFloatingFrameClass
成员(参见上面的高级示例)。_SCB_MINIFRAME_CAPTION
仅在前一个标志也已定义的情况下才能定义。它会导致自定义迷你框架保留工具窗口标题。
如果设置了此标志,CSizingControlBarG
和CSizingControlBarCF
类在浮动时都不会显示抓手。
另请参阅 www.datamekanix.com 以获取类参考、完整的更新日志、常见问题解答、专门的消息板等。