Программы Windows очень легко использовать, т.к. они предоставляют пользователю стандартный интерфейс. Например, большинство программ Windows используют меню для реализации команд программы, и курсор, который позволяет применять "мышь" в качестве управления такими инструментальными средствами, как указатель "мыши" стрелка или кисть для рисования.
    Меню и курсоры - это два примера ресурсов программы Windows. Ресурсы это данные, хранимые в выполняемом (.EXE) файле программы, но они располагаются отдельно от обычного сегмента данных программы. Ресурсы разрабатываются и специфицируются вне кода программы, затем добавляются к скомпилированному коду программы для создания выполняемого файла программы.
    Следующие ресурсы вы будете создавать и использовать наиболее часто:
    Обычно при загрузке приложения в память Windows оставляет ресурсы на диске и загружает в случае необходимости отдельные ресурсы в процессе выполнения программы. За исключением побитовых отображений (графических образов), Windows удаляет ресурс из памяти после окончания его использования. Если вы хотите загрузить ресурс при загрузке программы или не хотите, чтобы Windows имела возможность удалить ресурс из памяти, вы можете сменить его атрибуты. Детальное описание создания и модификации ресурсов содержится в руководстве пользователя по пакету разработчика ресурсов.
    Вы можете создавать ресурсы, используя редактор ресурсов или
компилятор ресурсов. Паскаль поддерживает оба эти метода, поэтому
вы сами можете выбрать, какой их них является более удобным. В
большинстве случаев проще использовать редактор ресурсов и
создавать ваши ресурсы визуально. Однако, иногда более удобно
использовать компилятор ресурсов для компиляции файла описания ресурса,
который может вам встретиться в книге или в журнале. Независимо
от выбранного вами подхода вы обычно создаете файл ресурса (.RES)
для каждого приложения. Этот файл ресурса будет содержать
двоичную информацию о всех меню, диалогах, графических образах и
других ресурсах, используемых вашим приложением.
    Двоичный файл ресурса (.RES) добавляется к вашему
исполняемому файлу (.EXE) в процессе компиляции с использованием
директивы компилятора $R, как это описано в данной главе. Вы также
должны написать код, который будет загружать ресурсы в память. Это
придаст вам дополнительную гибкость, поскольку ваша программа
будет использовать память лишь для ресурсов, которые используются в
данный момент. Загрузка ресурсов в память также рассматривается в
данной главе.
    Ресурсы хранятся в двоичном формате в файле .RES, поэтому
они должны быть добавлены к выполняемому файлу приложения (.EXE).
Результатом будет файл, который наряду со скомпилированным кодом
приложения будет содержать и его ресурсы.
    Есть три способа добавления ресурсов к выполняемому файлу:
    - Можно использовать редактор ресурсов для копирования
ресурсов из файла .RES в уже скомпилированный файл программы
.EXE. Инструкции по этой операции содержатся в руководстве
пользователя по пакету разработчика ресурсов.
    - Можно задать директиву в исходном коде файла. Например,
эта программа на языке Паскаль:
    добавит файл ресурсов SAMPLE.RES к выполняемому файлу.
Каждая программа на языке Паскаль может иметь только один
файл ресурсов (хотя этот файл ресурсов может включать
другие файлы ресурсов). Все эти файлы должны быть файлами
.RES и хранить ресурсы в двоичном формате. Директива
компилятора $R позволяет вам задать отдельный файл .RES.
    - Использовать компилятор ресурсов.
    После добавления ресурса к выполняемому файлу, он должен
быть явно загружен приложением до своего использования.
Конкретный способ загрузки ресурса зависит от типа ресурса.
    Меню окна является одним из атрибутов его создания. Другими
словами это характеристика окна, которая должна быть задана до
создания соответствующего элемента меню (с помощью метода
Create). Следовательно, меню может быть задано в типе
конструктора Init или вскоре после конструирования. Ресурсы меню
загружаются вызовом функции Windows LoadMenu со строкой идентификатора
меню при конструировании нового объекта окна. Например:
    Код PChar(100) переводит целое значение 100 в тип PChar,
совместимый с Windows тип строки. LoadMenu загружает ресурс меню
с идентификатором 100 в новый объект окна. Ресурс может иметь
символьное имя (строку), например, 'SampleMenu', а не числовой
идентификатор. В этом случае предыдущий код будет выглядеть
следующим образом:
    Дополнительная информация по созданию объектов окна
содержится в Главе 10, "Объекты окна".
    Для обработки выбора варианта меню просто определяется метод
для окна, которое владеет этим меню, используя специальное
расширение заголовка определения метода идентификатором cm_First:
    Обратите внимание на то, что 101 представляет собой
выбранного варианта меню (а не самого ресурса меню). Каждый пункт меню
имеет уникальный целочисленный идентификатор. В этом методе
задача состоит в организации соответствующей реакции на выбор пункта
меню. Обычно вы будете определять символьные константы для команд
вашего меню.
    Оперативные клавиши - это активные клавиши или комбинации
клавиш, которые используются для задания команд приложения.
Обычно оперативные клавиши определяются как эквиваленты выбора
пунктов меню. Например, клавиша Del - это стандартная оперативная
клавиша, которую можно использовать как альтернативу выбора
пункта Delete в меню Edit. Однако, оперативные клавиши могут
реализовывать команды, которые не соответствуют элементам меню.
    Ресурсы оперативных клавиш хранятся в таблице оперативных
клавиш. Для загрузки таблицы оперативных клавиш используется
функция Windows LoadAccelerators, которая просто возвращает
описатель таблицы. В отличие от ресурса меню, который связан с
конкретным окном, ресурс оперативной клавиши принадлежит всему
приложению. Каждое приложение может иметь только один такой ресурс.
Объекты приложения резервируют одно поле объекта, HAccTable, для
хранения описателя ресурса оперативных клавиш. Обычно вы будете
загружать ресурс оперативных клавиш в методе объекта приложения
InitInstance:
    Часто вы будете определять оперативные клавиши для быстрого
выбора вариантов меню. Например, Shift+Ins обычно используется
для быстрого выбора команды Paste. Оперативные клавиши генерируют
основанные на команде сообщения, которые идентичны сообщениям,
генерируемым выбором пункта меню. Для привязки метода реакции на
выбор в меню с соответствующей оперативной клавишей нужно
убедиться в том, что определенное в ресурсе значение оперативной
клавиши идентично идентификатору элемента меню.
    Блоки диалога являются единственным типом ресурса, который
непосредственно соответствует типу объекта ObjectWindows. TDialog
и его производные типы, включая TDlgWindow, определяют объекты
интерфейса, которые используют ресурсы блока диалога. Каждый
объект блока диалога обычно связан с одним ресурсом блока диалога,
который задает его размер, местоположение и ассортимент
управляющих элементов (таких, как командные кнопки и блоки списка).
    При конструировании блока диалога задайте ресурс объекта
блока диалога. Как ресурсы меню и командных клавиш, ресурс
диалога может иметь символьное имя или целочисленный идентификатор.
Например:
    Дополнительная информация по созданию объектов диалога
содержится в Главе 11, "Объекты диалоговых блоков".
Каждый тип объекта окна имеет специальные атрибуты,
называемые атрибутами регистрации. Среди этих атрибутов есть курсор окна
и пиктограмма. Для установки этих атрибутов для типа окна вы
должны определить метод GetWindowClass (как и GetClassName).
    Например, вы создаете курсор для выбора элементов в блоке
списка. Курсор имеет вид указательного пальца и хранится в
ресурсе курсора с именем 'Finger'. Кроме того, вы создаете ресурс
пиктограммы с именем 'SampleIcon', который выглядит как улыбающееся
лицо. Вы должны написать метод GetWindowClass следующим образом:
    Однако, между курсором и пиктограммой имеется одно отличие.
Оно состоит в том, что курсор задается для одного окна, а
пиктограмма представляет все приложение. Следовательно, пиктограмма
устанавливается в типе объекта только для основного окна. У этого
правила имеется одно исключение: для приложений, которые следуют
правилам многодокументального интерфейса (MDI), каждое дочернее
окно MDI имеет свою собственную пиктограмму.
Для использования одного из уже имеющихся курсоров или
пиктограмм Windows, передайте 0 в HInstance и используйте значение
idc_ (например, idc_IBeam) для курсора и значение idi_ (например,
idi_Hand) для пиктограммы. Например:
    Дополнительную информацию по регистрационным атрибутам окна
можно найти в Главе 10, "Объекты окна".
Принципиальная причина выделения строк приложения в качестве
ресурсов состоит в облегчении процесса настройки приложения на
конкретное применение или возможности перевода приложения на
иностранный язык. Если строки определены в исходном коде, то для
их изменения или перевода нужно иметь доступ к исходному коду.
Если же они определены как ресурсы, то хранятся в таблице строк
выполняемого файла приложения. Вы можете использовать редактор
строк для перевода строк в таблице, без изменения и даже доступа
к исходному коду. Каждый выполняемый файл может иметь только одну
таблицу строк.
    Для загрузки строки из таблицы в буфер сегмента данных
вашего приложения используется функция LoadString. Синтаксис
LoadString следующий:
    LoadString возвращает число скопированных в буфер символов,
или ноль, если ресурс не существует.
    Вы можете использовать ресурс строки для вывода текста в
блоке сообщения. Например, вы можете вывести сообщение об ошибке.
В данном примере вы определяете строку 'Program unavailable' в
таблице строк и определяете константу ids_NoProgrm в качестве
идентификатора строки. Для использования этого ресурса строки в
блоке сообщения об ошибке, вы можете написать следующую
процедуру:
    Данный пример загружает отдельную строку в блок сообщения об
ошибке. Для загрузки списка строк в блок списка вызывается
LoadString для загрузки каждой строки, затем вызывается AddString
для добавления ее в блок списка.
    Другое использование ресурса строк применяется для элементов
меню, которые добавляются в меню вашего исходного кода. В этом
случае сначала получается ресурс строки с помощью LoadString.
Затем эта строка передается как параметр в вызовы функций Window
CreateMenu и AppendMenu. Например:
    Функция Windows LoadBitmap загружает ресурсы графических
изображений (битовых отображений). LoadBitmap загружает побитовое
распределение в память и возвращает его описатель. Например:
загружает ресурс побитового отображения с идентификатором 501 и
записывает его описатель в переменную HMyBit. После загрузки
побитового отображения оно останется в памяти до его явного
удаления вами. В отличие от других ресурсов, оно остается в памяти
даже после закрытия пользователем вашего приложения.
    В Windows имеется ряд заранее определенных графических
изображений, которые используются как часть графического интерфейса
Windows. Ваше приложение может загружать эти изображения
(например, obm_DnArrow, obm_Close и obm_Zoom). Как и предопределенные
пиктограммы и курсоры, предопределенные графические изображения
могут быть загружены, если в вызове LoadBitmap вместо HInstance
задать ноль:
    После загрузки графического образа ваше приложение может
использовать его разными способами:
    Дополнительная информация относительно использования графики
с побитовым отображением содержится в Главе 17.
    Если побитовое отображение не используется, то его нужно
удалить из памяти. В противном случае занимаемая им память будет
недоступна другим приложениям. Даже если вы не удаляете его после
использования приложением, вы обязательно должны удалить его до
прекращения работы приложения. Графический образ удаляется из
памяти с помощью функции Windows DeleteObject:
    После удаления графического изображения его описатель
становится некорректным, и его нельзя использовать.
Создание ресурсов
Добавление ресурсов к выполняемой программе
program SampleProgram;
{$r SAMPLE.RES}
.
.
.
Загрузка ресурсов в приложение
Загрузка меню
constructor SampleMainWindow.Init(AParent: PWindowsObject;
ATitle: PChar);
begin
TWindow.Init(AParent, ATitle);
Attr.Menu:=LoadMenu(HInstance, PChar(100));
.
.
end;
constructor SampleMainWindow.Init(AParent: PWindowsObject;
ATitle: PChar);
begin
TWindow.Init(AParent, ATitle);
Attr.Menu:=LoadMenu(HInstance, 'SampleMenu');
.
.
end;
procedure HandleMenu101(var Msg: TMessage);
virtual cm_First+101;
Загрузка оперативных клавиш
procedure SampleApplication.InitInstance;
begin
TApplication.InitInstance;
HAccTable := LoadAccelerators(HInstance,
'SampleAccelerators');
end;
Загрузка блоков диалога
Adlg := New(PSampleDialog, Init(@Self, 'AboutBox'));
или
Adlg := New(PSampleDialog, Init(@Self, PChar(120)));
Загрузка курсоров и пиктограмм
procedure SampleWindow.GetWindowClass(var AWndClass:
TWndClass);
begin
TWindow.GetWindowClass(AWndClass);
AWndClass.hCursor:=LoadCursor(HInstance, 'Finger');
AWndClass.hIcon:=LoadIcon(HInstance, 'SampleIcon');
end;
procedure SampleWindow.GetWindowClass(var AWndClass:
TWndClass);
begin
TWindow.GetWindowClass(AWndClass);
AWndClass.hCursor := LoadCursor(HInstance, idc_IBeam);
AWndClass.hIcon := LoadIcon(HInstance, idi_Hand);
end;
Загрузка строковых ресурсов
LoadString(HInstance, StringID, @TextItem,SizeOf(TextItem));
procedure TestDialog.RunErrorBox(ErrorNumber:
Integer); virtual;
var
TextItem: array[0..255] of Char;
begin
LoadString(HInstance, ids_NoPrgrm, @TextItem, 20);
MessageBox(HWindow, @TextItem, 'Error', mb_OK or
mb_IconExclamation);
end;
procedure SampleWindow.Init(AParent: PWindpwsObject; ATitle:
PChar);
var
TextItem: array[0..255] of Char;
begin
TWindow.Init(AParent, ATitle);
Attr.Menu := LoadMenu(HInstance, PChar(100));
LoadString(HInstance, 301, @TextItem, 20);
AppendMenu(Attr.Menu, mf_String ormf_Enabled, 501,
@TextItem);
end;
Загрузка графических изображений
HMyBit:=LoadBitmap(HInstance, PChar(501));
HMyBit:=LoadBitmap(0, PChar(obm_Close));
if DeleteObject(HMyBit) then { успешно };