Go Premium for a chance to win a PS4. Enter to Win

  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 994
  • Last Modified:

Determine CButton type by button style

I have a dialog with several controls on it. I want to fill these controls by using a mapping algorithm that maps the control ID to some data ID. At that point of time I do not know what kind (type) of data I need to request from my database (no sql stuff here). So I want to find out what kind of control I got, i.e. if the control for IDC_CHECK1 is a checkbox I know that the data for it must be of boolean type. If it's a combobox it must me of string type, etc.

So that's what I do: I call GetClassName (HWND) for each control that I have. If the control is a button, a checkbox or a radiobutton this function returns "BUTTON". So I cast the CWnd* pointer I got from GetDlgItem() to CButton*

Now I check the button style for button style bits (GetButtonStyle); but here's the problem. I cannot determine exactly what kind of control I have, because a frame (that thing you can draw around your controls) appears to be a button too! And the style bits seem to be confusing too. Do you know of any way to determine exactly what kind of CButton I have?

Here's my code:

//  get the control
CWnd* pControl = GetDlgItem ( controlID );

// get its class name
char className [255];
memset ( className, 0, 255 );
GetClassName ( pControl->m_hWnd, className, 255 );

if ( strnicmp (className,"BUTTON",6)==0 ) {
  CButton* pButton = (CButton*)pControl;
  UINT style = pButton->GetButtonStyle();

  if ( isBitSet(style, BS_CHECKBOX) ) {                  
    TRACE ( "***CHECKBOX***\n" );
  else if ( isBitSet(style, BS_RADIOBUTTON) || isBitSet(style,BS_AUTORADIOBUTTON) ) {
   TRACE ( "***RADIO***\n" );
  else {
   TRACE ( "***BUTTON***\n" );


bool isBitSet (UINT a, UINT b) {
      UINT res = a & b;
      return (res!=0);

  • 3
  • 2
1 Solution
This is result I get finding various controls using Spy++.

Control            Class name   Style

Button             Button          5001000
Radion button  Button          5000009
Checkbox        Button          5001003
Frame             Static            5000007

hirnsiebAuthor Commented:
I thinkit's not a good idea to compare complete style values, because they might change, i.e. if you one checkbox might have BS_3STATE set whereas another might have BS_AUTO3STATE set. One button might have a client edge, the other doesn't, etc.

It should be possible to check the button style, but I don't know how to do this correctly.
I don't suggest you to compare complete button styles.
Algorithm should be:

if class name is "Button":

- if one of BS_AUTOCHECKBOX, BS_CHECKBOX  is 1, this is check box;
- else if one of BS_AUTORADIOBUTTON, BS_RADIOBUTTON  is 1, this is radio button;
- else this is push button.

Frame is not a problem because it has Static class.
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

hirnsiebAuthor Commented:
This is what I thought, too. but...

If I do it like

if (  isBitSet(style, BS_AUTOCHECKBOX) ||
      isBitSet(style, BS_CHECKBOX) ) {                  
     TRACE ( "***CHECKBOX***\n" );

I get "CHECKBOX" for a checkbox, a radiobutton AND a frame!

this is some output: (first line is a checkbox, then a radio, then a frame)
classname=Button, style=1342275587   ***CHECKBOX***
classname=Button, style=1476526089   ***CHECKBOX***
classname=Button, style=1342177287   ***CHECKBOX***

As you can see GetClassName returns "Button" for the frame as well!!! The check for BS_AUTOCHECKBOX || BS_CHECKBOX returns TRUE for all three controls, which is weird.

You see, this is my problem! :-)

If I use GetButtonStyle to get the value for "style" I get: (same order as above)
classname=Button, style=3   ***CHECKBOX***
classname=Button, style=9   ***CHECKBOX***
classname=Button, style=7   ***CHECKBOX***

hirnsiebAuthor Commented:
I just checked the bits of the button styles:

Style                       value                         bits
BS_AUTOCHECKBOX=3                        0011
BS_AUTORADIOBUTTON=9                  1001
BS_AUTO3STATE=6                        0110
BS_CHECKBOX=2                              0010
BS_DEFPUSHBUTTON=1                        0001
BS_GROUPBOX=7                              0111
BS_PUSHBUTTON=0                        0000
BS_RADIOBUTTON=4                        0100
BS_3STATE=5                              0101

I posted the sytle values of my three example controls above. So they have the following bits set:

classname=Button, 0011            //      checkbox
classname=Button, 1001            //      radio
classname=Button, 0111            //      frame

(remember: the first control is actually a checkbox, the second a radio button, the third a frame; all pointers to these controls where received by a call to GetDlgItem() without knowing their exact type; a call to GetClassName(HWND) returned "Button" as class name for all three controls)

The BS_RADIOBUTTON style has bit 4 set (0100). So my radiobutton control should have that bit too, but actually it's 9 (1001). what's going wrong here?

I've read that a call to GetDlgItem() returns a pointer of type CTempWnd*, so the cast to CButton* could be invalid and a calling GetButtonStyle() could return some bogus values? Am I right here?
Looking at the constants in the above example the bits are not disjunct. That means you can't compare single bits but you should comapre the style to a number like in a switch statement:

switch (iStyle) {
    TRACE ( "***CHECKBOX***\n" );
    TRACE ( "***RADIOBUTTON***\n" );

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now