2
当我在运行时在对话框窗口中将BS_AUTO3STATE样式添加到默认样式复选框时;3状态复选框Win32运行时
this->Style |= BS_AUTO3STATE; // wrapper of Get/SetWindowLongPtr, ignore the specifics
..它变成了一个组框,而不是一个三态复选框。我究竟做错了什么?
我有错误的控制风格吗?
当我在运行时在对话框窗口中将BS_AUTO3STATE样式添加到默认样式复选框时;3状态复选框Win32运行时
this->Style |= BS_AUTO3STATE; // wrapper of Get/SetWindowLongPtr, ignore the specifics
..它变成了一个组框,而不是一个三态复选框。我究竟做错了什么?
我有错误的控制风格吗?
此问题是由于BS_Xxx
值实际上未在标头中定义为位标志的事实引起的。相反,他们的价值观只是线性增加:
#define BS_PUSHBUTTON 0x00000000L
#define BS_DEFPUSHBUTTON 0x00000001L
#define BS_CHECKBOX 0x00000002L
#define BS_AUTOCHECKBOX 0x00000003L
#define BS_RADIOBUTTON 0x00000004L
#define BS_3STATE 0x00000005L
#define BS_AUTO3STATE 0x00000006L
#define BS_GROUPBOX 0x00000007L
#define BS_USERBUTTON 0x00000008L
#define BS_AUTORADIOBUTTON 0x00000009L
// ... and so on
注意BS_GROUPBOX
(这是你得到不想要的样式)等于0x7
。您的控制权以该样式标志设置结束,因为您正在设置标志的组合,其值为0x7
。不幸的是,你不能只将OR
的标志放在一起,并得到你想要的结果。
取而代之,您必须使用BS_TYPEMASK
标志清除当前按钮样式,然后设置您想要的各个BS_Xxx
标志。对于正常的复选框,可能是BS_AUTOCHECKBOX
;对于三态复选框,即BS_AUTO3STATE
。
工作示例代码:
void ToggleCheckboxCtrl(HWND hwndCheckBox)
{
// Retrieve the control's current styles.
LONG_PTR styles = GetWindowLongPtr(hwndCheckBox, GWL_STYLE);
// Remove any button styles that may be set so they don't interfere
// (but maintain any general window styles that are also set).
styles &= ~BS_TYPEMASK;
// Just for example purposes, we're maintain our last state as a static var.
// In the real code, you probably have a better way of determining this!
static bool isRegularCheckBox = true;
if (isRegularCheckBox)
{
// If we're a regular checkbox, toggle us to a 3-state checkbox.
styles |= BS_AUTO3STATE;
}
else
{
// Otherwise, we want to go back to being a regular checkbox.
styles |= BS_AUTOCHECKBOX;
}
isSet = !isSet;
// Update the control's styles.
// (You'll also need to force a repaint to see your changes.)
SetWindowLongPtr(hwndCheckBox, GWL_STYLE, styles);
}
间谍++实用程序(与Visual Studio捆绑)可以找出切换窗口样式时什么错误不可缺少的小工具。运行你的应用程序,并使用Spy ++来定位窗口并枚举它的当前样式。然后更改样式,使用Spy ++转储新样式,并查看出了什么问题。