Почему съезжает панель при обновлении настроек эксперта? - страница 3

 
Maxim Dmitrievsky:

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

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

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

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

файлы в аттаче.

Проблема в MQL4 есть. Я открою заявку в сервисдеске.

 

Добавлено: заявка #1423384.

 
Karputov Vladimir:

Проблема в MQL4 есть. Я открою заявку в сервисдеске.

 

Добавлено: заявка #1423384.

Хорошо, скиньте инфу плз как станет что-то известно..
 

Есть способ решить эту проблему.

class CTradePanel : public CAppDialog
{
private:

public:
                     CTradePanel();
                    ~CTradePanel();
bool isCreate;  //вводите переменную
.....
}

 В методе Create инициализируете ее

 

bool CTradePanel::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
{
  if(!CAppDialog::Create(chart,name,subwin,x1,y1,x2,y2)) return(false);
  isCreate = true;
  return(true);
}

 И в конструкторе и деструкторе

CTradePanel::CTradePanel()
{
   isCreate = false;
}

CTradePanel::~CTradePanel()
{
   isCreate = false;
}

 В самом эксперте или индикаторе в функции OnInit()

   if (!TradeDialog.isCreate)
   {
      if(!TradeDialog.Create(0,"Trade panel",0,10,10,250,150)) return(INIT_FAILED);
      if(!TradeDialog.Run()) return(INIT_FAILED);
   }

 В функции OnDeinit()

void OnDeinit(const int reason)
{
//--- destroy application dialog
   if ((reason != REASON_PARAMETERS) && (reason !=REASON_CHARTCHANGE) && (reason !=REASON_ACCOUNT)) TradeDialog.Destroy(reason);
   
}
 

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

.... 

Для сведения. Если вам надо изменить какой то метод класса или дополнить функционал класса, но класс написан не вами и может быть изменен кем то другим (к примеру классы позволяющие создавать панели с кнопками) то создавайте наследник от этого класса, а не редактируйте сам базовый класс. Тогда при очередном обновлении терминала изменения в базовом классе не затрут ваши изменения. Ваш класс просто унаследует все изменения базового класса. Это одно из преимуществ ООП.

 
Vitalii Ananev:

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

.... 

Для сведения. Если вам надо изменить какой то метод класса или дополнить функционал класса, но класс написан не вами и может быть изменен кем то другим (к примеру классы позволяющие создавать панели с кнопками) то создавайте наследник от этого класса, а не редактируйте сам базовый класс. Тогда при очередном обновлении терминала изменения в базовом классе не затрут ваши изменения. Ваш класс просто унаследует все изменения базового класса. Это одно из преимуществ ООП.

Спасибо! Для начала мне надо более подробно познакомиться с ооп, т.к. я не профессиональный прогер и пишу ботов для себя. И начал программирвать с языка mql :) Не совсем понял куда что вставлять и какой смысл, но думаю разберусь после более подробного ознакомления с ооп ) Основы знаю, но с классами плотно еще не работал
 
Maxim Dmitrievsky:
Спасибо! Для начала мне надо более подробно познакомиться с ооп, т.к. я не профессиональный прогер и пишу ботов для себя. И начал программирвать с языка mql :) Не совсем понял куда что вставлять и какой смысл, но думаю разберусь после более подробного ознакомления с ооп ) Основы знаю, но с классами плотно еще не работал

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

В других случаях деструктор не вызывается. Поэтому присваивание isCreate=false в деструкторе не выполняется. 

 
Vitalii Ananev:

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

В других случаях деструктор не вызывается. Поэтому присваивание isCreate=false в деструкторе не выполняется. 

Супер, все получилось :) Немного прошарился в ооп даже. 

Вы не подскажете, как можно менять цвет фона этой панели? 

 
Maxim Dmitrievsky:

Супер, все получилось :) Немного прошарился в ооп даже. 

Вы не подскажете, как можно менять цвет фона этой панели? 

Цвет фона устанавливается в классе CDialog в методе CreateBackground(void). Вам надо переопределить этот метод. И написать свою реализацию этого метода, где уже устанавливаете свой цвет фона.

class CPanel : public CAppDialog
{
private:
 ......
protected:
virtual bool      CreateBackground(void);
public:
                     CPanel();
                    ~CPanel();
.....
};
 
Vitalii Ananev:

Цвет фона устанавливается в классе CDialog в методе CreateBackground(void). Вам надо переопределить этот метод. И написать свою реализацию этого метода, где уже устанавливаете свой цвет фона.

изменяет только цвет рамки почему-то, или есть что-то еще поверх бэкграунда

class CTradePanel : public CAppDialog
{
private:
CPanel            m_background;
virtual bool      CreateBackground(void);
...
}

bool CTradePanel::CreateBackground(void)
{
 
 int off=(m_panel_flag) ? 0:CONTROLS_BORDER_WIDTH;
//--- coordinates
   int x1=off;
   int y1=off;
   int x2=Width()-off;
   int y2=Height()-off;
//--- create
   if(!m_background.Create(m_chart_id,m_name+"Back",m_subwin,x1,y1,x2,y2))
      return(false);
   if(!m_background.ColorBackground(C'0x3B,0x29,0x28')) - тут меняем цвет фона на черный, а меняется цвет рамки
      return(false);
   color border=(m_panel_flag) ? CONTROLS_DIALOG_COLOR_BG : C'0x3B,0x29,0x28';
   if(!m_background.ColorBorder(border))
      return(false);
   if(!CWndContainer::Add(m_background))
      return(false);
   m_background.Alignment(WND_ALIGN_CLIENT,off,off,off,off);
//--- succeed
   return(true);
}

 
Maxim Dmitrievsky:

изменяет только цвет рамки почему-то

Посмотрите еще метод bool CDialog::CreateClientArea(void) там создается клиентская область и тоже устанавливается ее цвет. Получается, что там два объекта CPanel накладываются друг на друга. 

.....

Сейчас экспериментировал. Там надо еще и метод Add()  будет переопределить.  

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