一种自定义 Windows 标题栏的技术






4.80/5 (11投票s)
2003年7月2日
2分钟阅读

189219

8398
使用一个易于使用的模板类来定制 windows 的标题栏。
引言
本文使用一种通过模拟窗口标题栏行为的方法来定制标题栏。 这种方法用一个替代窗口来模拟标题栏。 原来的窗口标题栏从窗口区域中移除, 并在窗口标题栏应该在的位置创建一个替代窗口,该窗口的行为就像一个窗口标题栏。 演示项目提供了一个实现此任务的框架,并且还提供了两种标题栏外观:一种类似于 X Windows 上的窗口标题栏,另一种是我创建的。
背景
我读了一篇关于通过窗口子类化来自定义窗口标题栏的优秀文章,作者是 James Brown。 很快我发现,通过窗口子类化技术来实现我想要的复杂视觉效果并不容易。 微软似乎不喜欢程序员更改 Windows 用户界面元素的默认行为,因此许多程序员不得不自己“创建”新的用户界面元素。 这是一个这样的例子。
类
Titlebar
: 从此类派生需要标题栏自定义的窗口类,并指定一个标题栏替代类和一个按钮类作为模板参数。
TitlebarSubstitute
: 标题栏替代窗口的基类。 这实现了大部分窗口标题栏的行为。 要实现各种视觉效果,只需从它派生您自己的替代窗口类,并覆盖其虚拟方法。 TitlebarSubstitute
最重要的虚拟方法是 DoPaint
,它负责绘制除系统按钮之外的所有标题栏元素。 演示项目中派生自 TitlebarSubstitute
的有两个类, LinuxTitlebarSubstitute
,它使窗口标题栏看起来像第一个截图,而 WrittenInMidnight
看起来像第二个截图。
PushButton
: 自定义绘制的按钮类,所有系统按钮类的基类。
Using the Code
首先,从类 Titlebar
派生您的窗口类。 例如
class CMainFrame : public CFrameWindowImpl<CMAINFRAME>, public CUpdateUI<CMAINFRAME>, public CMessageFilter, public CIdleHandler, public FreshUI::Titlebar < CMainFrame, FreshUI::LinuxTitlebarSubstitute < FreshUI::LinuxSystemButton > >
将消息映射链到类 Titlebar
typedef FreshUI::Titlebar < CMainFrame, FreshUI::LinuxTitlebarSubstitute < FreshUI::LinuxSystemButton > > baseClass; BEGIN_MSG_MAP(CMainFrame) // ... CHAIN_MSG_MAP(baseClass) END_MSG_MAP()
调用 Titlebar::Init
. 对于一般窗口,您应该在 OnCreate
中调用此方法;对于对话框,在 OnInitDialog
中调用它。 例如
LRESULT OnCreate( UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) { // ... // Initialize Titlebar Init(); return 0; }
历史
- 2003-02-07 - 初始上传