views:

1726

answers:

3

Hi there,

I have an MFC dialog in which there are two radio buttons. I have put them in a nice group, their IDCs are one after each other (RB_LEFT, RB_RIGHT).

I want to use DDX_Radio so I can access the buttons using an integer value so in the function DoDataExchange I call :

   DDX_Radio(pDX, RB_LEFT, mRBLeftRight);

where mRBLeftRight is a member variable of integer type. I also need to edit the buttons properties so I wanted to use a DDX_Control to map them on member variables mRBLeft and mRBRight (CButton):

   DDX_Control(pDX, RB_LEFT, mRBLeft);
   DDX_Control(pDX, RB_RIGHT, mRBRight);

now if I do the call to DDX_Control, whenever DoDataExchange is called, the application crashes because DDX_Control forces RB_LEFT to handle a message that DDX_Radio cannot handle. This part I understand.

I decided to not use DDX_Control (removed the calls in DoDataExchange) and just keep a pointer to my radio buttons (CButton*) in my classes. So in my OnInitDialog function, I do the following calls :

   mRBLeft= ((CButton*)GetDlgItem(RB_LEFT));
   mRBRight = ((CButton*)GetDlgItem(RB_RIGHT));

Now as long as I don't use mRBLeft it's going to be fine, but if I do, bam, crash on DoDataExchange. The thing that really puzzles me is if I change my left radio button using ((CButton*)GetDlgItem(RB_LEFT)->SetCheck(true) it's going to work. Sooo what's the difference ?

(I know it's a lot of hassle for little, but I just wanna understand the mechanics)

thanks!

JC

+1  A: 

There's an error in your premises. You can use DDX_Radio and DDX_Control for the same control, it would be pretty useless otherwise. Can you elaborate on

"now if I do the call to DDX_Control, whenever DoDataExchange is called, the application crashes because DDX_Control forces RB_LEFT to handle a message that DDX_Radio cannot handle. This part I understand."

because I think that this is already a symptom of the underlying problem.

Roel
I found the answer, if you care :)
JC
A: 

I found the answer here : http://www.flounder.com/getdlgitem.htm

There IS a problem with using DDX_Control and DDX_Radio at the same time :) This is a small hack to get around the problem.

Radio button variables

Another intrinsic problem, which represents some sort of strange philosophical viewpoint of Microsoft, is that you must not be allowed to create control variables for radio buttons. This makes no sense. They have some weird idea that the only way you will ever manipulate radio buttons is via an index. This is hopelessly inadequate. Therefore, you have to go through some serious contortions to get control variables for your radio buttons.

The first thing you have to do is go back and mark all radio buttons as having the WS_GROUP style. Only radio buttons with a WS_GROUP style can have a control variable. However, if you mark all of them with WS_GROUP, create the control variables, and then remove the WS_GROUP attribute, everything works just fine, thank you. Why we have to go through these extra steps makes no sense whatsoever, but like the derived classes problem, I've been complaining about this for years with no effect. My problem is that I keep forgetting to go back and undo all the WS_GROUP attributes, so the first time I run the program after this I find that all my radio buttons are one-button groups. Whoops. $#%! Fix, and recompile/relink.

JC
Hmm I still don't get it, this has always worked as expected for me. As mentioned below, you need to set the first control's style to WS_GROUP and then it just works. Ah well, at least you have your problem solved.
Roel
FYI, I have just stumbled upon this question and thought I'd let you know, I don't have this problem, and the standard advice from Goz is what I use. It might indicate a deeper problem for you.
Mark Ingram
@Mark, by a strange coincidence I ran across this today too. This answer is bad advice, it represents a misunderstanding of the workings of DDX_Radio. You open yourself to a lot of grief when you go contrary to what Microsoft expects. There was another underlying problem in the code that was never diagnosed, and with a workaround in place it never will be.
Mark Ransom
You guys are probably right. I don't have time to investigate this issue, but I marked goz's answer as the right answer.
JC
+3  A: 

TBH Its even easier than JC's post leads you to believe.

DDX_Control( pDX, IDC_RADIO3, m_r3 );
DDX_Control( pDX, IDC_RADIO4, m_r4 );

m_Val = 0;
DDX_Radio( pDX, IDC_RADIO3, m_Val );

You need to mark the FIRST radio button in the group with WS_GROUP (In this case IDC_RADIO3). You are now good to go and it will automatically select IDC_RADIO3).

Now to keep m_Val up to date it is probably worth putting a click handler on all the radio buttons in the group. Inside that function, simply, call UpdateData( TRUE ); m_Val will now point to the index of the radio button in the group.

Goz
I did mark the first radio button with `WS_GROUP` ...
JC
I did exactly this.. trust me it will crash if you use the m_r3.
JC
Strange ... to coin a phrase, "Works on my machine" ...
Goz