4 Оконные приложения
Простейшая программа для Windows состоит из двух функций – главной и оконной функции. Главная функция должна выполнять следующие действия: определение класса окна, регистрация класса окна, создание окна данного класса, отображение окна, запуск цикла обработки сообщений.
Когда программа, написанная для Windows, начинает выполняться впервые, ей необходимо определить и зарегистрировать класс окна. При регистрации класса окна Windows сообщается об основных атрибутах и функциях окна. Однако регистрация не означает создание окна. Класс окна определяется путем заполнения полей структуры WNDCLASS (ее вид можно посмотреть в любой справочной системе Win32:PlatformSDK).После определения полей структуры класс окна следует зарегистрировать функцией
ATOM RegisterClass(CONST WNDCLASS * lpWindowClass);
Функция возвращает значение типа word, идентифицирующее зарегистрированный класс окна. Когда класс окна определен и зарегистрирован, приложение может создавать окна этого класса, используя функцию
HWND CreateWindowEx(
DWORD dwExStyle, // дополнительный стиль окна
LPCSTR lpClassName, // имя класса окна
LPCSTR lpWindowName, // заголовок окна
DWORD dwStyle, // стиль окна
int X, int Y, // координаты верхнего левого угла
int nWidth, int nHeight, // размеры окна
HWND hWndParent , // дескриптор родительского окна
HMENU hMenu, // дескриптор главного меню
HINSTANCE hInstance, // дескриптор приложения
LPVOID lpParam); // дополнительная информация
Когда окно создано, оно еще не отображается на экране. Для того чтобы отобразить окно, следует вызвать функцию ShowWindow.
Все приложения Windows запускают цикл обработки сообщений. Этот цикл выбирает сообщения из очереди сообщений приложения и направляет их обратно ОС, которая вызывает оконную функцию приложения, передавая ей указанные сообщения в качестве параметров. Одна из причин реализации такой схемы состоит в том, что программа должна возвращать управление планировщику Windows, который распределяет время центрального процессора, чтобы обеспечить его оптимальную загрузку.
Оконная функция должна обрабатывать все сообщения, относящиеся к данному окну. В качестве параметров этой функции передаются первые четыре поля структуры MSG.
Ниже представлена простейшая программа, представляющая собой шаблон полномасштабного Windows–приложения.
.386
.model flat, stdcall
include windows.inc ;описание структур и
;идентификаторов событий
includelib import32.lib
.data
szClassName db 'WndClass32', 0 ;имя класса окна
szWindowName db 'Win32 ассемблерный шаблон', 0 ;заголовок окна
;структура, описывающая класс окна
wc WNDCLASSEX <4*12,0,offset WndProc, 0, 0, ?, ?, ?,\
COLOR_WINDOW, 0,offset szClassName,0>
;структура, в которой возвращается сообщение
messages MSG <?>
.code
start:
xor ebx, ebx
;получить идентификатор приложения и сохранить его в eax
call GetModuleHandle, ebx
mov esi, eax
;заполнить и зерегистрировать класс окна приложения
mov wc.hInstance, eax ;идентификатор предка
;загрузить иконку
call LoadIcon, ebx, IDI_APPLICATION
mov wc.hIcon, eax ;идентификатор иконки
call LoadCursor, ebx, IDC_ARROW ;загрузить курсор
mov wc.hCursor, eax ;идентификатор курсора
;зарегистрировать класс окна
call RegisterClassEx, offset wc
;создать окно
mov ecx, CW_USEDEFAULT
call CreateWindowEx, ebx, offset szClassName,\
offset szWindowName, WS_OVERLAPPEDWINDOW,\
ecx, ecx, ecx, ecx, ebx, ebx, esi, ebx
;отобразить окно
call ShowWindow, eax, SW_SHOWNORMAL
call UpdateWindow, eax ;перерисовать окно
;цикл сообщений
mov edi, offset messages
;получить сообщение от окна
call GetMessage, edi, 0, 0, 0
test eax, eax ;если получено WM_QUIT
jz EndMessageLoop ;закончить
call TranslateMessage, edi
call DispatchMessage, edi
jmp MessageLoop ;продолжить цикл сообщений
EndMessageLoop: ;завершить программу
call ExitProcess, 0
;оконная процедура – здесь обрабатываются сообщения окна
WndProc proc uses ebx edi esi,\
_hWnd:dword, _uMsg:dword, _wParam:dword, _lParam:dword
;начать обработку сообщений
cmp _uMsg, WM_DESTROY ;если окно не разрушается
jne NotWmDestroy ;дальнейший анализ сообщения
;иначе закочить выполнение программы
call PostQuitMessage, 0
jmp EndWmCheck ;посылая сообщение WM_QUIT
NotWmDestroy: ; дальнейший анализ сообщения
;если не принято обрабатываемых сообщений
;вызвать стандартный обработчик сообщения
call DefWindowProc,_hWnd, _uMsg, _wParam, _lParam
EndWmCheck:
ret ;возврат в Windows
endp
end start
Все необходимые объявления вынесены в отдельные заголовочные файлы. Файл windows.inc содержит описание используемых констант, структур данных и функций Win32 API , используемых в программе.
Для создания более функциональной программы, следует должным образом расширить представленный ассемблерный шаблон, при необходимости изменив лишь строки, связанные с настройкой окна, иконок, курсора и т.д.