<<
>>

Диалоговая процедура

В процессе работы с окном диалога пользователь выполняет некоторые действия, о которых с помощью сообщений становится известно приложению. В приложе- нии для каждого окна диалога должна существовать своя процедура, предназна- ченная для обработки сообщений этого окна.
Эта процедура называется диалоговой процедурой. Даже самое примитивное окно диалога содержит элемент, сообщение от которого поступает в диалоговую процедуру. Обычно это кнопка ОК или Cancel. На языках C/C++ соответствующая диалоговая процедура выглядит так, как по- казано в листинге 16.12. Листинг 16.12. Диалоговая процедура на языках C/C++ BOOL CALLBACK DiаlоgРrос (НWND hdwпd, UINT message, WPARAM wParam, LPARAM IParam) { swi tch(message) { ■ ' case WМ_INIТDIАLОG: return 1; case WМ_СОММАND: switch (LOWORD (wParam)) { case IDOK: //или IDCANCEL ЕпdDiаlоg(hdwпd, 0); return 1; } . } return 0; } В приложении рrдlб.4.asm, частично представленном в листинге 16.13, имеется фрагмент (строки 523-549), являющийся эквивалентом программы из листинга 16.12 на языке ассемблера.
Это процедура AboutDialog, поддерживающая работу окна диалога AboutBox, описанного в файле ресурсов (см. листинг 16.9). Заметьте, что если оконная процедура самостоятельно обрабатывает сообщение, то она долж- на возвратить 1 (return 1), если нет, то 0 (return 0). Листинг 16.13. Фрагменты приложения рrg16_4.аsm ;рrgl6_4.аsm ’.Пример приложения для Win32 с использованием меню, ;окон диалогов, решением проблемы перерисовки содержимого окна ; и демонстрацией некоторых принципов работы с графикой ;Внимание!!! Координаты вводить из четырех знаков с ведущими нулями: ;например, для ввода числа 12 вводить 0012, для 123 вводить 0123 и т.
д. .486 locals; разрешает применение локальных меток (с префиксом 00) в программе .model flat, SТDСАLL ;модель памяти flat, ;SТDСАLL - передача параметров в стиле С (справа налево), ;вызываемая процедура чистит за собой стек ■ include wiлdоwА.iпс ;включаемый файл с описаниями базовых структур ;и констант Win32 include рrgl6_4.iпс ;включаемый файл с определением имен ;пунктов меню и окна диалога ;Объявление внешними используемых в данной программе .-функций Win32 (ASCII): ехtrп GеtМоdulеНапdlеА:РRОС см. исходный текст программы ехtrп GеtDlgltеmТехtА:РRОС .-объявление оконной и диалоговых функций объектами, ;видимыми за пределами данного кода

Xstart dd 0, 0 Xend dd 0, 0 Ystart dd 0, 0 ' Yend dd о, о hwпd dd О hlnst ■ dd 0 , mеmdс dd о : ! ! (это глобальная переменная mахХ dd 0 ; !! !это глобальная переменная mахY dd 0 ; !!!это глобальная переменная ;lрVегsiопIпfогmаtiоп ОSVЕRSIОNINFО > > МesWindowLen= ;звуковые файлы рlауFilеСrеаtе рlауFilеРаiлt playFileDestroy db ;имена ресурсов 1рmелu db lрdlgl db 1рdlg2 db 1рdlgЗ db ;переменные для eedx dd eecx dd template МеsМsдВох .описание макрокоманд include show eax.inc Листинг 16.13 (продолжение) sim4 tо_ЕАХbin macro sim4:rеq start proc near :точка входа в программу: ;начало стартового кода ... ;конец стартового кода WiпМаiп/ определить класс окна АТОМ RеgistеrСlаssЕх(СОNSТ WNDСLАSSЕХ ; *'LрWпdСlаssЕх) , где *lрWпdСlаssЕх - адрес структуры WпdСlаssЕх ; ... call RegisterClassExA test ах, ах /проверить на успех регистрации класса окна jz епd__сусl_msg; неудача /создаем окно: ;...

call СrеаtеWiпdоwЕхА mоv hwпd, eax ; hwпd - дескриптор окна /показать окно: ;... call ShowWindow /перерисовываем содержимое окна ;... call UрdаtеWiпdоw /запускаем цикл сообщений: cycljnsg: ;..., call GetMessageA сmр ах, 0 jе епd_сусl_msg /трансляция ввода с клавиатуры ; .. . - call TranslateMessage /отправляем сообщение оконной процедуре ;... call DisраtсhМеssаgеА jmр сусl msg ;выход из приложения call ЕхitРrосеss start епdр ; ................ -. . . . .WlПdОWРrОС:----- :---------- :---------- :--------------------- WiпdоwРrос рrос аrg @@hwпd:DWORD, @@mеs:DWORD, @@wраrаm:DWORD, @@Iраrаm:DWORD uses еbх, еdi, еsi, еbх ; эти регистры обязательно должны сохраняться local @@hdс:DWORD, @@hbrush:DWORD, @@hbit:DWORD сmр @@mеs, WМ_DЕSТRОY jе wmdеstrоу сmр @@mеs, WМ_СRЕАТЕ jе wmсrеаtе . сmр @@mеs, WМ_РАINТ jе wmраiпt сmр @@mеs, WМ_СОММАND jе wmсоmmапd jmр default wmcreate: ; создание растрового изображения, совместимого с окном приложения ;обозначаем создание окна звуковым эффектом call PlaySoundA ;возвращаем значение О mоv еах, 0 jmр ехit_wпdрrос wmраi пt: ;обозначаем перерисовку окна звуковым эффектом вывод виртуального окна в реальное окно wmdestroy: ; удалить виртуальное окно DeleteDC (memdc) ; послать сообщение WМ_QUIТ wmcommand: ; вызов процедуры обработки сообщений от меню (DWORD @@hwпd, DWORD @@wраrаm) @@wраrаm @@hwпd МепuРrос ехi t_wпdрrос по умолчанию jmp exit_wпdрrос exi t_wпdрrос: ret WindowProc endp ; ............... -........... MenuProc.......................... — ;обработка сообщений от меню МепuРrосрrос arg @@hwпd:DWORD, @@wраrаm:DWORD usеsеах, еbх mоv еbх, @@wраrаm ;в Ьх идентификатор меню сmр bх, IDМ_DRАWТЕХТ jе @@idmdrаwtехt сmр bх, IDМ_ТЕХТОUТ jе @@idmtехtоut

Xend memdc LineTo push 0 push NULL push @@hwпd call InvalidateRect jmp @@ехit @@i dmrectangle: ;вызываем окно диалога offset DlаlодРrос2 @@hwпd offset 1рdtg2 hlnst Di alogBoxParamA ;вывод прямоугольника BOOL Rectangle(HDC hdc, inf nheftRect, ; i nt nTopRect, int nRightRect, inf nBottomRect) push Ystart pop eax push eax shоw_еах push Xstart pop eax push eax shоw_еах push Yend pop eax push eax shоw_еах push Xend pop eax push eax show eax memdc Rectangle push О push NULL push @@hwпd call.

InvalidateRect jmp @@ехit i>i dmpeacock : push МВ_IСОNINFОRМАТIОN+МВ_ОК push offset szTitleName push offset @@ТХТ_РЕACOCK push @@hwпd call MessageBoxA jmp @@ехit г>idmlасеs: push МВ_IСОNINFОRМАТIОN+МВ_ОК push offset szTitleName push offset @@ТХТ_LАСЕS push @@hwпd call MessageBoxA xi t offset AboutDialog @@hwпd offset IрdlgЗ hlnst
db ' IDМ_АВОUТ', О 'IDМ_LАСЕS\ О db 'IDМ_РЕАСОСК'. О _ db 'Текст выведен функцией ТЕХТОUТ1 lепТХТ_ТЕХТОUТ=$-@@ТХТ_ТЕХТОUТ @@ТХТ_DRАWТЕХТ db 'Текст выведен функцией DRAWTEXT' МепuРrосепdр тDi аlоgРгосl—::::::::——

Листинг 16.13 (продолжение)

GеtDlgltеmТехtА push push call j rap @@idcancel push push call jmp @@exit_false mov eax, 0 ret @@ехi t_truе: mov eax, 1 ret DialogProcl endp DiаlодРrос2 proc аrд @@hdlg:DWORD, @@mеssаgе:DWORD, @@wраrаm:DWORD, @@lраrаm:DV uses eax, еbх, edi, esi mov eax, @@mеssаgе cmp ах, WМ_INIТDIАLОG je @@wmiпitdialog cmp ах, WМ_СОММАND j ne @@exit_false mov еbх, @@wраrаm;в bx идентификатор элемента управления cmp bx, IDOK je @@idok cmp bx, IDCANCEL je @@idcancel jmp @@exit_false @@wmi ni tdi alog: jmp @@exit_true @@i dok: ;читаем Xstart UINT GеtDlgltеmТехt(НWND hDlg, int nlDDlgltem, ;LPTSTR IpString, int nMaxCount) ; push 5 push offset Xstart push IDС_ЕDIТ1 push @@hdlg call GetDlgltemTextA sim4_tо_ЕАХbiп Xstart ;читаем Ystаrt Листинг 16.13 (продолжение) push offset Yend push IDС_ЕDIТ4 push @@hdlg .

call GеtDlgltemTextA

AboutDialog proc arg @@hdlg:DWОRD, @@mеssаgе:DWORD, @@wраrаm:DWORD, @@lрагаm:DWORD uses eax, ebx, edi, esi mov eax, @@mеssаgе cmp ax, WМ_INIТDIАLОG je @@wminitdialog cmp ax, WМ_СОММАND jne @@ехit_fаlsе mov∙ebx, @@wрагаm;в bx идентификатор элемента управления cmp bx, IDOK je @@idоk jmp @@ехit_fаlsе @@wminitdialog: , jmp @@exit_true @@i dok: push NULL push @@hdlg call EndDialog jmp @@exit_true @@ехi t_false: mov eax, 0 ret . @@ехi t_truе: mov eax, 1 ret AboutDialog endp end start Окна диалога, имеющие большое количество элементов управления, должны, соответственно, иметь диалоговые процедуры, обрабатывающие сообщения от этих элементов. В нашем примере определены два окна диалога, внешне очень похожие друг на друга. С их помощью пользователь может задавать координаты начала и конца отрезка и углов прямоугольника. На рис. 16.3 приведен вид окна прило- жения с окном диалога для задания координат прямоугольника. При задании координат пользователь сам должен контролировать правильность ввода данных, так как алгоритм программы не предусматривает их проверки. Пра-

Рис. 16.3. Окно диалога для задания координат прямоугольника

вильные значения, вводимые в каждое из полей ввода, должны содержать все че- тыре десятичные цифры с включением, при необходимости, ведущих нулей (!). Для обработки сообщений от этих окон диалога программа рrglб.4.asm (см. ли- стинг 16.13) содержит две диалоговые процедуры, DiаlоgРrосl и DialogProc2. Про- цедура DiаlодРrосl (строки 357-439) предназначена для ввода координат отрезка, процедура DialogProc2 (строки 440-522) — координат прямоугольника. Структура диалоговой процедуры аналогична структуре оконной процедуры.

В начале диа- логовой процедуры находится код, определяющий тип поступившего сообщения и в зависимости от него передающий управление в определенную точку диалого- вой процедуры: mоv еах, @@mеssаgе сmр ах, WМ_INIТDIАLОG jе @@wmiпitdiаlоg сmр ах, WМ_СОММАND jпе @@ехit_fаlsе mоv еbх, @@wраrаm ;в bх идентификатор элемента управления сmр bх, IDОК jе @@idоk сmр bх, IDСАNСЕL jе @@idсапсеl jmр @@ехi t_fаlsе Главное сообщение, поступающее в оконную процедуру, — сообщение WМ_СОММАND. Именно оно несет информацию о действиях пользователя с элемен- тами управления окна диалога. Так, в строках 361-371 листинга 16.13, обрабаты- ваются два сообщения: WМ_INIТDIАLОG и WМ_СОММАND. Сообщение WМ_INIТDIАLОG приходит в диалоговую процедуру один раз. Это происходит в процессе инициа- лизации окна диалога перед его появлением в окне приложения. Далее в диалоге- вую процедуру поступает последовательность сообщений WМ_СОММАND. Параметр ' wParam такого сообщения содержит идентификатор того элемента управления, над которым пользователь произвел некоторое действие, например, щелкнул на кноп- ке ОК или Cancel (см. рис. 16.3). Обратите внимание на то, что при описании элемен- тов различных окон диалога используются одни и те же идентификаторы. Более того, в файле рrglб_4.h этим идентификаторам назначены одни и те же константы. Именно их значения передаются в структуре сообщения для идентификации кон- кретного элемента окна диалога. Одинаковые значения не вносят никакой пута- ницы в работу приложения, так как для каждого окна диалога существует своя оконная процедура. Интерес представляют детали реализации диалоговых процедур DialogProcl и DialogProc2. В них используются две отладочные макрокоманды, sim4_tо_ ЕАХbiп и show_eax. Макрокоманда sim4_tо_ЕАХbiп в программе рrдlб_4.asm предназначена для пре- образования строки из четырех символов десятичных цифр в эквивалентное дво- ичное число, помещаемое в регистр ЕАХ. В данной программе эта макрокоманда требуется для преобразования символьных строк, считываемых из полей ввода окна диалога. Эти символьные строки логически представляют собой координаты от- резка и прямоугольника. Преобразованные с помощью макрокоманды sim4_ tо_ЕАХbiп значения этих координат используются функциями Win32 API МоvеТоЕх (строки 272-277), LiпеТо (строки 278-282) и Rectangle (строки 297-316). В конце своей работы макрокоманда sim4_tо_ЕАХbiп с помощью окна, выводимого функци- ей МеssадеВох, сообщает о результатах преобразования. Это отладочный момент работы, и, учитывая учебный характер разрабатываемого приложения, он не убран из его конечной версии. Макрокоманда show_eax также используется для отладки и является аналогом макрокоманды show, описанной в главе 14. Попытка запустить макрокоманду show в нашем приложении ни к чему хорошему не приведет, поэтому для динамическо- го контроля за работой программы макрокоманда show_eax может оказаться очень полезной. Кстати, проблема отладки Windows-приложений довольно актуальна, и для ее решения подчас приходится применять самые нетрадиционные подходы, но это уже тема для отдельного разговора.
<< | >>
Источник: В. И. Юров. Assembler. Учебник для вузов. 2-е изд. 2003

Еще по теме Диалоговая процедура:

  1. ФАКТОРЫ РАЗВИТИЯ ДИАЛОГОВЫХ ОТНОШЕНИЙ
  2. Схема «Процедуры комфортизации».
  3. Схема «Процедуры комфортизации».
  4. 3. Процедуры банкротства гражданина
  5. ИТАК, ПРОЦЕДУРА КОМФОРТИЗАЦИИ.
  6. ИТАК, ПРОЦЕДУРА КОМФОРТИЗАЦИИ.
  7. 28. Процедура наблюдения
  8. ПРОЦЕДУРЫ И РИТУАЛЫ
  9. Процедуры и техники.
  10. Процедура комфортизации («Послушный» и «непослушный» мозг»).
  11. 3.3. Процедура экспериментирования