Solved

Determine CButton type by button style

Posted on 2003-11-06
6
909 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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Expand LInux Boot partition remotly 3 86
CRON statement to run every 3 minutes except on Monday morning 12am to 2am 7 89
Window placement 17 77
Making an alias 7 82
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: Load and Save to file, Document-View interaction inside the SDI. Continuing from the second article about sudoku.   Open the project in visual studio. From the class view select CSudokuDoc and double click to open the header …
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.
Many functions in Excel can make decisions. The most simple of these is the IF function: it returns a value depending on whether a condition you describe is true or false. Once you get the hang of using the IF function, you will find it easier to us…

863 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

Need Help in Real-Time?

Connect with top rated Experts

24 Experts available now in Live!

Get 1:1 Help Now