Работа с двоичными ресурсами (.rc) в MS Visual C++ 2010 Express
В бесплатной MS Visual C++ 2010 Express редактор двоичных ресурсов отсутствует. Но это не беда, ведь ресурсы (и скрипты для них) можно создавать в сторонних редакторах. После этого их останется только импортировать в MSVC++ . Хороший пример такого редактора - программа ResEdit. О ней мы и расскажем в данной статье.
Содержание
- Работа с двоичными ресурсами (.rc) в MS Visual C++ 2010 Express
- Структура исполняемого PE-модуля (теория)
- Двоичные ресурсы исполняемых PE-файлов (тоже теория)
- Создаём базовое оконное приложение Windows
- Мутим двоичные ресурсы в MSVC+ + 2010 Express
- Итоги
- Источники
Структура исполняемого PE-модуля (теория)
Рис.1 Структура PE-файла
Сокращение PE расшифровывается как Portable Executable (от англ. "переносной исполняемый"). Данный формат пришёл из UNIX, где аналогичный формат назывался COFF (Common Object File Format - Стандартный формат объектных файлов). Microsoft подвергла COFF-формат значительной переработке и в теперешнем виде исполняемые PE-файлы используются в среде Windows повсеместно. В группу PE-файлов входят:
- Исполняемые файлы приложений Windows (.exe);
- Динамически подсоединяемые библиотеки (Dynamic Link Library - DLL);
- Объектные модули (obj);
- Драйверы режима ядра.


Сокращение MZ - это инициалы сотрудника компании Microsoft Марка Збиковски (Mark Zbikowscki), разработчика структуры исполняемых модулей в ОС MS-DOS.
После сигнатуры MZ в PE-модуле идёт стандартный заголовок MS-DOS, а далее - маленькая программа-заглушка, которая обычно выводит на экран консоли сообщение: "This programm cannot be run in DOS mode." ("Эта программа не может выполняться в MS-DOS."), после чего приложение завершает свою работу. Данный кусок кода часто называют stub (от англ. "заглушка").
Сразу после заголовков MZ и PE располагается таблица секций, состоящая из структур по 40 байтов каждая. Вот наиболее часто встречающиеся секции, генерируемые различными компиляторами:1
СЕКЦИЯ | ОПИСАНИЕ |
---|---|
.text | Секция содержит исполняемый код (Microsoft). |
CODE | Секция содержит исполняемый код (Borland). |
.data | Секция, содержащая инициализированные глобальные переменные (Microsoft). |
.bss | Все неинициализированные данные. Размер секции в файле равен нулю. |
.CRT | Секция, содержащая инициализированные данные (Microsoft). |
CRT | Секция, содержащая инициализированные данные (Borland). |
.rdata | Данные доступны только для чтения (константы, отладочная информация). |
По таблице секций можно вычислить положение секции в файле, её размер и, тем самым, получить возможность посмотреть, что в ней хранится.
Двоичные ресурсы исполняемых PE-файлов (тоже теория)
Форматы исполняемых файлов, используемых в Windows, позволяют хранить внутри них особые типы данных - ресурсы. К стандартным ресурсам Windows относятся:- Диалоговые окна (Dialog)
- Значки (Icons)
- Определения меню (Menu)
- Определения панелей инструментов (Toolbar)
- Растровые изображения (Bitmap)
- Курсоры мыши (Cursor)
Помимо редактора ресурсов, MS Visual C++ также включает в себя интерпретатор встроенного языка описания ресурсов. Его директивы можно увидеть, если открыть в текстовом редакторе, предварительно созданный в MS Visual C++, шаблон ресурсов (файл с расширением .rc).
Ресурсы можно создавать двумя способами:
- Описать ресурсы программы в текстовом ASCII файле с расширением RC. (Этот способ практически не используется.)
- Создать ресурс при помощи специализированного редактора ресурсов в режиме WYSIWYG (What You See Is What You Get - "Что видишь, то и получаешь").
Существуют также редакторы ресурсов от сторонних производителей (ResEdit, PE-Editor, Resource Workshop и др.). Все они имеют схожий функционал и пользовательский интерфейс, не требующий много времени на освоение.
- Стандартный (заменим значок на тулбаре);
- Кастомный (опишем и разместим внутри exe-шника рандомный двоичный файл).
Создаём базовое оконное приложение Windows
- В MS Visual C++ 2010 Express создай Проект базового оконного приложения WinTest01.
О том, где взять и как правильно установить MS Visual C++ 2010 Express, читай здесь: MS Visual Cpp 2010 Express. Установка и указание путей к DirectX SDK.


Напомним, что создаваемый проект изначально должен быть пустым, для чего ставится соответствующая галка в мастере (См. Рис.2).
Рис.2 Создаём пустой проект Windows-приложения
Добавляем в Проект файл исходного кода WinMain.cpp
- Добавь в Проект WinTest01 файл исходного кода WinMain.cpp.
- Добавь в него исходный код из статьи Создание приложений Сpp Win32:
WinMain.cpp
// Файл: WinMain.cpp // Описание: Шаблон оконного приложения Windows. Простейшее (базовое) приложение Windows, // выводящее на экран окно. // www.igrocoder.ru 2015 // При использовании просьба указывать ссылку на источник. #define STRICT #define WIN32_LEAN_AND_MEAN // Уменьшаем кол-во используемых компонентов в программе. #include <windows.h> // Прототип функции WinMain int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR szCmdLine, int nCmdShow); // Объявление оконной процедуры LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); // Реализация главной функции программы int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { HWND hWnd; // Дескриптор окна MSG msg; // Структура сообщения WNDCLASSEX wndClass; // Объявляем экземпляр класса программы на базе WNDCLASSEX // Заполняем структуру оконного класса wndClass.cbSize=sizeof(wndClass); wndClass.style=CS_CLASSDC; // Поочерёдный доступ к контексту устройства (Device Context) wndClass.lpfnWndProc=WindowProc; // Оконная процедура wndClass.cbClsExtra=0; wndClass.cbWndExtra=0; wndClass.hInstance=hInstance; // Экземпляр окна wndClass.hIcon=LoadIcon(NULL, IDI_APPLICATION); // Пиктограмма приложения wndClass.hIconSm=LoadIcon(NULL, IDI_APPLICATION); // Малая пиктограмма приложения wndClass.hCursor=NULL; // Курсор при наведении на окно wndClass.hbrBackground=NULL; // Закрашиваем окно белым цветом wndClass.lpszMenuName=NULL; // Дескриптор Главного меню окна. Сейчас оно не нужно wndClass.lpszClassName="GameClass"; // Обзываем оконный класс. // Если класс не зарегистрируется, досрочно прерываем выполнение программы if(!RegisterClassEx(&wndClass)) return FALSE; // Создание окна на основе зарегистрированного класса hWnd=CreateWindow( "GameClass", // Класс окна. "My game title", // Текст заголовка (на верхнем тулбаре). WS_OVERLAPPEDWINDOW, // Обычное окно с кнопками в правом верхнем углу. 0, 0, // Координаты X и Y GetSystemMetrics(SM_CXSCREEN), // Ширина окна GetSystemMetrics(SM_CYSCREEN), // Высота окна NULL, // Дескриптор родительского окна NULL, // Дескриптор меню hInstance, // Дескриптор экземпляра приложения NULL); // Дополнительные данные if(hWnd==NULL) return(FALSE); // Собственно, показываем окно ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); // Очищаем структуру сообщения ZeroMemory(&msg, sizeof(MSG)); // Процедура выборки сообщений // Продолжаем бесконечно, пока не получим сообщение WM_QUIT (завершение). while(msg.message != WM_QUIT) { // Просмотрим очередь: вдруг там ожидает сообщение... if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { // Есть сообщение! Обработаем его как обычно... TranslateMessage(&msg); DispatchMessage(&msg); } else { // Нет сообщений, ожидающих обработки. // Значит приступим к выполнению критичных ко времени операций. // Например, займёмся рендерингом. } } //Удаляем регистрацию класса UnregisterClass("GameClass", hInstance); // Выходим из приложения return (msg.wParam); } // Оконная процедура LRESULT CALLBACK WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_DESTROY: // В случае этого сообщения... PostQuitMessage(0); // Говорим Windows закрыть приложение break; // В случае любых других сообщений... default: return DefWindowProc(hWnd, msg, wParam, lParam); } return 0; }
Готовим Проект WinTest01 к компиляции
Для успешной компиляции Проекта WinTest01 изменим пару его свойств.Устанавливаем многобайтовую кодировку (multibyte encoding)


В MS Visual C++ 2010 в настройках по умолчанию стоит набор (кодировка) символов UNICODE. В MS Visual C++ 6.0 - напротив, по умолчанию стоит кодировка ANSI (многобайтовая). Данная настройка сильно влияет на типы используемых переменных, что приводит к заметным различиям в исходном коде.
Несмотря на то, что во всех случаях рекомендуется использовать кодировку UNICODE, поддерживаемую во всех современных ОС семейства MS Windows (начиная с Win 2000/XP), большинство книг по программированию игр на классическом C++ придерживаются именно многобайтовой кодировки. Чтобы сильно не переделывать исходные коды под UNICODE, данный Проект мы настроим под многобайтовую кодировку.
Для этого...
- В Обозревателе решений щёлкаем по названию только что созданного Проекта Test01.
- Во всплывающем меню выбираем "Свойства"
- В появившемся окне установки свойств Проекта жмём "Свойства конфигурации", в правой части в строке "Набор символов" выставляем значение "Использовать многобайтовую кодировку".
- Жмём ОК.
Отключаем инкрементную компоновку (incremental linking)
Иначе при компиляции возможны ошибки вроде этой:Error LNK1123: сбой при преобразовании в COFF: файл недопустим или поврежден
- В Главном меню MS Visual C++ 2010 выбираем Проект -> Свойства.
- В появившемся окне установки свойств Проекта жмём Свойства конфигурации -> Компоновщик -> Общие (Configuration Properties -> Linker -> General), в правой части в строке "Включить инкрементную компоновку" ставим значение "Нет (/INCREMENTAL:NO)".
- Жмём ОК.
- Сохрани Решение/Проект (Файл -> Сохранить все).
Компилируем Проект Test01
Проект готов к компиляции.- Скомпилируй Проект/Решение (кнопка с зелёным треугольником на Панели инструментов MSVC++ или <F5> на клавиатуре).
Если весь код был введён без ошибок, после компиляции запустится приложение, отображающее окно с белым фоном.
Мутим двоичные ресурсы в MSVC+ + 2010 Express
Продолжаем работать с Проектом Test01.Организуем в нашем приложении оригинальные значки (иконки)
У каждой игры есть стартовый (запускной) .exe файл, который в Проводнике Windows отображается с оригинальным значком с логотипом игры. В каждом таком приложении, как правило, используется два значка, в исходном виде представляющие собой растровые изображения с расширением .ico:- Значок размером 32х32 точек, отображаемый в Проводнике Windows.
- Уменьшенная копия первого значка размером 16х16 точек, отображаемая на тулбаре (верхней полоске) окна приложения.
В нашем случае мы нашли готовое ICO-изображение в Интернете по запросу "ico 16x16". Скачанный файл почему-то оказался больше - 128x128 пикселей.
- Открой скачанный файл в бесплатной программе-просмотрщике XnView
и поочерёдно измени размер изображения (Изображение -> Изменение размера... ):
- сначала до размеров 32х32, пересохранив результат как Test01.ico,
- затем до размеров 16х16, пересохранив результат как Test01_sm.ico.

Напомним, для дальнейшей работы нам требуется 2 значка размером 16х16 и 32х32.
- Подготовь два значка размером 16х16 и 32х32.
- Переименуй значок 32х32 в Test01.ico, а значок 16х16 в Test01_sm.ico.
- Скопируй оба значка в каталог с текущим Проектом Test01.
Создаём скрипт ресурсов. Редактор скриптов ресурсов (RC) ResEdit.
Просто добавить значки в Проект Test01 не получится. Сперва необходимо их описать в специальном скрипте ресурсов, представляющем собой обычный текстовый файл с расширением .rc . Напомним, в бесплатной MSVC++2010 Express редактор ресурсов вырезан напрочь. Поэтому для создания скрипта ресурсов воспользуемся сторонним приложением ResEdit. Далее в этом абзаце будем работать только в ней.- Скачай программу ResEdit например отсюда: http://soft.oszone.net/program/11258/ResEdit
Распаковщик 7z-архивов (программу 7-zip

- Распакуй содержимое архива в любую папку на жёстком диске. В нашем случае это будет C:\ResEdit .
- Перейди в каталог с программой и запусти ResEdit.exe .
- Выбираем первый пункт Developer mode (режим разработчика).
- На следующей странице мастера отмечаем пункт Resource script (*.rc) (скрипт ресурсов), в строке Location выбираем папку с Проектом Test01 (по умолчанию C:\Users\User1\Documents\Visual Studio 2010\Projects\WinTest01\WinTest01\).
- В поле Name введи имя файла скрипта. В нашем случае Resource01.
- Убери галку с пункта "Создать отдельный подкаталог проекта" (Create project folder).
- Жмём Finish.
- В появившемся диалоговом окне о том, что программа не может найти windows.h (windows.h could not be found in any include path. Continue anyway?) жмём "Да" (=всё равно продолжить).
- В появившемся диалоговом окне о том, что программа не может найти commctrl.h (commctrl.h could not be found in any include path. Continue anyway?) жмём "Да" (=всё равно продолжить).
- В появившемся диалоговом окне о том, что программа не может найти richedit.h (richedit.h could not be found in any include path. Continue anyway?) жмём "Да" (=всё равно продолжить).
- На запрос программы сконфигурировать пути к include-файлам жмём "Нет" (отказ). После этого мы получаем доступ к главному окну программы с пустым проектом скрипта.
- Открой папку с Проектом Test01 (по умолчанию C:\Users\User1\Documents\Visual Studio 2010\Projects\WinTest01\WinTest01\).
- Resource01.rc
- resource.h
- Открой оба файла в любом текстовом редакторе. Ознакомься с их содержимым.
Как ни странно, ResEdit не открыла только что созданный файл Enum01.rc для редактирования, из-за чего мы не можем добавлять новые ресурсы. Поэтому...
- В Главном меню ResEdit жми: File -> Open project... и выбери только что созданный скрипт ресурсов Resource01.rc.
- В окне Resources щёлкни правой кнопкой мыши.
- Во всплывающем меню выбери Add Resource... (Добавить ресурс) -> icon.
- В появившемся диалоге Insert a new resource отметь пункт Create from an existing file (Создать из существующего файла) и жми Next.


Если выбрать пункт Create a new resource программа откроет вполне толковый редактор значков, где ты сможешь легко пересоздать (и потом пересохранить) созданные ранее значки Test01.ico и Test01_sm.ico. Главное - проследи чтобы они имели размер 32х32 и 16х16 соответственно. Чтобы не уходить от темы (создание скрипта ресурсов) сам встроенный редактор значков (иконок) здесь не рассматриваем. Там всё просто. При желании разберёшься сам.
- Выбери первый значок Test01.ico, ранее сохранённый в папку с Проектом Test01 (по умолчанию C:\Users\User1\Documents\Visual Studio 2010\Projects\WinTest01\WinTest01\).
- В появившемся диалоге Path designation (Назначение пути) выбери Relative path (относительный путь) жми OK.
- Добавь таким же образом второй значок Test01_sm.ico.
- Сохрани проект скрипта (в главном меню ResEdit выбери File->Save).
- Снова открой файлы Resource01.rc и resource.h в любом текстовом редакторе (через Проводник Windows). Просмотри их содержимое.
В принципе всё. Скрипт ресурсов Resource01.rc и сопутствующий заголовок resource.h готовы. Осталось добавить оба файла в наш Проект Test01.
Добавляем файл Resource01.rc в Проект WinTest01
- Стартуй MSVC++2010 Express, если не сделал этого раньше. Открой Решение/Проект WinTest01, созданное выше.
- В Обозревателе решений щёлкни правой кнопкой мыши по "папке" (Напомним, что в терминологии Microsoft это не папки, а фильтры!) "Файлы ресурсов".
- Во всплывающем контекстном меню выбери Добавить->Существующий элемент.
- В появившемся окне выбора файла выбери файл скрипта ресурсов Resource01.rc и нажми "Добавить".
Добавляем файл resource.h в Проект Test01
- В Обозревателе решений MSVC++2010 Express щёлкни правой кнопкой мыши по фильтру "Заголовочные файлы".
- Во всплывающем контекстном меню выбери Добавить->Существующий элемент.
- В появившемся окне выбора файла выбери файл скрипта ресурсов resource.h и нажми "Добавить".
Изменения в WinMain.cpp . Подключаем resource.h к Проекту Test01
- В начале листинга WinMain.cpp найди список подключаемых заголовочных файлов (include-строки):
Фрагмент WinMain.cpp
#define STRICT #define WIN32_LEAN_AND_MEAN // Уменьшаем кол-во используемых компонентов в программе. #include <windows.h> #include <windowsx.h> ...
- Добавь чуть ниже остальных следующую строку :
#include "resource.h"
- Сохрани Решение (Файл->Сохранить всё).
Изменения в Main.cpp . Прописываем новые значки в структуре оконного класса
- В WinMain.cpp найди следующий фрагмент:
Фрагмент WinMain.cpp
... // Реализация главной функции программы int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { HWND hWnd; // Дескриптор окна MSG msg; // Структура сообщения WNDCLASSEX wndClass; // Объявляем экземпляр класса программы на базе WNDCLASSEX // Заполняем структуру оконного класса wndClass.cbSize=sizeof(wndClass); wndClass.style=CS_CLASSDC; // Поочерёдный доступ к контексту устройства (Device Context) wndClass.lpfnWndProc=WindowProc; // Оконная процедура wndClass.cbClsExtra=0; wndClass.cbWndExtra=0; wndClass.hInstance=hInstance; // Экземпляр окна wndClass.hIcon=LoadIcon(NULL, IDI_APPLICATION); // Пиктограмма приложения wndClass.hIconSm=LoadIcon(NULL, IDI_APPLICATION); // Малая пиктограмма приложения wndClass.hCursor=NULL; // Курсор при наведении на окно wndClass.hbrBackground=NULL; // Закрашиваем окно чёрным цветом wndClass.lpszMenuName=NULL; // Дескриптор Главного меню окна. Сейчас оно не нужно wndClass.lpszClassName="GameClass"; // Обзываем оконный класс. ...
- Строку wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); замени на
wndClass.hIcon=LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));
- Строку wndClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); замени на
wndClass.hIconSm = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON2));
- Сохрани Решение (Файл->Сохранить всё).


Если до этого в первом параметре функции LoadIcon стояло NULL (идентификатор экземпляра окна), то теперь мы прописали текущий экземпляр (инстанс) hInstance. Без этого тоже компилируется, но значок в заголовке выводится в виде знака вопроса.
Макрос MAKEINTRESOURCE конвертирует имя ресурса в строковой указатель (string pointer), который требуют многие функции.
- Скомпилируй Решение/Проект(F5).
Работа с кастомными (пользовательскими ресурсами)
Как мы уже говорили, что помимо стандартных ресурсов (значки, меню, строки и т.д.), MSVC++ также поддерживает загрузку и использование нестандартных ресурсов, например игровых карт (level maps).Подготовка кастомного (нестандартного) ресурса
Вновь работаем с ResEdit. Ты же его не закрыл? Если закрыл...Упёртая прога отказывается открывать ранее созданный Resource01.rc из-за строк, добавленных MSVC++.
- Создавай новый проект в ResEdit, следуя шагам выше. Назови его так же Resource01, согласившись на перезапись. Добавь в плаваюшее окно Resources ранее подготовленные значки Test01.ico и Test01_sm.ico.
- Пересохрани Resource01 в том же каталоге Проекта WinTest01 (по умолчанию C:\Users\User1\Documents\Visual Studio 2010\Projects\WinTest01\WinTest01\).
Предположим, что нашим кастомным ресурсом будет игровая карта. Парсить мы её сейчас, конечно, не будем. И вообще, карты не компилируют вместе с exe-шником. Важно усвоить сам принцип.
- Найди и скачай в Интернете по запросу "Quake 2 maps" любую карту.

- Открой архив, например, программой 7-Zip и распакуй из него 187city_w.bsp из подкаталога maps.
В программе ResEdit:
- В окне Resources щёлкни правой кнопкой мыши.
- Во всплывающем меню выбери Add Resource... (Добавить ресурс) -> User defined.
- Поставь галку на пункте "Name Identifier", ниже в строке укажи тип: bsp_maps. Жми OK.
- В появившемся диалоговом окне выбери файл 187city_w.bsp, предварительно размещённый в каталоге Проекта Test01 (по умолчанию C:\Users\User1\Documents\Visual Studio 2010\Projects\WinTest01\WinTest01\). Жми Open.
- Поставь флажок у пункта Relative path и жми OK.
- Сохрани ResEdit-проект (File->Save).
- Правой кнопкой мыши по имени нового ресурса и во всплывающем меню выбери Rename (Переименовать).
- В появившемся диалоге измени имя ресурса с IDR_bsp_maps1 на IDR_187city. Жми OK.
- Сохрани ResEdit-проект (File->Save).
- Снова открой файлы Resource01.rc и resource.h в любом текстовом редакторе. Изучи их содержимое.
Перекомпилируем Проект Test01
Обновив всего 2 файла (Resource01.rc и resource.h) с помощью ResEdit, мы можем смело отправлять Проект WinTest01 на перекомпиляцию! При этом ни один из ресурсов даже не был добавлен в MSVC++2010. Всё делалось через однажды указанный скрипт ресурсов Resource.rc .- Стартуй MSVC++2010 Express, если не сделал этого раньше. Открой Решение/Проект WinTest01, созданное выше.
- Скомпилируй Решение/Проект(F5).
Применение кастомного ресурса в коде приложения
После включения (посредством скрипта ресурсов) кастомного ресурса в Проект Test01 (и размещения его внутри исполняемого файла приложения), мы можем получить к нему доступ из исходного кода через его (ресурса) указатель, который получают с помощью одной из трёх специальных функций:2Таблица 1. Функции для работы с ресурсами
ФУНКЦИЯ | ОПИСАНИЕ |
---|---|
FindResource | Ищет прикреплённый к исполняемому .exe-файлу ресурс и возвращает его дескриптор (handle). |
LoadResource | Загружает прикреплённый к исполняемому .exe-файлу ресурс в глобальную область памяти и возвращает его дескриптор (handle). |
LockResource | Блокирует (locks) участок памяти с размещённым в нём ресурсом и возвращает указатель (memory pointer) на него. |
Функция FindResource... Вот её прототип:
Прототип функции FindResource
HRSRC FindResource( HMODULE hModule, // Указатель на модуль ресурсов, обозначенный в WinMain. LPCSTR lpName, // Имя ресурса. LPCSTR lpType // Тип ресурса. );
...находит ресурс в блоке ресурсов исполняемого .exe-файла и возвращает его дескриптор (handle), который затем использует функция LoadResource. Параметр hModule представляет собой указатель на экземпляр (instance handle), получаемый от функции WinMain. lpName - имя ресурса (например IDR_MAP1). lpType - имя типа ресурса (например GameMaps). Как мы видели в программе ResEdit ресурсы каждого типа помещаются в отдельную папку-фильтр.
Функция LoadResource загружает ресурс в память и возвращает ещё один дескриптор, в этот раз для использования в функции LockResource.
Прототип функции LoadResource
GLOBAL LoadResource( HMODULE hModule, // Указатель на модуль ресурсов, обозначенный в WinMain. HRSRC hResInfo // Дескриптор (handle) из вызова функции FindResource. );
Вызовы функций FindResource и LoadResource можно комбинировать в один:
HGLOBAL hResource = LoadResource(hInstance, FindResource(hInstance, MAKEINTRESOURCE(IDR_MAP1), "GameMaps"));
Функция LockResource принимает всего 1 параметр - дескриптор (handle), полученный от функции LoadResource:
Прототип функции LockResource
LPVOID LockResource(HGLOBAL hResData);
Дескриптор, возвращаемый функцией LockResource представляет собой void-указатель, который затем можно транслировать (cast) в любой тип данных.
В качестве примера загрузки кастомного ресурса возьмём текстовый файл readme.txt и зададим ему пользовательский тип ресурсов TEXT. Допустим, имя данного ресурса IDR_TEXT1. Данный фрагмент кода загружает ресурс в память и выводит содержимое текстового файла во всплывающем окне сообщений (Message box):
HGLOBAL hResource = LoadResource(hInst, FindResource(hInst, MAKEINTRESOURCE(IDR_TEXT1), "TEXT")); if(hResource!=NULL) { char *pText = (char*)LockResource(hResource); MessageBox(NULL, pText, "Text", MB_OK); }
Итоги
Урезанность бесплатной MS Visual C++ 2010 - не помеха. Раздобыв дополнительную бесплатную программу по созданию ресурсов ResEdit, мы запросто можем "подсунуть" нашей IDE практически любой готовый ресурс.Источники
1. Пирогов В.Ю. Ассемблер и дизассемблирование. - СПб.: БХВ-Петербург, 2006
2. Adams J. Programming Role Playing Game in DirectX 8.0 - Premier Press, 2002
Последние изменения страницы Вторник 17 / Май, 2022 14:18:23 MSK
Sidebar
Search Wiki Page
Категории
Последние изменения
- Основы языка Cpp
- Формы и методы управления игровым движком
- Оптимизация 3D-приложений
- Технология COM (Component Object Model)
- Каркас (framework) игры
- Тайлы (Tiles). Создание игровых террейнов
- Ссылки
- Связные списки (Linked lists)
- Работа с данными приложения (Handling an Application Data)
- Стейты игры и процессы (Game States and Processes)