Описание ресурсов с помощью директивы #resource

Для включения файла ресурса в откомпилированную версию программы следует использовать в исходном коде директиву #resource. Директива имеет разные формы в зависимости от типа файла. В любом случае в директиве присутствует основная часть: ключевое слово #resource и далее константная строка.

#resource "путь_имя_файла"

Команда #resource предписывает компилятору включить в генерируемую исполняемую программу (в двоичном формате ex5) файл с указанным именем и, при необходимости, местом его размещения (в момент компиляции). Путь является опциональным: если в строке указано только имя файла, он ищется в каталоге рядом с компилируемым исходным кодом. При наличии в строке пути применяются правила его разбора, описанные ниже.

Компилятор ищет ресурс по указанному пути в следующей последовательности:

  • Если в начале пути стоит символ-разделитель обратная косая черта '\\' (она должна быть задвоена, поскольку одиночный обратный слэш является управляющим символом: в частности, '\' используется для переводов строк '\r', '\n' и табуляций '\t'), то ресурс ищется, начиная с папки MQL5 внутри каталога данных терминала.
  • Если обратной косой черты нет, то ресурс ищется относительно расположения исходного файла, в котором этот ресурс прописан.

Обратите внимание: в константных строках с путями ресурсов обязательно использовать удвоенные обратные косые черты в качестве разделителей — прямые одинарные черты здесь не поддерживаются, в отличие от путей в файловой системе.

Например:

#resource "\\Images\\euro.bmp" // euro.bmp находится в /MQL5/Images/
#resource "picture.bmp"        // picture.bmp находится в том же каталоге,
                               // где и исходный файл (mq5 или mqh)
#resource "Resource\\map.bmp"  // map.bmp находится в подпапке Resource того каталога,
                               // где и исходный файл (mq5 или mqh)

Если ресурс декларируется с относительным путем в заголовочном mqh-файле, путь рассматривается от этого mqh-файла, а не от mq5-файла компилируемой программы.

В пути ресурса недопустимо использовать подстроки "..\\" и ":\\".

С помощью нескольких директив можно, например, поместить непосредственно в ex5-файл все необходимые картинки и звуки. Тогда для запуска такой программы в другом терминале не потребуется передавать их отдельно. Программные способы обращения к ресурсам из MQL5 мы рассмотрим в следующих разделах.

Длина константной строки "путь_имя_файла" не должна превышать 63 символа.

Размер файла ресурса не может быть больше 128 Mb.

Файлы ресурсов перед включением в исполняемый файл автоматически сжимаются.

После того как ресурс объявлен директивой #resource, его можно использовать в любой части программы. Именем ресурса становится указанная в директиве константная строка без косой черты в начале (если есть), причем перед содержимым строки следует добавлять специальный признак ресурса — два двоеточия "::".

Ниже приведены примеры ресурсов и их имена в комментариях.

#resource "\\Images\\euro.bmp"          // имя ресурса - ::Images\\euro.bmp
#resource "picture.bmp"                 // имя ресурса - ::picture.bmp
#resource "Resource\\map.bmp"           // имя ресурса - ::Resource\\map.bmp
#resource "\\Files\\Pictures\\good.bmp" // имя ресурса - ::Files\\Pictures\\good.bmp
#resource "\\Files\\demo.wav";          // имя ресурса - ::Files\\demo.wav"
#resource "\\Sounds\\thrill.wav";       // имя ресурса - ::Sounds\\thrill.wav"

Далее в MQL-коде можно ссылаться на эти ресурсы следующим образом (здесь приведены только уже известные нам функции ObjectSetString и PlaySound, но есть и другие варианты использования, такие как ResourceReadImage, которые будут описаны в следующих разделах).

ObjectSetString(0bitmap_nameOBJPROP_BMPFILE0"::Images\\euro.bmp");
...
ObjectSetString(0my_bitmapOBJPROP_BMPFILE0"::picture.bmp");
...
ObjectSetString(0bitmap_labelOBJPROP_BMPFILE0"::Resource\\map.bmp");
ObjectSetString(0bitmap_labelOBJPROP_BMPFILE1"::Files\\Pictures\\good.bmp");
...
PlaySound("::Files\\demo.wav");
...
PlaySound("::Sounds\\thrill.wav");

Необходимо отметить, что при установке объектам OBJ_BITMAP и OBJ_BITMAP_LABEL изображения из ресурса, значение свойства OBJPROP_BMPFILE уже нельзя менять вручную (в диалоге свойств объекта).

Обратите внимание, что wav-файлы задаются по умолчанию для функции PlaySound относительно папки Sounds (или её вложенных папок), расположенной в каталоге данных терминала. В то же время, ресурсы (включая и звуковые), если они описываются с начальной косой чертой в пути, ищутся внутри каталога MQL5. Поэтому в примере выше строка "\\Sounds\\thrill.wav" обозначает файл MQL5/Sounds/thrill.wav, но не Sounds/thrill.wav относительно каталога данных (там действительно есть каталог Sounds со стандартными звуками терминала).

Рассмотренный выше простой синтаксис директивы #resource позволяет описать только ресурсы-картинки (формата BMP) и ресурсы-звуки (формата WAV). Попытка описать как ресурс файл другого типа приведет к ошибке "неизвестный ресурс" ("unknown resource type").

В результате обработки директивы #resource файлы фактически встраиваются в исполняемую двоичную программу и становятся доступны в ней по имени ресурса. Причем следует обратить внимание на особое свойство подобных ресурсов — их публичную доступность и из других программ (подробнее об этом — в следующем разделе).

MQL5 поддерживает и другой способ встраивания файла в программу — в виде ресурсной переменной. Этот способ использует расширенный синтаксис директивы #resource и позволяет подключать не только файлы типов BMP или WAV, но и других, например, текст или массив структур.

Практический пример подключения ресурсов мы разберем через пару разделов.