Заголовочный файл для приложения, содержащий определения констант, внешних процедур и структур (его имя
.
.386P
;Плоская модель.
.MODEL FLAT, STDCALL
include pr21_1.asm
;Директивы компоновщику для подключения библиотек.
includelib c:\masm32\lib\user32.lib
includelib c:\masm32\lib\kernel32.lib
includelib c:\masm32\lib\gdi32.lib
;------------------------------------------------
;Сегмент данных.
_DATA SEGMENT DWORD PUBLIC USE32 'DATA'
NEWHWND DD 0
MSG MSGSTRUCT <?>
WC WNDCLASS <?>
PNT PAINTSTR <?>
SZT SIZET <?>
RCT RECT <?>
lg LOGFONT <?>
HINST DD 0 ;Здесь хранится дескриптор приложения.
TITLENAME DB 'Текст в окне',0
NAM DB 'CLASS32',0
NFONT DB 'Arial Cyr',0
XT DWORD ?
YT DWORD ?
TEXT DB 'Текст в окне',0
CONT DWORD ?
_DATA ENDS
;Сегмент кода.
_TEXT SEGMENT DWORD PUBLIC USE32 'CODE'
START:
;Получить дескриптор приложения.
PUSH 0
CALL GetModuleHandleA@4
MOV [HINST], EAX
REG_CLASS:
;Заполнить структуру окна.
;Стиль.
MOV [WC.CLSSTYLE],stylcl
;Процедура обработки сообщений.
MOV [WC.CLWNDPROC], OFFSET WNDPROC
MOV [WC.CLSCBCLSEX], 0
MOV [WC.CLSCBWNDEX], 0
MOV EAX, [HINST]
MOV [WC.CLSHINST], EAX
;------------ пиктограмма окна
PUSH IDI_APPLICATION
PUSH 0
CALL LoadIconA@8
MOV [WC.CLSHICON], EAX
;------------ курсор окна
PUSH IDC_CROSS
PUSH 0
CALL LoadCursorA@8
MOV [WC.CLSHCURSOR], EAX
;------------
PUSH RGBW ;Цвет кисти.
CALL CreateSolidBrush@4;Создать кисть.
MOV [WC.CLBKGROUND],EAX
MOV DWORD PTR [WC.CLMENNAME],0
MOV DWORD PTR [WC.CLNAME], OFFSET NAM
PUSH OFFSET WC
CALL RegisterClassA@4
;Создать окно зарегистрированного класса.
PUSH 0
PUSH [HINST]
PUSH 0
PUSH 0
PUSH DY0 ; DY0 - высота окна.
PUSH DX0 ; DX0 - ширина окна.
PUSH 100 ; Координата Y.
PUSH 100 ; Координата X.
PUSH WS_OVERLAPPEDWINDOW
PUSH OFFSET TITLENAME ;Имя окна.
PUSH OFFSET NAM ;Имя класса.
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
;-----------------------------------------
;Процедура окна.
;Расположение параметров в стеке:
;[ЕВР+14Н] LPARAM
;[ЕВР+10Н] WPARAM
;[ЕВР+0СН] MES
;[ЕВР+08H] 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_PAINT
JE WMPAINT
JMP DEFWNDPROC
WMPAINT:
;--------------------------
PUSH OFFSET PNT
PUSH DWORD PTR [EBP+08H]
CALL BeginPaint@8
MOV CONT,EAX ;Сохранить контекст (дескриптор)
;------------------------ цвет фона = цвет окна
PUSH RGBW
PUSH EAX
CALL SetBkColor@8
;------------------------ цвет текста (красный)
PUSH RGBT
PUSH CONT
CALL SetTextColor@8
;Здесь определение координат.
MOV XT,120
MOV YT,140
;Задать (создать) шрифт.
MOV lg.LfHeight,12 ;Высота шрифта.
MOV lg.LfWidth,9 ;Ширина шрифта.
MOV lg.LfEscapement,900 ;Ориентация -
MOV lg.LfOrientation,0 ;вертикальная.
MOV lg.LfWeight,400 ;Толщина линий шрифта.
MOV lg.LfItalic,0 ;курсив
MOV lg.LfUnderline,0 ;Подчеркивание.
MOV lg.LfStrikeOut,0 ;Перечеркивание.
MOV lg.LfCharSet,0 ;Набор шрифтов.
MOV lg.LfOutPrecision,0
MOV lg.LfClipPrecision,0
MOV lg.LfQuality,2
MOV lg.LfPitchAndFamily,0
PUSH OFFSET lg
;Задать название шрифта.
PUSH OFFSET NFONT
PUSH OFFSET lg.LfFaceName
CALL COPYSTR
CALL CreateFontIndirectA@4
;-------------------- выбрать созданный объект
PUSH EAX
PUSH CONT
CALL SelectObject@8
PUSH EAX
;-------------------- вычислить длину текста в пикселах текста
PUSH OFFSET TEXT
CALL LENSTR
;-------------------- вывести текст
PUSH EBX
PUSH OFFSET TEXT
PUSH YT
PUSH XT
PUSH CONT
CALL TextOutA@20
;Удалить объект "FONT".
;Идентификатор уже в стеке.
CALL DeleteObject@4
;-------------------- закрыть контекст
PUSH OFFSET PNT
PUSH DWORD PTR [EBP+08H]
CALL EndPaint@8
MOV EAX, 0
JNP 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@16
JMP FINISH
WMDESTROY:
PUSH 0 ;MB_OK
CALL PostQuitMessage@4 ;Сообщение WM_QUIT.
MOV EAX, 0
FINISH:
POP EDI
POP ESI
POP EBX
POP EBP
RET 16
WNDPROC ENDP
;---------------- ФУНКЦИЯ -----------------------
;Длина строки, [ЕВР+08Н] - указатель на строку.
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
;Процедура копирования одной строки в другую.
;Строка, куда копировать [ЕВР+08Н].
;Строка, что копировать [ЕВР+0СН].
COPYSTR PROC
PUSH EBP
MOV EBP,ESP
MOV ESI,DWORD PTR [EBP+0CH]
MOV EDI,DWORD PTR [EBP+08H]
L1:
MOV AL, BYTE PTR [ESI]
MOV BYTE PTR [EDI], AL
CMP AL,0
JE L2
INC ESI
INC EDI
JMP L1
L2:
POP EBP
RET 8
COPYSTR ENDP
_TEXT ENDS
END START