CAppDialog create problem when the timeframe change ( from an Example of Metaquotes)

 

Hi! 

The following code is an example of metaquotes. 

#include <Controls\Dialog.mqh> 
#include <Controls\CheckBox.mqh> 
//+------------------------------------------------------------------+ 
//| defines                                                          | 
//+------------------------------------------------------------------+ 
//--- indents and gaps 
#define INDENT_LEFT                         (11)      // indent from left (with allowance for border width) 
#define INDENT_TOP                          (11)      // indent from top (with allowance for border width) 
#define INDENT_RIGHT                        (11)      // indent from right (with allowance for border width) 
#define INDENT_BOTTOM                       (11)      // indent from bottom (with allowance for border width) 
#define CONTROLS_GAP_X                      (5)       // gap by X coordinate 
#define CONTROLS_GAP_Y                      (5)       // gap by Y coordinate 
//--- for buttons 
#define BUTTON_WIDTH                        (100)     // size by X coordinate 
#define BUTTON_HEIGHT                       (20)      // size by Y coordinate 
//--- for the indication area 
#define EDIT_HEIGHT                         (20)      // size by Y coordinate 
//--- for group controls 
#define GROUP_WIDTH                         (150)     // size by X coordinate 
#define LIST_HEIGHT                         (179)     // size by Y coordinate 
#define RADIO_HEIGHT                        (56)      // size by Y coordinate 
#define CHECK_HEIGHT                        (93)      // size by Y coordinate 
//+------------------------------------------------------------------+ 
//| Class CControlsDialog                                            | 
//| Usage: main dialog of the Controls application                   | 
//+------------------------------------------------------------------+ 
class CControlsDialog : public CAppDialog 
  { 
private: 
   CCheckBox         m_check_box1;                    // CCheckBox object 
   CCheckBox         m_check_box2;                    // CCheckBox object 
public: 
                     CControlsDialog(void); 
                    ~CControlsDialog(void); 
   //--- create 
   virtual bool      Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2); 
   //--- chart event handler 
   virtual bool      OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam); 
protected: 
   //--- create dependent controls 
   bool              CreateCheckBox1(void); 
   bool              CreateCheckBox2(void); 
   //--- handlers of the dependent controls events 
   void              OnChangeCheckBox1(void); 
   void              OnChangeCheckBox2(void); 
  }; 
//+------------------------------------------------------------------+ 
//| Event Handling                                                   | 
//+------------------------------------------------------------------+ 
EVENT_MAP_BEGIN(CControlsDialog) 
ON_EVENT(ON_CHANGE,m_check_box1,OnChangeCheckBox1) 
ON_EVENT(ON_CHANGE,m_check_box2,OnChangeCheckBox2) 
EVENT_MAP_END(CAppDialog) 
//+------------------------------------------------------------------+ 
//| Constructor                                                      | 
//+------------------------------------------------------------------+ 
CControlsDialog::CControlsDialog(void) 
  { 
  } 
//+------------------------------------------------------------------+ 
//| Destructor                                                       | 
//+------------------------------------------------------------------+ 
CControlsDialog::~CControlsDialog(void) 
  { 
  } 
//+------------------------------------------------------------------+ 
//| Create                                                           | 
//+------------------------------------------------------------------+ 
bool CControlsDialog::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); 
//--- create dependent controls 
   if(!CreateCheckBox1()) 
      return(false); 
   if(!CreateCheckBox2()) 
      return(false); 
//--- succeed 
   return(true); 
  } 
//+------------------------------------------------------------------+ 
//| Create the "CheckBox" element                                    | 
//+------------------------------------------------------------------+ 
bool CControlsDialog::CreateCheckBox1(void) 
  { 
//--- coordinates 
   int x1=INDENT_LEFT; 
   int y1=INDENT_TOP+(EDIT_HEIGHT+CONTROLS_GAP_Y)+ 
          (BUTTON_HEIGHT+CONTROLS_GAP_Y)+ 
          (EDIT_HEIGHT+CONTROLS_GAP_Y)+ 
          (EDIT_HEIGHT+CONTROLS_GAP_Y)+ 
          (RADIO_HEIGHT+CONTROLS_GAP_Y); 
   int x2=x1+GROUP_WIDTH; 
   int y2=y1+BUTTON_HEIGHT; 
//--- create 
   if(!m_check_box1.Create(m_chart_id,m_name+"CheckBox1",m_subwin,x1,y1,x2,y2)) 
      return(false); 
   if(!m_check_box1.Text("CheckBox1")) 
      return(false); 
   if(!m_check_box1.Color(clrBlue)) 
      return(false); 
   if(!Add(m_check_box1)) 
      return(false); 
//--- succeed 
   return(true); 
  } 
//+------------------------------------------------------------------+ 
//| Create the "CheckBox" element                                    | 
//+------------------------------------------------------------------+ 
bool CControlsDialog::CreateCheckBox2(void) 
  { 
//--- coordinates 
   int x1=INDENT_LEFT+GROUP_WIDTH+CONTROLS_GAP_X; 
   int y1=INDENT_TOP+(EDIT_HEIGHT+CONTROLS_GAP_Y)+ 
          (BUTTON_HEIGHT+CONTROLS_GAP_Y)+ 
          (EDIT_HEIGHT+CONTROLS_GAP_Y)+ 
          (EDIT_HEIGHT+CONTROLS_GAP_Y)+ 
          (RADIO_HEIGHT+CONTROLS_GAP_Y); 
   int x2=x1+GROUP_WIDTH; 
   int y2=y1+BUTTON_HEIGHT; 
//--- create 
   if(!m_check_box2.Create(m_chart_id,m_name+"CheckBox2",m_subwin,x1,y1,x2,y2)) 
      return(false); 
   if(!m_check_box2.Text("CheckBox2")) 
      return(false); 
   if(!m_check_box2.Color(clrBlue)) 
      return(false); 
   if(!Add(m_check_box2)) 
      return(false); 
   m_check_box2.Checked(true); 
   Comment(__FUNCTION__+" : Checked="+IntegerToString(m_check_box2.Checked())); 
//--- succeed 
   return(true); 
  } 
//+------------------------------------------------------------------+ 
//| Event handler                                                    | 
//+------------------------------------------------------------------+ 
void CControlsDialog::OnChangeCheckBox1(void) 
  { 
   Comment(__FUNCTION__+" : Checked="+IntegerToString(m_check_box1.Checked())); 
  } 
//+------------------------------------------------------------------+ 
//| Event handler                                                    | 
//+------------------------------------------------------------------+ 
void CControlsDialog::OnChangeCheckBox2(void) 
  { 
   Comment(__FUNCTION__+" : Checked="+IntegerToString(m_check_box2.Checked())); 
  } 
//+------------------------------------------------------------------+ 
//| Global Variables                                                 | 
//+------------------------------------------------------------------+ 
CControlsDialog ExtDialog; 
//+------------------------------------------------------------------+ 
//| Expert initialization function                                   | 
//+------------------------------------------------------------------+ 
int OnInit() 
  { 
//--- create application dialog 
   if(!ExtDialog.Create(0,"Controls",0,40,40,380,344)) 
      return(INIT_FAILED); 
//--- run application 
   ExtDialog.Run(); 
//--- succeed 
   return(INIT_SUCCEEDED); 
  } 
//+------------------------------------------------------------------+ 
//| Expert deinitialization function                                 | 
//+------------------------------------------------------------------+ 
void OnDeinit(const int reason) 
  { 
//--- 
   Comment(""); 
//--- destroy dialog 
   ExtDialog.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); 
  }



If this code implemented to MQL5 and change the timeframe it is working fine like the picture below :

Mql5 Picture



but if this code implemented to MQL4 and change the timeframe it doesn't work properly :

MQL4 Picture


It seem to create extra objects every time i change the timeframe 

MQl4 object list


Any idea to solve that problem ?


Thanks!

 

Some more Info about that issue :

So i fixed the problem by change the code of the function CAppDialog::Destroy, from the include Dialog.mqh .

//+------------------------------------------------------------------+
//| Application dialog deinitialization function                     |
//+------------------------------------------------------------------+
void CAppDialog::Destroy(const int reason)
  {
/*  HERE IS THE PROBLEM !!!!!!!!!!!!!!!!
//--- 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);
  }

I think that the problem is on "m_deinit_reason " (private variable inside the Dialog.mqh). If the timeframe change then the OnDeinit function call and pass the reason = 3 to function Destroy(reason) .So the function Destroy set the m_deinit_reason variable with value 3 and the next time to change the timeframe again the check 

if(m_deinit_reason!=WRONG_VALUE)return;

doesn't allow to destroy the CAppDialog because already have.So i make comment the section that check m_deinit_reason variable and the problem solved.

I don't like that kind of solution because it change the build in code. Another possible solution is to explicit change the m_deinit_reason value after deinit occur.  In Order to reset the m_deinit_reason private variable you need to call the constructor of the class CAppDialog . But the constructor call only when the object created. Since we need the CAppDialog's classes to be used inside to others functions like " void OnDeinit, void OnChartEvent etc " i have to create the object on global scope. So the constructor call once and not every time that timeframe change.

Another question is why in MQL5 it works properly.... Looking at the ml5 code and i haven't notice any big change to the code...

So i hope that maybe you guys see that change or find a solution. 

Thanks !

 
Which build of MT4 are you using? There were some issues when switching timeframes in the recent builds. I've not looked into it, but perhaps the wrong uninitialization reason codes are being sent?
 
honest_knave:
Which build of MT4 are you using? There were some issues when switching timeframes in the recent builds. I've not looked into it, but perhaps the wrong uninitialization reason codes are being sent?


Thank for the reply!

I use :

FxPro - Metatrader 4 
Version: 4.00 Build 1065 
(23 Mar 2017)

 
Dennis Nikolopoulos:


Thank for the reply!

I use :

FxPro - Metatrader 4 
Version: 4.00 Build 1065 
(23 Mar 2017)


I've compared the MQL5 and MQL4 Dialog.mqh files.

This could be the issue (the MQL4 version is on the right):


 
Dennis Nikolopoulos:


Thank for the reply!

I use :

FxPro - Metatrader 4 
Version: 4.00 Build 1065 
(23 Mar 2017)

I can't recreate this issue on my build 1065. Have you tried a fresh installation in a new program files folder ?
 
honest_knave:


I've compared the MQL5 and MQL4 Dialog.mqh files.

This could be the issue (the MQL4 version is on the right):



Good job mate!!! They miss to reset the m_deinit_reason variable on the CreateCommon function!! Thank you !


So could you somehow point them to correct that line ?  I think that other developers will face similar problem. 

 
Dennis Nikolopoulos:


Good job mate!!! They miss to reset the m_deinit_reason variable on the CreateCommon function!! Thank you !


So could you somehow point them to correct that line ?  I think that other developers will face similar problem. 


The best way to address things like this is to send a message to the Service Desk

 

yea this happened with me also , and it seems that there is a problem in Destroy function of CAppDialog . however i solved it this way

OnDeinit method i added additional part to manually destroy controls contained within the CAppDialog as follows

   for(int i=main.ControlsTotal()-1;i>=0;i--)
     {
       main.Control(i).Destroy(reason);
     }

and it seems that the problem was solved . however when the minimum button is pressed the Whole Panel just disappears and i don't know why 

 
Mohamed Nabil:

yea this happened with me also , and it seems that there is a problem in Destroy function of CAppDialog . however i solved it this way

OnDeinit method i added additional part to manually destroy controls contained within the CAppDialog as follows

and it seems that the problem was solved . however when the minimum button is pressed the Whole Panel just disappears and i don't know why 

Did you find a solution for that meanwhile?

When I press the minimum button my panel doesn't disappear but it gets a little "weird" - see pic

 
Jagg:

Did you find a solution for that meanwhile?

When I press the minimum button my panel doesn't disappear but it gets a little "weird" - see pic

This is a bug in standard library in file Dialog.mqh. Fixed in MT5 btw. Add a line to that file as follows:

//+------------------------------------------------------------------+
//| Initialize common area                                           |
//+------------------------------------------------------------------+
bool CAppDialog::CreateCommon(const long chart,const string name,const int subwin)
  {
//--- save parameters
   m_chart_id    =chart;
   m_name        =name;
   m_subwin      =subwin;
   m_program_name=name;
   m_deinit_reason=WRONG_VALUE;
//--- get unique ID
   m_instance_id=CreateInstanceId();
//--- initialize chart object
   m_chart.Attach(chart);
//--- determine type of program
   m_program_type=(ENUM_PROGRAM_TYPE)MQLInfoInteger(MQL_PROGRAM_TYPE);
//--- specify object and mouse events
   if(!m_chart.EventObjectCreate() || !m_chart.EventObjectDelete() || !m_chart.EventMouseMove())
     {
      Print("CAppDialog: object events specify error");
      m_chart.Detach();
      return(false);
     }
//--- get subwindow offset
   SubwinOff();
//--- succeed
   return(true);
  }
Reason: