Ассемблер под Windows №5

MessageBox, за чем он нужен?


Доброго время суток, уважаемые подписчики. Итак, мы уже написали штаблон окна. В этом уроке мы его немного дополним, а также обсудим все процедуры Windows, которые мы использовали!


Вот список всех процедур, которые мы использовали. Первый столбец содержит название процедуры, второй - параметры, третий - описание!
Процедуры из kernel32.dll:
GetModuleHandleмодульВозвращает указатель на заданый модуль
ExitProcessкод выходаЗавершает приложение
Процедуры из user32.dll:
DispatchMessageадрес структуры сообщенийРаспаковывает сообщения для процедуры окна
TranslateMessageадрес структуры сообщенийПереводит сообщение о нажатии клавиши в сообщение клавиши
GetMessageПервое сообщение
Последнее сообщ.
Указатель на окно
Адрес струк. сообщ.
Получает сообщения заданного объекта в заданную структуру сообщения
LoadIconУказатель иконки
Указатель на процедуру
Устанавливает заданному приложению заданную иконку
UpdateWindowуказатель на процедуруПозылает заданной процедуре сообщение wm_paint
ShowWindowПараметры
указатель на проц.
Устанавливает вид окна
DefWindowProcПервое сообщение
Последнее сообщ.
Указатель на окно
Адрес струк. сообщ.
Передаёт управление процедуре окна по умолчанию
PostQuitMessageКод выходаПосылает сообщения выхода всем частям приложения
RegisterClassExАдрес структуры параметров окнаРегистрирует структуру для последующего создания окна
LoadCursorУказатель курсора
Указатель на процедуру
Устанавливает заданному приложению заданный курсор
DestroyWindowуказатель на окноУничтожает окно

Вы, наверно, уже заметили, что в таблице нет процедуры CreateWindowEX. Я специально не поместил её в таблицу, так как она получает 12 параметров, и Вы бы только больше запутались увидев её в таблице. Её мы рассмотрим отдельно. Процедура создаёт "окно" заданного класса в заданное место. При этом она получает следующие параметры:
- указатель на данные создания окна
- указатель на приложение, вызывающие окно
- указатель на меню
- указатель на окно-отца
- высота окна
- длинна окна
- вертикальное положение окна
- горизонтальное положение окна
- стиль окна
- имя окна
- класс окна
- дополнительные параметры стиля окна
Возвращаемый в eax параметр является указателем на окно.


А теперь займёмся повторением MessageBox и улучшением нашего окна! Итак, что такое MessageBox. Многие считают, что это просто вывод сообщения, однако это всего лишь заблуждение. Messagebox бывают разные, и то, как они выглядят зависит от заданного типа. Вот основные типы:
типкол-во кнопоккнопки
MB_ABORTRETRYIGNORE3abort,retry,ignore
MB_OK1OK
MB_OKCANCEL2OK,Cancel
MB_RETRYCANCEL2retry,cancel
MB_YESNO2yes,no
MB_YESNOCANCEL3yes,no,Cancel
При этом в русском Windows все названия кнопок будут русскими, в немецком, соответсвенно, немецкими. Это делает MessageBox очень полезной вещью. При этом стоит заметить, что тот же самый эффект можно достигнуть написав диалог, использующий две кнопки, однако это заняло бы гораздо больше места.
Приступим непосредственно к коду. Писать программу с нуля я считаю не нужным, поэтому я лишь добавлю пару строчек в программу окна, рассматриваемую до этого. Добавленные части я выделил красным!
include def32.inc
include user32.inc
include kernel32.inc
 .386
 .model flat

 .const
class db "window class 1",0
name_ db "Da window!",0
sure  db "Предупреждение",0
ask   db "Вы уверены, что хотите выйти?",0

 .data
wc   wndclassex<4*12, CS_HREDRAW or CS_VREDRAW, offset win_proc, 0, 0, ?, ?, ?, COLOR_WINDOW+1, 0, offset class, 0>

 .data?
msg_ msg <?,?,?,?,?,?>

;сам код
 .code
_start: ;начальная метка
 xor ebx,ebx
 push ebx
 call GetModuleHandle
 mov esi,eax
 mov dword ptr wc.hInstance,eax
 push IDI_APPLICATION
 push ebx
 call LoadIcon
 mov wc.hIcon,eax
 push idc_arrow
 push ebx
 call LoadCursor
 mov wc.hCursor,eax
 push offset wc
 call RegisterClassEx
 mov ecx,CW_USEDEFAULT
 push ebx
 push esi
 push ebx
 push ebx
 push ecx
 push ecx
 push ecx
 push ecx
 push WS_OVERLAPPEDWINDOW
 push offset name_
 push offset class
 push ebx
 call CreateWindowEx
 push eax
 push SW_SHOWNORMAL
 push eax
 call ShowWindow
 call UpdateWindow
 mov edi,offset msg_
main_:
 push ebx
 push ebx
 push ebx
 push edi
 call GetMessage
 test eax,eax
 jz exit_
 push edi
 call TranslateMessage
 push edi
 call DispatchMessage
 jmp main_
exit_:
 push ebx
 call ExitProcess

win_proc proc
 push ebp
 mov ebp,esp

wp_hWnd   equ dword ptr [ebp+08h]
wp_uMsg   equ dword ptr [ebp+0Ch]
wp_wParam equ dword ptr [ebp+10h]
wp_lParam equ dword ptr [ebp+14h]

cmp wp_uMsg,wm_close
 jne not_close
 push MB_YESNO
 push offset sure
 push offset ask
 push 0
 call MessageBox
 cmp eax,IDYES
 je not_close
 mov wp_uMsg,0
 jmp not_
not_close:
 cmp wp_uMsg,WM_DESTROY
 jne not_
 push 0
 call PostQuitMessage
 jmp end_
not_:
 leave
 jmp DefWindowProc
end_:
 leave
 ret 16
win_proc endp

 end _start
При этом в файл user32.inc следует дописать следующие строки:
 extrn __imp__MessageBoxA@16:dword
MessageBox equ __imp__MessageBoxA@16
А в файл def32.inc
MB_YESNO equ 4
IDYES    equ 6
WM_CLOSE equ 10h
Причём, если Вы получили файлы inc от меня, то проверьте, возможно это уже записано в них! Тогда нет надобности записовать всё дважды. Если что не работает, пишите.


Вот вроде и всё! Если есть какие вопросы, пишите, обязательно отвечу. В следующем уроке рассмотрим меню! Пишите, Dark_Lord@RusFAQ.ru и Dark_Lord@land.ru.

Сайт управляется системой uCoz