Assembler - Просто и Эффективно. Глава #10 - Ресурсы
Assembler
Глава #10 - Ресурсы
Ресурсы.
Программа может содержать ресурсы - изображения, иконки, курсоры, меню, описание окон, файлы и т.д. Использование ресурсов значительно упрощает создание окон с большим количеством контролов и меню. Иконки, курсоры и изображения позволяют улучшить внешинй вид программы, сделать интерфейс более юзабельным.
-------------------------------
Использование ресурсов
Для использования ресурсов нужно:
создать т.н .RC script - файл с расширением .rc содержащий описание ресурсов.
Откомпилировать его в .res файл при помощи компилятора ресурсов.
указать при линковке .res файл.
При использовании MASM, создание программы с ресурсами выглядит следующим образом:
ml.exe /c /coff /Cp AnyFile.asm - компиляция программы - получим .obj файл
rc.exe AnyFile.rc - компиляция ресурсов - получим .res файл
link.exe /subsystem:windows AnyFile.obj AnyFile.res - линковка - .exe файл.
-------------------------------
Общая информация
Существует множество программ для редактирования и создания как .rc и .res файлов, так и модификации ресурсов в готовой программе. Редакторы ресурсов обычно входят в пакет с современным компилятором / средой разработки, но существуют и отдельные програмные продукты. Часто в комплект входит редактор изображений /иконок/ курсоров и т.д. Использование редактора ресурсов значительно упрощает описание окон т.к избавляет от необходимости вычислять координаты контролов.
Можно редактировать .rc файл используя любой текстовый редактор.
Скрипт имеет стиль языка "C". Каждый элемент ресурсов идентифицируется номером или именем; принадлежностью к некому типу (который тоже определяется именем либо числом), и языком (с.м выражение LANGUAGE)
Пример объявления ресурса: 123 icon AnyIcon.ico
Данный ресурс имеет номер 123, тип icon и данные из файла AnyIcon.ico.
Типы ресурсов под номерами от 1 до 255 зарезервированы, некоторые из них имеют специальное назначение и определяются константами RT_. Кроме общих функций Windows работы с ресурсами, существуют функции, работающие с конкретным типом, например тип icon означает иконку, и используется ф-цией LoadIconA. Данные ресурсов RT_ типов имеют определенный формат, описанный в MSDN.
Ресурсы, тип которых задается именем или числом более 255 обычно используются для добавления файлов в программу.
Пример: в .rc файле: 123 456 AnyFile.txt - объявим ресурс номер 123 типа 456, содержание которого будет из файла AnyFile.txt.
Для доступа к данным ресурса можно использовать следующий код:
invoke GetModuleHandle,0
mov [hInst],eax
invoke FindResource,[hInst],123,456 ; 0 при ошибке.
mov [hRes],eax
;в eax - адрес структуры IMAGE_RESOURCE_DATA_ENTRY ресурса.
;[eax]+[hInst] - адрес даных ресурса, [eax+4] - размер (не документировано).
invoke SizeofResource,[hInst],[hRes]
mov [ResSize],eax
invoke LoadResource,[hInst],[hRes]
invoke LockResource,eax
в eax получим адрес данных ресурса в памяти, [ResSize] - размер данных.
Некоторые ф-ции работы с ресурсами RT_ типов используют аналогичный алгоритм для получения адреса данных ресурса, а после вызывают схожую по названию ф-цию, но содержащую в названии слово Indirect. Т.к формат данных ресурсов описан в MSDN, можно создать данные соответствующего формата в самой программе и использовать "Indirect" ф-цию.
Для использования ресурсов из другого файла, загрузите его при помощи ф-ции LoadLibraryEx с флагом LOAD_LIBRARY_AS_DATAFILE.
Чтобы просмотреть данные некоторых ресурсов, можно использовать протокол res://
Дерево ресурсов программы можно посмотреть при помощи программы PE Viewer с сайта рассылки.
С.м также в MSDN: User Interface Design and Development -> Windows Managment -> Windows User Interface -> Resources
и Visual Tools and Languages ->Platform SDK Tools -> SDK Documentation -> Resource Tools -> Resource Compiler.
-------------------------------
Диалоги (Dialog)
Ресурсы типа DIALOG, DIALOGEX используются для создания окон с контролами. Для отображения окна, описанного в ресурсах, обычно используются ф-ции:
DialogBoxParam - создать / отобразить окно. Возврат произойдет при вызове ф-ции EndDialog из процедуры обработки сообщений, указанной в качестве параметра. Возвращает 0 или -1 при ошибке, или число, которое было указано завершающей ф-ции EndDilalog. Процедура обработки сообщений должна возвращать FALSE если сообщение не обработано и TRUE если обработка произошла. DefWindowProc вызывать не нужно. Если необходимо работать с хэндлом окна, добавьте код в обработчик сообщения WM_INITDIALOG.
Ф-ция DialogBoxParam сама организовывает цикл обработки сообщений, используя класс "#32770", процедура обработки сообщений которого вызывает указаную в параметре вызова ф-ции процедуру, и действует в зависимости от полученого результата. Поэтому не нужно указывать класс в описании ресурса.
Использовать DialogBoxParam удобно для отображения простых диалогов, сообщений пользователю.
Для создания полнофункционального окна из ресурсов используется ф-ция CreateDialogParam. Она создает окно, и указаные дочерние окна, возвращая хэндл главного окна или 0 при ошибке. До вызова ф-ции необходимо зарегистрировать класс, указаный в ресурсе, а после - организовать цикл обработки сообщений.
В примере из главы #9 создавались шрифты для контролов, главное окно, вычислялись его размеры. Создавались два дочерних контрола; устанавливались в них созданные шрифты. Ф-ция CreateDialogParam делает аналогичную работу автоматически на основе ресурса.
О процедуре обработки сообщений, регистрации классов и цикле обработки сообщений можно узнать из главы #7.
-------------------------------
Функции создания диалогов используют ф-цию CreateWindowEx для создания окна и контролов. Поддерживаются только одноуровневые диалоги т.е дочерние окна не могут в описании содержать других дочерних окон. Кроме WS_ стилей, диалоги также могут иметь DS_ стили, неподдержываемые ф-цией CreateWindowEx.
Для получения хэндла элемента диалога, можно использовать ф-цию GetDlgItem. Для упрощения работы с контролами диалога, сущетвуют ф-ции, имеющие в названии слово "DlgItem", например GetWindowTextA - GetDlgItemTextA.
Координаты окон указываются не в точках, а в т.н "dialog template units". Для конвертации координат в точки используется ф-ция MapDialogRect
С.м MSDN: User Interface Design and Development ->Windows Managment -> Windows User Interface -> Windowing ->Dialog Boxes
MSDN - это справка по программированию под Windows. Распространяется на CD. Содержит полное описание большинства функций и их использования. Без MSDN обучаться программированю под Windows будет намного сложнее.
-------------------------------
Пример
.asm файл
.386
.model flat,stdcall
include c:\masm32\include\windows.inc
include c:\masm32\include\kernel32.inc
includelib c:\masm32\lib\kernel32.lib
include c:\masm32\include\user32.inc
includelib c:\masm32\lib\user32.lib
.data
.code
MyDlgProc proc hWnd:dword,uMsg:dword,wParam:dword,lParam:dword
cmp uMsg,WM_COMMAND
jnz NotWmCommand
cmp [wParam],500 ;500 - ID меню
jz CloseDilalog
NotWmCommand:
cmp uMsg,WM_CLOSE
jnz NotWmClose
CloseDilalog:
invoke EndDialog,hWnd,0
mov eax,TRUE ;xor eax,eax/inc eax
ret
NotWmClose:
mov eax,FALSE ;xor eax,eax
ret
MyDlgProc endp
start:
invoke GetModuleHandle,0
invoke DialogBoxParam,eax,200,0,offset MyDlgProc,0
invoke ExitProcess,0
end start
-------------------------------
.rc файл. Содержит иконку и изображение. Иконка будет отображаться в проводнике как иконка файла. Изображение можно нарисовать в программе Paint. Формат должен быть .bmp
-------------------------------
#include "c\masm32\include\resource.h"
100 icon AnyIcon.ico //Если у вас нет иконки для тестов - закомментируйте
600 bitmap AnyImage.bmp
MainMenu MENU
{
POPUP "&File"
{
MENUITEM "&Exit",500
}
}
200 DIALOGEX 0, 0, 90, 46
STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Dialog Box"
MENU MainMenu
//CLASS "AnyClass" //закомментировано. класс нужно указывать для CreateDialogParam
FONT 8 , "MS Sans Serif"
{
CONTROL "", 0, "static", SS_ETCHEDFRAME | WS_CHILD | WS_VISIBLE, 5, 0, 80, 1
CONTROL 600, 0, "static", SS_BITMAP | SS_CENTERIMAGE | SS_SUNKEN | WS_CHILD | WS_VISIBLE, 5, 6, 35, 35
CONTROL "Dialog Box Example\x85", 0, "static", SS_CENTER | WS_CHILD | WS_VISIBLE, 45, 6, 40, 19
CONTROL "E&xit", 500, "button",WS_TABSTOP|WS_CHILD |WS_VISIBLE, 45, 26, 40, 15, 0
}
-------------------------------
Скрипт для компиляции
Для компиляции программ удобно использовать следующий .bat файл:
echo off
cls
set AsmDir=c:\masm32\bin
%AsmDir%\ml.exe /c /coff /Cp %1.asm
if exist %1.rc goto CompileWithRC
echo -=File without resources=-
%AsmDir%\link.exe /subsystem:windows %1.obj
goto ScriptEnd
:CompileWithRC
%AsmDir%\rc.exe %1.rc
%AsmDir%\link.exe /subsystem:windows %1.obj %1.res
:ScriptEnd
pause
Скопируйте этот текст в текстовый файл, и укажите ему расширение .bat
Запускать, указывая в параметре директорию и имя без расширения. .rc файл должен иметь тоже имя, что и .asm.
Пример: сompile.bat c:\asm\anyfile
-------------------------------
Вы можете проголосовать за рассылку внизу письма.
-------------------------------
Содержание дальнейших выпусков зависит от вас. Будут разъясняться те темы, которые непонятны большинству читателей. Присылайте свои вопросы и предложения по адресу: asm32@nm.ru . -------------------------------
Автор рассылки Владимир Пронин. Любое коммерческое использование материалов рассылки без ведома и прямого согласия автора запрещено.
Письма присланные автору рассылки могут быть опубликованы целиком или частично без предварительного уведомления. Если вы не хотите, чтобы ваше письмо было опубликовано укажите это в начале письма.
Перепечатка материалов разрешена только с непосредственной ссылкой на asm32.nm.ru