Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Visual C++/MFC/WTL > Действия в зависимости от состояния радиокнопки


Автор: Hawkmoth 24.5.2010, 14:02
Такой нубский вопрос. В диалоге есть две радиокнопки, Radio1 и Radio2. После выбора одной из них пользователь жмет на кнопку "Ок", и должно выполняться действие, соответствующее выбранной радиобаттон. Для простоты, пусть вылазят сообщения "Нажата радиокнопка 1" и "Нажата радиокнопка 2", соответственно.
Ход моей мысли такой: создаем собственно диалог, добавляем 2 радиокнопки -> для первой ставим галочку на "Group" -> присваиваем член-переменную m_Radio. В OnInitDialog() прописываю

Код
 m_Radio=0      // (программно выделяется первая кнопка)
UpdateData(FALSE)   // (прорисовка этого выделения)

return TRUE;


Затем в обработчике событий при нажатии на кнопку "Ок" прописываю

Код


void CFdormDlg::OnButtonOk() 
{
    // TODO: Add your control notification handler code here
    switch (m_Radio) {
    case 0: {MessageBox("Нажата радиокнопка 1"); break; }
    case 1: {MessageBox("Нажата радиокнопка 2"); break; }
    default: {MessageBox("Ничего не нажато"); break; }
    }
}


И теперь при тестировании получившегося приложения независимо от положения кнопок, выдается сообщение "Нажата радиокнопка 1". Как поправить?

Автор: BorisVorontsov 24.5.2010, 16:47
CButton::GetState?

Автор: Earnest 24.5.2010, 17:38
Если m_Radio - это переменная, связанная с радиокнопками, и в DoDataExchange есть соответствующее предложение DDX_Radio и кнопки правильно расположены (подряд, на второй кнопке нет WS_GROUP) и т.д. - то добавть перед swith'ем UpdateData (TRUE).

Добавлено через 1 минуту и 35 секунд
Кстати, в OnInitDialog не нужно вызывать UpdateData (FALSE) - это будет уже второй раз. Достаточно вызвать базовый метод OnInitDialog, а перед ним (или в конструкторе) сделать необходимые присваивания.

Автор: Hawkmoth 24.5.2010, 20:32
Цитата
то добавть перед swith'ем UpdateData (TRUE)




Earnest, спасибо! Именно этого, по-видимому, и не хватало smile 

Цитата

CButton::GetState?


BorisVorontsov, возможно, более логичный вариант... Я еще деревянный, и синтаксис с ходу мне плохо дается... Что-то вроде этого:
Код


    if ( [первая_кнопка].GetState()&0x0003)
    {  //блок действий  ;  }
        else if ( [вторая_кнопка].GetState()&0x003)
        {  //блок действий }
            else
            {...;}
 ?

Или совсем вру?

Автор: Earnest 25.5.2010, 07:36
Можно и так, только тогда удобнее через диалог спрашивать: IsDlgButtonChecked (IDC_MYBUTTON) - чтобы каждую кнопку не извлекать.

Автор: Albor 26.5.2010, 12:00
Код

int GetCheckedRadioButton(
   int nIDFirstButton,
   int nIDLastButton 
);

Это метод CWnd. Возвращает ID выбранной радиокнопки в группе от nIDFirstButton до nIDLastButton.
Использовать можно примерно так:
Код

int ID_BUTTON = GetCheckedRadioButton(ID_RADIO1,ID_RADIO5);
switch (ID_BUTTON )
{
   case ID_RADIO1:
     // что-то делаем
   break;
   case ID_RADIO2:
     // что-то делаем
    break;
//...............и т.д.........................
}


Добавлено через 4 минуты и 54 секунды
Заодно - установить радиокнопку:
Код

void CheckRadioButton(
   int nIDFirstButton,
   int nIDLastButton,
   int nIDCheckButton // устанавливаемая кнопка
);


Автор: Hawkmoth 26.5.2010, 19:22
Спасибо, с этим вопросом я более-менее разобрался)).  Тогда еще вопрос вдогонку: как изначально неактивную группу радиокнопок (у каждой в свойствах проставлено "Disabled" сделать активной программно? Т. е. есть, допустим, диалог с группой из трех "серых" радиокнопок и кнопка, при нажатии на которую эти контролы активизируются. Конструкция

Код

void CPage_1::OnButton1()
{       
        m_Radio1.EnableWindow(TRUE);


Не работает, ругается на
 left of '.EnableWindow' must have class/struct/union type

(m_Radio - переменная, присвоенная через CW первой радиокнопке в группе).

Автор: Hawkmoth 26.5.2010, 19:45
Так, в своём частном случае разобрался. Вот в таком виде желаемый эффект достигнут:

void CPage_1::OnButton1()
{       
        GetDlgItem(IDC_RADIO1)->EnableWindow(TRUE);
        GetDlgItem(IDC_RADIO2)->EnableWindow(TRUE);

}

А если у меня не две кнопки в радиогруппе, а 1000?

Автор: Albor 26.5.2010, 23:05
Цитата(Hawkmoth @  26.5.2010,  19:45 Найти цитируемый пост)
А если у меня не две кнопки в радиогруппе, а 1000? 

Примерно так:
Код

CWnd * pFirstCtrl = GetDlgItem(IDC_RADIO1);
CWnd * pLastCtrl = GetDlgItem(IDC_RADIO1000);
BOOL b(FALSE);
CWnd * pNextWnd=pFirstCtrl;
while(pNextWnd)
{
     pNextWnd->EnableWindow(TRUE);
     if(b)break;
     pNextWnd=pNextWnd->GetWindow(GW_HWNDNEXT);
     b=(pNextWnd==pLastCtrl);
}

Данный код переберёт все окна от IDC_RADIO1 до IDC_RADIO1000 и выполнит над ними операцию EnableWindow. Необязательно, чтобы все окна были радиокнопками.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)