0
votes

I have a simple problem that is driving me slightly nuts. I have a dialog-based MFC app which has 3 radio buttons on it, each with a click handler doing different things.

The third button activates a separate modal dialog, which has an OnCancel handler. The OnCancel handler calls CheckRadioButton on the parent dialog, to try to set the check to the first button in the group (thus indicating that the Modal dialog is no longer up). This does indeed set the check correctly, but for some reason it also generates a call to the third radio button click handler, and so the modal dialog reappears. This happens repeatedly (about 7 times), until eventually the repetitive calls stop, the modal dialog disappears, and all is apparently normmal.

This first became apparent in a large desktop app that I am adding features to, but it also occurs in a simple minimal dialog-based app, which I put together to test things.

I've tried this all sorts of ways, including using CButton::SetCheck, and also having a control variable and using UpdateData(FALSE). All generate the same problem.

I'm probably doing something daft, but I can't see what it is!! I'm using Visual Studio 2013. Any help greatly appreciated.


// in parent dialog
void Ctest_radioDlg::OnBnClickedRadio3()
{
    TRACE(_T("Clicked 3"));
    CTestDlg testDlg;
    testDlg.m_pParent = this;
    testDlg.DoModal();
}

// in modal dialog
void CTestDlg::OnCancel()
{
    m_pParent->CheckRadioButton(IDC_RADIO1, IDC_RADIO3, IDC_RADIO1);
    CDialogEx::OnCancel();
}
2
You can simplify this, change OnBnClickedRadio3 to call if (IDCANCEL==testDlg.DoModal()) CheckRadioButton(...) This way CTestDlg is removed as suspect. You should perhaps show the message map, otherwise there shouldn't be any problem from what is shown here.Barmak Shemirani
Thanks for the suggestion. Unfortunately (and I didn't make this clear), the problem actually arose in a much larger and more complex program, in which the subsidiary dialog is non-modal. The code I posted is my attempt to narrow things down to produce the simplest example of the problem. In reality, I really do need to feed the information back from the (non-modal) dialog to its parent, indicating that the user has shut down the non-modal dialog, and the parent has to change its button state in response. I tried posting a message, but that was no better than calling the parent directly.Bill Heitler

2 Answers

1
votes

I would utilize MFC's DDX/DDV mechanism auto-handle the radio button behavior (otherwise, you end up having to do work-arounds for your own radio-button behavior).

Add a radio button control data member, m_iRadio (0 based radio button group enum). Then in your CheckRadioButton(), just set m_iRadio to the 0-based value instead of the control ID

enum {RADIO_OPTION1, RADIO_OPTOIN2, RADIO_OPTION3};

Ctest_radioDlg::CheckRadioButton(int eRadioOption)
{
  m_iRadio = eRadioOption;
  UpdateData(false);  // MFC magic occurs here
}
1
votes

If you want to check a radiobutton with id IDC_RADIO1. m_Radio is the controlvariable of radiobutton group.

m_Radio.GetParent()->CheckRadioButton(IDC_RADIO1, IDC_RADIO2, IDC_RADIO1);