自定义标题栏按钮实现指南

在Windows应用程序中,经常需要在标题栏添加自定义按钮以增强用户界面的交互性。然而,直接在标题栏上添加按钮并不像在客户区添加按钮那样简单。尽管有一些应用程序已经实现了标题栏上的自定义按钮,但很难找到可重用的代码实现。因此,决定创建一个名为CCaptionButton的类来实现这个功能。

准备图片

由于需要在标题栏上绘制按钮,因此需要准备一些图片来模拟按钮的外观。CCaptionButton类需要一个图片列表,其中包含以下状态的图片:

  • 正常状态
  • 按下状态
  • 悬停状态
  • 选中状态(可选)
  • 禁用状态(可选)

以下是创建按钮图片列表的示例图片:

// 示例代码 HIMAGELIST himl = ImageList_LoadImage(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDB_BUTTONS), 16, 4, RGB(255, 0, 255));

添加标题栏按钮

需要支持一个窗口上添加多个标题栏按钮。每个按钮内部使用以下数据结构存储:

struct _button { UINT uID; // 命令ID int cx; // 宽度 int cy; // 高度 HIMAGELIST himl; // 图片列表 UINT uStatus; // 状态(图片索引) char szHint[80]; // 提示文本 };

使用向量来内部存储按钮。要添加按钮,只需调用:

int AddButton(UINT uID, int cx, int cy, HIMAGELIST himl, LPCTSTR lpszHint=NULL);

其中uID是按钮的命令ID。当按钮被点击时,会向窗口发送一个带有uID参数的WM_COMMAND消息。因此,处理标题栏按钮点击与处理普通按钮点击是一样的。cxcy指定按钮的大小,这个大小必须与相应图片列表中的图片大小匹配。himl包含绘制按钮所需的所有图片。它必须至少包含三个图片,按照前面描述的正确顺序,或者如果需要选中和禁用状态,则包含五个图片。lpszHint是按钮的提示文本。

定位

在哪里绘制这些按钮?自动定位听起来对于一个可重用的类是必须的。然而,发现在所有窗口样式中将按钮放置在正确位置是不可能的。窗口是否是工具窗口,标题栏相对较薄?窗口是否包含最小化按钮?窗口是否包含最大化按钮?窗口是否包含帮助按钮?……所有这些都会使自动定位变得混乱。最后,决定让派生类定位按钮。函数GetButtonPos被设计为可以覆盖,以为每个按钮提供位置。

POINT GetButtonPos(int index);

CCaptionButton类提供了GetButtonPos的默认实现。但它假设目标窗口是一个工具窗口,并且没有现有的系统按钮。对于任何其他样式,必须实现自己的GetButtonPos来正确定位按钮。通过提供自定义GetButtonPos函数,按钮定位变得更加强大和灵活。甚至可以像演示应用程序中那样垂直堆叠两个按钮。

使用指南

CCaptionButton类可以轻松添加到任何直接或间接派生自CWindowImpl的ATL/WTL窗口类中。使用总结:

  • 使用CCaptionButton类作为基类。
  • 使用CHAIN_MSG_MAP将消息链接到CCaptionButton类。
  • 调用AddButton向标题栏添加一个或多个按钮。
  • (重要)覆盖GetButtonPos函数以为添加的每个按钮提供位置。
  • 像处理普通按钮点击一样处理标题栏按钮发送的WM_COMMAND通知。
  • (可选)调用CheckButton更改标题栏按钮的选中状态。
  • (可选)调用EnableButton更改标题栏按钮的启用状态。

功能

  • 在标题栏上添加一个或多个按钮。
  • 灵活定位。
  • 支持按钮点击的WM_COMMAND
  • 支持提示。

示例应用程序

附带的示例应用程序演示了CCaptionButton的使用。CAppBar类也用于AppBar功能。要获取更多关于CAppBar的详细信息,请查看这里。示例中使用了五个标题栏按钮。固定按钮控制AppBar窗口的自动隐藏属性;其他四个按钮将窗口停靠到屏幕的四个边缘;“底部停靠”按钮被禁用,以便可以看到禁用按钮的外观。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485