Несколько окон ControlsDialog

 

Добрый день!

Прошу совета специалистов по классам, в частности стандартному примеру ControlsDialog.

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

Вообще возможна ли раздельная обработка событий для одного класса? Если да, то где копать информацию

ControlsDialog.mqh не трогал. Исправленный код controls.mq5

//+------------------------------------------------------------------+
//|                                                     Controls.mq5 |
//|                             Copyright 2000-2023, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2000-2023, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
#include "ControlsDialog.mqh"
//+------------------------------------------------------------------+
//| Global Variables                                                 |
//+------------------------------------------------------------------+
CControlsDialog ExtDialog;
CControlsDialog ExtDialog2;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- create application dialog
   if(!ExtDialog.Create(0,"Controls",0,20,20,360,324))
     return(INIT_FAILED);
//--- run application
   ExtDialog.Run();
//--- create application dialog
   if(!ExtDialog2.Create(0,"Controls2",0,420,20,760,324))
     return(INIT_FAILED);
//--- run application
   ExtDialog2.Run();
   
//--- succeed
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- destroy dialog
   ExtDialog.Destroy(reason);
   ExtDialog2.Destroy(reason);
  }
//+------------------------------------------------------------------+
//| Expert chart event function                                      |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,         // event ID  
                  const long& lparam,   // event parameter of the long type
                  const double& dparam, // event parameter of the double type
                  const string& sparam) // event parameter of the string type
  {
   ExtDialog.ChartEvent(id,lparam,dparam,sparam);
   ExtDialog2.ChartEvent(id,lparam,dparam,sparam);
  }
//+------------------------------------------------------------------+

Результат

Заранее спасибо!

 

У каждого из этих диалогов есть свой пятизначный ID, с которого начинается значение sparam.

sparam: 20328ClientBack
sparam: 01677Border

По этому ID (член класса CAppDialog::m_instance_id) и нужно вызывать соответствующий инстанс. А так, как сейчас, в OnChartEvent() передается управление обоим инстансам. Вот они и реагируют одинаково.

 
Ihor Herasko #:

У каждого из этих диалогов есть свой пятизначный ID, с которого начинается значение sparam.

По этому ID (член класса CAppDialog::m_instance_id) и нужно вызывать соответствующий инстанс. А так, как сейчас, в OnChartEvent() передается управление обоим инстансам. Вот они и реагируют одинаково.

Спасибо за ответ! В теории понятно, а практически буду разбираться...

 
Aleksei Ostroborodov #:

Спасибо за ответ! В теории понятно, а практически буду разбираться...

Данная проблема фиксилась наравне со многими другими в этой статье.

Если вкратце, то вот фрагмент:

Класс CAppDialog теперь учитывает instance_id окна при назначении идентификаторов элементам интерфейса. Без этой правки элементы управления в разных окнах с одинаковыми именами конфликтовали (влияли друг на друга).

В файле Dialog.mqh нужно в методе bool CAppDialog::Run заменить строку:

if(Id(m_subwin*CONTROLS_MAXIMUM_ID)>CONTROLS_MAXIMUM_ID)

на такую:

if(Id(StringToInteger(m_instance_id) + m_subwin * CONTROLS_MAXIMUM_ID) > CONTROLS_MAXIMUM_ID)
Без правки стандартных классов в любом случае не обойтись, потому что поле m_instance_id сделано приватным и нет метода-аксессора к нему.
Язык MQL как средство разметки графического интерфейса MQL-программ. Часть 2
Язык MQL как средство разметки графического интерфейса MQL-программ. Часть 2
  • www.mql5.com
В статье продолжается проверка новой концепции описания оконного интерфейса MQL-программ с помощью конструкций языка MQL. Автоматическое создание GUI на основе MQL-разметки предоставляет дополнительный функционал для кэширования и динамического порождения элементов, управления стилями, новых схем обработки событий. Прилагается усовершенствованная версия стандартной библиотеки элементов управления.
 
Stanislav Korotky #:

В файле Dialog.mqh нужно в методе bool CAppDialog::Run заменить строку:

на такую:

Без правки стандартных классов в любом случае не обойтись, потому что поле m_instance_id сделано приватным и нет метода-аксессора к нему.

Вот так вроде заработало хорошо. Огромное спасибо!!!

Вопрос наверное дурацкий, но после дальнейших обновлений придется каждый раз править Dialog.mqh ?

 
Aleksei Ostroborodov #:

Вот так вроде заработало хорошо. Огромное спасибо!!!

Вопрос наверное дурацкий, но после дальнейших обновлений придется каждый раз править Dialog.mqh ?

Да
 
Aleksei Ostroborodov #:

Вопрос наверное дурацкий, но после дальнейших обновлений придется каждый раз править Dialog.mqh ?

Можно везде использовать свои классы, пропатченные.

Еще, хоть я и не пробовал, можно поставить у модифицированных исходников атрибут "только чтение". По идее, инсталлятор должен их оставить как есть.

 
Aleksei Ostroborodov #:

Вот так вроде заработало хорошо. Огромное спасибо!!!

Вопрос наверное дурацкий, но после дальнейших обновлений придется каждый раз править Dialog.mqh ?

Диалог1.мкх сделайте с правками и его вызывайте.

 

Основная задача выполнена - несколько окон работают и управляются раздельно. Спасибо всем откликнувшимся!

Но!)) Теперь появилась другая проблемка - диалоги минимизируются при переходе на другие графики и возврате обратно. Причем накладываются друг на друга и их уже невозможно восстановить в стандартном размере. Попробовал исправить так

 virtual void      OnClickButtonMinMax(void) {}

но минимизация по кнопке отключается, а при переходе на другие графики диалоги все равно сворачиваются.

Может заодно и по этому вопросу кто-нибудь укажет решение?)

 
Aleksei Ostroborodov #:

Основная задача выполнена - несколько окон работают и управляются раздельно. Спасибо всем откликнувшимся!

Но!)) Теперь появилась другая проблемка - диалоги минимизируются при переходе на другие графики и возврате обратно. Причем накладываются друг на друга и их уже невозможно восстановить в стандартном размере. Попробовал исправить так

 virtual void      OnClickButtonMinMax(void) {}

но минимизация по кнопке отключается, а при переходе на другие графики диалоги все равно сворачиваются.

Может заодно и по этому вопросу кто-нибудь укажет решение?)

Проблема фиксилась в моих статьях, но так просто как предыдущую её не пропатчить. Потребуется прочитать, например, статью (раздел "Резиновые" окна), но с тех пор могло что-то измениться в MQL и потребуется "допиливать". Попробуйте для начала взять папку ControlsPlus и работать с ней. Вероятно, более поздняя версия "плюсовых контролов" лежит в более поздних статьях, в частности, про формы (но там не описываются принципы окон) https://www.mql5.com/ru/articles/7795.

Применение OLAP в трейдинге (Часть 2): Визуализация результатов интерактивного анализа многомерных данных
Применение OLAP в трейдинге (Часть 2): Визуализация результатов интерактивного анализа многомерных данных
  • www.mql5.com
В статье рассматриваются различные аспекты создания интерактивного графического интерфейса MQL-программы, предназначенной для OLAP-обработки истории счета и торговых отчетов. Для получения наглядного результата используются максимизируемые и масштабируемые окна, адаптивная раскладка "резиновых" элементов управления, новый "контрол" для вывода диаграмм. На основе этого реализован GUI с выбором показателей по координатным осям, агрегатных функций, типов графиков и сортировок.
 
Aleksei Ostroborodov #:
Но!)) Теперь появилась другая проблемка - диалоги минимизируются при переходе на другие графики и возврате обратно. Причем накладываются друг на друга и их уже невозможно восстановить в стандартном размере.

Проблема была только в МТ4, в МТ5 все работает норм. 

Решил для себя, просто обнулив функцию Minimize:

   #ifdef __MQL4__

      virtual void      Minimize() {};

   #endif}


Конечно после этого сворачивать окна нельзя, но меня пока вполне и так устраивает. Всем спасибо за помощь!