Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Отчеты по Курсовой Работе / Макросрдства Орефков 8-78-2.docx
Скачиваний:
37
Добавлен:
12.03.2015
Размер:
194.42 Кб
Скачать

5 Демонстрационная программа

5.1 Листинг:

Файл edit.inc:

; константы

WM_SETFOCUS equ 7h

; сообщение приходит при закрытии окна

WM_DESTROY equ 2

; сообщение приходит при содании окна

WM_CREATE equ 1

; сообщение, если что-то происходит с элементами на окне

WM_COMMAND equ 111h

; сообщение, позволяющее послать элементу строку

WM_SETTEXT equ 0Ch

WM_PAINT equ 0FH

; сообщение, позволяющее получить строку

WM_GETTEXT equ 0Dh

; компоненты цветов

RED equ 49

GREEN equ 106

BLUE equ 197

RGBW equ (RED or (GREEN shl 8)) or (BLUE shl 16)

RGBT equ 255 ; красный

; свойства окна

CS_VREDRAW equ 1h

CS_HREDRAW equ 2h

CS_GLOBALCLASS equ 4000h

WS_OVERLAPPEDWINDOW equ 000CF0000H

STYLE equ CS_HREDRAW + CS_VREDRAW + CS_GLOBALCLASS

; CS_HREDRAW equ 2h

BS_DEFPUSHBUTTON equ 1h

WS_VISIBLE equ 10000000h

WS_CHILD equ 40000000h

WS_BORDER equ 800000h

WS_TABSTOP equ 00010000h

STYLBTN equ WS_CHILD + BS_DEFPUSHBUTTON + WS_VISIBLE + WS_TABSTOP

STYLEDT equ WS_CHILD + WS_VISIBLE + WS_BORDER + WS_TABSTOP

; идентификатор стандартной иконки

IDI_ERROR equ 32513

; идентификатор курсора

IDC_ARROW equ 32512 ;

; режим показа окна — нормальный

SW_SHOWNORMAL equ 1

; прототипы внешних процедур

EXTERN SetFocus@4:NEAR

EXTERN SendMessageA@16:NEAR

EXTERN MessageBoxA@16:NEAR

EXTERN CreateWindowExA@48:NEAR

EXTERN DefWindowProcA@16:NEAR

EXTERN DispatchMessageA@4:NEAR

EXTERN ExitProcess@4:NEAR

EXTERN GetMessageA@16:NEAR

EXTERN GetModuleHandleA@4:NEAR

EXTERN LoadCursorA@8:NEAR

EXTERN LoadIconA@8:NEAR

EXTERN PostQuitMessage@4:NEAR

EXTERN RegisterClassA@4:NEAR

EXTERN ShowWindow@8:NEAR

EXTERN TranslateMessage@4:NEAR

EXTERN UpdateWindow@4:NEAR

EXTERN BeginPaint@8:NEAR

EXTERN EndPaint@8:NEAR

EXTERN TextOutA@20:NEAR

EXTERN GetStockObject@4:NEAR

EXTERN CreateSolidBrush@4:NEAR

EXTERN SetBkColor@8:NEAR

EXTERN SetTextColor@8:NEAR

EXTERN InvalidateRect@12:NEAR

; структуры

; структура сообщения

MSGSTRUCT STRUC

MSHWND DD ?

MSMESSAGE DD ?

MSWPARAM DD ?

MSLPARAM DD ?

MSTIME DD ?

MSPT DD ?

MSGSTRUCT ENDS

;----структура класса окон

WNDCLASS STRUC

CLSSTYLE DD ?

CLWNDPROC DD ?

CLSCBCLSEX DD ?

CLSCBWNDEX DD ?

CLSHINST DD ?

CLSHICON DD ?

CLSHCURSOR DD ?

CLBKGROUND DD ?

CLMENNAME DD ?

CLNAME DD ?

WNDCLASS ENDS

PAINTSTR STRUC

hdc DWORD 0

fErase DWORD 0

left DWORD 0

top DWORD 0

right DWORD 0

bottom DWORD 0

fRes DWORD 0

fIncUp DWORD 0

Reserv DB 32 dup(0)

PAINTSTR ENDS

Файл edit.asm:

.386P

; плоская модель

.MODEL FLAT, stdcall

include D:/masm32 /include/edit.inc

; подключение библиотек

includelib D:/masm32 /lib/user32.lib ;Модуль для поддержки пользовательского интерфейса

includelib D:/masm32 /lib/kernel32.lib ;Модуль для работы с ядром ОС

includelib D:/masm32 /lib/gdi32.lib ;Модуль для поддержки графического интерфейса

;------------------------------------------------------------

; сегмент данных

_DATA SEGMENT DWORD PUBLIC USE32 'DATA'

NEWHWND DD 0 ;хэндлер окна

MSG MSGSTRUCT <?>

WC WNDCLASS <?>

PNT PAINTSTR <?>

HINST DD 0 ; дескриптор приложения

TITLENAME DB 'My Prog',0

CLASSNAME DB 'CLASS32',0

CPBUT DB 'Копирование',0

CPBUT1 DB 'Повторить 20 раз с помощью REPT',0

CPEDT DB ' ',0

CLSBUTN DB 'BUTTON',0

CLSEDIT DB 'EDIT',0

TMP DB 0

HWNDBTN DWORD 0

HWNDBTN1 DWORD 0

HWNDEDT DWORD 0

HWNDEDT1 DWORD 0

XT DWORD 10

YT DWORD 90

TEXT DB 'Введите текст',0

DB 50 DUP(0) ; продолжение буфера

TEXTM DB 'Строка выведена 10 раз с помощью макрокоманды REPT',0

DB 50 DUP(0) ; продолжение буфера

_DATA ENDS

; сегмент кода

_TEXT SEGMENT DWORD PUBLIC USE32 'CODE'

START:

; получить дескриптор приложения

PUSH 0

CALL GetModuleHandleA@4 ; Возвращает дескриптор модуля, содержащего тип, представленный данным экземпляром

MOV [HINST], EAX

REG_CLASS: ;регистрация класса окна

; заполнить структуру окна

; стиль

MOV [WC.CLSSTYLE], STYLE

; процедура обработки сообщений

MOV [WC.CLWNDPROC], OFFSET WNDPROC

MOV [WC.CLSCBCLSEX],0

MOV [WC.CLSCBWNDEX],0

MOV EAX, [HINST]

MOV [WC.CLSHINST], EAX

;------—— иконка окна

PUSH IDI_ERROR

PUSH 0

CALL LoadIconA@8 ;загружаем иконку

MOV [WC.CLSHICON], EAX

;---------- курсор окна

PUSH IDC_ARROW

PUSH 0

CALL LoadCursorA@8 ;загружаем курсор

MOV [WC.CLSHCURSOR], EAX

;--------—

MOV [WC.CLBKGROUND], 30 ; цвет окна

MOV DWORD PTR [WC.CLMENNAME], 0

MOV DWORD PTR [WC.CLNAME], OFFSET CLASSNAME

PUSH OFFSET WC

CALL RegisterClassA@4 ;Регистрирует класс, определенный конструктором, с дополнительным базовым типом и типом интерфейса

; создать окно зарегистрированного класса

PUSH 0

PUSH [HINST]

PUSH 0

PUSH 0

PUSH 600 ; DY - высота окна

PUSH 600 ; DX - ширина окна

PUSH 100 ; Y - координата левого верхнего угла

PUSH 100 ; X - координата левого верхнего угла

PUSH WS_OVERLAPPEDWINDOW

PUSH OFFSET TITLENAME ; имя окна

PUSH OFFSET CLASSNAME ; имя класса

PUSH 0

CALL CreateWindowExA@48

; проверка на ошибку

CMP EAX, 0

JZ _ERR

MOV [NEWHWND], EAX ; дескриптор окна

PUSH SW_SHOWNORMAL

PUSH [NEWHWND]

CALL ShowWindow@8 ; показать созданное окно

;------------------------------------------------------------

PUSH [NEWHWND]

CALL UpdateWindow@4 ; команда перерисовать видимую

; часть окна, сообщение WM_PAINT

; цикл обработки сообщений

MSG_LOOP:

PUSH 0

PUSH 0

PUSH 0

PUSH OFFSET MSG

CALL GetMessageA@16 ;получаем сообщение из очереди

CMP EAX, 0 ;если в очередь пришел ноль, значит выходим из программы

JE END_LOOP

PUSH OFFSET MSG

CALL TranslateMessage@4

PUSH OFFSET MSG

CALL DispatchMessageA@4

JMP MSG_LOOP

END_LOOP:

; выход из программы (закрыть процесс)

PUSH [MSG.MSWPARAM]

CALL ExitProcess@4

_ERR:

JMP END_LOOP

; процедура окна

; расположение параметров в стеке

; [EBP+014Н] ; LPARAM

; [EBP+10H] ; WAPARAM

; [EBP+0CH] ; MES

; [EBP+8] ; HWND

WNDPROC PROC

PUSH EBP

MOV EBP,ESP

; PUSH EBX

; PUSH ESI

; PUSH EDI

IRP REG, <EBX,ESI,EDI> ; макроповторение IRP

PUSH REG

ENDM

CMP DWORD PTR [EBP+0CH] ,WM_DESTROY

JE WMDESTROY

CMP DWORD PTR [EBP+0CH] ,WM_CREATE

JE WMCREATE

CMP DWORD PTR [EBP+0CH] ,WM_PAINT

JE WMPAINT

CMP DWORD PTR [EBP+0CH] ,WM_COMMAND

JE WMCOMMND

JMP DEFWNDPROC

WMCOMMND:

MOV EAX,HWNDBTN

CMP DWORD PTR [EBP+14H],EAX ; определяем нажата ли кнопка «Событие 1»

JNE BUTT1

; получить отредактированную строку

PUSH OFFSET TEXT

PUSH 150

PUSH WM_GETTEXT

PUSH HWNDEDT

CALL SendMessageA@16 ; показать эту строку

; записать отредактированную строку текстовое поле HWNDEDT1

PUSH OFFSET TEXT

PUSH 0

PUSH WM_SETTEXT

PUSH HWNDEDT1

CALL SendMessageA@16

JMP NODESTROY

BUTT1:

MOV EAX,HWNDBTN1

CMP DWORD PTR [EBP+14H],EAX ; определяем нажата ли кнопка «Событие 2»

JNE NODESTROY

PUSH [NEWHWND]

PUSH 0

PUSH 0

CALL InvalidateRect@12 ; принудительная перерисовка окна

.IF TMP==0 ; изменение условий перерисовки окна

MOV TMP,1

.ELSE

MOV TMP,0

.ENDIF

JMP NODESTROY

NODESTROY:

MOV EAX, 0

JMP FINISH

WMPAINT:

PUSH OFFSET PNT

PUSH DWORD PTR [EBP+08H]

CALL BeginPaint@8

PUSH EAX ; сохранить контекст (дескриптор)

;---------------- цвет фона = цвет окна

PUSH RGBW

PUSH EAX

CALL SetBkColor@8

;---------------- контекст

POP EAX

PUSH EAX

;---------------- цвет текста (красный)

PUSH RGBT

PUSH EAX

CALL SetTextColor@8

POP EAX

.IF TMP==1 ; проверка условия прорисовки текста по событию 2

REPT 20 ; макроповторение REPT

PUSH EAX

;---------------- вывести текст

PUSH OFFSET TEXT

CALL LENSTR ; вызов процедуры определения длины сообщения

PUSH EBX ; длина строки

PUSH OFFSET TEXT ; адрес строки

ADD YT,20

PUSH YT ; Y

PUSH XT ; X

PUSH EAX ; контекст окна

CALL TextOutA@20

POP EAX

ENDM

.ENDIF

MOV YT,90

PUSH OFFSET PNT

PUSH DWORD PTR [EBP+08H]

CALL EndPaint@8

MOV EAX, 0

JMP FINISH

WMCREATE:

; создать окно-кнопку "Событие1"

PUSH 0

PUSH [HINST]

PUSH 0

PUSH DWORD PTR [EBP+08H]

PUSH 20 ; DY

PUSH 100 ; DX

PUSH 10 ; Y

PUSH 10 ; X

PUSH STYLBTN

PUSH OFFSET CPBUT ; имя окна

PUSH OFFSET CLSBUTN ; имя класса

PUSH 0

CALL CreateWindowExA@48

MOV HWNDBTN,EAX ; запомнить дескриптор кнопки

; создать окно-кнопку "Событие2"

PUSH 0

PUSH [HINST]

PUSH 0

PUSH DWORD PTR [EBP+08H]

PUSH 20 ; DY

PUSH 240 ; DX

PUSH 85 ; Y

PUSH 10 ; X

PUSH STYLBTN

PUSH OFFSET CPBUT1 ; имя окна

PUSH OFFSET CLSBUTN ; имя класса

PUSH 0

CALL CreateWindowExA@48

MOV HWNDBTN1,EAX ; запомнить дескриптор кнопки

; создать окно редактирования1

PUSH 0

PUSH [HINST]

PUSH 0

PUSH DWORD PTR [EBP+08H]

PUSH 20 ; DY

PUSH 350 ; DX

PUSH 40 ; Y

PUSH 10 ; X

PUSH STYLEDT

PUSH OFFSET CPEDT ; имя окна

PUSH OFFSET CLSEDIT ; имя класса

PUSH 0

CALL CreateWindowExA@48

MOV HWNDEDT,EAX

; создать окно редактирования 2

PUSH 0

PUSH [HINST]

PUSH 0

PUSH DWORD PTR [EBP+08H]

PUSH 20 ; DY

PUSH 350 ; DX

PUSH 60 ; Y

PUSH 10 ; X

PUSH STYLEDT

PUSH OFFSET CPEDT ; имя окна

PUSH OFFSET CLSEDIT ; имя класса

PUSH 0

CALL CreateWindowExA@48

MOV HWNDEDT1,EAX

;--------- поместить строку в окно редактирования

PUSH OFFSET TEXT

PUSH 0

PUSH WM_SETTEXT

PUSH HWNDEDT

CALL SendMessageA@16

;--------- установить фокус на окне редактирования

PUSH HWNDEDT

CALL SetFocus@4

;------------------------------------------------------------

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@16 ; вызывается оконной процедурой по умолчанию,

;чтобы обеспечить обработку по умолчанию любого сообщения окна,

;которые приложение не обрабатывает

JMP FINISH

WMDESTROY:

PUSH 0

CALL PostQuitMessage@4 ; сообщение WM_QUIT

MOV EAX, 0

FINISH:

POP EDI

POP ESI

POP EBX

POP EBP

RET 16

WNDPROC ENDP

;----------- функция определения длины строки --------------------------

; длина строки

; [EBP+08H] - указатель на строку

LENSTR PROC

PUSH EBP

MOV EBP, ESP

PUSH ESI

MOV ESI, DWORD PTR [EBP+8]

XOR EBX, EBX

LBL1:

CMP BYTE PTR [ESI], 0

JZ LBL2

INC EBX

INC ESI

JMP LBL1

LBL2:

POP ESI

POP EBP

RET 4

LENSTR ENDP

_TEXT ENDS

END START