Событие изменений графика

При изменении размеров, способа отображения котировок, масштаба или прочих настроек графика терминал посылает событие CHARTEVENT_CHART_CHANGE, которое не имеет параметров — суть изменений MQL-программа должна выяснить самостоятельно с помощью вызовов ChartGet-функций.

Мы уже использовали это событие в примере ChartModeMonitor.mq5 в разделе Режимы отображения графика. Сейчас разберем еще один пример.

Как известно, MetaTrader 5 позволяет сохранять образ текущего графика в файл заданного размера (команда Сохранить как рисунок контекстного меню). Однако такой способ получения скриншота подходит не во всех случаях. В частности, если требуется изображение вместе со всплывающей подсказкой или при активном состоянии объекта типа "поле ввода" (когда внутри поля выделен текст и виден текстовый курсор), штатная команда не поможет, поскольку она формирует образ графика заново без учета этих и некоторых других нюансов текущего состояния окна.

Единственной альтернативой для получения точной копии окна является использование внешних по отношению к терминалу средств (например, клавишей PrtSc через буфер обмена Windows), но такой способ не гарантирует необходимый размер окна. Чтобы не подбирать размер методом проб и ошибок или какими-то дополнительными программами, создадим индикатор EventWindowSizer.mq5, который будет на лету отслеживать настройку размера пользователем и выводить текущее значение в комментарий.

Вся работа производится в обработчике OnChartEvent, начиная с проверки идентификатора события на равенство CHARTEVENT_CHART_CHANGE. Размеры окна в пикселях можно получить с помощью свойств CHART_WIDTH_IN_PIXELS и CHART_HEIGHT_IN_PIXELS. Однако они возвращают размеры без учета рамок, а скриншот обычно требуется с рамками. Поэтому мы выведем в комментарий не только значения свойств (помечены словом "Screen"), но и откорректированные величины (помечены словом "Picture"): по ширине следует прибавить 2 пикселя, а по вертикали — 1 (таковы особенности отрисовки окна в терминале).

void OnChartEvent(const int idconst long &lparamconst double &dparamconst string &sparam)
{
   if(id == CHARTEVENT_CHART_CHANGE)
   {
      const int w = (int)ChartGetInteger(0CHART_WIDTH_IN_PIXELS);
      const int h = (int)ChartGetInteger(0CHART_HEIGHT_IN_PIXELS);
      // "Сырые" размеры "как есть" выводятся с пометкой "Screen",
      // поправка на (-2,-1) нужна для включения рамок - выведено с пометкой "Picture",
      // поправка на (-54,-22) нужна для включения шкал - выведено с пометкой "Including scales".
      Comment(StringFormat("Screen: %d x %d\nPicture: %d x %d\nIncluding scales: %d x %d",
         whw + 2h + 1w + 2 + 54h + 1 + 22));
   }
}

Более того, полученные значения не учитывают шкалы времени и цен. Если они также должны быть учтены в размере скриншота, то следует внести поправку и на их размер. К сожалению, MQL5 API не предоставляет возможности узнать эти размеры, так что мы можем определить их лишь эмпирическим путем: для стандартных настроек шрифтов Windows ширина шкалы цен составляет 54 пикселя, и высота шкалы времени — 22 пикселя. В вашей версии Windows эти константы могут отличаться, поэтому их следует отредактировать или задать с помощью входных параметров.

Запустив индикатор на графике, попробуйте менять размеры окна и смотрите, как будут меняться числа в комментарии.

Скриншот окна со всплывающей подсказкой и текущими размерами в комментарии
Скриншот окна со всплывающей подсказкой и текущими размерами в комментарии