Изменение CAppDialog

 
Можно ли изменить цвет, заголовка и фона CAppDialog или же изменить их прозрачность, либо просто скрыть фон и заголовок с рамкой, чтобы данные элементы не мешали просмотру графика? Смотрел в документации, но ничего там не нашел по этому поводу.
 
Mihail Matkovskij:
Можно ли изменить цвет, заголовка и фона CAppDialog или же изменить их прозрачность, либо просто скрыть фон и заголовок с рамкой, чтобы данные элементы не мешали просмотру графика? Смотрел в документации, но ничего не там нашел по этому поводу.

Кое-что можно: Панели и диалоги. Можно задавать цвет, шрифт ...

Про индикаторы смотреть тут:

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Панели и диалоги. Можно задавать цвет, шрифт ...

Vladimir Karputov, 2018.03.19 13:05

Кстати, если создавать панель на базе CAppDialog в индикаторе, то undef, затем входной параметр и define позволяет применять изменения без принудительного пересоздания панели:

//+------------------------------------------------------------------+
//|                                  ControlsBmpButton INDICATOR.mq5 |
//|                              Copyright © 2018, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2018, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.000"
#property indicator_chart_window
#property indicator_plots 0
#property description "Control Panels and Dialogs. Demonstration class CBmpButton"
#include <Controls\Defines.mqh>
#undef CONTROLS_FONT_NAME 
#undef CONTROLS_FONT_SIZE 

#undef CONTROLS_BUTTON_COLOR
#undef CONTROLS_BUTTON_COLOR_BG
#undef CONTROLS_BUTTON_COLOR_BORDER

#undef CONTROLS_DIALOG_COLOR_BORDER_LIGHT
#undef CONTROLS_DIALOG_COLOR_BORDER_DARK
#undef CONTROLS_DIALOG_COLOR_BG
#undef CONTROLS_DIALOG_COLOR_CAPTION_TEXT
#undef CONTROLS_DIALOG_COLOR_CLIENT_BG
#undef CONTROLS_DIALOG_COLOR_CLIENT_BORDER 

input string   font_name                  = "Trebuchet MS";
input int      font_size                  = 10;

input color    button_color               = C'0x3B,0x29,0x28';
input color    button_color_bg            = C'0xDD,0xE2,0xEB';
input color    button_color_border        = C'0xB2,0xC3,0xCF';

input color    dialog_color_border_light  = White;
input color    dialog_color_border_dark   = C'0xB6,0xB6,0xB6';
input color    dialog_color_bg            = C'0xF0,0xF0,0xF0';
input color    dialog_color_caption_text  = C'0x28,0x29,0x3B';
input color    dialog_color_client_bg     = C'0xF7,0xF7,0xF7';
input color    dialog_color_client_border = C'0xC8,0xC8,0xC8';

#define CONTROLS_FONT_NAME                font_name
#define CONTROLS_FONT_SIZE                font_size

#define CONTROLS_BUTTON_COLOR             button_color
#define CONTROLS_BUTTON_COLOR_BG          button_color_bg
#define CONTROLS_BUTTON_COLOR_BORDER      button_color_border

#define CONTROLS_DIALOG_COLOR_BORDER_LIGHT dialog_color_border_light
#define CONTROLS_DIALOG_COLOR_BORDER_DARK dialog_color_border_dark
#define CONTROLS_DIALOG_COLOR_BG          dialog_color_bg
#define CONTROLS_DIALOG_COLOR_CAPTION_TEXT dialog_color_caption_text
#define CONTROLS_DIALOG_COLOR_CLIENT_BG   dialog_color_client_bg
#define CONTROLS_DIALOG_COLOR_CLIENT_BORDER dialog_color_client_border

#include <Controls\Dialog.mqh>
#include <Controls\BmpButton.mqh>
//+------------------------------------------------------------------+
//| defines                                                          |
//+------------------------------------------------------------------+

а всё потому, что при смене входных параметров индикаторы загружаются заново. Справка Выполение программ


Индикатор

ControlsBmpButton INDICATOR.mq5 |
version   "1.000"


 
Спасибо, Владимир! Буду пробовать.
 

Поскольку, мой очередной вопрос тоже касается изменения CAppDialog решил его написать сюда.

При удалении индикатора с графика диалог удаляет график. При попытке разобраться, в чем дело обнаружил, что метод Destroy диалога вызывается с параметром reason=REASON_PROGRAM. То есть, независимо от причины удаления метод Destroy понимает её, как удаление эксперта с графика. В самом методе жестко прописано:

if(reason==REASON_PROGRAM)
     {
      if(m_program_type==PROGRAM_EXPERT)
         ExpertRemove();
      if(m_program_type==PROGRAM_INDICATOR)
         ChartIndicatorDelete(m_chart_id,m_subwin,m_indicator_name);
     }

В общем, да. Диалог удаляет чарт. Посмотрел дальше по коду, обработчик OnClickButtonClose вызывает метод Destroy, без каких-либо изменений. Это значит, что данный код, который по умолчанию, делает диалог совершенно непригодным для использования в качестве окна настроек советника либо индикатора. Потому, как при нажатии на кнопку закрытия окно просто должно прятаться. А при удалении советника/индикатора должно удаляться вместе с элементами управления.

В результате попытки изменить поведение диалога получилось следующее:

MQWidgetMain::~MQWidgetMain(){
  CAppDialog::Destroy(REASON_REMOVE); 
}

получилось добиться того, что диалог не трогает чарт но себя тоже не удаляет. Как сделать, чтобы при удалении индикатора удалялось только окно а не весь график?

 
Mihail Matkovskij:

Поскольку, мой очередной вопрос тоже касается изменения CAppDialog решил его написать сюда.

При удалении индикатора с графика диалог удаляет график. При попытке разобраться, в чем дело обнаружил, что метод Destroy диалога вызывается с параметром reason=REASON_PROGRAM. То есть, независимо от причины удаления метод Destroy понимает её, как удаление эксперта с графика. В самом методе жестко прописано:

В общем, да. Диалог удаляет чарт. Посмотрел дальше по коду, обработчик OnClickButtonClose вызывает метод Destroy, без каких-либо изменений. Это значит, что данный код, который по умолчанию, делает диалог совершенно непригодным для использования в качестве окна настроек советника либо индикатора. Потому, как при нажатии на кнопку закрытия окно просто должно прятаться. А при удалении советника/индикатора должно удаляться вместе с элементами управления.

В результате попытки изменить поведение диалога получилось следующее:

получилось добиться того, что диалог не трогает чарт но себя тоже не удаляет. Как сделать, чтобы при удалении индикатора удалялось только окно а не весь график?

Есть стандартный пример индикатора-панели на базе CAppDialog: [data folder]\MQL5\Indicators\Examples\Panels\SimplePanel\SimplePanel.mq5. Так вот - этот индикатор-панель при закрытии НЕ УДАЛЯЕТ график. Ищите ошибку.

 
Vladimir Karputov:

Есть стандартный пример индикатора-панели на базе CAppDialog: [data folder]\MQL5\Indicators\Examples\Panels\SimplePanel\SimplePanel.mq5. Так вот - этот индикатор-панель при закрытии НЕ УДАЛЯЕТ график. Ищите ошибку.

Оно и понятно. Там деструктор панели никак не переопределен и имеет следующий вид:

CPanelDialog::~CPanelDialog(void)
  {
  }

Но строка

if(m_program_type==PROGRAM_INDICATOR)
  ChartIndicatorDelete(m_chart_id,m_subwin,m_indicator_name);

из кода

void CAppDialog::Destroy(const int reason)
  {
//--- destroyed already?
   if(m_deinit_reason!=WRONG_VALUE)
      return;
//---
   m_deinit_reason=reason;
   IniFileSave();
//--- detach chart object from chart
   m_chart.Detach();
//--- call parent destroy
   CDialog::Destroy();
//---
   if(reason==REASON_PROGRAM)
     {
      if(m_program_type==PROGRAM_EXPERT)
         ExpertRemove();
      if(m_program_type==PROGRAM_INDICATOR)
         ChartIndicatorDelete(m_chart_id,m_subwin,m_indicator_name);
     }
//--- send message
   EventChartCustom(CONTROLS_SELF_MESSAGE,ON_APP_CLOSE,m_subwin,0.0,m_program_name);
  }

удаляет подокно, а не чарт, так как индикатор работает в подокне. Мой же индикатор работает в главном окне. Поэтому, диалог и удаляет главное окно.

 
Mihail Matkovskij:

Оно и понятно. Там деструктор панели никак не переопределен и имеет следующий вид:

Но строка

из кода

удаляет подокно, а не чарт, так как индикатор работает в подокне. Мой же индикатор работает в главном окне. Поэтому, диалог и удаляет главное окно.

А, вот оно что. Я это поведение давеча описал в статье:

Панель на базе CAppDialog может быть создана как из эксперта, так и из индикатора. При этом создание панели отличается, в зависимости от того, какой тип программы (эксперт или индикатор) создаёт панель и в каком подокне работает программа:

  • если программа является экспертом (тип запущенной программы PROGRAM_EXPERT) — тогда панель создаётся ТОЛЬКО в главном окне (номер окна "0") и только при помощи метода CAppDialog::CreateExpert;
  • если программа является индикатором (тип запущенной программы PROGRAM_INDICATOR) — тогда проверяется номер окна, в котором запущена программа:
    • если это главное окно (номер окна "0"), то панель создаётся при помощи метода CAppDialog::CreateIndicator;
    • если это подокно — панель создаётся при помощи метода CAppDialog::CreateExpert.

Особенность метода CAppDialog::CreateIndicator в том, что при создании панель автоматически:

  • подстраивается под ширину окна;
  • подстраивает под себя высоту окна. 

Пример панели-индикатора [data folder]\MQL5\Indicators\Examples\Panels\SimplePanel\SimplePanel.mq5 после создания и после минимизации:


"CreateExpert" создаёт панель в главном окне (номер окна равен "0"), и подразумевается, что программа, создающая панель, является советником.

Есть исключение из этих правил: можно из индикатора создать панель в главном окне. В таком случае будет применён метод создания панели "CreateIndicator".


 
Mihail Matkovskij:

Оно и понятно. Там деструктор панели никак не переопределен и имеет следующий вид:

Но строка

из кода

удаляет подокно, а не чарт, так как индикатор работает в подокне. Мой же индикатор работает в главном окне. Поэтому, диалог и удаляет главное окно.

То, что Вы называете «деструктор не предопределён» подразумевает вызов деструктора родительского класса. В Вашем случае, перед удалением панели нужно вызвать для неё функцию Detach, тогда график не будет закрыт.

 
Dmitriy Gizlyk:

То, что Вы называете «деструктор не предопределён» подразумевает вызов деструктора родительского класса. В Вашем случае, перед удалением панели нужно вызвать для неё функцию Detach, тогда график не будет закрыт.

Уже решил данную проблему следующим образом:

MQSettingsControlWidget::~MQSettingsControlWidget(){
  CAppDialog::Destroy(REASON_REMOVE);
  ChartRedraw(chart);
} 

Оказалось, что при таком деструкторе, диалог и раньше удалялся, просто этого не было видно на графике, так как не была вызвана функция ChartRedraw.

Причина обращения: