2009-07-22 3 views
8

У меня есть диалог MFC, в котором есть два переключателя. Я положил их в хорошую группу, их IDC один за другим (RB_LEFT, RB_RIGHT).Переключатели MFC - поведение DDX_Radio и DDX_Control

Я хочу использовать DDX_Radio таким образом я могу получить доступ к кнопкам, используя целочисленное значение, так в функции DoDataExchange я называю:

DDX_Radio(pDX, RB_LEFT, mRBLeftRight); 

где mRBLeftRight является переменным членом целого типа. Также нужно отредактировать пуговицы свойства, так что я хотел использовать DDX_Control чтобы отобразить их на переменные членов mRBLeft и mRBRight (CButton):

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

теперь, если я делаю вызов DDX_Control всякий раз, когда DoDataExchange называется, то сбои приложений, потому что DDX_Control заставляет RB_LEFT обрабатывать сообщение, которое не может обрабатывать DDX_Radio. Эта часть я понимаю.

Я решил не использовать DDX_Control (удалить вызовы в DoDataExchange) и просто держать указатель на мои переключатели (CButton *) в моих классах. Так что в моей OnInitDialog функции, я делаю следующие вызовы:

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

Теперь, пока я не использую mRBLeft это будет хорошо, но если я делаю, бам, авария на DoDataExchange. То, что меня действительно озадачивает, если я изменю свой левый переключатель, используя ((CButton*)GetDlgItem(RB_LEFT)->SetCheck(true) он будет работать. Ооо какая разница?

(я знаю, что это много хлопот для немного, но я просто хочу понять механику)

+0

Я где-то читал, что не должен хранить указатель, возвращенный из GetDlgItem, что, вероятно, правильно, возможно, это причина моей проблемы? – levesque

ответ

7

TBH Его даже легче, чем сообщение JC, заставляет вас поверить.

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

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

Вы должны отметить кнопку ПЕРВОЕ радио в группе с WS_GROUP (В этом случае IDC_RADIO3). Теперь вы можете пойти, и он автоматически выберет IDC_RADIO3).

Теперь, чтобы обновить m_Val, вероятно, стоит положить обработчик кликов на все переключатели в группе. Внутри этой функции просто вызовите UpdateData (TRUE); Теперь m_Val укажет на индекс переключателя в группе.

+0

Я пометил первый переключатель с помощью 'WS_GROUP' ... – levesque

+0

Я сделал именно это. Поверьте, он сработает, если вы используете m_r3. – levesque

+2

Странно ... подделать фразу «Работает на моей машине» ... – Goz

1

Там есть ошибка в вашем помещении. Вы можете использовать DDX_Radio и DDX_Control для одного и того же элемента управления, в противном случае это было бы бесполезно. Можете ли вы подробнее рассказать о

«теперь, если я вызываю DDX_Control, когда вызывается DoDataExchange, приложение вылетает из-за того, что DDX_Control заставляет RB_LEFT обрабатывать сообщение, которое DDX_Radio не может обрабатывать. Эта часть, которую я понимаю».

потому что я думаю, что это уже признак основной проблемы.

+0

Я нашел ответ, если вам интересно :) – levesque

3

Я нашел ответ здесь: http://www.flounder.com/getdlgitem.htm

Там проблема с использованием DDX_Control и DDX_Radio одновременно :) Это небольшой хак, чтобы обойти эту проблему.

Селективная кнопка Переменные

Другая внутренняя проблема, которая представляет какой-то странной философской точки зрения Microsoft, является то, что вы не должны быть разрешено создавать переменные управления для радио кнопок. Это не имеет никакого смысла. У них есть какая-то странная идея о том, что вы всегда будете манипулировать радиокнопками через индекс. Это безнадежно неадекватно.Поэтому вам нужно пойти через некоторые серьезные искажения до получить контрольные переменные для вашего радио кнопок.

Первое, что вам нужно сделать, это перевести назад и отметить все радиокнопки как , имеющие стиль WS_GROUP. Только переключатели с WS_GROUP в стиле могут иметь управляющую переменную. Тем не менее, если вы отметите все из них с WS_GROUP, создать элемент управления переменные, а затем удалить WS_GROUP атрибут, все работает просто отлично, спасибо. Почему мы должны до пройти эти дополнительные шаги, не делает никакого смысла , но, как и производная проблема , я жаловался на это об этом в течение многих лет без эффекта. Моя проблема заключается в том, что я забываю , чтобы вернуться назад и отменить все WS_GROUP атрибутов в, так что первый раз я бег программы после этого я считаю, что вся моя радио кнопки одна кнопки группы. Упс. $ #%! Fix, и перекомпиляция/релинк.

+1

Хм я все еще не понимаю, это всегда срабатывало, как и ожидалось для меня. Как уже упоминалось ниже, вам нужно установить стиль первого элемента управления WS_GROUP, а затем он просто работает. Хорошо, по крайней мере, проблема решена. – Roel

+1

FYI, я только что наткнулся на этот вопрос и подумал, что дам вам знать, у меня нет этой проблемы, и стандартный совет от Goz - это то, что я использую. Это может указывать на более глубокую проблему для вас. –

+0

@ Марк, странным совпадением, я тоже натолкнулся на это сегодня. Этот ответ является плохим советом, он представляет собой непонимание работы DDX_Radio. Вы открываете себе много горя, когда идете вопреки ожиданиям Microsoft. В коде, который никогда не был диагностирован, возникла еще одна основная проблема, и с обходным решением это никогда не будет. –