Solved

Determine CButton type by button style

Posted on 2003-11-06
6
918 Views
Last Modified: 2013-11-20
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" );
  }
}



and:

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


0
Comment
Question by:hirnsieb
  • 3
  • 2
6 Comments
 
LVL 48

Expert Comment

by:AlexFM
ID: 9693523
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


0
 
LVL 1

Author Comment

by:hirnsieb
ID: 9693586
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.
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 9693651
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.
0
U.S. Department of Agriculture and Acronis Access

With the new era of mobile computing, smartphones and tablets, wireless communications and cloud services, the USDA sought to take advantage of a mobilized workforce and the blurring lines between personal and corporate computing resources.

 
LVL 1

Author Comment

by:hirnsieb
ID: 9693702
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***

0
 
LVL 1

Author Comment

by:hirnsieb
ID: 9694063
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?
0
 
LVL 13

Accepted Solution

by:
SteH earned 125 total points
ID: 9694857
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) {
case BS_AUTOCHECKBOX:
case BS_CHECKBOX:
    TRACE ( "***CHECKBOX***\n" );
     break;
case BS_AUTORADIOBUTTON:
case BS_RADIOBUTTON:
    TRACE ( "***RADIOBUTTON***\n" );
     break;
}
0

Featured Post

ScreenConnect 6.0 Free Trial

Check out the updates in one game-changing release, ScreenConnect 6.0, based on partner feedback. New features include a redesigned UI that improves session organization and overall user experience. See the enhancements for yourself!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Generic progress indicator 6 117
How to determine file rename from EventLog ? 2 49
Thin secure Windows 10 5 98
Way to decrease size of apk file 9 70
Here is how to use MFC's automatic Radio Button handling in your dialog boxes and forms.  Beginner programmers usually start with a OnClick handler for each radio button and that's just not the right way to go.  MFC has a very cool system for handli…
Introduction: Database storage, where is the exe actually on the disc? Playing a game selected randomly (how to generate random numbers).  Error trapping with try..catch to help the code run even if something goes wrong. Continuing from the seve…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …

803 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question