Solved

Determine CButton type by button style

Posted on 2003-11-06
6
898 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
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 
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

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

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 …
Introduction: Displaying information on the statusbar.   Continuing from the third article about sudoku.   Open the project in visual studio. Status bar – let’s display the timestamp there.  We need to get the timestamp from the document s…
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.
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…

706 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

16 Experts available now in Live!

Get 1:1 Help Now