3状态复选框Win32运行时

kva*_*nck 2 c++ winapi

当我在运行时将对象窗口上的BS_AUTO3STATE样式添加到默认样式的复选框时;

this->Style |= BS_AUTO3STATE; // wrapper of Get/SetWindowLongPtr, ignore the specifics
Run Code Online (Sandbox Code Playgroud)

..它变成了一个组合框,而不是一个三态复选框.我究竟做错了什么?

我有错误的控制风格吗?

Cod*_*ray 7

这个问题是由于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
Run Code Online (Sandbox Code Playgroud)

请注意BS_GROUPBOX(这是你得到和不想要的风格)等于0x7.您的控件最终会以该样式标志集结束,因为您正在设置标记的组合,其值为0x7.不幸的是,你不能只OR把旗子放在一起,得到你想要的结果.

相反,您必须使用BS_TYPEMASK标志清除当前按钮样式,然后设置BS_Xxx您想要的单个标志.对于普通复选框,这可能是BS_AUTOCHECKBOX; 对于3状态复选框,即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);
}
Run Code Online (Sandbox Code Playgroud)

Spy ++实用程序(与Visual Studio捆绑在一起)是一个不可或缺的小工具,用于确定切换窗口样式时出现的问题.运行您的应用程序,并使用Spy ++找到窗口并枚举其当前样式.然后更改样式,使用Spy ++转储新样式,看看出了什么问题.