Интерактивные события на графиках

Графики MetaTrader 5 не только обеспечивают визуальное представление данных и являются средой выполнения MQL-программ, но и поддерживают механизм интерактивных событий — за счет него программы могут реагировать на действия пользователя и других программ. Как уже говорилось в Обзоре функций обработки событий, для этих целей выделен особый тип событий — OnChartEvent.

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

Событие OnChartEvent генерируется клиентским терминалом при следующих действиях пользователя с графиком:

  • изменение размера или настроек графика;
  • нажатия клавиатуры, когда окно графика находится в фокусе;
  • перемещение курсора мыши;
  • щелчок мыши на графике;
  • щелчок мыши на графическом объекте;
  • создание графического объекта;
  • удаление графического объекта;
  • перемещение графического объекта при помощи мыши;
  • окончание редактирования текста в поле ввода графического объекта OBJ_EDIT.

MQL-программа получает перечисленные события только от графика, на котором она запущена. Как и прочие типы событий, они поступают в очередь. Все события затем обрабатываются одно за другим в порядке поступления. Если в очереди MQL-программы уже находится событие OnChartEvent конкретного типа или оно обрабатывается, новое событие такого же типа в очередь не ставится (отбрасывается).

Некоторые типы событий активны всегда, а некоторые по умолчанию выключены и их необходимо явным образом разрешить, установив соответствующие свойства графика с помощью вызова ChartSetInteger. К подобным выключенным событиям относятся, в частности, перемещения мыши и прокрутка её колесика. Все они характеризуются тем, что могут генерировать массовые потоки событий, и в целях экономии ресурсов рекомендуется их включать только при необходимости.

Помимо стандартных событий существует понятие "пользовательских событий", смысл и содержимое параметров которых назначает и интерпретирует сама MQL-программа (одна или несколько, если речь о взаимодействии комплекса программ). MQL-программа может посылать "пользовательские события" на график (в том числе, на другой) при помощи функции EventChartCustom. Такие события также обрабатываются функцией OnChartEvent.

Если на графике несколько MQL-программ с обработчиком OnChartEvent, они все получат одинаковый поток событий.

Все MQL-программы работают в потоках, отличных от главного потока приложения. Главный поток терминала отвечает за обработку всех системных сообщений Windows, и в результате этой обработки в свою очередь порождает сообщения Windows для своего же приложения. Например, буксировка графика мышью порождает несколько системных сообщений WM_MOUSE_MOVE (в терминах Windows API) для последующей отрисовки окна приложения, а также посылает внутренние сообщения экспертам и индикаторам, запущенным на этом графике. При этом может возникнуть ситуация, что главный поток приложения ещё не успел обработать системное сообщение о перерисовке окна WM_PAINT (и поэтому ещё не изменил внешний вид графика), а эксперт или индикатор уже получили событие о перемещении курсора мыши. Тогда свойство графика CHART_FIRST_VISIBLE_BAR будет изменено только после отрисовки графика.

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