Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Ch-11.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
1.26 Mб
Скачать

Работа с дочерними элементами управления окна диалога

В главе 8 было показано, что большинство дочерних окон элементов управления посылают своему родительскому окну сообщения WM_COMMAND. (Исключение составляют полосы прокрутки.) Кроме этого было показано, что родительское окно может изменять состояние своих дочерних окон элементов управления (например, включать или выключать переключатели или флажки), посылая дочерним окнам управления сообщения. Аналогичным образом можно изменять состояние дочерних окон управления в процедуре диалога. Например, при наличии нескольких групп переключателей с помощью сообщений можно включать и выключать переключатели в каждой группе. Кроме этого для работы с окнами управления в окнах диалога Windows обеспечивает нас еще несколькими возможностями. Рассмотрим один из способов взаимодействия процедуры диалога и дочерних окон управления.

Шаблон окна диалога программы ABOUT2, представленной на рис. 11.3, находится в файле описания ресурсов ABOUT2.RC. Элемент управления GROUPBOX — это просто рамка с заголовком (Color или Figure), окружающая каждую из двух групп переключателей. Восемь переключателей первой группы, как и два переключателя второй, являются взаимоисключающими.

При щелчке мышью на одном из переключателей (или при нажатии клавиши <Spacebar>, когда переключатель имеет фокус ввода) дочернее окно посылает своему родительскому окну сообщение WM_COMMAND, в котором младшее слово параметра wParam равно идентификатору окна элемента управления. Старшим словом параметра wParam является код опознавания, а значением параметра lParam — описатель окна управления. Для переключателя код уведомления равен либо BN_CLICKED, либо 0. Затем процедура окна диалога внутри Windows передает это сообщение WM_COMMAND в процедуру диалога программы ABOUT2.C. Если для одного из переключателей процедура диалога получает сообщение WM_COMMAND, она устанавливает контрольную метку на этом переключателе и снимает контрольные метки с остальных переключателей данной группы.

В главе 8 было показано, что для включения и выключения переключателя необходимо, чтобы дочернему окну управления было отправлено сообщение BM_SETCHECK. Поэтому для установки переключателя используется следующий оператор:

SendMessage (hwndCtrl, BM_SETCHECK, 1, 0) ;

А для снятия выключения, такой:

SendMessage (hwndCtrl, BM_SETCHECK, 0, 0) ;

Параметр hwndCtrl является описателем дочернего окна элемента управления.

Но этот способ приводит к небольшой проблеме, поскольку в процедуре окна диалога неизвестны описатели всех окон-переключателей. Известен только тот идентификатор переключателя, от которого приходит сообщение. К счастью, в Windows имеется функция для получения описателя окна элемента управления окна диалога, в которой используются описатель окна диалога и идентификатор элемента управления:

hwndCtrl = GetDlgItem (hDlg, id) ;

(Кроме этого, с помощью функции GetWindowLong можно получить значение идентификатора окна управления, зная описатель этого окна:

id = GetWindowLong(hwndCtrl, GWL_ID);

но это выражение используется редко.)

Обратите внимание, что в представленном на рис. 11.3 заголовочном файле ABOUT2.Н, значения идентификаторов для восьми цветов заданы последовательно от IDD_BLACK до IDD_WHITE. Такая упорядоченность помогает обрабатывать сообщения WM_COMMAND от переключателей. Для включения и выключения переключателей в процедуре окна диалога можно использовать примерно такой код:

static int iColor ;

[другие строки программы]

case WM_COMMAND :

switch (LOWORD(wParam))

{

[другие строки программы]

case IDD_BLACK :

case IDD_RED :

case IDD_GREEN :

case IDD_YELLOW :

case IDD_BLUE :

case IDD_MAGENTA :

case IDD_CYAN :

case IDD_WHITE :

iColor = LOWORD (wParam) ;

for (i = IDD_BLACK; i <= IDD_WHITE; i++)

SendMessage (GetDlgItem(hDlg, i),

BM_SETCHECK, i == LOWORD(wParam), 0) ;

return TRUE ;

[другие строки программы]

Такой подход работает вполне удовлетворительно. В iColor сохраняется новое значение цвета, а также запускается цикл по идентификаторам всех восьми цветов. Для каждого переключателя получают описатель окна, и каждому описателю с помощью функции SendMessage посылается сообщение BM_SETCHECK. Значение wParam этого сообщения устанавливается в 1 для того переключателя, который стал источником сообщения WM_COMMAND, отправленного оконной процедуре окна диалога.

Первым усовершенствованием является специальная функция SendDlgItemMessage :

SendDlgItemMessage (hDlg, id, iMsg, wParam, lParam) ;

Эта функция эквивалентна следующей:

SendMessage (GetDlgItem(hDlg, id), id, wParam, lParam) ;

Теперь цикл будет выглядеть так:

for(i = IDD_BLACK; i <= IDD_WHITE; i++)

SendDlgItemMessage (hDlg, i, BM_SETCHECK, i == LOWORD(wParam), 0) ;

Это несколько лучше. Но реальное улучшение появляется при использовании функции CheckRadioButton:

CheckRadioButton (hDlg, idFirst, idLast, idCheck) ;

Эта функция снимает контрольные метки со всех переключателей с идентификаторами от idFirst до idLast, за исключением переключателя с идентификатором idCheck, который, наоборот, включается. Идентификаторы должны быть заданы последовательно. Теперь, используя эту функцию, можно избавиться от целого цикла:

CheckRadioButton (hDlg, IDD_BLACK, IDD_WHITE, LOWORD(wParam)) ;

Именно так сделано в процедуре окна диалога программы ABOUT2.

Похожая функция имеется и для работы с флажками. Если в окне диалога создается элемент управления CHECKBOX, то снять или установить контрольную метку можно с помощью следующей функции:

CheckDlgButton (hDlg, idCheckbox, iCheck) ;

Если iCheck устанавливается в 1, флажок включается, если в 0 – выключается. Чтобы получить состояние флажка в окне диалога, можно использовать такую функцию:

iCheck = IsDlgButtonChecked (hDlg, idCheckbox) ;

Вы можете либо сохранить текущее состояние флажка в статической переменной внутри диалоговой процедуры, либо использовать такую конструкцию про обработке сообщения WM_COMMAND:

CheckDlgButton (hDlg, idCheckbox,

!IsDlgButtonChecked(hDlg, idCheckbox)) ;

Если элемент управления определен с флагом BS_AUTOCHECKBOX, то нет необходимости обрабатывать сообщение WM_COMMAND. Текущее состояние кнопки перед закрытием окна диалога можно получить просто с помощью функции IsDlgButtonChecked.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]