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

MFC Radio button handler called multiple times.

I am using 2 radio buttons.   BUTTON1-Group property set.
I have ON_BN_CLICKED handlers say BUTTON1_Handler(), BUTTON2_Handler().

After clcking on any of the two radio buttons, I display a message box with MB_YESNO style and get confirmation from the user. If user chooses "NO", I have to revert the selection.

If I try to change the state of BUTTON1 using "SetCheck()" inside BUTTON1_Handler(), then BUTTON1_handler() is called multiple times and the messge box is popped up again and again.

Please help me how to change the radio button state inside its own handler...


BUTTON1_Handler()
{
       if( IDNO == AfxMessageBox("Confirm ?",MB_YESNO) )
       {
           m_Button1.SetCheck(0);
           m_Button2.SetCheck(1);
       }
}
 
BUTTON2_Handler()
{
       if( IDNO == AfxMessageBox("Confirm ?",MB_YESNO) )
       {
             m_Button1.SetCheck(1);
             m_Button2.SetCheck(0);
        }
}

Open in new window

0
arun123prasad
Asked:
arun123prasad
  • 2
2 Solutions
 
DanRollinsCommented:
Here is the MFC way to handle a group of radio buttons automatically -- you should never have to do SetCheck()

In the dialog editor, make sure the tab-order of the radio buttons are sequential.
Then in only the first radio button, set the Group checkbox in its properties.
Then right-click that first button and press Ctrl+W (class wizard)
In the Variables page, only the first radio button is listed. Give it a variable name, say,
    m_nRadioGrpSel
This will add a DDX_Radio(...) to the DoDataExchange for the dlg.

Now before you open the dialog, set the member variable to indicate which radio button is set (0...n-1). For instance:

CMyDialog dlg;
dlg.m_nRadioGrpSel= 0; // pre-select the first Rb
if ( IDOK == dlg.DoModal() ) {
    if ( dlg.m_nRadioGrpSel==2 ) {
        // the third Rb was selected
    }
}

If you set...
dlg.m_nRadioGrpSel= -1; // or other invalid value

then none of the radio buttons will be selected when the user first sees the dialog box. Furthermore, the user will not be able to use the Tab key to get to any of the radio buttons in the group (so he can't accidentally select one except by using the mouse).
So we have a way to determine not just the status of individual buttons but the group as a whole, and we can set the desired option on screen by just putting a number (0,1,2...) into a member variable and then using
UpdateData(FALSE)

And conversely, we can set the variable to match the current selection by using:
UpdateData( TRUE )
I think the comments in the attached code should cover it.

void CD55Dlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CD55Dlg)
	DDX_Radio(pDX, IDC_RADIO1, m_nRadioGrpSel);  // <<--- Note
	//}}AFX_DATA_MAP
}
 
 
BEGIN_MESSAGE_MAP(CD55Dlg, CDialog)
...
	ON_BN_CLICKED(IDC_RADIO1, OnRadioGrpClick) // << note: same fn
	ON_BN_CLICKED(IDC_RADIO2, OnRadioGrpClick)
	ON_BN_CLICKED(IDC_RADIO3, OnRadioGrpClick)
...
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()
 
void CD55Dlg::OnRadioGrpClick() 
{
	int nCurOption= m_nRadioGrpSel;
	UpdateData(TRUE);  // collect the (possibly new) value
 
	if ( nCurOption != m_nRadioGrpSel ) { // user requested to change the settings
	int nResp= AfxMessageBox("Confirm ?",MB_YESNO);
		 if ( nResp == IDNO ) {
			m_nRadioGrpSel= nCurOption;  // revert to earlier value
			UpdateData( FALSE );         
		 }
	}
}

Open in new window

0
 
AndyAinscowCommented:
You need a boolean flag to prevent the messagebox when you set the radio programatically.
eg (pseudo code).

bool m_bDisplay = false;

Handler1()
{
  if (m_bDisplay)
    return;
m_bDisplay = true;
DisplayWarning;
SetCheck;
m_bDisplay = false;
}

and the same for handler2

0
 
DanRollinsCommented:
Next time, I shall strive to work harder and provide more information, in hopes that I can earn an A.
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

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