Препроцессор

Назначение препроцессора — обработка исходного текста программы до ее компиляции. Таким образом он занимается предварительной подготовкой исходного текста программы непосредственно перед ее компиляцией.

Препроцессор позволяет улучшить читаемость исходного кода. Структурирование кода может быть достигнуто путем включения отдельных файлов с исходными кодами MQL4-программ. Улучшению читаемости кода способствует и возможность присвоения мнемонических имен отдельным константам.

Препроцессор позволяет также определять специфические параметры MQL4-программ.

Если в качестве первого символа в строке программы используется символ #, то эта строка является директивой препроцессора. Директива препроцессора заканчивается символом перевода на новую строку

Объявление константы

Используя конструкцию #define, можно в начале программы определить символическое имя или символическую константу, которая будет конкретной строкой символов. Впоследствии компилятор заменит все не заключенные в кавычки появления этого имени на соответствующую строку. По сути дела это имя может быть заменено абсолютно произвольным текстом, не обязательно цифрами:

#define идентификатор значение

Идентификатор константы подчиняется тем же правилам, что и для имен переменных. Значение может быть любого типа:

#define ABC 100
#define PI 0.314
#define COMPANY_NAME "MetaQuotes Software Corp." 
... 
void ShowCopyright()
{
   Print("Copyright ? 2001-2007, ",COMPANY_NAME);
   Print("http://www.metaquotes.net");
}

Специальные параметры

У любой программы, написанной на языке MQL, можно указать дополнительные специфические параметры #property, которые помогают терминалу MT4 корректно обслуживать программы без необходимости их явного запуска. В первую очередь это касается внешних настроек индикаторов.

#property идентификатор значение

Константа Тип Описание
link string ссылка на сайт компании-производителя
copyright string название компании-производителя
stacksize int размер стека для рекурсивных вызовов
library библиотека; не назначается никакой стартовой функции, не удаляются функции, которые не вызываются из других функций
indicator_chart_window void выводить индикатор в окно графика
indicator_separate_window void выводить индикатор в отдельное окно
indicator_buffers int количество буферов для расчета индикатора, максимум до 8
indicator_minimum double нижнее ограничение шкалы отдельного окна индикатора
indicator_maximum double верхнее ограничение шкалы отдельного окна индикатора
indicator_colorN color цвет для вывода линии N, где N от 1 до 8
indicator_widthN int толщина линии N, где N от 1 до 8
indicator_styleN int стиль линии N, где N от 1 до 8
indicator_levelN double горизонтальный уровень N в отдельном окне индикатора, где N от 1 до 8
indicator_levelcolor color цвет горизонтальных уровней индикатора
indicator_levelwidth int толщина горизонтальных уровней индикатора
indicator_levelstyle int стиль горизонтальных уровней индикатора
show_confirm void выводить окно подтверждения перед запуском скрипта
show_inputs void выводить окно со свойствами перед запуском скрипта и запретить вывод окна подтверждения

Примеры:

#property link "http://www.metaquotes.net"
#property copyright "MetaQuotes Software Corp."
#property library
#property stacksize 1024

Компилятор сохранит в настройках выполняемого модуля объявленные значения.

Включение файлов

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

#include <имя_файла>

#include «имя_файла»;

Примеры:

#include <WinUser32.mqh>
#include "mylib.mqh"

Препроцессор заменяет строку #include <имя_файла> содержимым файла WinUser32.mqh. Угловые скобки обозначают, что файл WinUser32.mqh будет взят из стандартного каталога (обычно это каталог_терминала\experts\include). Текущий каталог не просматривается.

Если имя файла заключено в кавычки, то поиск производится в текущем каталоге (в котором содержится основной файл исходного текста). Стандартный каталог не просматривается

Импорт функций

Импорт функций осуществляется из откомпилированных модулей MQL4 (файлы *.ex4) и из модулей операционной системы (файлы *.dll). Имя модуля указывается в директиве #import. Для того, чтобы компилятор мог правильно оформить вызов импортируемой функции и организовать корректную передачу параметров, необходимо полное описание функций. Описания функций следуют непосредственно за директивой #import «имя модуля». Новая команда #import (можно без параметров) завершает блок описания импортируемых функций.

#import «имя_файла»

func1 define;

func2 define;

funcN define;

#import

Все импортируемые функции должны иметь уникальные имена. Недопустимо одновременно импортировать из разных модулей одноимённые функции. Также импортируемые функции не должны иметь имен, совпадающих с именами встроенных функций.

Так как импортируемые функции находятся вне вашего модуля, то компилятор не может проверить корректность передаваемых параметров. Поэтому, во избежание ошибок выполнения, необходимо точно описывать состав и порядок параметров, передаваемых в импортируемые функции. Параметры, передаваемые в импортируемые функции (как из EX4, так и из DLL-модулей), не могут иметь значения по умолчанию.

Примеры:

#import "user32.dll"
int MessageBoxA(int hWnd, string lpText, string lpCaption, int uType);
#import "stdlib.ex4"
string ErrorDescription(int error_code);
int RGB(int red_value, int green_value, int blue_value);
bool CompareDoubles(double number1, double number2);
string DoubleToStrMorePrecision(double number, int precision);
string IntegerToHexString(int integer_number);
#import "ExpertSample.dll"
int GetIntValue(int);
double GetDoubleValue(double);
string GetStringValue(string);
double GetArrayItemValue(double arr[], int, int);
bool SetArrayItemValue(double& arr[], int,int, double);
double GetRatesItemValue(double rates[][6], int, int, int);
int SortStringArray(string& arr[], int);
int ProcessStringArray(string& arr[], int);
#import

Для импорта функций во время выполнения mql4-программы используется так называемое позднее связывание. Это значит, что пока не вызвана импортируемая функция, соответствующий модуль (ex4 или dll) не загружается.

Не рекомендуется использовать полностью квалифицированное имя загружаемого модуля вида Drive:\Directory\FileName.Ext. Библиотеки MQL4 загружаются из папки terminal_dir\experts\libraries. Если библиотека не была найдена, то производится попытка загрузить библиотеку из папки terminal_dir\experts