Обучающие курсы:

Обучение профессии "Разработчик C#" + стажировка в Mail.ru
Обучение профессии "Разработчик Python" + трудоустройство
Обучение профессии "Веб-разработчик" + стажировка в Mail.ru


Главная страница
Библиотека (скачать книги)
Скачать софт
Введение в программирование
Стандарты для C++
Уроки по C#
Уроки по Python
HTML
Веб-дизайн
Ассемблер в среде Windows
ActiveX
Javascript
Общее о Линукс
Линукс - подробно
Линукс - новое
Delphi
Паскаль для начинающих
Турбопаскаль
Новости
Партнеры
Наши предложения
Архив новостей





Исходный текст программы довольно сложен, и перед его анализом имеет
смысл рассмотреть более подробно структуру программы в целом. Поскольку
функция winMain является стандартной, рассматривать ее мы не будем.
Нас будет интересовать только работа оконной процедуры WndProc. Процедура
содержит несколько обработчиков сообщений. Рассмотрим их более
подробно как в плане реализации программного кода, так и в плане взаимодействия
друг с другом и с операционной системой.

• Обработчик сообщения WMPAINT выполняет обновление (перерисовку)
окна приложения при инициализации программы. При изменениях
размера окна или при перекрытии окном другого приложения операционная
система генерирует сообщение WMPAINT. Чтобы обеспечить прорисовку
окна, программный код обработчика посылает сообщение
WM_PRINT нашему приложению.

• Обработчик сообщения WMRBUTTONDOWN вызывается при нажатии на
правую кнопку мыши. При этом приложение должно изменить вид
строк текста в клиентской области окна. Чтобы обеспечить такую возможность,
программный код обработчика посылает сообщение WMPRINT
нашему приложению.

• Обработчик сообщения WMPRINT, так же как и WMPAINT, выполняет перерисовку клиентской области окна приложения. Оконная процедура
передает управление обработчику при получении соответствующего сообщения
от операционной системы. Кроме этого, здесь же выполняется
вся обработка текстовых строк, включая установки цвета и шрифтов.
Новым для нас является то, что оконная процедура может посылать сообщения
сама себе. Этот прием очень часто используется программистами. Реализуется
такой подход довольно просто — необходимо в нужном месте оконной
процедуры послать сообщение. Заметим, что посылать сообщения можно не
только самим себе^ но и другому приложению! Для этих целей служит функция
WIN API sendMessage, принимающая в качестве параметров дескриптор
окна приложения, которому посылается сообщение, идентификатор (тип)
сообщения, первый параметр сообщения (wParam) и второй параметр сообщения (lParam).

Функция SendMessage имеет следующий синтаксис:
LRESULT SendMessage (HWND hWnd, // дескриптор окна, которому
// посылается сообщение
UINT Msg, // сообщение
WPARAM wParam, // первый параметр
LPARAM lParam); // второй параметр

Следует иметь в виду то, что для каждого сообщения определены свои параметры.
Для WM_PRINT вызов функции SendMessage выполняется также,
как, например, в обработчике WMRBUTTONDOWN:
cmp uMsg, WM_RBUTTONDOWN
j ne next_3
invoke SendMessage, hWin, WM_PRINT, hdc, PRF_CLIENT
Здесь в качестве первого параметра выступает дескриптор контекста hdc, а в
качестве второго — константа P R F C L I E N T , означающая, что необходимо
перерисовать клиентскую область окна.
После анализа структуры программного кода детально рассмотрим обработчик
сообщения WMPRINT, который, как мы знаем, выполняет всю основную
работу с текстом и шрифтами. Нас будет интересовать работа функции
SetTextcoior в этом обработчике. Фрагмент исходного текста, где вызывается
эта функция:
colorRef DD 0FlAA7Ch
mov CL, 4
rol colorRef, CL
invoke SetTextColor, hdc, colorRef
Переменная colorRef в секции объявления данных определяет цветовую
комбинацию. В двойном слове значения первых трех байт определяют относительную интенсивность цветов:
• байт 0 (7Ch) — красного;
• байт 1 (ААЬ) — зеленого;
• байт 2 (Fih) — синего.
Старший байт должен быть равен 0. Я задал произвольные значения интенсивности
цветов, а для демонстрации изменения цвета текста использовал
команду циклического сдвига гог ассемблера. Цвет текстовых строк будет
меняться при нажатии правой кнопки мыши, изменении размеров окна
приложения, восстановлении окна приложения после перекрытия.
Далее приводится вариант оконной процедуры этой программы, разработанный
с использованием только ассемблерных команд. Команды, смысл
которых не очевиден, снабжены комментариями. Исходный текст процедуры
WndProc приведен в листинге 5.10.

WndProc proc hWin
uMsg
:DWORD,
:DWORD,
wParam :DWORD,
1Param :DWORD
LOCAL hdc
LOCAL ps
LOCAL rect
LOCAL myFont
HDC
PAINTSTRUCT
RECT
HFONT
LOCAL tm
LOCAL tx, ty
LOCAL cnt
LOCAL x, у
rTEXTMETRIC
:DWORD
:DWORD
:DWORD
cmp
jne
lea
push
push
call
mov
push
push
push
call
lea
push
push
call
ret
next_l:
cmp
jne
uMsg, WM_PAINT
next_l
ESI, ps
ESI
hWin
BeginPaint
hdc, EAX
PRF_CLIENT
hdc push WM_PRINT
[EBP+8]
SendMessage
ESI, ps
ESI
hWin
EndPaint
DWORD PTR [EBP+12], WM_PRINT
next 2
дескриптор окна hWin
/второй параметр по смещению +12
push [ЕВР+8] call GetDC mov hdc, EAX
mov CL, 4
rol colorRef, CL
push
push
call
colorRef
hdc
SetTextColor
300 Гпава 5
lea ESI,rect
push ESI
push [EBP+8]
call GetciientRect
lea ESI,tm
push ESI
push hdc
call GetTextMetrics
mov EAX, tm.tmHeight
mov ECX, 3
div ECX
mov x, EAX
mov EAX, rect.bottom
sub EAX, rect.top
xor EDX, EDX
mov ECX, 5
div ECX
mov y, EAX
push vHeight
mov cnt, 1
lea ESI, myStr
push offset myf
push mypitch
push myq
push myclip
push myout
push myansi
push 0
push 0
push 0
push 600
push 0
push 0
push 0
push
call
vHeight
CreateFont push myFont
push
call
call
mov
push
push
hdc
SelectObject
LenStr
Is, EAX
Is
ESI
push ESI
push
push
push
call
add
mov
add
add
inc
cmp
У
x
hdc
TextOut
vHeight, 3
EAX, ty
y, EAX
ESI, Is
ESI
cnt, 3
inc
cont
cnt
jmp
cont:
push
push
call
[EBP+8]
push
push
push
next_raw
hdc
[EBP+8]
ReleaseDC
call GetDC
hdc
WM_PRINT
[EBP+8]
DWORD PTR [EBP+12]
push PRF CLIENT
push
call SendMessage push
push [EBP+8]
call ReleaseDC
push NULL
hdc
302 Глава 5
call PostQuitMessage
xor EAX, EAX
ret
next_4:
push lParam
push wParam
push uMsg
push hWin
call DefWindowProc
ret
WndProc endp


 
 
 

Библиотека программиста. 2009.
Администратор: admin@programmer-lib.ru