Win32中TBBUTTON的fsStyle值无法适配BYTE类型的疑问
问题背景
TBBUTTON结构体定义如下:
typedef struct _TBBUTTON { int iBitmap; int idCommand; BYTE fsState; BYTE fsStyle; #ifdef _WIN64 BYTE bReserved[6]; // padding for alignment #elif defined(_WIN32) BYTE bReserved[2]; // padding for alignment #endif DWORD_PTR dwData; INT_PTR iString; } TBBUTTON, NEAR* PTBBUTTON, *LPTBBUTTON; typedef const TBBUTTON *LPCTBBUTTON;
其中fsStyle字段为BYTE类型(取值范围0-255),但常见的一些TBSTYLE_*宏定义如下:
#define TBSTYLE_TOOLTIPS 0x0100 #define TBSTYLE_WRAPABLE 0x0200 #define TBSTYLE_ALTDRAG 0x0400 #define TBSTYLE_FLAT 0x0800 #define TBSTYLE_LIST 0x1000 #define TBSTYLE_CUSTOMERASE 0x2000 #define TBSTYLE_REGISTERDROP 0x4000 #define TBSTYLE_TRANSPARENT 0x8000
当执行以下代码时,编译器会抛出警告warning C4305: '=': truncation from 'int' to 'BYTE':
TBBUTTON button; button.fsStyle = TBSTYLE_TOOLTIPS;
MSDN文档未明确提及该问题,核心疑问是这里存在什么认知误区。
误区解析
问题的核心是混淆了工具栏控件的整体样式和单个按钮的样式:
- 你使用的
TBSTYLE_*系列宏,是用于设置整个工具栏控件的样式,应该在调用CreateWindowEx创建工具栏时,作为窗口样式参数传递,而非赋值给单个TBBUTTON的fsStyle字段。 TBBUTTON.fsStyle字段对应的是单个按钮的样式,对应的宏是TBBS_*前缀的,比如TBBS_BUTTON(普通按钮,值为0)、TBBS_SEPARATOR(分隔符,值为0x01)、TBBS_CHECKBOX(复选框按钮,值为0x02)等,这些值都在BYTE的取值范围内,不会触发截断警告。
正确用法示例
设置工具栏整体样式
// 创建工具栏时传入TBSTYLE_*系列样式 HWND hToolbar = CreateWindowEx( 0, TOOLBARCLASSNAME, NULL, WS_CHILD | WS_VISIBLE | TBSTYLE_FLAT | TBSTYLE_TOOLTIPS, // 工具栏整体样式 0, 0, 0, 0, hWndParent, (HMENU)ID_TOOLBAR, GetModuleHandle(NULL), NULL );
设置单个按钮样式
TBBUTTON button = {0}; button.iBitmap = 0; button.idCommand = ID_BUTTON_TEST; button.fsStyle = TBBS_CHECKBOX; // 使用TBBS_*系列的单个按钮样式
内容的提问来源于stack exchange,提问作者Zoli
相关产品推荐
相关产品推荐

