
- •1 Оглавление
- •2 Введение
- •3 Описание использованного набора макросредств.
- •4. ИспользованныеApi-функции и системные константы.
- •4.1 Список использованных констант и структур.
- •4.2 Список использованныхApi-функций.
- •4.3 Основы вызова api-функций.
- •5 Демонстрационная программа
- •5.1 Листинг:
- •5.2 Демонстрация работы:
- •6 Вывод
- •7 Литература:
- •8 Программное обеспечение:
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