Графическая библиотека GUI для MetaTrader: руководство по установке и использованию
✔️ Графическая библиотека GUI MT4©: https://www.mql5.com/en/market/product/206760
✔️ Графическая библиотека GUI MT5©: https://www.mql5.com/en/market/product/206761
✔️ Полная документация, галерея элементов и инструмент «Изображение в код»5: https://www.betasoft.dev/gui-graphic-library
Таблица позиций, ордер и график в реальном времени.
Библиотека GUI Graphic Library предоставляет вашим советникам и индикаторам полный интерфейс: окна, вкладки, меню, таблицы, графики, средства выбора, диалоговые окна и торговые виджеты. Все отображается на одном холсте, один и тот же код работает в MetaTrader 4 и MetaTrader 5, а весь API состоит из 15 функций.
Это руководство проведет вас от загрузки до создания вашей первой работающей панели, а затем к задачам, которые вы будете выполнять чаще всего. В каждом примере кода используется только общедоступный включаемый файл, поэтому вы можете вставить его в свою собственную программу.
Небольшая часть из 78 элементов: кнопки, поля ввода, ползунки и вкладки.
1. Прежде чем начать
- MetaTrader 4 или MetaTrader 5 для Windows. Шрифты и значки соответствуют масштабу отображения Windows (100, 125, 150 и 200 процентов).
- MetaEditor — для компиляции демонстрационных версий и ваших собственных программ.
- В параметрах терминала ничего не разрешается: библиотека не использует DLL, не выполняет веб-запросы и не использует глобальные переменные терминала.
- Версии MT4 и MT5 — это отдельные продукты. Установите ту, которая подходит для вашего терминала.
2. Установка
- В терминале выберите «Файл», затем «Открыть папку с данными».
- Откройте папку MQL5 (MetaTrader 5) или папку MQL4 (MetaTrader 4).
- Скопируйте каждый файл в папку, указанную в таблице выше: Libraries, Include, Experts и Indicators.
- Откройте каждую демо-версию в MetaEditor и нажмите F7. В результате должно отобразиться 0 ошибок и 0 предупреждений.
- Вернувшись в терминал, обновите навигатор (щелкните правой кнопкой мыши, выберите «Обновить»), чтобы появились новые программы.
Папки должны выглядеть следующим образом:
MQL5/
Include/GUI_Graphic_Library.mqh
Libraries/GUI_Graphic_Library.ex5
Experts/GUI_Graphic_Library_FullDemo.mq5
GUI_Graphic_Library_ElementTests.mq5
Indicators/GUI_Graphic_Library_IndicatorWindow.mq5
GUI_Graphic_Library_IndicatorChart.mq5
MQL4/ the same files with .mq4 and .ex4
Не переименовывайте файл библиотеки. Файл включения загружает его под этим именем.
Проверки после установки
| Проверять | Где |
|---|---|
| Файл .ex5 (или .ex4) находится в папке «Библиотеки». | Папка данных |
| Файл .mqh находится в папке Include. | Папка данных |
| Демо-версия компилируется без ошибок. | Метаредактор |
| Демонстрация показывает окно на графике. | Диаграмма |
| На вкладке «Эксперты» нет строк, содержащих пометку «не поддерживается». | Терминал, Панель инструментов |
Что находится внутри файла GUI_Graphic_Library.mqh?
Файл включения намеренно сделан небольшим. Над блоком импорта он объявляет перечисления (типы объектов, свойства, события, темы и значки). Блок импорта ниже загружает скомпилированную библиотеку и перечисляет её 15 функций. MetaTrader 5 загружает файл .ex5, а MetaTrader 4 — файл .ex4, выбранный компилятором. Вы включаете файл, но никогда не редактируете его.
#ifdef __MQL5__ #import "\\Market\\GUI_Graphic_Library.ex5" #else #import "\\Market\\GUI_Graphic_Library.ex4" #endif string Gui_Version(); bool Gui_Create( const long chart= 0 , const string name= "GUI_Graphic_Library" , const int subwin= 0 ); void Gui_Destroy(); void Gui_ChartEvent( const int id, const long lparam, const double dparam, const string sparam); void Gui_Timer(); void Gui_Update( const bool force= false ); bool Gui_NextEvent(ENUM_GUI_EVENT &event, int &sender, long &lparam, double &dparam, string &sparam); int Gui_Add( const ENUM_GUI_OBJECT type, const int parent, const string name, const string text, const int x, const int y, const int w, const int h); int Gui_Set( const int id, const ENUM_GUI_PROP prop, const string s= "" , const double a= EMPTY_VALUE , const double b= EMPTY_VALUE , const double c= EMPTY_VALUE , const double d= EMPTY_VALUE ); string Gui_Get( const int id, const ENUM_GUI_PROP prop, const string s= "" , const double a= EMPTY_VALUE , const double b= EMPTY_VALUE ); double Gui_GetNum( const int id, const ENUM_GUI_PROP prop, const string s= "" , const double a= EMPTY_VALUE , const double b= EMPTY_VALUE ); int Gui_SetArray( const int id, const ENUM_GUI_PROP prop, const double &values[], const double a= EMPTY_VALUE ); int Gui_AddImage( const string name, const uint &argb[], const int w, const int h); int Gui_Find( const string name); void Gui_BringToFront(); #import
15 функций в порядке их появления:
| Функция | Что это делает | Где вы это называете |
|---|---|---|
| Версия Gui | Возвращает версию библиотеки в текстовом виде. | В любом месте |
| Gui_Create | Запускает графический интерфейс пользователя на графике. Передайте 0 для текущего графика, имя вашей программы и номер дочернего окна для индикаторов. Возвращает true, если все прошло успешно. | OnInit |
| Gui_Destroy | Удаляет графический интерфейс пользователя и все, что он отображал. | ОнДейнит |
| Gui_ChartEvent | Передает библиотеке событие обработки графика (мышь, клавиши, щелчки). | OnChartEvent |
| Gui_Timer | Запускает таймеры библиотеки: анимацию, всплывающие уведомления, счетчики. | OnTimer |
| Обновление графического интерфейса | Перерисовывает то, что изменилось. Передайте true, чтобы перерисовать всё. | Конец каждого обработчика |
| Gui_NextEvent | Извлекает следующее событие из очереди (клик, изменение, результат диалога, запрос на обмен). Возвращает false, если очередь пуста. | Цикл событий |
| Gui_Add | Создает элемент и возвращает его идентификатор. Вы указываете тип, родительский элемент, имя, текст, а также координаты x, y, ширину и высоту. | OnInit |
| Gui_Set | Изменяет свойство или выполняет действие над элементом. Возвращает -1 и выводит строку в консоль, если элемент этого не поддерживает. | В любом месте |
| Gui_Get | Считывает свойство как текст. | В любом месте |
| Gui_GetNum | Считывает свойство как число. | В любом месте |
| Gui_SetArray | Отправляет элементу список чисел, например, целую серию диаграмм. | В любом месте |
| Gui_AddImage | Регистрирует изображение из массива пикселей ARGB, чтобы элементы могли его отображать. Инструмент Image to Code на веб-сайте создает этот массив из файла PNG. | OnInit |
| Gui_Find | Находит элемент по его идентификатору и имени. | В любом месте |
| Gui_BringToFront | Перемещает графический интерфейс пользователя поверх объектов диаграммы, которые вы нарисовали после него. | После создания объектов диаграммы |
Это весь интерфейс. Всё остальное в этом руководстве — это комбинация этих 15 вызовов.
3. Запустите полную демоверсию.
- Откройте диаграмму. Большое окно, например, размером 1280 на 720 пикселей или больше, отображает наибольшее значение.
- Перетащите элемент GUI_Graphic_Library_FullDemo из навигатора на диаграмму.
- Воспользуйтесь вкладками разделов вверху: Главная, Варианты использования, Кнопки, Ввод данных, Выбор параметров, Данные, Графики, Макет, Обратная связь, Торговля и Настройки.
Демо-счет никогда не отправляет ордера, если вы не установите параметр InpLiveTrading в значение true. На реальном счете этот параметр следует отключить. Если вы закроете главное окно, советник удалит себя.
Используйте GUI_Graphic_Library_ElementTests, если хотите просмотреть только один элемент за раз: щелкните группу в окне выбора элементов.
Панель управления, созданная исключительно из элементов библиотеки.
4. Ваша первая панель
Это полноценный советник: окно с полем выбора размера лота, кнопкой «Купить» и строкой состояния. Он не совершает сделок, а лишь отображает сообщение.
#include <GUI_Graphic_Library.mqh> int wMain, spLots, btnBuy, lblInfo; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int OnInit () { if (!Gui_Create( 0 , "MyPanel" )) return INIT_FAILED ; // 0 = this chart Gui_Set( 0 , GUI_PROP_THEME, "" , GUI_THEME_DARK); wMain = Gui_Add(GUI_OBJ_WINDOW, 0 , "wMain" , "My panel" , 20 , 40 , 300 , 170 ); Gui_Set(wMain, GUI_PROP_THEME_BUTTON, "" , true ); // sun / moon button Gui_Set(wMain, GUI_PROP_MAIN_WINDOW, "" , true ); // close asks to remove the program spLots = Gui_Add(GUI_OBJ_SPIN, wMain, "spLots" , "" , 10 , 10 , 280 , 30 ); Gui_Set(spLots, GUI_PROP_RANGE, "" , 0.01 , 50 , 0.01 , 2 ); // min, max, step, digits Gui_Set(spLots, GUI_PROP_VALUE, "" , 0.10 ); Gui_Set(spLots, GUI_PROP_SUFFIX, "lots" ); btnBuy = Gui_Add(GUI_OBJ_BUTTON, wMain, "btnBuy" , "BUY" , 10 , 50 , 280 , 40 ); Gui_Set(btnBuy, GUI_PROP_STYLE, "" , GUI_BUTTON_SUCCESS); Gui_Set(btnBuy, GUI_PROP_ICON, "" , GUI_ICON_ARROW_UP); lblInfo = Gui_Add(GUI_OBJ_LABEL, wMain, "lblInfo" , "Ready" , 10 , 100 , 280 , 20 ); Gui_Set(lblInfo, GUI_PROP_DIM, "" , true ); Gui_Set( 0 , GUI_PROP_REDRAW); return INIT_SUCCEEDED ; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void ProcessEvents() { ENUM_GUI_EVENT ev; int sender; long l; double d; string s; while (Gui_NextEvent(ev, sender, l, d, s)) if (ev == GUI_EVENT_CLICK && sender == btnBuy) { double lots = Gui_GetNum(spLots, GUI_PROP_VALUE); Gui_Set(lblInfo, GUI_PROP_TEXT, "Buy " + DoubleToString (lots, 2 ) + " lots" ); Gui_Set( 0 , GUI_PROP_TOAST, "Buy|" + DoubleToString (lots, 2 ) + " lots" , GUI_NOTICE_SUCCESS, 3000 ); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void OnDeinit ( const int r) { Gui_Destroy(); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void OnTimer () { Gui_Timer(); ProcessEvents(); Gui_Update(); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void OnChartEvent ( const int id, const long &l, const double &d, const string &s) { Gui_ChartEvent(id, l, d, s); ProcessEvents(); Gui_Update(); }
Закономерность никогда не меняется:
- Функция OnInit создает графический интерфейс пользователя и его элементы.
- Функции OnChartEvent и OnTimer передают события в библиотеку, считывают данные из очереди и вызывают функцию Gui_Update.
- OnDeinit уничтожает графический интерфейс пользователя.
5. Как мыслит библиотека
- Идентификаторы. Функция Gui_Add возвращает целочисленный идентификатор. Сохраните нужные идентификаторы или найдите нужный позже по имени с помощью функции Gui_Find("name"). Идентификатор 0 — это сам графический интерфейс: тема, всплывающие уведомления, диалоги, счетчики.
- Родительские элементы. Каждый элемент добавляется к родительскому элементу, окну или контейнеру. Окна, меню и ценники используют родительский элемент 0. Для вкладки родительским элементом является элемент вкладки, а возвращаемый идентификатор — это страница, на которую добавляются дочерние элементы.
- Свойства. Функция Gui_Set(id, property, text, a, b, c, d) изменяет свойство или выполняет действие. Текст передается в аргумент text; числа, цвета и перечисления передаются в аргументы от a до d. Функция Gui_Get считывает текст, а Gui_GetNum — числа.
- События. Библиотека ставит в очередь действия пользователя. Чтение очереди осуществляется с помощью функции Gui_NextEvent.
- Координаты указаны в пикселях в масштабе 100 процентов. Библиотека автоматически умножает их на масштаб отображения Windows.
Если передать свойство, которое элемент не поддерживает, ничего не сломается: вызов вернет -1, и в журнал экспертов будет записана одна строка.
6. Задачи, которые вы будете выполнять чаще всего.
Прочитать то, что пользователь напечатал или выбрал.
string name=Gui_Get(edName,GUI_PROP_TEXT); double lots=Gui_GetNum(spLots,GUI_PROP_VALUE); int tab =( int )Gui_GetNum(tabs,GUI_PROP_SELECTED);
Вкладки
int t=Gui_Add(GUI_OBJ_TABS,win, "tabs" , "" , 10 , 10 , 600 , 300 ); int pOrders =Gui_Add(GUI_OBJ_TAB,t, "" , "Orders" , 0 , 0 , 0 , 0 ); // returns the page int pHistory=Gui_Add(GUI_OBJ_TAB,t, "" , "History" , 0 , 0 , 0 , 0 ); Gui_Add(GUI_OBJ_BUTTON,pOrders, "b1" , "Close all" , 10 , 10 , 120 , 30 );
Таблицы
int tb=Gui_Add(GUI_OBJ_TABLE,page, "tbl" , "" , 10 , 10 , 600 , 300 ); Gui_Set(tb,GUI_PROP_ADD_COLUMN, "Symbol" , 120 ,GUI_ALIGN_LEFT); Gui_Set(tb,GUI_PROP_ADD_COLUMN, "Strength" , 130 ,GUI_ALIGN_LEFT,GUI_COL_PROGRESS); Gui_Set(tb,GUI_PROP_ADD_BUTTON_COLUMN, "Action" , 100 ,GUI_BUTTON_PRIMARY); Gui_Set(tb,GUI_PROP_ADD_ROW, "EURUSD|64|Trade" ); Gui_Set(tb,GUI_PROP_SORT, "" , 0 , true );
При нажатии на ячейку кнопки отправляется событие GUI_EVENT_CELL_BUTTON, в котором строка указана в параметре lparam, а столбец — в параметре dparam.
Диаграммы
int ch=Gui_Add(GUI_OBJ_LINECHART,page, "chart" , "Price" , 10 , 10 , 500 , 260 ); int ln=Gui_Set(ch,GUI_PROP_ADD_SERIES, "Close" , clrDodgerBlue ); // returns the series index double closes[]; CopyClose ( _Symbol , PERIOD_H1 , 0 , 100 ,closes); Gui_SetArray(ch,GUI_PROP_SERIES,closes,ln); // a whole series at once int cd=Gui_Add(GUI_OBJ_CANDLECHART,page, "cd" , _Symbol , 10 , 280 , 500 , 260 ); Gui_Set(cd,GUI_PROP_LOAD_BARS, _Symbol , 80 ); Gui_Set(cd,GUI_PROP_ADD_MA, "" , 20 , clrDodgerBlue ); Gui_Set(cd,GUI_PROP_ADD_BANDS, "" , 20 , 2.0 );
Диалоги и тосты
enum { CMD_CLOSE_ALL= 500 }; Gui_Set( 0 ,GUI_PROP_CONFIRM, "Close all|Close every position?|Close|Cancel" ,CMD_CLOSE_ALL); // later, in the event loop: if (ev==GUI_EVENT_DIALOG && Gui_GetNum(sender,GUI_PROP_CMD)==CMD_CLOSE_ALL && l== 0 ) CloseAll(); // l = button index, -1 = cancelled Gui_Set( 0 ,GUI_PROP_TOAST, "Order|Filled" ,GUI_NOTICE_SUCCESS, 3000 );
Темы и цвета
Gui_Set( 0 ,GUI_PROP_THEME, "" ,GUI_THEME_MIDNIGHT); // DARK, LIGHT, MIDNIGHT, HIGHCONTRAST, SOFT Gui_Set( 0 ,GUI_PROP_ACCENT, "" , clrOrange ); Gui_Set( 0 ,GUI_PROP_RADIUS, "" , 10 );
Помните об окнах и значениях
Gui_Set( 0 ,GUI_PROP_AUTO_LAYOUT, "" , true ); // load now, save when the GUI is destroyed Gui_Set( 0 ,GUI_PROP_LOAD_VALUES); // in OnInit Gui_Set( 0 ,GUI_PROP_SAVE_VALUES); // in OnDeinit
Оба варианта используют небольшие текстовые файлы. Глобальные переменные в терминале не используются.
Делайте что-нибудь каждую секунду
Gui_Set( 0 ,GUI_PROP_COUNTER, "refresh" , 1000 , true ); // name, ms, repeat // in OnTimer: if (Gui_GetNum( 0 ,GUI_PROP_COUNTER_DONE, "refresh" )!= 0 ) RefreshNumbers();
7. Торговая панель с собственной функцией размещения ордеров.
Система обработки ордеров, панель позиций и калькулятор рисков считывают данные со счета и тикера, а затем предоставляют информацию о событиях. Они никогда не отправляют ордера. Вы сами решаете, что произойдет, когда пользователь нажмет кнопку «Купить» или «Продать».
#include <GUI_Graphic_Library.mqh> #ifdef __MQL5__ #include <Trade\Trade.mqh> CTrade g_trade; #endif input bool InpLiveTrading = false ; // send real orders int g_ticket = 0 ; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int OnInit () { if (!Gui_Create( 0 , "GUI_TradePanel" )) return INIT_FAILED ; int w = Gui_Add(GUI_OBJ_WINDOW, 0 , "w" , "Trade" , 20 , 40 , 360 , 260 ); Gui_Set(w, GUI_PROP_MAIN_WINDOW, "" , true ); g_ticket = Gui_Add(GUI_OBJ_ORDERTICKET, w, "ticket" , _Symbol , 10 , 10 , 340 , 212 ); Gui_Set(g_ticket, GUI_PROP_LOTS, "" , 0.10 ); Gui_Set(g_ticket, GUI_PROP_STOP_POINTS, "" , 300 ); Gui_Set(g_ticket, GUI_PROP_TP_POINTS, "" , 600 ); Gui_Set(g_ticket, GUI_PROP_SHOW_LINES, "" , true ); // SL and TP lines on the chart Gui_Set( 0 , GUI_PROP_CLEAR_EVENTS); return INIT_SUCCEEDED ; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void MyTrade( const bool buy, const double lots, const double sl, const double tp) { if (!InpLiveTrading) { Print ( "Trading is off. Would " , buy ? "buy " : "sell " , lots, " lots" ); return ; } #ifdef __MQL5__ if (buy) g_trade.Buy(lots, _Symbol , 0.0 , sl, tp); else g_trade.Sell(lots, _Symbol , 0.0 , sl, tp); #else if (buy) OrderSend ( _Symbol , OP_BUY, lots, Ask, 3 , sl, tp, "GUI" , 0 , 0 , clrGreen ); else OrderSend ( _Symbol , OP_SELL, lots, Bid, 3 , sl, tp, "GUI" , 0 , 0 , clrRed ); #endif } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void ProcessEvents() { ENUM_GUI_EVENT ev; int sender; long l; double d; string s; while (Gui_NextEvent(ev, sender, l, d, s)) if (ev == GUI_EVENT_TRADE) // l: 0 buy, 1 sell d: lots s: "sl|tp" prices { string p[]; StringSplit (s, '|' , p); double sl = ( ArraySize (p) > 0 ) ? StringToDouble (p[ 0 ]) : 0.0 ; double tp = ( ArraySize (p) > 1 ) ? StringToDouble (p[ 1 ]) : 0.0 ; MyTrade(l == 0 , d, sl, tp); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void OnDeinit ( const int r) { Gui_Destroy(); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void OnTimer () { Gui_Timer(); ProcessEvents(); Gui_Update(); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void OnChartEvent ( const int id, const long &l, const double &d, const string &s) { Gui_ChartEvent(id, l, d, s); ProcessEvents(); Gui_Update(); }
Сначала протестируйте на демо-счете. Перед отправкой реальных ордеров также проверьте размер лота на соответствие минимальному, максимальному и шаговому значениям для данного символа, а также расстояние стоп-лосса на уровне стоп-лосса брокера.
Позиции работают аналогично: добавьте GUI_OBJ_POSITIONS, затем реагируйте на GUI_EVENT_POSITION (параметр lparam — это ключ, dparam — 1 для закрытия и 2 для изменения).
8. Использование его в качестве индикатора
Индикатор может отображать графический интерфейс пользователя в собственном дочернем окне. Передайте номер этого окна в функцию Gui_Create:
#property indicator_separate_window int OnInit () { int sub= ChartWindowFind (); Gui_Create( 0 , "GUI_MyIndicator" ,sub); // add windows and controls as usual return INIT_SUCCEEDED ; }
Для отображения графика цены с помощью индикатора используйте подокно 0. Два демонстрационных примера индикаторов являются полными примерами. Для каждой программы и графика используется один графический интерфейс, поэтому дайте каждой программе собственное имя графического интерфейса.
9. MetaTrader 4 и MetaTrader 5
| Тема | МетаТрейдер 4 | MetaTrader 5 |
|---|---|---|
| Файл библиотеки | .ex4 | .ex5 |
| Контекстное меню | Нажмите и удерживайте левую кнопку мыши или нажмите Ctrl + щелчок. | Щелкните правой кнопкой мыши |
| Колесо мыши | Отправка не осуществляется терминалом. Используйте полосы прокрутки. | Работы |
| Глубина рынка | Добавьте уровни самостоятельно. | Читает книгу рыночных котировок |
| Экономический календарь | Добавьте строки самостоятельно. | Грузы с терминала |
| Набор текста | Встроенная карта США | Подойдет любая раскладка клавиатуры. |
10. Если что-то не работает
| Проблема | Что делать |
|---|---|
| На диаграмме ничего не отображается. | Убедитесь, что функция Gui_Create вернула значение true, и прочтите последние строки вкладки «Эксперты». |
| Компилятор не может открыть файл GUI_Graphic_Library.mqh. | Включаемый файл находится не в папке Include, а в папке с данными находится не та же папка, что и ваша программа. |
| Программа не может загрузить библиотеку во время выполнения. | Файл с расширением .ex5 или .ex4 отсутствует в библиотеках, или его имя было изменено. |
| Измененное в коде значение не отображается. | Вызовите функцию Gui_Update() в конце обработчика. |
| На вкладке «Эксперты» указано, что данное свойство не поддерживается. | Это свойство отсутствует для данного элемента. Проверьте справочник API. |
| На одной диаграмме соревнуются две программы. | Присвойте каждому из них собственное имя в функции Gui_Create. |
| Линии диаграммы покрывают графический интерфейс пользователя. | Вызовите функцию Gui_BringToFront() после создания объектов диаграммы. |
| Текст слишком мелкий или слишком крупный | Установите значение Gui_Set(0,GUI_PROP_SCALE,"",1.5) или перезапустите терминал после изменения масштаба окна Windows. |
| Вы хотите узнать, чем занимается библиотека? | Включите Gui_Set(0,GUI_PROP_DEBUG,"",true) для отображения отладочной информации. |
11. Советы
- Вызывайте метод Gui_Update() в конце каждого обработчика. Он перерисовывает только то, что изменилось.
- Скрытые вкладки и свернутые окна не вызывают перерисовки, поэтому их обновление по таймеру обходится недорого.
- Используйте GUI_PROP_MAX_FPS для ограничения частоты кадров, если вы запускаете много графиков.
- Используйте GUI_PROP_CLEAR_EVENTS в конце OnInit, чтобы отбросить события, поставленные в очередь во время создания панели.
- Воспользуйтесь инструментом «Изображение в код» на веб-сайте, чтобы преобразовать логотип или значок в формате PNG в массив для функции Gui_AddImage.
- Новые значения перечисления добавляются только в конце, поэтому программы, собранные с использованием более старого включаемого файла, продолжат работать после обновления. Замените файл библиотеки и включаемый файл одновременно.
12. Куда отправиться дальше?
- Галерея элементов, установка, руководство, справочник API, преобразование изображений в код и помощь: https://www.betasoft.dev/gui-graphic-library
- Версия MetaTrader 5: https://www.mql5.com/en/market/product/206761
- Версия MetaTrader 4: https://www.mql5.com/en/market/product/206760
Ваше мнение приветствуется. Если у вас есть вопросы или предложения по улучшению, пожалуйста, напишите в комментариях к продукту или отправьте мне сообщение на MQL5.com.





