Помогите понять как правильно удалять элементы с панели, и добавлять заново при нажатии кнопки - страница 2

 
Dmitry Fedoseev:
Поразительно какие тут все читатели. Писал же про это выше. Будут проблемы при сворачивании/разворачивании формы.

:) да, есть такая проблема, вижу теперь... вчера соображалка уже не работала, читал ваш камент и не понимал что читаю )

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

 

В классе СButton например в методе Create создается вот что, ну и для любого контрола так же:

bool CButton::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
  {
//--- call method of the parent class
   if(!CWndObj::Create(chart,name,subwin,x1,y1,x2,y2))
      return(false);
//--- create the chart object
   if(!m_button.Create(chart,name,subwin,x1,y1,Width(),Height()))
      return(false);
//--- call the settings handler
   return(OnChange());
  }

А когда мы вызываем метод Destroy() для контрола, он походу удаляет только сам объект CWndObj, но не ссылку на этот объект m_button, поэтому при повторном создании происходит наложение... отсюда и ваше предположение что он остается в памяти... но это неточно, я еще не разобрался до конца :) Поэтому ссылку на m_button надо тоже удалять, пока не разобрался как

 
Maxim Dmitrievsky:

В классе СButton например в методе Create создается вот что, ну и для любого контрола так же:

bool CButton::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
  {
//--- call method of the parent class
   if(!CWndObj::Create(chart,name,subwin,x1,y1,x2,y2))
      return(false);
//--- create the chart object
   if(!m_button.Create(chart,name,subwin,x1,y1,Width(),Height()))
      return(false);
//--- call the settings handler
   return(OnChange());
  }

А когда мы вызываем метод Destroy() для контрола, он походу удаляет только сам объект CWndObj, но не ссылку на этот объект m_button, поэтому при повторном создании происходит наложение... отсюда и ваше предположение что он остается в памяти... но это неточно, я еще не разобрался до конца :) Поэтому ссылку на m_button надо тоже удалять, пока не разобрался как

Если только Destroy(), то объект точно остается в памяти (какая тут может быть неточность), а ссылка на него в массиве у формы. Но я пробовал полностью удалять объект: Destroy() и delete.

Вы тут все хронически, не разобрались... но сначала всегда поспорить надо.

 
Dmitry Fedoseev:

Если только Destroy(), то объект точно остается в памяти (какая тут может быть неточность), а ссылка на него в массиве у формы. Но я пробовал полностью удалять объект: Destroy() и delete.

Вы тут все хронически, не разобрались... но сначала всегда поспорить надо.

так я не спорю, просто рассуждаю )

то есть если мы при повторном добавлении кнопки оставим только

bool CButton::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
  {
//--- call method of the parent class
   if(!CWndObj::Create(chart,name,subwin,x1,y1,x2,y2))
      return(false);

  } 

 ничего не изменится?

 
Maxim Dmitrievsky:

так я не спорю, просто рассуждаю )

то есть если мы при повторном добавлении кнопки оставим только

bool CButton::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
  {
//--- call method of the parent class
   if(!CWndObj::Create(chart,name,subwin,x1,y1,x2,y2))
      return(false);

  } 

 ничего не изменится?

Так не пробовал
 

Уважаемый @Ilnur Khasanov  помог решить проблему таким образом, получилось немного громоздко, возможно, будет работать и без переопределения методов, не пробовал еще.


//+------------------------------------------------------------------+
//|                                                      MyPanel.mqh |
//|                                    Copyright © 2013, DeltaTrader |
//|                                    http://www.deltatrader.com.br |
//+------------------------------------------------------------------+
#property copyright     "DeltaTrader © 2013"
#property link          "www.deltatrader.com.br"
#property version       "1.000"
#property description   "Test Panel"
#property indicator_plots 0
//+------------------------------------------------------------------+
//| Includes                                                         |
//+------------------------------------------------------------------+
#include <Controls\WndObj.mqh>
#include <ChartObjects\ChartObjectsTxtControls.mqh>
#include <Controls\Dialog.mqh>
#include <Controls\Label.mqh>
#include <Controls\Panel.mqh>
#include <Controls\Edit.mqh>
#include <Controls\Defines.mqh>
#include <Controls\Button.mqh>

//+------------------------------------------------------------------+
//| Global parameters                                                |
//+------------------------------------------------------------------+
int      panelXX     =  200;
int      panelYY     =  200;
int      panelWidth  =  600;
int      panelHeight =  400;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class CMyLabel : public CLabel
  {
private:
   CChartObjectLabel m_label;               // chart object

public:
                     CMyLabel(void);
                    ~CMyLabel(void);
   bool              isCreate;
public:
   virtual bool      Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2);

protected:
   virtual bool      OnCreate(void);
   virtual bool      OnMove(void);
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
CMyLabel::CMyLabel()
  {
   isCreate=false;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
CMyLabel::~CMyLabel()
  {
   isCreate=false;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool CMyLabel::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
  {
//--- call method of the parent class
  
   if(!CWndObj::Create(chart,name,subwin,x1,y1,x2,y2))
      return(false);
    
//--- create the chart object
   //if(!isCreate)
  // {
    if(!m_label.Create(chart,name,subwin,x1,y1))
      return(false);
  // }

//--- call the settings handler
   isCreate=true;
   return(OnChange());
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool CMyLabel::OnCreate(void)
  {
//--- create the chart object by previously set parameters
   return(m_label.Create(m_chart_id,m_name,m_subwin,m_rect.left,m_rect.top));
  }
  
bool CMyLabel::OnMove(void)
  {
//--- position the chart object
   return(m_label.X_Distance(m_rect.left) && m_label.Y_Distance(m_rect.top));
  }

CAppDialog m_panel;
CMyLabel *m_bidlabel;
CMyLabel *m_asklabel;
CButton m_button;
//+------------------------------------------------------------------+
//| On Init                                                          |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- Panel create
   m_panel.Create(0,"blablabla",0,panelXX,panelYY,panelWidth,panelHeight);
//--- Bid label and colors

   m_bidlabel = new CMyLabel();
   m_bidlabel.Create(0,"Bid Text",0,5,5,0,0);
   m_bidlabel.Color(clrBlue);
   m_panel.Add(m_bidlabel);
  
   m_asklabel = new CMyLabel();
   m_asklabel.Create(0,"Ask Text",0,5,30,0,0);
   m_asklabel.Color(clrRed);
   m_panel.Add(m_asklabel);

   m_button.Create(0,"My button",0, 150,5,250,50);
   m_button.Text("Show or hide");
   m_panel.Add(m_button);
//--- Run panel
   m_panel.Run();
   return(0);
  }
//+------------------------------------------------------------------+
//| On DeInit                                                        |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- Destroy panel
   m_panel.Destroy(reason);
//--- Delete all objects
   ObjectsDeleteAll(0,0);
  }
//+------------------------------------------------------------------+
//| On Calculate                                                     |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
  {

   return(rates_total);
  }
//+------------------------------------------------------------------+
//| On Chart Event                                                   |
//+------------------------------------------------------------------+

void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//--- Move the panel with the mouse
   m_panel.ChartEvent(id,lparam,dparam,sparam);
   if(id==CHARTEVENT_OBJECT_CLICK)
      if(sparam=="My button")
        {
         if(m_button.Pressed())
           {
            m_button.Locking(true);

            if(CheckPointer(m_bidlabel) == POINTER_INVALID)
            {
               m_bidlabel = new CMyLabel();
               m_bidlabel.Create(0,"Bid Text",0,5,5,0,0);
               m_bidlabel.Text("Bid "+DoubleToString(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits));
               m_bidlabel.Color(clrBlue);
               m_panel.Add(m_bidlabel);
            }
          
           if(CheckPointer(m_asklabel) == POINTER_INVALID)
            {
            m_asklabel = new CMyLabel();
            m_asklabel.Create(0,"Ask Text",0,5,30,0,0);
            m_asklabel.Text("Ask "+DoubleToString(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits));
            m_asklabel.Color(clrRed);
            m_panel.Add(m_asklabel);
            }
            Print("press");
           }
         else
           {
                    
            if(CheckPointer(m_bidlabel) != POINTER_INVALID)
            {
               m_bidlabel.Destroy();              
               delete(m_bidlabel);            
            }
            
            if(CheckPointer(m_asklabel) != POINTER_INVALID)
            {
               m_asklabel.Destroy();
               delete(m_asklabel);
            }
          }
        }
//---
  }
//+------------------------------------------------------------------+


 

 

Как так вы не пробовали? Зачем тогда показываете? Так работает или нет?

Есть большие сомнения по этому коду. Почему m_panel.Add d в OnChartEvent()? Подразумевается, что Add вызывается не один раз? 

 
Dmitry Fedoseev:

Как так вы не пробовали? Зачем тогда показываете? Так работает или нет?

Есть большие сомнения по этому коду. Почему m_panel.Add d в OnChartEvent()? Подразумевается, что Add вызывается не один раз? 

всё работает ) я про то что можно методы стандартных классов не переопределять вообще, убрать всю эту простыню сверху кода. Аdd вызывается только при нажатии кнопки по событию if(id==CHARTEVENT_OBJECT_CLICK), если ее флаг Pressed, т.е. создаем текстовую метку в панели. Если Unpressed то удаляем текстовую метку с панели. Я уже протестировал этот вариант в другой панели, работает.

Попробуйте, этот вариант для mt5, рабочий. 

 

Упрощенный вариант:

//+------------------------------------------------------------------+
//|                                                      MyPanel.mqh |
//|                                    Copyright © 2013, DeltaTrader |
//|                                    http://www.deltatrader.com.br |
//+------------------------------------------------------------------+
#property copyright     "DeltaTrader © 2013"
#property link          "www.deltatrader.com.br"
#property version       "1.000"
#property description   "Test Panel"
#property indicator_plots 0
//+------------------------------------------------------------------+
//| Includes                                                         |
//+------------------------------------------------------------------+
#include <Controls\Dialog.mqh>
#include <Controls\Label.mqh>
#include <Controls\Panel.mqh>
#include <Controls\Edit.mqh>
#include <Controls\Defines.mqh>
#include <Controls\Button.mqh>

//+------------------------------------------------------------------+
//| Global parameters                                                |
//+------------------------------------------------------------------+
int      panelXX     =  200;
int      panelYY     =  200;
int      panelWidth  =  600;
int      panelHeight =  400;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+


CAppDialog m_panel;
CLabel *m_bidlabel;
CLabel *m_asklabel;
CButton m_button;
//+------------------------------------------------------------------+
//| On Init                                                          |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- Panel create
   m_panel.Create(0,"blablabla",0,panelXX,panelYY,panelWidth,panelHeight);
//--- Bid label and colors

   m_bidlabel=new CLabel();
   m_bidlabel.Create(0,"Bid Text",0,5,5,0,0);
   m_bidlabel.Color(clrBlue);
   m_panel.Add(m_bidlabel);

   m_asklabel=new CLabel();
   m_asklabel.Create(0,"Ask Text",0,5,30,0,0);
   m_asklabel.Color(clrRed);
   m_panel.Add(m_asklabel);

   m_button.Create(0,"My button",0, 150,5,250,50);
   m_button.Text("Show or hide");
   m_panel.Add(m_button);
//--- Run panel
   m_panel.Run();
   return(0);
  }
//+------------------------------------------------------------------+
//| On DeInit                                                        |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- Destroy panel
   m_panel.Destroy(reason);
//--- Delete all objects
   ObjectsDeleteAll(0,0);
  }
//+------------------------------------------------------------------+
//| On Calculate                                                     |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
  {

   return(rates_total);
  }
//+------------------------------------------------------------------+
//| On Chart Event                                                   |
//+------------------------------------------------------------------+

void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//--- Move the panel with the mouse
   m_panel.ChartEvent(id,lparam,dparam,sparam);
   if(id==CHARTEVENT_OBJECT_CLICK)
      if(sparam=="My button")
        {
         if(m_button.Pressed())
           {
            m_button.Locking(true);

            if(CheckPointer(m_bidlabel)==POINTER_INVALID)
              {
               m_bidlabel=new CLabel();
               m_bidlabel.Create(0,"Bid Text",0,5,5,0,0);
               m_bidlabel.Text("Bid "+DoubleToString(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits));
               m_bidlabel.Color(clrBlue);
               m_panel.Add(m_bidlabel);
              }

            if(CheckPointer(m_asklabel)==POINTER_INVALID)
              {
               m_asklabel=new CLabel();
               m_asklabel.Create(0,"Ask Text",0,5,30,0,0);
               m_asklabel.Text("Ask "+DoubleToString(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits));
               m_asklabel.Color(clrRed);
               m_panel.Add(m_asklabel);
              }
            Print("press");
           }
         else
           {
            if(CheckPointer(m_bidlabel)!=POINTER_INVALID)
              {
               m_bidlabel.Destroy();
               delete(m_bidlabel);
              }

            if(CheckPointer(m_asklabel)!=POINTER_INVALID)
              {
               m_asklabel.Destroy();
               delete(m_asklabel);
              }
           }
        }
//---
  }
//+------------------------------------------------------------------+
 
Сейчас работает, почему раньше тоже самое не работало?
Причина обращения: