Диалоговая процедура
В процессе работы с окном диалога пользователь выполняет некоторые действия,
о которых с помощью сообщений становится известно приложению. В приложе-
нии для каждого окна диалога должна существовать своя процедура, предназна-
ченная для обработки сообщений этого окна. Эта процедура называется диалоговой
процедурой. Даже самое примитивное окно диалога содержит элемент, сообщение
от которого поступает в диалоговую процедуру. Обычно это кнопка
или Cancel.
На языках C/C++ соответствующая диалоговая процедура выглядит так, как по-
казано в листинге 16.12.
Листинг
Диалоговая процедура на языках C/C++
BOOL CALLBACK
(HWND
message,
LPARAM
{
{
case
return 1;
case
switch
{
case
IDCANCEL
return 1;
}
}
return 0;
}
В приложении
частично представленном в листинге 16.13, имеется
фрагмент (строки 523-549), являющийся эквивалентом программы из листинга
16.12 на языке ассемблера. Это процедура AboutDialog, поддерживающая работу
окна диалога AboutBox, описанного в файле ресурсов (см. листинг 16.9). Заметьте,
что если оконная процедура самостоятельно обрабатывает сообщение, то она долж-
на возвратить 1 (return 1), если нет, то 0 (return 0).
Углубленное программирование на ассемблере для Win32 425
Листинг
Фрагменты приложения
<1>
<2>
приложения для Win32 с использованием
<3>
диалогов, решением проблемы перерисовки содержимого окна
<4>
демонстрацией некоторых принципов работы с графикой
Координаты вводить из четырех знаков с ведущими нулями:
;например, для ввода числа 12 вводить 0012, для 123 вводить 0123 и т. д.
<5> .486
<6>
применение локальных меток (с префиксом @@) в программе
<7>
flat,
памяти flat,
<8>
- передача параметров в стиле С (справа
<9>
процедура чистит за собой стек
<10> include
файл с описаниями базовых структур
констант Win32
<11> include
файл с определением имен
;пунктов меню и окна диалога
<12>
внешними используемых в данной программе
;функций Win32 (ASCII):
<13> extrn
<...> см. исходный текст программы
<55> extrn
<5б> ;объявление оконной и диалоговых функций объектами,
за пределами данного кода
<57>
<58>
<59>
<60>
<61>
<62>
<63>
<64>
<65>
<66>
<67>
<68>
<69>
<70>
public
public
public
Xstart
Xend
Ystart
Yend
DialogProc2
dd
dd
dd
dd
dd
dd
dd
dd
dd
0,
0,
0,
0,
0
0
0
0
0
0
0
0
0
! ! !это глобальная
глобальная
глобальная
переменная
переменная
переменная
OSVERSIONINFO
>
WNDCLASSEX >
<72> message
>
<73> ps
>
<74>
RECT>
<75> pt POINT >
<76> szClassName db
0
<77>
db
приложение Win32 на
0
<78> MesWindow db
Ну как вам процесс разработки приложения
на
<79> MesWindowLen=
<80>
файлы
<81>
db
0
<82>
db
0
<83> playFileDestroy db
0
<84> ;имена ресурсов:
db
0
<86>
db
0
<87>
db
0
<88>
db
0
<89>
для макроса
<90> eedx dd 0
<91> eecx dd 0, 0
<92> template db
<93> MesMsgBox db
(содержимое
' , 0
<94> ;описание макрокоманд
<95> include show eax.inc
— продолжение
426 Глава
Создание Windows-приложений на ассемблере
Листинг
<96>
<97>
<98>
<99>
<100>
<101>
<102>
<103>
<104>
<105>
<10б>
<107>
<109>
<111>
<112>
<113>
<114>
<115>
<116>
<117>
<118>
<119>
<120>
<121>
<122>
<123>
<124>
<125>
<12б>
<127>
<128>
<129>
<130>
<131>
<132>
<133>
<134>
<135>
<13б>
<137>
<138>
<139>
<140>
<142>
<143>
<144>
<145>
<146>
<147>
<148>
<149>
<150>
<152>
<153>
<154>
<155>
<156>
<157>
macro sim4:req
local ml
push eax
push ebx
push ecx
mov
ebx, 1
mov eax,
eax
mov sim4, 0
push eax
mov
ecx, 4
ml: and
eax, 0fh
imul eax, ebx
imul ebx, 10
add sim4, eax
pop eax
shr
eax, 8
push eax
loop ml
pop eax
pop ecx
pop ebx
pop eax
dm
start proc near
точка входа в программу:
начало стартового кода
конец стартового кода
определить класс окна ATOM
WNDCLASSEX
- адрес структуры WndClassEx
call RegisterClassExA
test ax, ax ;проверить на успех регистрации класса окна
jz
создаем окно:
call
mov
eax
- дескриптор окна
показать окно:
call ShowWindow
перерисовываем содержимое окна
call
запускаем цикл сообщений:
cycljnsg:
call GetMessageA
cmp ax, 0
трансляция ввода с клавиатуры
call TranslateMessage
отправляем сообщение оконной процедуре
call DispatchMessageA
Углубленное программирование на ассемблере для Win32 427
<158>
из приложения
<159> ;...
<160> call ExitProcess
<161> start
<162>
;
-
<164> WindowProc proc
<165> arg
<166> uses ebx,
ebx
регистры обязательно должны сохраняться
<167> local
<168>
<169> je
<170>
WM_CREATE
<171> je
<172> cmp
<173> je
<174> cmp
<175> je
<176>
default
<177> wmcreate:
<178>
<179>
<180>
<182>
<183>
создание растрового изображения, совместимого с окном приложения
обозначаем создание окна звуковым эффектом
call PlaySoundA
возвращаем значение 0
<184>
eax,
<185> jmp
<186>
<187> ;...
<188>
перерисовку окна звуковым эффектом
<189>
<190>
виртуального окна в реальное окно
<192> wmdestroy:
<193> ;удалить виртуальное окно DeleteDC(memdc)
<194>
<195> ; послать сообщение
<196> :...
<197> wmcommand:
<198>
процедуры обработки сообщений от меню
<199> ;MenuProc (DWORD
DWORD @@wparam)
<200> push
<201> push
call MenuProc
<203> jmp
<204> default:
<205>
<206>
<207>
<208>
<209>
<210> ret
<211> WindowProc endp
; ........... - ....... MenuProc ................. ----- ................
<213>
сообщений от меню
<214>
<215> arg
<21б> useseax, ebx
<217> mov ebx,
;в Ьх идентификатор меню
<218> cmp bx,
<219> je @@idmdrawtext
<220> cmp bx,
<221> je
л
продолжение
обработка по умолчанию
jmp
428 Глава
Создание Windows-приложений на ассемблере
Листинг
<222>
<223>
<224>
<225>
<226>
<227>
<228>
<229>
<230>
<231>
<232>
<233>
<234>
<235>
<236>
<237>
<238>
<239>
<240>
<241>
<242>
<243>
<244>
<245>
<246>
<247>
<248>
<249>
<250>
<251>
<252>
<253>
<254>
<255>
<256>
<257>
<258>
<259>
<260>
<261>
<262>
<263>
<264>
<265>
<266>
<267>
<268>
<269>
<271>
<272>
<273>
<274>
<275>
<27б>
<277>
<278>
<279>
(продолжение)
cmp bx,
je
cmp b x , IDM_RECTANGLE
je
cmp bx, IDM_PEACOCK
je
cmp bx,
je @@idmlaces
cmp bx,
je
размер рабочей области BOOL
push offset IpRect
push
call
выводим строку текста в окно int DrawText(HDC hDC,
LPCTSTR
int
LPRECT IpRect,
uFormat) ;
push DT_SINGLELINE+DT_BOTTOM
push offset IpRect
push -1
push offset
push
call
сообщения
для вывода строки на экран
push 1
push NULL
push
call InvalidateRect
jmp
строку текста в окно BOOL TextOut(HDC hdc, int
nYStart, LPCTSTR I p S t r i n g , int c b S t r i n g ) ;
I
call TextOutA
сообщения
для вывода строки на экран
push 0
push NULL
push @@hwnd
call InvalidateRect
jmp
окно диалога int
;HWND
DLGPROC
push 0
push offset DialogProcl
push
push offset
push
call
текущую точку BOOL
hdc, int X, int Y,
;LPPOINT
push N U L L
push Ystart
push Xstart
push memdc
call MoveToEx
л и н и и BOOL
hdc, i n t n X E n d , int nYEnd)
push Yend
Углубленное программирование на ассемблере для Win32 429
<280>
<281>
<282>
<283>
<284>
<285>
<286>
<287>
<288>
<289>
<290>
<291>
<292>
<293>
<294>
<295>
<296>
<297>
<298>
<299>
<300>
<301>
<302>
<303>
<304>
<305>
<306>
<307>
<308>
<309>
<310>
<312>
<313>
<314>
<315>
<316>
<317>
<318>
<319>
<320>
<321>
<322>
<323>
<324>
<325>
<326>
<327>
<328>
<329>
<330>
<331>
<332>
<333>
<334>
<335>
<336>
<337>
<338>
<339>
<340>
<341>
<342>
<343>
push
push
call
;генерация сообщения WM_PAINT для вывода строки на экран
push
push
push
call
окно диалога
0
NULL
InvalidateRect
push
push
push
push
push
call
0
offset DialogProc2
offset
BOOL Rectangle(HDC
int nLeftRect,
nRightRect, int
push Ystart
pop eax
push eax
push Xstart
pop eax
push eax
show_eax
push
pop eax
push eax
push Xend
pop eax
push eax
show eax
push
call
memdc
Rectangle
сообщения
вывода строки на экран
push 0
push NULL
push
InvalidateRect
jmp
push
push
push
push
call
jmp
push
push
push
push
call
jmp
окно диалога
offset
offset
MessageBoxA
offset szTitleName
offset
MessageBoxA
push 0
push offset
push
push offset
push
430 Глава
Создание Windows-приложений на ассемблере
Листинг
(продолжение)
<344> call
<345>
@@exit
<34б> ;...
<347>
<348>
eax, 0
<349> ret
<350>
db
0
<351>
db
0
<352> @@TXT_PEACOCK db
0
<353>
db
выведен функцией TEXTOUT
1
<354>
<355>
db
выведен функцией
0
<357> ;
- —
<358> DialogProcl proc
<359> arg @@hdlg:DWORD,
<360> uses
ebx,
esi
<361> mov eax,
<362> cmp ax,
<363> je
<364> cmp ax,
<365> jne @@exit_false
<366> mov ebx,
bx идентификатор элемента управления
<367> cmp bx,
<368>
<369> cmp bx,
<370> je
<371> jmp
<372>
<373> jmp
<374>
<375>
Xstart
int
<376>
int
<377> push 5
<378> push offset Xstart
<379> push IDC_EDIT1
<380> push
<381> call
<382> push
< . . . >
<387>
Xstart
<388>
Ystart
<389>
<390> push offset Ystart
<391> push IDC_EDIT2
<392> push
<393> call GetDlgltemTextA
< . . . >
<399>
Ystart
<400>
Xend
<401> push 5
<402> push offset Xend
<403> push IDC_EDIT3
<404> push
<405> call GetDlgltemTextA
< . . . >
<411>
Xend
<412>
Yend
<413> push 5
<414> push offset Yend
<415> push IDC_EDIT4
<416> push
Углубленное программирование на ассемблере для Win32
<417>
< . . . >
<423>
<424> push 0
<425> push
<426> call
<427>
@@exit_true
<428> @@idcancel:
<429> push N U L L
<430> push @@hdlg
<431> call EndDialog
<432> jmp
<433> @@exit_false:
<434> mov eax, 0
<435>
<436>
<437> mov eax, 1
<438>
<439>
endp
<440> ;
<441> DialogProc2 proc
arg
<443> uses eax, ebx,
<444> mov eax,
<445>
ax, WM_INITDIALOG
<446> je
<447> cmp ax,
<448>
<449> mov ebx,
bx идентификатор элемента управления
<450> cmp bx,
<451> je @@idok
<452> cmp bx, IDCANCEL
<453> je @@idcancel
<454> jmp
<455>
<456> jmp
<457>
<458>
int
<459> ;LPTSTR
int
<460> push 5
<461> push offset Xstart
<462> push
<463> push
<464> call GetDlgltemTextA
< . . . >
<470>
Xstart
<471>
Ystart
<472> push 5
<473> push offset Ystart
<474> push IDC_EDIT2
<475> push
<476> call GetDlgltemTextA
< . . . >
<482>
Ystart
<483>
Xend
<484> push 5
<485> push offset Xend
<486> push IDC_EDIT3
<487> push
<488> call GetDlgltemTextA
< . . . >
<494> sim4_to_EAXbin Xend
<495>
Yend
<496> push 5
432 Глава
Создание Windows-приложений на ассемблере
Листинг
(продолжение)
<497> push offset
<498> push
<499> push
.
<500>
< . . . >
<506>
<507> push N U L L
<508> push @@hdlg
<509>
EndDialog
<510>
<511>
<512> push NULL
<513> push
<514> call EndDialog
<515> jmp
<516> @@exit_false:
<517>
eax, 0
<518> ret
<519> @@exit_true:
<520> mov eax, 1
<521> ret
<522> DialogProc2 endp
-
<524> AboutDialog proc
<525> arg
<526> uses eax, ebx,
esi
<527> mov eax,
<528>
ax, WM_INITDIALOG
<529> je
<530> cmp ax,
<531> jne
<532>
bx идентификатор элемента управления
<533> cmp bx,
<534> je
<535> jmp
<536>
<537> jmp
<538>
<539> push NULL
<540> push
<541> call EndDialog
<542> jmp
<543>
<544> mov eax, 0
<545> ret
<546>
<547> mov eax, 1
<548> ret
<549> AboutDialog endp
<550> end start
Окна диалога, имеющие большое количество элементов управления, должны,
соответственно, иметь диалоговые процедуры, обрабатывающие сообщения от этих
элементов. В нашем примере определены два окна диалога, внешне очень похожие
друг на друга. С их помощью пользователь может задавать координаты начала
и конца отрезка и углов прямоугольника. На рис. 16.3 приведен вид окна прило-
жения с окном диалога для задания координат прямоугольника.
При задании координат пользователь сам должен контролировать правильность
ввода данных, так как алгоритм программы не предусматривает их проверки.
Углубленное программирование на ассемблере для Win32 433
550>549>548>547>546>545>544>543>542>541>540>539>538>537>536>535>534>533>532>531>530>529>528>527>526>525>524>522>521>520>519>518>517>516>515>514>513>512>511>510>509>508>507>506>500>499>498>497>496>495>494>488>487>486>485>484>483>482>476>475>474>473>472>471>470>464>463>462>461>460>459>458>457>456>455>454>453>452>451>450>449>448>447>446>445>444>443>441>440>439>438>437>436>435>434>433>432>431>430>429>428>427>426>425>424>423>417>416>415>414>413>412>411>405>404>403>402>401>400>399>393>392>391>390>389>388>387>382>381>380>379>378>377>376>375>374>373>372>371>370>369>368>367>366>365>364>363>362>361>360>359>358>357>355>354>353>352>351>350>349>348>347>345>344>343>342>341>340>339>338>337>336>335>334>333>332>331>330>329>328>327>326>325>324>323>322>321>320>319>318>317>316>315>314>313>312>310>309>308>307>306>305>304>303>302>301>300>299>298>297>296>295>294>293>292>291>290>289>288>287>286>285>284>283>282>281>280>279>278>277>275>274>273>272>271>269>268>267>266>265>264>263>262>261>260>259>258>257>256>255>254>253>252>251>250>249>248>247>246>245>244>243>242>241>240>239>238>237>236>235>234>233>232>231>230>229>228>227>226>225>224>223>222>221>220>219>218>217>215>214>213>211>210>209>208>207>206>205>204>203>201>200>199>198>197>196>195>194>193>192>190>189>188>187>186>185>184>183>182>180>179>178>177>176>175>174>173>172>171>170>169>168>167>166>165>164>162>161>160>159>158>157>156>155>154>153>152>150>149>148>147>146>145>144>143>142>140>139>138>137>135>134>133>132>131>130>129>128>127>125>124>123>122>121>120>119>118>117>116>115>114>113>112>111>109>107>105>104>103>102>101>100>99>98>97>96>95>94>93>92>91>90>89>88>87>86>84>83>82>81>80>79>78>77>76>75>74>73>72>70>69>68>67>66>65>64>63>62>61>60>59>58>57>55>13>12>11>10>9>8>7>6>5>4>3>2>1> Do'stlaringiz bilan baham: |