КАТЕГОРИИ:
АстрономияБиологияГеографияДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРиторикаСоциологияСпортСтроительствоТехнологияФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника
|
Методические рекомендации по выполнению лабораторной работы. Рассмотрим простую программу графического приложенияРассмотрим простую программу графического приложения. Разберите ее внимательно – она будет фундаментом, на котором мы будем строить дальнейшее рассмотрение. Прежде всего обратите внимание на директиву INCLUDELIB. В пакете TASM32 довольно много разных библиотек. Для данного примера необходима: import32.lib. При наборе текста программы нужно изменить путь к библиотеке. Сначала определяются константы и внешние библиотечные процедуры. В действительности все эти определения можно найти в include-файлах, прилагаемых к пакету TASM32. Мы не будем использовать стандартные include-файлы, т.к. так удобнее понять технологию программирования. Необходимо четко понимать способ функционирования процедуры окна, так как именно это определяет суть программирования под Windows. Задача данной процедуры – правильная реакция на все приходящие сообщения. Нужно детально разобратся в работе нашего приложения. Сначала обратите внимание на то, что необработанные сообщения должны возвращаться в систему при помощи функции DefWindowProcA. Программа отслеживает четыре сообщения: WM_CREATE, WM_DESTROY, WM_LBUTTONDOWN, WM_RBUTTONDOWN. Сообщения WM_CREATE и WM_DESTROY в терминах объектного программирования играют роль конструктора и деструктора: они приходят в функцию окна при создании окна и при уничтожении окна. Если щелкнуть по крестику в правом углу окна, то в функцию окна придет сообщение WM_DESTROY. Далее будет выполнена функция PostQuitMessage и приложению будет послано сообщение WM_QUIT, которое вызовет выход из цикла ожидания и выполнение функции ExitProcess, что, в свою очередь, приведет к удалению приложения из памяти. Обратите внимание на метку _ERR – переход на нее происходит при возникновении ошибки, и здесь можно поместить соответствующее сообщение. Выполните набор программы в блокноте или в любом другом простом текстовом редакторе. Чтобы получить загружаемый модуль, выполните следующие команды: TASM32 /ml prog.asm TLINK32 –aa prog.obj
Текст программы: .386P .MODEL FLAT, stdcall ; константы ; сообщение приходит при закрытии окна WM_DESTROY equ 2 ; сообщение приходит при создании окна WM_CREATE equ 1 ; сообщение при щелчке левой кнопкой мыши в области окна WM_LBUTTONDOWN equ 201h ; сообщение при щелчке праввой кнопкой мыши в области окна WM_RBUTTONDOWN equ 204h ; свойства окна CS_VREDRAW equ 1h CS_HREDRAW equ 2h CS_GLOBALCLASS equ 4000h WS_OVERLAPPEDWINDOW equ 000CF0000H style equ CS_HREDRAW + CS_VREDRAW + CS_GLOBALCLASS ; идентификатор стандартной иконки IDI_APPLICATION equ 32512 ; идентификатор курсора IDC_CROSS equ 32515 ; режим показа окна - нормальный SW_SHOWNORMAL equ 1 ; прототипы внешних процедур EXTERN MessageBoxA: NEAR EXTERN CreateWindowExA: NEAR EXTERN DefWindowProcA: NEAR EXTERN DispatchMessageA: NEAR EXTERN ExitProcess: NEAR EXTERN GetMessageA: NEAR EXTERN GetModuleHandleA: NEAR EXTERN LoadCursorA: NEAR EXTERN LoadIconA: NEAR EXTERN PostQuitMessage: NEAR EXTERN RegisterClassA: NEAR EXTERN ShowWindow: NEAR EXTERN TranslateMessage: NEAR EXTERN UpdateWindow: NEAR ; директивы компоновщику для подключения библиотек includelib c:\win32\tasm32\lib\import32.lib ;------------------------------------------------------------------------- ; структуры ; структура сообщения MSGSTRUCT STRUC MSHWND DD ? ; идентификатор сообщения MSWPARAM DD ? ; доп. информация о сообщении MSLPARAM DD ? ; доп. информация о сообщении MSTIME DD ? ; время посылки сообщения MSPT DD ? ; положение курсора во время посылки сообщения MSGSTRUCT ENDS ;--------------------------- WNDCLASS STRUC CLSSTYLE DD ? ; стиль окна CLWNDPROC DD ? ; указатель на процедуру окна CLSCEXTRA DD ? ; информация о доп. байтах для данной структуры CLWNDEXTRA DD ? ; информация о доп. байтах для окна CLSHINSTANCE DD ? ; дискриптор приложения CLSHICON DD ? ; идентификатор иконы окна CLSHCURSOR DD ? ; идентификатор курсора окна CLBKGROUND DD ? ; идентификатор кисти окна CLMENUNAME DD ? ; имя-идентификатор меню CLNAME DD ? ; специфицирует имя класса окна WNDCLASS ENDS ; сенмент данных _DATA SEGMENT DWORD PUBLIC USE32 'DATA' NEWHWND DD 0 MSG MSGSTRUCT <?> WC WNDCLASS <?> HINST DD 0 ; здесь хранится дескриптор приложения TITLENAME DB 'Простой пример 32-битного приложения',0 CLASSNAME DB 'CLASS32',0 CAP DB 'Сообщение',0 MES1 DB 'Вы нажали левую кнопку мыши',0 MES2 DB 'Выход из программы. Пока!',0 _DATA ENDS ; сегмент кода _TEXT SEGMENT DWORD PUBLIC USE32 'CODE' START: ; получить дескриптор приложения PUSH 0 CALL GetModuleHandleA MOV [HINST],EAX REG_CLASS: ; заполнить структуру окна MOV [WC.CLSSTYLE], style ; процедура обработки сообщений MOV [WC.CLWNDPROC], OFFSET WNDPROC MOV [WC.CLSCEXTRA], 0 MOV [WC.CLWNDEXTRA], 0 MOV EAX, [HINST] MOV [WC.CLSHINSTANCE],EAX ;------------------иконка окна PUSH IDI_APPLICATION PUSH 0 CALL LoadIconA MOV [WC.CLSHICON], EAX ;------------------курсор окна PUSH IDC_CROSS PUSH 0 CALL LoadCursorA MOV [WC.CLSHCURSOR], EAX ;------------------- MOV [WC.CLBKGROUND],17 ; цвет окна MOV DWORD PTR [WC.CLMENUNAME], 0 MOV DWORD PTR [WC.CLNAME], OFFSET CLASSNAME PUSH OFFSET WC CALL RegisterClassA ; создать окно зарегистрированного класса PUSH 0 PUSH [HINST] PUSH 0 PUSH 0 PUSH 400 ; DY - высота окна PUSH 400 ; DX - ширина окна PUSH 100 ; Y - координата левого верхнего угла PUSH 100 ; X - координата левого верхнего угла PUSH WS_OVERLAPPEDWINDOW PUSH OFFSET TITLENAME ; имя окна PUSH OFFSET CLASSNAME ; имя класса PUSH 0 CALL CreateWindowExA ; проверка на ошибку CMP EAX, 0 JZ _ERR MOV [NEWHWND], EAX PUSH SW_SHOWNORMAL PUSH [NEWHWND] CALL ShowWindow ; показать созданное окно PUSH [NEWHWND] CALL UpdateWindow ; команда перерисовать видимую часть окна, сообщение WM_PAINT ; цикл обработки сообщений MSG_LOOP: PUSH 0 PUSH 0 PUSH 0 PUSH OFFSET MSG CALL GetMessageA CMP EAX, 0 JE END_LOOP PUSH OFFSET MSG CALL TranslateMessage PUSH OFFSET MSG CALL DispatchMessageA JMP MSG_LOOP END_LOOP: ; выход из программы (закрыть процесс) PUSH [MSG.MSWPARAM] CALL ExitProcess _ERR: JMP END_LOOP ;---------------------------------------------------------------------------- ; процедура окна ; расположение параметров в стеке ; [EBP+14H] LPARAM ; [EBP+10H] WPARAM ; [EBP+0CH] MES ; [EBP+8] HWND WNDPROC PROC PUSH EBP MOV EBP, ESP PUSH EBX PUSH ESI PUSH EDI CMP DWORD PTR [EBP+0CH], WM_DESTROY JE WMDESTROY CMP DWORD PTR [EBP+0CH], WM_CREATE JE WMCREATE CMP DWORD PTR [EBP+0CH], WM_LBUTTONDOWN ; левая кнопка JE LBUTTON CMP DWORD PTR [EBP+0CH], WM_RBUTTONDOWN ; правая кнопка JE RBUTTON JMP DEFWNDPROC ; нажатие правой кнопки приводит к закрытию окна RBUTTON: JMP WMDESTROY ; нажатие левой кнопки мыши LBUTTON: ; выводим сообщение PUSH 0 ; MB_OK PUSH OFFSET CAP PUSH OFFSET MES1 PUSH DWORD PTR [EBP+08H] CALL MessageBoxA MOV EAX, 0 JMP FINISH WMCREATE: MOV EAX, 0 JMP FINISH DEFWNDPROC: PUSH DWORD PTR [EBP+14H] PUSH DWORD PTR [EBP+10H] PUSH DWORD PTR [EBP+0CH] PUSH DWORD PTR [EBP+08H] CALL DefWindowProcA JMP FINISH WMDESTROY: PUSH 0 ; MB_OK PUSH OFFSET CAP PUSH OFFSET MES2 PUSH DWORD PTR [EBP+08H] ; дескриптор окна CALL MessageBoxA PUSH 0 CALL PostQuitMessage ; сообщение WM_QUIT MOV EAX, 0 FINISH: POP EDI POP ESI POP EBX POP EBP RET 16 WNDPROC ENDP _TEXT ENDS END START Основная литература– 5[27-68] Контрольные вопросы.
|