关于工具栏控件

工具栏是一个包含一个或多个按钮的控件。 用户单击每个按钮时,都会向父窗口发送一条命令消息。 通常,工具栏中的按钮对应于应用程序菜单项,为用户另外提供了一种更直接的方式来访问应用程序命令。

以下屏幕截图显示的窗口包含一个用于文件操作的简单工具栏。 应用程序启用了视觉样式。 “保存”按钮是“热”按钮,因为抓取屏幕截图时光标正悬停在该按钮上。 控件的实际外观会因操作系统和用户选择的主题而异。

screen shot of a window with a three-button toolbar; one button is hot

以下屏幕截图显示了在未启用视觉样式的情况下编译的应用程序中的相同控件。

screen shot of a window without visual styles: none of the buttons looks hot

以下主题讨论了在规划工具栏时需要考虑的功能。 有关实现和示例代码的特定信息,请参阅使用工具栏控件

指定工具栏大小和位置

如果使用 CreateToolbarEx 来创建工具栏,则可以使用该函数以像素为单位指定工具栏的高度和宽度。

注意

不建议使用 CreateToolbarEx,因为它不支持工具栏的新功能,包括图像列表。 有关创建工具栏的详细信息,请参阅使用工具栏控件

 

CreateWindowEx 函数没有用于指定工具栏大小的参数。 工具栏窗口过程会自动设置工具栏窗口的大小和位置。 高度基于工具栏中按钮的高度。 宽度与父窗口工作区的宽度一样。 要更改自动大小设置,请发送 TB_SETBUTTONSIZE 消息。 CCS_TOPCCS_BOTTOM 常用控件样式决定了工具栏是沿客户区的顶部还是底部定位。 默认工具栏具有 CCS_TOP 样式。

此外,工具栏窗口过程会在收到 WM_SIZETB_AUTOSIZE 消息时自动调整工具栏的大小。 每当父窗口的大小发生变化,或者在发送需要调整工具栏大小的消息(例如 TB_SETBUTTONSIZE 消息)后,应用程序都应发送上述任一消息。

可以通过设置 CCS_NORESIZECCS_NOPARENTALIGN 常用控件样式来关闭工具栏默认大小和定位行为。 由 rebar 控件托管的工具栏控件必须设置这些样式,因为 rebar 控件会调整工具栏的大小和位置。

透明工具栏

工具栏控件支持透明外观,可显示工具栏下的客户区。 透明工具栏有两种,一种是平面按钮,另一种是三维按钮。 如果想让应用程序与 Windows 界面保持一致,请使用扁平透明风格的工具栏。

以下屏幕截图显示了两种未使用视觉样式的透明工具栏。

screen shot of two windows with different styles of toolbars, but both toolbars are transparent

以下屏幕截图显示了在 Windows Vista 中启用视觉样式后可能出现的透明工具栏。 对话框的背景色已被更改,以便让透明度更加明显。

screen shot of a window in windows vista with a transparent toolbar

要创建透明工具栏,只需在 CreateWindowEx 的窗口样式参数中添加 TBSTYLE_FLATTBSTYLE_TRANSPARENT 即可。 如果不想用一条线来表示工具栏的底部,请不要使用 WS_BORDER 窗口样式。

注意

在使用视觉样式时,工具栏可能会默认为扁平。

 

列表样式工具栏

可以通过工具栏按钮来显示文本和位图。 使用 TBSTYLE_LIST 样式创建的工具栏上的按钮会将文本放在位图的右侧,而不是位图的下方。

以下屏幕截图显示了一个列表样式的工具栏。

screen shot of a toolbar with text to the right of each icon

可以将 TBSTYLE_LIST 工具栏样式与 TBSTYLE_FLAT 样式结合使用,以便创建带有扁平按钮的工具栏。

定义按钮图像

为按钮指定图像有两种方法 — 位图或图像列表。 应用程序必须选择使用哪种方法。 它不能在同一个工具栏控件上同时使用两种方法。 请注意,CreateToolbarEx 函数使用的是位图方法。 想要使用图像列表方法的应用程序必须使用 CreateWindowEx 函数来创建工具栏控件。

使用位图定义按钮图像

工具栏中的每个按钮都可以包含一个位图图像。 工具栏会使用内部列表来存储绘制图像所需的信息。 在调用 CreateToolbarEx 函数时,需要指定包含初始图像的单色或彩色位图,然后工具栏就会将这些信息添加到内部图像列表中。 可以稍后使用 TB_ADDBITMAP 消息来添加其他图像。

每个图像都有一个从 0 开始的索引。 添加到内部列表的第一个图像的索引为 0,第二个图像的索引为 1,以此类推。 TB_ADDBITMAP 会将图像添加到列表末尾,并返回所添加的第一个新图像的索引。 要将图像与按钮相关联,必须在将位图添加到内部图像列表后发送 TB_ADDBUTTONS 消息并指定图像的索引。

Windows 假定工具栏的所有位图图像大小均相同。 在创建工具栏时,可以使用 CreateToolbarEx 来指定工具栏的大小。 如果使用 CreateWindowEx 来函数创建工具栏,则图像的大小将被设置为默认尺寸 16 x 15 像素。 可以使用 TB_SETBITMAPSIZE 消息来更改位图图像的尺寸,但必须在向内部列表添加任何图像之前进行更改。

使用图像列表定义按钮图像

还可以在一组图像列表中存储按钮图像。 图像列表是大小相同的图像集合,其中的每个图像都可以通过其索引进行引用。 图像列表用于管理大图标或位图集。 最多可以使用三个不同的图像列表来显示不同状态的按钮,如下表所示。

状态 说明
普通 处于默认状态的按钮。
指针下方或按下的按钮。 仅在具有 TBSTYLE_FLAT 样式的工具栏控件中支持热项目。
已禁用 被禁用的按钮。

 

在销毁工具栏后,应用程序必须释放其创建的任何图像列表。

定义按钮的文本

除了显示图像外,每个按钮还可以显示字符串。 工具栏有一个内部列表,其中包含了可用于工具栏按钮的所有字符串。 可以使用 TB_ADDSTRING 消息将字符串添加到内部列表,并指定包含要添加字符串的缓冲区地址。 每个字符串都必须以 null 结尾,而最后一个字符串必须以两个 null 字符结尾。

每个字符串都有一个从 0 开始的索引。 添加到内部字符串列表的第一个字符串的索引为 0,第二个字符串的索引为 1,以此类推。 TB_ADDSTRING 会将字符串添加到列表末尾,并返回第一个新字符串的索引。 可以使用字符串的索引将字符串与按钮相关联。

使用 TB_ADDSTRING 并不是向工具栏添加字符串的唯一方法。 可以在将被传递给 TB_ADDBUTTONSTBBUTTON 结构的 iString 成员中传递字符串指针,以便在按钮中显示字符串。 此外,还可以使用 TB_SETBUTTONINFO 来为工具栏按钮指定文本。

添加工具栏按钮

如果使用 CreateToolbarEx 函数来创建工具栏,则可以通过填充 TBBUTTON 结构数组并在函数调用中指定数组的地址来为工具栏添加按钮。 但是,CreateWindowEx 函数没有用于传递 TBBUTTON 结构的参数。 CreateWindowEx 将创建一个空工具栏,然后可以通过发送 TB_ADDBUTTONS 消息来填充该工具栏并指定 TBBUTTON 结构的地址。

在创建工具栏后,可以通过发送 TB_INSERTBUTTONTB_ADDBUTTONS 消息来添加按钮。 每个按钮都由 TBBUTTON 结构来描述,该结构定义了按钮的属性,包括字符串和位图的索引,以及按钮的样式、状态、命令标识符和应用程序定义的 32 位值。

注意

如果使用 CreateWindowEx 函数来创建工具栏,则必须在添加任何按钮之前发送 TB_BUTTONSTRUCTSIZE 消息。 该信息会将 TBBUTTON 结构的大小传递给工具栏。

 

工具栏按钮样式

按钮的样式决定了按钮的显示方式以及按钮对用户输入的响应方式。 例如,BTNS_BUTTON 样式会创建一个行为类似于标准按钮的工具栏按钮。 具有 BTNS_CHECK 样式的按钮与标准按钮类似,不同之处在于每次用户单击按钮时,它都会在按下和未按下状态之间切换。

可以使用 BTNS_GROUPBTNS_CHECKGROUP 样式来创建类似单选按钮的工具栏按钮组。 这会让一个按钮保持按下状态,直至用户选择了组中的另一个按钮。 组被定义为连续的按钮集合,其中的所有按钮都具有 BTNS_GROUPBTNS_CHECKGROUP 样式。

BTNS_SEP 样式可在按钮之间创建一个小间距,或在扁平工具栏上的按钮之间绘制一个蚀刻痕迹。 具有 BTNS_SEP 样式的按钮不会接收用户输入。

5.80 版的常用控件引入了一些新的工具栏按钮样式,并重新命名了一些较早的样式。 所有按钮样式标志现在都以 BTNS_XXX 开头,而不是 TBSTYLE_XXX 开头。 有关按钮样式的列表和讨论,请参阅工具栏控件和按钮样式

工具栏按钮状态

工具栏中的每个按钮都有一个状态。 工具栏会更新按钮的状态以反映用户的操作,如单击按钮。 状态表示按钮当前是按下还是未按下、启用还是禁用、隐藏还是可见。 虽然应用程序会在将按钮添加到工具栏时设置按钮的初始状态,但它可以通过向工具栏发送 TB_GETSTATETB_SETSTATE 消息来更改和检索状态。 有关工具栏按钮状态列表,请参阅工具栏状态

命令标识符

每个按钮都有一个与之关联的应用程序定义的命令标识符。 按钮标识符通常在应用程序头文件中定义。 例如,“粘贴”按钮可定义为:

#define ID_PASTE 100

当用户选择按钮时,工具栏会向父窗口发送 WM_COMMANDWM_NOTIFY 消息,其中包含了按钮的命令标识符。 父窗口会检查命令标识符,并执行与按钮相关的命令。 有关控件何时发送 WM_COMMAND 消息以及何时发送 WM_NOTIFY 消息的信息,请参阅 WM_NOTIFY 文档的“备注”部分。

按钮位置和大小

工具栏通过为每个按钮分配一个位置索引来跟踪其按钮。 索引从 0 开始,即最左边的按钮的索引为 0,右边下一个按钮的索引为 1,以此类推。 应用程序在发送消息以检索按钮信息或设置按钮属性时,必须指定按钮的索引。

工具栏会在插入和移除按钮时更新位置索引。 应用程序可以使用 TB_COMMANDTOINDEX 消息获取按钮的当前位置索引。 该消息可指定按钮的命令标识符,而工具栏窗口将使用该标识符来定位按钮并返回其位置索引。

工具栏中的所有按钮大小均相同。 CreateToolbarEx 函数要求在创建工具栏时设置按钮的初始大小。 使用 CreateWindowEx 函数时,初始大小将设置为默认尺寸 24 x 22 像素。 可以使用 TB_SETBUTTONSIZE 消息来更改按钮大小,但必须在向工具栏添加任何按钮之前进行更改。 TB_GETITEMRECT 消息将检索按钮的当前尺寸。

当添加的字符串比当前工具栏中的任何字符串都长时,工具栏会自动重新设置按钮的宽度。 宽度会被设置为可容纳工具栏中最长的字符串。

启用自定义

工具栏具有内置的自定义功能,可以通过为工具栏设置 CCS_ADJUSTABLE 常用控件样式来向用户提供这些功能。 用户可以通过自定义功能将按钮拖动到新位置,或通过将按钮拖出工具栏删除该按钮。 此外,用户可以双击工具栏以显示“自定义工具栏”对话框,以便添加、删除和重排工具栏按钮。 要显示对话框,请使用 TB_CUSTOMIZE 消息。 应用程序确定自定义功能是否对用户可用,并控制用户可自定义工具栏的程度。

作为自定义过程的一部分,应用程序经常需要保存和还原工具栏的状态。 例如,许多应用程序会在用户开始自定义工具栏之前存储工具栏状态,以防用户日后想将工具栏还原为原始状态。 工具栏控件不会自动保留其自定义前状态的记录。 应用程序必须保存工具栏状态才能将它还原。 有关详细信息,请参阅使用工具栏控件

启用热跟踪

热跟踪是指当指针移动到某个项目上时,按钮的外观会发生变化。 在启用视觉样式后,工具栏就会默认支持热跟踪。 否则,只有使用 TBSTYLE_FLAT 样式创建的工具栏控件才支持热跟踪。 可以将其他窗口样式与 TBSTYLE_FLAT 结合使用,以便生成支持热跟踪但外观不同于平面工具栏的工具栏。 有关详细信息,请参阅使用工具栏控件