关于选项卡控件

选项卡控件类似于笔记本中的分隔条或文件柜中的标签。 通过使用选项卡控件,应用程序可以为窗口或对话框的相同区域定义多个页。 每个页面都包含某类信息或一组控件,当用户选择相应的选项卡时,应用程序就会显示这些信息或控件。

以下屏幕截图显示了一个简单的选项卡控件,其中包含一周中各天的选项卡。 已选择“星期二”选项卡。

screen shot of a property sheet with five tabs, one for each day of the week

本主题包含以下各节。

创建选项卡控件

通过调用 CreateWindowEx 函数并指定 WC_TABCONTROL 窗口类即可创建一个选项卡控件。 加载通用控件 DLL 时,会注册此窗口类。 要确保 DLL 已加载,请使用 InitCommonControlsEx 函数。

在 Microsoft Visual Studio 中,可以使用工具箱来创建选项卡控件。

将消息发送到选项卡控件以添加选项卡,否则会影响控件的外观和行为。 每个消息都有一个对应的宏,可以用它来代替显式发送消息。 不能禁用选项卡控件中的单个选项卡。 但是,可以通过禁用相应的页面来禁用属性表中的选项卡控件。

选项卡控件样式

通过在创建控件时指定选项卡控件样式,可以为选项卡控件应用某些特性。 例如,可以在选项卡控件中指定选项卡的对齐方式和一般外观。

可以通过指定 TCS_BUTTONS 样式,让选项卡看起来像按钮。 这类选项卡控件中的选项卡应具有与按钮控件相同的功能;也就是说,单击选项卡应执行命令,而不是显示页面。 由于通常都不会使用按钮选项卡控件中的显示区域,因此不会在其周围绘制边框。

可以通过指定 TCS_FOCUSONBUTTONDOWN 样式,让选项卡在被单击时接收输入焦点。 此样式通常只与 TCS_BUTTONS 样式一起使用。 可以使用 TCS_FOCUSNEVER 样式来指定在单击时不接收输入焦点的选项卡。

默认情况下,选项卡控件只会显示一行选项卡。 如果不能同时显示所有选项卡,则选项卡控件会显示一个上下控件,以便用户滚动查看其他选项卡。 如果需要,可以通过指定 TCS_MULTILINE 样式,让选项卡控件显示多行选项卡。 使用此样式可以同时显示所有选项卡。 除非指定 TCS_RIGHTJUSTIFY 样式,否则每一行中的选项卡都将左对齐。 在这种情况下,每个选项卡的宽度都会增大,这样每一行选项卡就会填满整个控件宽度。

选项卡控件会自动调整每个选项卡的大小,以适合其图标(如有)和标签。 要让所有选项卡具有相同的宽度,可以指定 TCS_FIXEDWIDTH 样式。 控件会调整所有选项卡的大小以适应最宽的标签,也可以使用 TCM_SETITEMSIZE 消息来指定特定的宽度和高度。 在每个选项卡中,控件都会将图标和标签置于居中位置,并将图标放在标签的左侧。 可以通过指定 TCS_FORCEICONLEFT 样式来将图标强制移至左侧,而让标签居中。 可以使用 TCS_FORCELABELLEFT 样式将图标和标签同时左对齐。 不能将 TCS_FIXEDWIDTH 样式与 TCS_RIGHTJUSTIFY 样式一起使用。

可以使用 TCS_OWNERDRAWFIXED 样式来指定父窗口在控件中绘制选项卡。 有关详细信息,请参阅所有者绘制的选项卡

可以通过使用 TCS_TOOLTIPS 样式来指定选项卡控件将创建一个工具提示控件。 有关此内容的详细信息,请参阅选项卡控件工具提示

选项卡和选项卡属性

选项卡控件中的每个选项卡都由一个图标、一个标签以及应用程序定义的数据组成。 这些信息由 TCITEM 结构指定。 可以向选项卡控件添加选项卡、检索选项卡数量、检索和设置选项卡的内容以及删除选项卡。 选项卡由从 0 开始的索引来标识。

要在选项卡控件中添加选项卡,请使用 TCM_INSERTITEM 消息,指定项目的位置和 TCITEM 结构的地址。 可以使用 TCM_GETITEMTCM_SETITEM 消息来检索和设置现有选项卡的内容。 可以为每个选项卡指定图标、标签或两者。 还可以指定要与选项卡关联的应用程序定义的数据。

可以使用 TCM_GETITEMCOUNT 消息获取当前选项卡的数量,使用 TCM_DELETEITEM 消息删除一个选项卡,使用 TCM_DELETEALLITEMS 消息删除选项卡控件中的所有选项卡。

可以将应用程序定义的数据与每个选项卡相关联。例如,可以将每个页面的信息保存在相应的选项卡中。默认情况下,选项卡控件会为每个选项卡分配 4 个额外字节用于应用程序定义的数据。 可以使用 TCM_SETITEMEXTRA 消息来更改每个选项卡的额外字节数。 只有当选项卡控件为空时,才能使用此消息。

应用程序定义的数据由 TCITEM 结构的 lParam 成员指定。 如果使用的应用程序定义数据超过了 4 个字节,则需要定义自己的结构,并使用该结构而不是 TCITEM。 可以使用 TCM_GETITEM and TCM_SETITEM 消息,以与检索和设置有关选项卡的其他信息相同的方式来检索和设置应用程序定义的数据。

结构的第一个成员必须是 TCITEMHEADER 结构,而其余成员必须指定应用程序定义的数据。 TCITEMHEADERTCITEM 相同,只是它没有 lParam 成员。 结构大小与 TCITEMHEADER 大小之间的差值应等于每个选项卡的额外字节数。

显示区域

选项卡控件的显示区域是应用程序显示当前页面的区域。 通常,应用程序会创建一个子窗口或对话框,从而设置窗口大小和位置以适应显示区域。 给定选项卡控件的窗口矩形后,可以使用 TCM_ADJUSTRECT 消息来计算显示区域的边界矩形。

有时,显示区域必须具有特定大小,例如,无模式子对话框的大小。 如果给定了显示区域的边界矩形,则可以使用 TCM_ADJUSTRECT 来为选项卡控件计算相应的窗口矩形。

选项卡选择

当用户选择某个选项卡时,选项卡控件会以 WM_NOTIFY 消息的形式向其父窗口发送通知代码。 TCN_SELCHANGING 通知代码在选择更改之前发送,而 TCN_SELCHANGE 通知代码在选择更改之后发送。

可以处理 TCN_SELCHANGING 以保存传出页面的状态。 可以返回 TRUE 以防止选择发生更改。 例如,如果子对话框中某个控件的设置无效,你可能不希望切换离开子对话框。

必须处理 TCN_SELCHANGE 才能在显示区域显示传入的页面。 这可能只需要更改子窗口中显示的信息。 更常见的情况是,每个页面都由一个子窗口或对话框组成。 在这种情况下,应用程序可能会通过销毁或隐藏传出子窗口或对话框以及创建或显示传入子窗口或对话框来处理此通知。

可以使用 TCM_GETCURSELTCM_SETCURSEL 消息来检索和设置当前选择。

选项卡控件图像列表

每个选项卡都可以有一个与之关联的图标,该图标由选项卡控件图像列表中的索引指定。 在创建选项卡控件时,它没有与之关联的图像列表。 应用程序可以使用 ImageList_Create 函数来创建图像列表,然后使用 TCM_SETIMAGELIST 消息将其分配给选项卡控件。

可以将图像添加到选项卡控件的图像列表中,就像添加到其他图像列表中一样。 但是,应用程序应使用 TCM_REMOVEIMAGE 消息而不是 ImageList_Remove 函数来删除图像。 此消息可确保每个选项卡都与之前的相同图像保持关联。

销毁选项卡控件不会销毁与之关联的图像列表。 必须单独销毁图像列表。 如果要将同一个图像列表分配给多个选项卡控件,这将非常有用。

要检索当前与选项卡控件关联的图像列表句柄,可以使用 TCM_GETIMAGELIST 消息。

选项卡大小和位置

选项卡控件中的每个选项卡都有一个大小和位置。 可以设置选项卡的大小,获取选项卡的边界矩形,或者确定哪个选项卡位于指定的位置。

对于固定宽度和所有者绘制的选项卡控件,可以使用 TCM_SETITEMSIZE 消息来设置选项卡的确切宽度与高度。 在其他选项卡控件中,每个选项卡的大小是根据选项卡的图标和标签计算得出的。选项卡控件包含边框和额外边距的空间。 可以使用 TCM_SETPADDING 消息来设置页边距的宽窄。

可以使用 TCM_GETITEMRECT 消息来确定选项卡的当前边界矩形。 可以使用 TCM_HITTEST 消息来确定指定位置上的选项卡(如有)。

在具有 TCS_MULTILINE 样式的选项卡控件中,可以使用 TCM_GETROWCOUNT 消息来确定当前选项卡的行数。

所有者绘制的选项卡

如果选项卡控件具有 TCS_OWNERDRAWFIXED 样式,则父窗口必须通过处理 WM_DRAWITEM 消息来绘制选项卡。 每当需要绘制选项卡时,选项卡控件都会发送此消息。 lParam 参数指定 DRAWITEMSTRUCT 结构的地址,该结构包含选项卡的索引、其边界矩形以及要在其中绘制的设备上下文 (DC)。

默认情况下,DRAWITEMSTRUCTitemData 成员包含 TCITEM 结构的 lParam 成员的值。 但是,如果更改每个选项卡中应用程序定义的数据量,则 itemData 将包含数据地址。 可以使用 TCM_SETITEMEXTRA 消息来更改每个选项卡的应用程序定义数据量。

要指定选项卡控件中项目的大小,父窗口必须处理 WM_MEASUREITEM 消息。 由于所有者绘制的选项卡控件中的所有选项卡的大小均相同,因此此消息只会发送一次。 对于所有者绘制的不同大小的选项卡,没有选项卡控件样式。 还可以使用 TCM_SETITEMSIZE 消息来设置选项卡的宽度和高度。

选项卡控件工具提示

可以使用工具提示控件来简要说明选项卡控件中的每个选项卡。 具有 TCS_TOOLTIPS 样式的选项卡控件会在创建时创建一个工具提示控件,并在选项卡控件被销毁时也将其销毁。 还可以创建一个工具提示控件,并将其分配给一个选项卡控件。

如果将工具提示控件与选项卡控件一起使用,则父窗口必须处理 TTN_GETDISPINFO 通知代码,以便根据请求提供每个选项卡的说明。

要在多个选项卡控件中使用同一个工具提示控件,请自行创建工具提示控件,并使用 TCM_SETTOOLTIPS 消息将其分配给选项卡控件。 可以使用 TCM_GETTOOLTIPS 消息来获取选项卡控件当前工具提示控件的句柄。 如果创建了自己的工具提示控件,则不应使用 TCS_TOOLTIPS 样式。

默认选项卡控件消息处理

本节介绍选项卡控件执行的消息处理。 有关选项卡控件的特定信息将在本文档的其他章节中讨论。

Message 已执行的处理
WM_CAPTURECHANGED 如果选项卡控件自己释放了鼠标捕获,则不执行任何操作。 如果另一个窗口捕获了鼠标并按下了按钮,则命令会释放按钮。
WM_CREATE 分配并初始化内部数据结构。 如果指定了 TCS_TOOLTIPS 样式,则控件将创建一个工具提示控件。
WM_DESTROY 释放在 WM_CREATE 处理过程中分配的资源。
WM_GETDLGCODE 返回 DLGC_WANTARROWS 和 DLGC_WANTCHARS 值的组合。
WM_GETFONT 返回用于标签的字体的句柄。
WM_KEYDOWN 处理方向键并酌情更改选择。
WM_KILLFOCUS 让拥有焦点的选项卡失效,以便将它重新绘制以反映失去焦点的状态。
WM_LBUTTONDOWN 将信息转发给工具提示控件(如有),如果用户单击的是选项卡,则更改选择。如果用户单击的是按钮,则控件会重新绘制按钮,使其呈现凹陷外观并捕获鼠标。 如果用户正在单击选项卡或按钮,并且指定了 TCS_FOCUSONBUTTONDOWN 样式,则控件会将焦点设置为自身。
WM_LBUTTONUP 如果按下按钮,则释放鼠标。 如果光标位于按钮上方并且按钮已被按下,则控件会相应更改选择并重新绘制按钮。
WM_MOUSEMOVE 将信息转发给工具提示控件(如有)。 如果指定了 TCS_BUTTONS 样式,并且在单击后按住鼠标按钮不放,则控件还可能重新绘制受影响的按钮,使其呈现凸起或凹陷的外观。
WM_NOTIFY 转发工具提示控件发送的通知代码。
WM_PAINT 在显示区域周围绘制边框(除非指定了 TCS_BUTTONS 样式),并绘制与无效矩形相交的任何选项卡。 对于每个选项卡,控件都会绘制选项卡的主体(或向父窗口发送 WM_DRAWITEM 消息),然后在选项卡周围绘制边框。如果 wParam 参数为非空,则控件会假定该值为 HDC,并使用该设备上下文进行绘制。
WM_RBUTTONDOWN 向父窗口发送 NM_RCLICK 通知代码。
WM_SETFOCUS 让拥有焦点的选项卡失效,以便将它重新绘制以反映焦点状态。
WM_SETFONT 设置用于标签的字体。
WM_SETREDRAW 设置一个内部标志的状态,该标志将决定在插入和删除项目、更改字体等情况下是否重新绘制控件。
WM_SIZE 重新计算选项卡的位置,并可能使部分选项卡控件失效,从而强制重新绘制部分或全部选项卡。