2011-09-03 110 views
0

我想使用原始的winapi32来检查按钮样式,无论是复选框按钮还是按钮。GetWindowlong检查按钮样式

bool isPushBtn(HWND hBtn, DWORD dwStyle) 
{ 
    return (0!=dwStyle | GetWindowLong(hBtn,GWL_STYLE)); 
} 

但是,这总是返回false。你知道一个方法来检查这个吗?谢谢。

+0

你通过'dwStyle'传递了什么? –

+1

谢谢,我使用BS_PUSHBUTTON。 –

+1

BS_PUSHBUTTON等于零 – shf301

回答

5

为了了解按钮样式是如何工作的,我们需要看看在风格常数使用的值:

#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 
#define BS_PUSHBOX   0x0000000AL 
#define BS_OWNERDRAW  0x0000000BL 
#define BS_TYPEMASK   0x0000000FL 
#define BS_LEFTTEXT   0x00000020L 

#define BS_TEXT    0x00000000L 
#define BS_ICON    0x00000040L 
#define BS_BITMAP   0x00000080L 
#define BS_LEFT    0x00000100L 
#define BS_RIGHT   0x00000200L 
#define BS_CENTER   0x00000300L 
#define BS_TOP    0x00000400L 
#define BS_BOTTOM   0x00000800L 
#define BS_VCENTER   0x00000C00L 
#define BS_PUSHLIKE   0x00001000L 
#define BS_MULTILINE  0x00002000L 
#define BS_NOTIFY   0x00004000L 
#define BS_FLAT    0x00008000L 
#define BS_RIGHTBUTTON  BS_LEFTTEXT 

另一个重要参考是Button Styles topic at MSDN。但是,该文档没有解释的是BS_PUSHBUTTONBS_OWNERDRAW标志,类型标志是互斥的。其他标志可以与其中一个类型标志组合使用。这可以从值的位模式推断出来。

的文档BS_TYPEMASK状态:

的Windows 2000:一种复合样式位,从使用OR操作上BS_ *样式位结果。它可以用来屏蔽来自给定位掩码的有效BS_ *位。请注意,这是过时的并且不能正确包含所有有效的样式。因此,你不应该使用这种风格。

但是我认为这是误导性的,并认可ybungalobill在his answer中所说的内容。遵循这个建议不会有什么伤害。

换句话说,你应该掩盖风格与BS_TYPEMASK,然后测试一个特定的按钮类型。

bool isButtonType(HWND hBtn, DWORD dwType) 
{ 
    assert(dwType<=BS_TYPEMASK); 
    return (GetWindowLong(hBtn, GWL_STYLE) & BS_TYPEMASK) == dwType; 
} 
+0

祝贺你,来自&和|的分配性,你的代码只是一种混淆的方式来编写'(GetWindowLong(hBtn,GWL_STYLE)&0xF)!= 0', – ybungalobill

+1

@ybungalobill我不明白你的意思,我说,我的专长不是C++ –

+0

这不是C++,它是数学。 (x&y1)!= 0)&&!((x&y2)!= 0)'iff'(x&y1)== 0 &&(x&y2)== 0' iff' (y1 | y2))== 0'。将上面的'yn'应用到BS_ *中的每一个,并且您的检查等同于'(style&(BS_3STATE | BS_AUTO3STATE | BS_GROUPBOX | ...))== 0'。但是所有这些常量的位或者等于0xf,所以你检查的实际上是'(style&0xf)== 0'(是的,对不起,我的意思是我在以前的评论中是平等的)。 – ybungalobill

2

应该

return (dwStyle == (GetWindowLongPtr(hBtn, GWL_STYLE) & dwStyle)); 
+4

谢谢,我传递了值为0的dwStyle BS_PUSHBUTTON,因此当GetWindowLongPtr失败(返回0)时,上面的语句变为true,这实际上并不帮助我检查给定的按钮是push还是checkbox类型。 –

4

它应该是:

return (GetWindowLong(hBtn,GWL_STYLE) & BS_TYPEMASK) == dwStyle; 
+2

“BS_TYPEMASK”的文档声明:“请注意,这是过时的并且不能正确包含所有有效的样式,因此,您不应该使用此样式。” –

+0

@大卫:是的。所以呢?这是你可以做的最好的一般事情,它适用于低于Vista的任何事情。 – ybungalobill

+0

@大卫:我以为它只包含了互斥的风格...... –