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 ++轉儲新樣式,並查看出了什麼問題。