Обсуждение статьи "MQL5 для начинающих: Антивандальная защита графических объектов"

 

Опубликована статья MQL5 для начинающих: Антивандальная защита графических объектов:

Что должна делать ваша программа, если графические панели управления были удалены или изменены кем-то еще? В этой статье мы покажем, как после удаления приложения не иметь на графике "бесхозные" объекты, и как не потерять над ними контроль в случае переименования или удаления созданных программно объектов.

Одним из достоинств языка программирования MQL5 является то, что из имеющихся стандартных функций MQL5 можно формировать коды, решающие различными способами различные задачи и цели при работе в торговом терминале MetaTrader 5.

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

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

Рис. 1. Пример внешнего вида панели управления до изменения свойств ее объектов вручную и после

Описанные в статье варианты конструирования в коде ответных действий на вмешательство "со стороны" могут оказаться не лишними для таких случаев, когда, например, в сторонней программе, запущенной на графике и не предназначенной непосредственно для его очистки, может применяться функция для удаления объектов (ObjectsDeleteAll() или созданная самостоятельно), производящая по заданным в ней параметрам:

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

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

Статья может быть полезна и тем, кто только начинает знакомиться с обработкой событий в функции OnChartEvent().

Автор: Dina Paches

 

Весьма хорошая статья, я от подобного вандализма защищаю программы чуть по другому ...

Все необходимые обьекты создаю с префиксом, за пределами видимости графика в специальной функции типа CREATE_OBJECTS(),

далее проверяю ошибку 4202 ERR_OBJECT_DOES_NOT_EXIST Объект не существует , и если ошибка такая есть то снова вызываю функцию CREATE_OBJECTS().

Остальные свойства обьектов изменяются по мере необходимости на графике. 

 

Молодец. Статья хорошая. Примеры неплохие.

Но вроде есть простой способ проверки существования объекта и при необходимости всегда его можно восстановить. 

 
Victor Nikolaev:

Но вроде есть простой способ проверки существования объекта и при необходимости всегда его можно восстановить. 

Фишка в том чтобы сократить число проверок до минимума вместо проверок без перекуров. Для этого их привязали к конкретному событию. Если я правильно понял. Жаль тока что всё это не привязано к стандартной библиотеке
 

Спасибо вам всем за отзывы!

Victor Nikolaev:

Молодец. Статья хорошая. Примеры неплохие.

Но вроде есть простой способ проверки существования объекта и при необходимости всегда его можно восстановить. 

Спасибо, вам, Виктор!

На всякий случай скажу, что приведённые варианты не в противовес обычным привычным (простым или не очень).

Просто обычные привычные способы (простые или не очень) могут быть не всегда "своевременными". Тем более, что те же различные "шаловливые ручки" ведь никто не отменял. В том числе, и возможно в каких-то случаях наши собственные или пользовательские.

То бишь, если, к примеру, объекты панели управления программы случайно удалены через "Список объектов" вместе с другими выделением через Shift или же сторонней программой, где может применяться функция для удаления объектов (ObjectsDeleteAll() или созданная самостоятельно), производящая по заданным в ней параметрам:

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

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

Как-то так.

Т.е., для "охраны" объектов программы конечно же разные варианты, способы и их сочетания могут применяться.

Да и описываемые в статье - это не какие-то обязательные для каждого кода, а из тех, что в каких-то случаях могут оказаться быть предусмотренными не лишними.

Alexander Puzanov:
Фишка в том чтобы сократить число проверок до минимума вместо проверок без перекуров. Для этого их привязали к конкретному событию. Если я правильно понял. 

Да, спасибо, верно, сокращение числа обработок при проверках - это есть из фишек там.

 

Эта статья полностью устарела.

1. Она точно не для новичков.

2. Это не MQL5 - это MQL4!

3. Способ кодирования абсолютно сложен и - с учетом MQL5 - в любом случае абсолютно неправилен.

Если вы считаете проблемой то, что другой советник или индикатор может уничтожать объекты, то это можно сделать гораздо эффективнее и элегантнее:

- Определить MQL-объект для каждого объекта графика, как это уже сделано в стандартной библиотеке Control. Каждый такой MQL-объект представляет объект графика и хранит все его данные - обычный стиль MQL5.

- Упакуйте все объекты в главный контейнер.

- Только главный контейнер проверяет, не был ли объект графика удален, либо время от времени, либо по соответствующему chart-событию в OnChartEvent().

- Добавьте функцию-член .ReCreate() в CWnd и виртуальную функцию OnRecreate() во все объекты, реализующие эту функциональность.

- Если главный контейнер обнаруживает своего рода "вандализм", он посылает .ReCreate() всем своим дочерним объектам.

Готово.

 

Я плохо понимаю английский язык. Я не читал версию этой статьи на английском.

Простите, но...вы читали эту статью полностью?

Вы говорите по-русски?

Если вы говорите по-русски, то мы с вами можем более конструктивно пообщаться в дискуссии на русской версии этой статьи.


Doerk Hilger:

Эта статья полностью устарела.

Вы ошибаетесь.

Doerk Hilger:

1. Это точно не для новичков

Почему вы так думаете? Расскажите мне об этом, пожалуйста, подробнее.

Doerk Hilger:

2. Это не MQL5 - это MQL4!

Вы ошибаетесь.

Но схемы, описанные в этой статье, можно использовать не только для MQL5, но и для MQL4.

Doerk Hilger:

3. Способ кодирования совершенно сложен и - с учетом MQL5 - в любом случае совершенно неправилен.

Пожалуйста, прочитайте эту статью "MQL5 для начинающих: Антивандальная защита графических объектов" ещё раз внимательно. И, пожалуйста, не торопитесь с выводами. Если и после этого ваше мнение не изменится, то напишите более конкретно непонятные для вас моменты.

Ознакомьтесь со статьей "MQL5 для начинающих:Антивандальная защита графических объектов" еще раз внимательно. И, пожалуйста, не спешите с выводами. Если после этого ваше мнение не изменится, пишите еще, особенно сложные для вас моменты.


Доерк Хилгер:

Если кто-то считает проблемой, что другой советник или индикатор может уничтожить объекты, то это можно сделать гораздо эффективнее и элегантнее:

- Определите MQL-объект для каждого объекта графика, как это уже сделано в стандартной библиотеке Control. Каждый такой MQL-объект представляет объект графика и хранит все его данные - обычный стиль MQL5.

- Упакуйте все объекты в главный контейнер.

- Только главный контейнер проверяет, не был ли объект графика удален, либо время от времени, либо по соответствующему chart-событию в OnChartEvent().

- Добавьте функцию-член .ReCreate() в CWnd и виртуальную функцию OnRecreate() во все объекты, реализующие эту функциональность.

- Если главный контейнер обнаруживает своего рода "вандализм", он посылает .ReCreate() всем своим дочерним объектам.

Готово.

В статье "MQL5 для начинающих: Антивандальная защита графических объектов" рассматриваются схемы только двух вариантов (способов) из множества возможных. Но различных вариантов (способов), конечно, может быть много.
Применять или не применять схемы из этой статьи - это зависит только от ваших решений.


Скажу только, что эти две схемы из статьи "MQL5 для начинающих: Антивандальная защита графических объектов" обладают следующими положительными качествами:

  • экономно используют ресурсы компьютера и торгового терминала;
  • имеют высокий уровень своевременности срабатывания (не все другие обычные привычные способы могут быть своевременными);
  • могут быть применены совместно со многими другими вариантами (способами).

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

Если вам не нравятся эти схемы или они не подходят вам по каким-то другим причинам, вы, конечно, можете использовать другие схемы. И, естественно, в том стиле программирования, что для вас привычен.

Применять эти схемы из статьи или не применять - это ваше личное дело и право.


В статье"MQL5 для начинающих: Антивандальная защита графических объектов" рассмотрены только два варианта схем (методов) из множества возможных. Но вариантов (методов) может быть очень много.
Использовать или не использовать схемы из этой статьи - зависит только от ваших решений.

Я могу только сказать, что эти две схемы из статьи"MQL5 для начинающих: Антивандальная защита графических объектов" обладают следующими положительными качествами:
  • экономно расходуют ресурсы компьютера и торгового терминала;
  • имеют высокий уровень своевременности реагирования (не все остальные привычные способы могут быть своевременными);
  • их можно использовать в сочетании со многими другими способами.

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

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

Использовать или не использовать схемы из этой статьи - зависит от ваших решений.


Извините за мой английский.


P./S.: Пожалуйста, прочитайте эту статью ещё раз внимательно. И, пожалуйста, не торопитесь с выводами. Если у вас затем будут конструктивные вопросы или предложения, то пишите, пожалуйста. Я смогу ответить вам скорее всего только после новогодних каникул. Это через пять дней.

Пожалуйста, прочитайте эту статью еще раз внимательно. И, пожалуйста, не торопитесь с выводами. Если у вас возникнут конкретные вопросы и предложения, пожалуйста, пишите. Ответить вам я смогу, скорее всего, только после новогодних праздников. Это будет через пять дней.

П./С.: Сегодня у нас праздник Нового года. Поэтому и вас поздравляю с наступающим новым 2016-м годом!

Сегодня у нас новогодний праздник. Поэтому поздравляем вас с Новым 2016 годом!

 

При компиляции в MetaEditor Version 5.00 build 1241 прилагаемых к статье тестовых кодов с именами:

  • test_count_click_0.mq5
  • test_count_click_1.mq5
  • test_count_click_2.mq5

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

Ниже описание проблемы, способ её решения и файлы с решением проблемы, взамен прилагаемых к статье:

Но сначала вновь подчеркну, что функции, относящиеся к антивандальным работали и работают корректно при компиляции в новом билде.

Не корректность работы названных тестовых кодов проявляется в том, что при щелчках по объектам панели управления этих тестовых кодов перестало происходить изменение отображения количества щелчков, кроме самых первых. Т.е., сколько ни щёлкать по кнопкам, цифры будут такие:

Однако эти же тестовые коды, скомпилированные у меня в более ранних версиях, продолжают работать корректно и в новом 1241-м билде, если их там не компилировать. Т.е., при кликах на объекты этих тестовых кодов идёт нормальный подсчёт кликов:

Выявила, что обнаруженная проблема связана с применением функции ArrayFill() в блоке обработки событий CHARTEVENT_OBJECT_CLICK в OnChartEvent().

               count=countClick[index]+count;
               int summ=countClick[NUMBER_ALL]+1;
               //---
               ArrayFill(countClick,index,1,count);
               ArrayFill(countClick,NUMBER_ALL,1,summ)

Однако если перед этой функцией поставить вывод на печать данных или ChartRedraw(), то названные коды из статьи начинают работать корректно после компиляции:

               count=countClick[index]+count;
               int summ=countClick[NUMBER_ALL]+1;
               //---
               //TEST_PRINT_TWO(count,summ);
               ChartRedraw();
               //---
               ArrayFill(countClick,index,1,count);
               ArrayFill(countClick,NUMBER_ALL,1,summ);

В прилагаемых ниже трёх файлах с исправлениями, как и в одноимённых их версиях, прикреплённых к статье, эти участки, как и исправление проблемы в кодах ниже - идентичны. То есть:

  • в файле test_count_click_0.mq5 - антивандальные защитные меры не применяются;
  • в файле test_count_click_1.mq5 - вариант «самоудаления» программы с чарта при несанкционированном вмешательстве в её объекты на графике;
  • в файле test_count_click_2.mq5 - вариант «самовосстановления» объектов программы при их несанкционированном изменении или удалении.

P./S.: Для корректной работы прилагаемых ниже кодов требуется в папке "Include" иметь в наличии файл objectcreateandset.mqh, прикреплённый к статье, где прикреплены и коды, на основе которых обнаружила не корректную работу названной функции. Так же этот файл можно скачать из Code Base

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

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

 
Dina Paches:

Я плохо понимаю английский язык. Я не читал версию этой статьи на английском.

Простите, но...вы прочитали эту статью полностью?


+1

Очень хороший ответ.

 
Doerk Hilger:

- Определите MQL-объект для каждого объекта графика, как это уже сделано в стандартной библиотеке Control. Каждый такой MQL-объект представляет объект графика и хранит все его данные - обычный стиль MQL5.

- Упакуйте все объекты в главный контейнер.

- Только главный контейнер проверяет, не был ли объект графика удален, либо время от времени, либо по соответствующему chart-событию в OnChartEvent().

- Добавьте функцию-член .ReCreate() в CWnd и виртуальную функцию OnRecreate() во все объекты, реализующие эту функциональность.

- Если главный контейнер обнаруживает "вандализм", он посылает всем своим дочерним объектам запрос .ReCreate().

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

Ваше решение: купить новый ООП-костюм. А также не забудьте купить галстук к новому костюму.

PS Что касается стандартной библиотеки: к сожалению, библиотека Control является худшей частью этой библиотеки - слишком много ошибок и нереализованных или недоступных опций. Как результат - иногда эта библиотека является источником проблем (мусор на графике), о которых говорится в этой статье