Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Последние темы форума

Показать новые сообщения »

Почтовая рассылка

Подписчиков: 11631
Последний выпуск: 19.06.2015

Создание окна MessageBox

В этой статье Вы научитесь создавать нормальное Windows-приложение, отображающее окно сообщения (messagebox) с текстом: "Программировать на Ассемблере под Win32 очень просто!".

Windows cодержит очень много ресурсов для программ. Центральное место в них занимает Win32 API. Windows API это набор очень полезных и готовых к использованию любой программой функций, расположенных внутри Windows и функционально объединенных в DLL-файлах, таких как Kernel32.dll, User32.dll и Gdi32.dll. Kernel32.dll содержит API-функции, работающие с памятью и управляющие процессами. User32.dll управляет интерфейсом Вашей программы. Gdi32.dll содержит графические функции. Кроме трех основных существуют и другие библиотеки, информация о них вам также доступна.

Windows-приложение динамически связано с dll-файлами, т.е. код API-функции не включается в исполняемый файл, в это место помещается команда безусловного перехода в то место соответствующей библиотеки, где находится данная функция. Для того, чтобы Ваша программа смогла найти необходимые API-функции в процессе работы, Вы должны включить некоторую информацию в .exe файл. Необходимая информация находится в библиотечных импортируемых функций. Вы должны связать свою программу с верной библиотекой импортируемых функций, иначе она не сможет найти необходимую функцию.

Существует два типа API-функций: ANSI и Unicode. Имена ANSI функций оканчиваются символом "А", например MessageBoxA. Имена Unicode функций оканчивается символом "W" (Wide char), например MessageBoxW. Windows 95 в основном использует ANSI функции, Windows NT - Unicode.

Чаще всего, Вы будете использовать включаемый файл, который в зависимости от платформы позволит определить, какой тип API-функций написать. Поэтому, в своей программе используйте имена функций без окончаний "А" и "W", например MessageBox.

Я хотел бы привести структуру всех Windows-приложений:

.386 
.model flat, stdcall 
.data 
.code 
   Main: 
   end Main

А теперь давайте попытаемся постепенно заполнить ее остальными необходимыми строками.

Любое Windows-приложение должно вызывать API-функцию ExitProcess для завершения программы. В заголовочном файле языка Си winbase.h мы можем видеть следующий прототип этой функции:

void WINAPI ExitProcess(UINT uExitCode);

Тип void означает, что функция ничего не возвращает. WINAPI означает использование способа передачи аргументов в функцию - stdcall. UINT - тип данных, беззнаковое целое число, разрядностью 32-бит. uExitCode - значение, передаваемое в Windows после завершения программы. Это значение в Windows не используется.

Чтобы вызвать ExitProcess из программы на Ассемблере, Вы должны определить ее прототип:

.386 
.model flat, stdcall 
ExitProcess     PROTO      ,:DWORD 
.data 
.code 
   Main: 
    INVOKE    ExitProcess, 0 
   end Main 

Это Ваше первое Windows-приложение. Сохраните его в файле msgbox.asm. Затем попробуйте ассемблировать этот файл с помощью программы-ассемблера ml.exe (удостовертесь в наличии пути к этому файлу в Вашем autoexec.bat) с помощью следующей строки:

ml.exe /c /coff /Cp msgbox.asm

/c сообщает MASM, что необходимо только ассемблировать файл, не производя линковку с помощью link.exe

/coff сообщает MASM, что файлы с расширением .obj должны создаватся в формате COFF

/Cp сообщает MASM, что он должен различать в файле строчные и прописные буквы (в именах функций, переменных и т.д.)

После этого произведем линковку (связывание) Вашего приложения с помощью команды link.exe:

link /SUBSYSTEM:WINDOWS  /LIBPATH:c:\masm611\lib  msgbox.obj  kernel32.lib

/SUBSYSTEM:WINDOWS сообщает Link, о типе создаваемого .exe файла

/LIBPATH: сообщает Link, где находятся библиотеки импортируемых функций. На моем компьютере это c:\masm611\lib

Ассемблирование и линковка вместе называются компиляцией.

Итак, мы получили приложение msgbox.ехе. Пробуем его запустить... но ничего не происходит. Не волнуйтесь, единственное, что пока делает наше приложение - закрывается после старта. Но все-таки это нормальное Windows-приложение. Обратите внимание на размер ехе-файла - 1,536 байт!

Вы определяете функцию с помощью следующей строки:

ExitProcess PROTO, :DWORD,

а потом записываете список типов параметров функции. MASM использует прототип функции для проверки количества и типа параметров, передаваемых функцию. Лучшим местом для прототипов функций является включаемый файл (include file). Вы можете поместить в этот файл описание части используемых функций и структур данных и включаете его в начале вашей программы на Ассемблере.

Вызов функции в программе осуществляется с помощью ключевого словa INVOKE:

INVOKE ExitProcess, 0

INVOKE является особым типом вызова функции. При его использовании проверяется количество и тип передаваемых аргументов, и они передаются в стек согласно выбранному по умолчанию способу вызова функций (в нашем случае используется stdcall). Используя INVOKE вместо обычного вызова, вы освободитесь от стековых ошибок при неверной передаче аргументов. Это очень удобно!

Для создания окна сообщения используется фукнция MessageBoxA. Определение этой функции выглядит следующим образом:

int WINAPI MessageBoxA(HWND hwnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType),

где hwnd - указатель на родительское окно

lpText - указатель на строку текста, который Вы хотите вывести в области отображения окна сообщения

lpCaption - указатель на текст заголовка окна сообщения

uType определяет тип иконки, а также количество и вид кнопок в окне сообщения

В Win32 HWND, LPCSTR и UINT имеют разрядность 32 бит.

Давайте изменим файл msgbox.asm включив в него вызов функции MessageBoxA:

.386 
.model flat, stdcall 
ExitProcess PROTO      ,:DWORD 
MessageBoxA PROTO      ,:DWORD, :DWORD, :DWORD, :DWORD 
.data 
   MsgBoxCaption  db "Пример окна сообщения",0 
   MsgBoxText     db "Программировать на Ассемблере под Win32 очень просто!",0 
.const 
   NULL        equ  0 
   MB_OK    equ  0 
.code 
   Main: 
    INVOKE    MessageBoxA, NULL, ADDR MsgBoxText, ADDR MsgBoxCaption, MB_OK 
    INVOKE    ExitProcess, NULL 
   end Main 

Скомпилируйте программу, как мы это уже сделали выше. Но в данном случае при линковке необходимо в конце строки добавить user32.lib, т.к. описание функции MessageBoxA находится именно в этом файле. После компиляции, запустите программу - Вы увидите окно сообщения с текстом "Программировать на Ассемблере под Win32 очень просто!".

Вернемся опять к исходному тексту программы. В секции .data мы определили две строки, закрытые нулем. Запомните: в Windows все строки должны быть закрыты нулем (двоичным, т.е. числом 0, а не символом "0"). В секции .const мы определили две константы. Мы использовали константы для большей понятности программы (константа MB_OK больше говорит о типе окна, чем число 1, хотя по сути это одно и тоже).

И на последок о аргументах функции MessageBoxA. Первый аргумент - NULL, говорит о том, что окно сообщения не имеет родителя. Оператор ADDR используется, когда необходимо передать не значение переменной, а ее адрес. Последний аргумент - MB_OK, сообщает о том, что окно будет иметь иконку в виде восклицательного знака и кнопку OK.

Оставить комментарий

Комментарий:
можно использовать BB-коды
Максимальная длина комментария - 4000 символов.
 

Комментарии

1.
Аноним
+3 / -1
Мне нравитсяМне не нравится
6 марта 2006, 14:16:30
Очень интересная статья и отличнейшее обьяснение! Автор молодец!!! именно для чайников (для меня) -всё понятно описано. Хотелось бы ещё статеек таких-же!
2.
Аноним
+3 / -0
Мне нравитсяМне не нравится
22 декабря 2005, 19:32:38
Нигде не видел более ясных и понятных объяснений!
Пожалуйста, продолжайте!
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог