assembler. Учебник для вузов_Юров В.И_2003 -637с (862834), страница 97
Текст из файла (страница 97)
Если что-то вас неустраивает, то описанный ранее процесс придется повторить, внеся необходимые коррективы.Диалоговая процедураВ процессе работы с окном диалога пользователь выполняет некоторые действия,о которых с помощью сообщений становится известно приложению. В приложении для каждого окна диалога должна существовать своя процедура, предназначенная для обработки сообщений этого окна. Эта процедура называется диалоговойпроцедурой. Даже самое примитивное окно диалога содержит элемент, сообщениеот которого поступает в диалоговую процедуру.
Обычно это кнопка ОК или Cancel.На языках C/C++ соответствующая диалоговая процедура выглядит так, как показано в листинге 16.12.Листинг 16.12. Диалоговая процедура на языках C/C++BOOL CALLBACK DialogProc (HWND hdwnd, DINT message, WPARAM wParam,LPARAM IParam){switch(message){case WM_INITDIALOG:return 1;case WM_COMMAND:switch (LOWORD (wParam)){case IDOK: //или IDCANCELEndDialog(hdwnd, 0);return 1;}}return 0;}В приложении prg!6.4.asm, частично представленном в листинге 16.13, имеетсяфрагмент (строки 523-549), являющийся эквивалентом программы из листинга16.12 на языке ассемблера.
Это процедура AboutDialog, поддерживающая работуокна диалога AboutBox, описанного в файле ресурсов (см. листинг 16.9). Заметьте,что если оконная процедура самостоятельно обрабатывает сообщение, то она должна возвратить 1 (return 1), если нет, то 0 (return 0).Углубленное программирование на ассемблере для Win32425Листинг 16.13. Фрагменты приложения prg16_4.asm<1> ;prg!6_4.asm<2> ;Пример приложения для Win32 с использованием меню,<3> ;окон диалогов, решением проблемы перерисовки содержимого окна<4> ;и демонстрацией некоторых принципов работы с графикой;Внимание!!! Координаты вводить из четырех знаков с ведущими нулями:;например, для ввода числа 12 вводить 0012, для 123 вводить 0123 и т.
д.<5> .486<6> locals'.разрешает применение локальных меток (с префиксом @@) в программе<7> .model flat, STDCALL ;модель памяти flat,<8> ;STDCALL - передача параметров в стиле С (справа налево),<9> ;вызываемая процедура чистит за собой стек<10>include windowA.inc включаемый файл с описаниями базовых структур;и констант Win32<11>include prg!6_4.inc включаемый файл с определением имен;пунктов меню и окна диалога<12>Объявление внешними используемых в данной программе;функций Win32 (ASCII):<13>extrnGetModuleHandleA:PROC<...> см.
исходный текст программы<55>extrnGetDlgItemTextA:PROC<5б>;объявление оконной и диалоговых функций объектами,;видимыми за пределами данного кода<57>public WindowProc<58>public DialogProcl<59>public DialogProc2<60>.data<61>Xstart dd 0, 0<62>Xenddd 0, 0Ystart dd 0, 0<63><64>Yenddd 0, 0<65>hwnddd 0<66>hlnstdd 0! ! !это глобальная переменная<67>memdcdd 0! ! !это глобальная переменная<68>maxXdd 0maxYdd 0! ! !это глобальная переменная<69>; IpVersionlnformationOSVERSIONINFO<70><?>wcl WNDCLASSEX <?><72>message MSG <?><73>ps PAINTSTRUCT <?><74>IpRect RECT<?><75>pt POINT<?><76>szClassName db 'Приложение Win32', 0<77>szTitleName db 'Каркасное приложение Win32 на ассемблере', 0<78>MesWindowdb 'Привет! Ну как вам процесс разработки приложенияна ассемблере?'<79>MesWindowLen=$-MesWindow<80>;звуковые файлы<81>playFileCreate db 'create.wav', 0<82>playFilePaintdb 'paint.wav', 0<83>playFileDestroy db 'destroy.wav', 0<84>;имена ресурсов:<-85>Ipmenu db "MYMENU", 0<86>Ipdlgl db "IDD_DIALOG1", 0<87>Ipdlg2 db "IDD_DIALOG2", 0<88>Ipdlg3 db "AboutBox", 0<89>;переменные для макроса show_eax<90>eedxdd 0<91>eecxdd 0, 0<92>templatedb '0123456789ABCDEF'<93>MesMsgBoxdb 'Отладка (содержимое еах): ' , 0<94>;описание макрокоманд<95>include show— eax.inc-,продолжение•426Глава 16.
Создание Windows-приложений на ассемблереЛистинг 16.13 (продолжение)sim4_to_EAXbin macro sim4:req<96>local ml<97>pusheax<98>pushebx<99>pushecx<100><101>movebx, 1moveax, sim4<102>bswap eax<103>movsim4, 0<104>pusheax<105>movecx, 4<10б>ml: andeax, 0fh<107>imuleax, ebx<108>imulebx, 10<109><Ц0>addsim4, eax<111>popeax<112>shreax, 8pusheax<113>loopml<114>popeax<115>popecx<116><117>popebxpopeax<118>en dm<119><120>.codestart proc near<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>конец стартового кодаWinMain:определить класс окна ATOM Regi sterClassEx(CONST WNDCLASSEX*lpWndClassEx) , где "IpWndClassEx - адрес структуры WndClassExcallRegisterClassExAtestax, ax;проверить на успех регистрации класса окнаjzend_cycl_msg; неудачасоздаем окно:callCreateWindowExAmovhwnd, eax ; hwnd - дескриптор окнапоказать окно:callShowWindowперерисовываем содержимое окнаcallUpdateWindowзапускаем цикл сообщений:cycljnsg:callGetMessageAcmpax, 0jeend_cycl_msgтрансляция ввода с клавиатурыcallTranslateMessageотправляем сообщение оконной процедуреcallDispatchMessageAjmpcycl msgend_cycl_msg:Углубленное программирование на ассемблере для Win32<158><159><160><161><162><163><164><165><166><167><168><169><170><171><172><173><174><175><176><177><178><179><180>;выход из приложения;...callExitProcessstartendp; -WindowProcWindowProc procarg @@hwnd:DWORD, @@mes:DWORD, @@wparam:DWORD, @@lparam:DWORDuses ebx, edi, esi, ebx ;эти регистры обязательно должны сохранятьсяlocal @@hdc:DWORD, @@hbrush:DWORD, @@hbit:DWORDcrop @@mes, WM_DESTROYje wmdestroycmp @@mes, WM_CREATEje wmcreatecmp @@mes, WH_PAINTje wmpaintcmp @@mes, WM_COMMANDje wmcommandjmp defaultwmcreate:создание растрового изображения, совместимого с окном приложенияобозначаем создание окна звуковым эффектом<182><183><184><185><186><187>callPlaySoundAвозвращаем значение 0mov eax, Оjmp exit_wndprocwmpaint:;...<189>; .
. .<188><190>427обозначаем перерисовку окна звуковым эффектом;вывод виртуального окна в реальное окно<192> wmdestroy:<193>;удалить виртуальное окно DeleteDC(memdc)<194> ; . . .<195> ; послать сообщение WM_QUIT<196>:...<197> wmcommand:<198>; вызов процедуры обработки сообщений от меню<199>;MenuProc (DWORD @@hwnd. DWORD @@wparam)<200>push@@wparam<201>push@@hwnd<202>callMenuProc<203>jmpexit_wndproc<204>default:обработка по умолчанию<205><206><207>jmpexit_wndproc<208><209>exi t_wndproc:<210>ret<211> WindowProc endp<212> ; ...........
- ....... MenuProc ................. ----- ................<213>обработка сообщений от меню<214>MenuProcproc<215> arg @@hwnd:DWORD, @@wparam: DWORD<21б> useseax, ebx<217>mov ebx, @@wparam;в Ьх идентификатор меню<218>cmp bx, IDM_DRAWTEXT<219>je @@idmdrawtext<220>cmp bx, IDM_TEXTOUTJ<221>je@@idmtextout,продолжение•£/л428Глава 16. Создание Windows-приложений на ассемблереЛистинг 16.13 (продолжение)<222><223><224><225><226><227><228><229><230><231><232><233><234>cmp bx, IDM_LENGTHje@@idmlengthje@@idmrectangleje@@idmpeacockcmp b x , IDM_RECTANGLEcmp bx, IDM_PEACOCKcmp bx, IDMJ.ACESje@@idmlacescmp bx, IDM_ABOUTje @@idmaboutjmp @@exit@@idmdrawtext :;получим размер рабочей области BOOL GetClientRect (HWND hWnd,; LPRECT IpRect) ;<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><270><271><272><273><274><275><27б><277><278><279>pushoffset IpRectpush@@hwndcallGetClientRectвыводим строку текста в окно int DrawText(HDC hDC,LPCTSTR IpString, int nCount,LPRECT IpRect, UINT uFormat) ;pushDT_SINGLELINE+DT_BOTTOMpushpushoffset IpRect-1pushoffset @@TXT_DRAWTEXTpushmemdccallDrawTextA; генерация сообщения WM_PAINT для вывода строки на экранpush1pushNULLpush@@hwndcallInvalidateRectjmp@@exit@(a>idmtextout :; выводим строку текста в окно BOOL TextOut(HDC hdc, int nXStart,;int nYStart, LPCTSTR I p S t r i n g , int c b S t r i n g ) ;I ...callTextOutA; генерация сообщения WM_PAINT для вывода строки на экранpush0pushNULLpush@@hwndcallInvalidateRectjmp@@exit@@idmlength :;вызываем окно диалога int DialogBoxParam(HINSTANCE hlnstance,; LPCTSTR IpTemplateName,;HWND h W n d P a r e n t , DLGPROC IpDi alogFunc , LPARAH d w I n i t P a r a m )pushpushpushpushpushcallустановить0offset DialogProcl@@hwndoffset IpdlglhlnstDialogBoxParamAтекущую точку BOOL MoveToEx(HDC hdc, int X, int Y,;LPPOINT IpPoint)pushNULLpushpushpushcallYstartXstartmemdcMoveToEx;вывод л и н и и BOOL LineTo(HDC hdc, i n t n X E n d , int nYEnd)pushYendУглубленное программирование на ассемблере для Win32<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>429pushXendpushmemdccallLineTo;генерация сообщения WM_PAINT для вывода строки на экранpush0pushNULLpush@@hwndcallInvalidateRectjmp@(s>exit@@idmrectangle:;вызываем окно диалогаpush0pushoffset DialogProc2push@@hwndpushoffset Ipdlg2pushhl'nstcallDialogBoxParamA;вывод прямоугольника BOOL Rectangle(HDC hdc, int nLeftRect,;int nTopRect, int nRightRect, int nBottomRect)pushYstartpopeaxpusheaxshow_eaxpushXstartpopeaxpusheaxshow_eaxpushVendpopeaxpusheaxshow_eaxpushXendpopeaxpusheaxshow eaxpushmemdcRectanglecall;генерация сообщения WM_PAINT для вывода строки на экранpush0pushNULLpush@@hwndcallInvalidateRectjmp@@exit@@idmpeacock:pushMB_ICONINFORMATION+MB_OKpushoffset szTitleNamepushoffset @@TXT_PEACOCKpush@@hwndMessageBoxAcalljmp@@exit@@idmlacespushMB_ICONINFORMATION+MB_OKpushoffset szTitleNamepushoffset @@TXT_LACESpush@(o>hwndMessageBoxAcalljmp@@exit@@idmabout:;вызываем окно диалогаpush0pushoffset AboutDialogpush@@hwndpushoffset Ipdlg3pushhlnstпродолжение •430Глава 16.