Raymond Chen 2007年09月21日
BS_PUSHLIKE 按钮样式有什么用?
一个较少为人所知的按钮样式是BS_PUSHLIKE
。
它使得一个按钮(比如复选框、三态复选框或单选按钮)看起来和行为上像是一个推按钮。 按钮在未被按下或未被选中时看起来是凸起的,在被按下或选中时看起来是凹陷的。
换句话说,你给复选框或单选按钮添加这个样式,使其看起来像推按钮,尽管它会继续像复选框或单选按钮那样行为。
除了外观之外,其他复选框和单选按钮的行为都被保留了。每次点击自动复选框,它会在未选中和选中之间切换;只是不是隐藏和显示复选标记,而是弹出按钮和按下按钮。
类似地,自动单选按钮在你点击它时变为选中,并且在你选择组中的另一个单选按钮时变为未选中。唯一改变的是视觉效果。
让我们通过一个简单的示例程序来说明这一点。
首先,我们将使用传统的复选框和单选按钮。
1 DIALOG 64, 64, 100, 70
STYLE WS_CAPTION | WS_SYSMENU
CAPTION "Demo"
FONT 8, "MS Shell Dlg"
BEGIN
AUTORADIOBUTTON "Search &forward", 100, 4, 9,
75, 14, WS_GROUP | WS_TABSTOP
AUTORADIOBUTTON "Search &backward", 101, 4, 27,
75, 14
AUTOCHECKBOX "&Ignore case", 102, 4, 45,
75, 14, WS_TABSTOP
END
INT_PTR CALLBACK DlgProc(
HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg) {
case WM_INITDIALOG: return TRUE;
case WM_CLOSE: EndDialog(hdlg, 1); break;
}
return FALSE;
}
int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hinstPrev,
LPSTR lpCmdLine, int nShowCmd)
{
DialogBox(hinst, MAKEINTRESOURCE(1), 0, DlgProc);
return 0;
}
当你运行这个程序时,你会得到两个单选按钮和一个复选框,它们没有任何特别之处。
但是添加了BS_PUSHLIKE
样式……
1 DIALOG 64, 64, 100, 70
STYLE WS_CAPTION | WS_SYSMENU
CAPTION "Demo"
FONT 8, "MS Shell Dlg"
BEGIN
AUTORADIOBUTTON "Search &forward", 100, 4, 9,
75, 14, WS_GROUP | WS_TABSTOP | BS_PUSHLIKE
AUTORADIOBUTTON "Search &backward", 101, 4, 27,
75, 14, BS_PUSHLIKE
AUTOCHECKBOX "&Ignore case", 102, 4, 45,
75, 14, WS_TABSTOP | BS_PUSHLIKE
END
现在单选按钮和复选框看起来像推按钮。但是如果你点击它们,它们仍然像两个单选按钮和一个复选框那样行为。
如果你选择“搜索向前”,那么“搜索向后”会自动取消选择,反之亦然。每次你点击“忽略大小写”,它就会在按下和弹出之间切换。
然而,如果你启用了Windows XP视觉样式,视觉效果会有些混乱,因为当你悬停在按钮上时,主题引擎会以“悬停”的外观绘制按钮,这会导致它弹出,尽管按钮实际上是被按下的。你必须将鼠标从按钮上移开,才能看到它确实被按下了。
我个人认为这是一个bug。Windows Vista的情况只是稍微好一点;但仍然相当糟糕。
由于推按钮样式的按钮在视觉上与单选按钮和复选框重复,同时呈现了欺骗性的外观,所以它们并不常用。因为它们看起来像按下按钮,用户自然会期望它们像按下按钮那样的行为,然后并不是这样,事情就变得混乱了。
我能想到的唯一一个按压式按钮样式实际上符合用户期望的情况是在工具栏中,那里有一个长期使用按压式按钮代替单选按钮和复选框的惯例。(幸运的是,工具栏管理它们自己的按钮,并且不会遭受我上面讨论的混乱悬停外观行为的影响。)