SpinEdit does not show value when changing timeframes.

 

When the following Expert is initially attached to a chart, The SpinEdit value 25 is displayed.

If the timeframe is changed, the value 25 is no longer displayed.

However, clicking the up/down arrows will re-display the value.

Changing timeframes again will hide the value.

Is there a way to keep the value displayed when changing timeframes??

#include <Controls/Dialog.mqh> 
#include <Controls/SpinEdit.mqh>
CAppDialog  TradePanel;
CSpinEdit   slSpin;
//+------------------------------------------------------------------+
int OnInit()
  {    
    TradePanel.Create(0,"TradePanel",0,50,50,300,200);    
    slSpin.Create(0,"slSpin",0,20,20,100,50);
    slSpin.MaxValue(100);
    slSpin.MinValue(0);
    slSpin.Value(25);
    TradePanel.Add(slSpin);     
    TradePanel.Run();       
    return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  { TradePanel.Destroy(reason);  }
//+------------------------------------------------------------------+
void OnTick()
  {   }
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {  TradePanel.OnEvent(id,lparam,dparam,sparam);  }
 
Not using the standard lib GUI, but tried your example now and seems you need to have dynamic CSpinEdit object in order for it to delete successfully. 


CSpinEdit   *slSpin;                            // declare dynamic
//+------------------------------------------------------------------+
int OnInit()
  {
   slSpin=new CSpinEdit();                      // allocate 
... // rest




 

It's working now.  Thanks.

I'm not really familiar with OOP.

I'd like to know how you discovered the problem if the explanation is not too long.

 
michaelMNB:

It's working now.  Thanks.

I'm not really familiar with OOP.

I'd like to know how you discovered the problem if the explanation is not too long.

Sure. I used mql5 debugger to do what you did. Changed timeframe and breakpoint at the statement that assigns 25 as value after changing TF - because that seemed what was not working.


Stepped inside with the debugger into the Value(int value) method of CSpinEdit (of course after changing TF)




Saw that the if statement is false because the old value (m_value - before changing the timeframe) is still saved in the object instance variable m_value (=25) and that's the cause of not displying the value - OnChangeValue() is not called. Then I realized it should have been initialized after changing the time frame, and as we know that changing the timeframe calls the OnDeinit() and then again the OnInit() - so destroying CSpinEdit should have occured in the OnDeinit() of the script. 

Then I changed again the timeframe, and started tracing the OnDeinit() of the script, looking for why the value in the CSpinEdit was not reset. 
OnDeinit calls the Destroy method of CAppDialog (Which TradePanel is an instance of)


Went inside and located the call to Destroy() method of CDialog - which by reason and elimination of all the rest should have done the destroy of CSpinEdit (which failed as we know)



This is the method - then located the Delete() method call - and traced it in. It deletes all controls of the dialog in the for loop, so you should get to the CSpinEdit control

Inside the Delete() method of the specific control, there is a delete statement (MQL5). Here it should have already be enough to conclude, because delete can delete only dynamic objects, but still went on:





The delete m_data[index] was not executed. Looking for the reason you can see that it needs the memory allocation to be POINTER_DYNAMIC which is the solution.

*-And that means of course all type of controls when working with the standard lib GUI should be dynamic, not just spin edit. Actually it generally is better to do so anyway, in all types of libraries, whenever possible and you have types of objects which have something in common or are part of a larger part to be dynamic - becuase libraries usually work with arrays of objects, and they need the object to be dynamic in order to call the correct virtual methods. And of course for it's destruction when needed. 

**-In my opinion, it is a bug in the standard library, becuase it should have prevented you to use static control - I would have checked the type of control memory at the beginning right when adding a control to the CDialog - and not cause that kind of problems. Or, at minimum, reset all internal data (m_value) when not possible to delete.
 

Wow that response was fast.

I'm going to need some time to study the solution, but I wanted to say Thanks right away.

 
Amir Yacoby:
Not using the standard lib GUI, but tried your example now and seems you need to have dynamic CSpinEdit object in order for it to delete successfully. 






Thanks! It helped me too.

 
michaelMNB:

When the following Expert is initially attached to a chart, The SpinEdit value 25 is displayed.

If the timeframe is changed, the value 25 is no longer displayed.

However, clicking the up/down arrows will re-display the value.

Changing timeframes again will hide the value.

Is there a way to keep the value displayed when changing timeframes??

The serious problem is that m_text.Text("") is called in CSpinEdit::CreateEdit().

This causes the displayed values to be blank every time the timeframe has been changed.

I tried to override it, but m_edit is a private variable.

So I copied the original source and replaced it with the following patch

if(!m_edit.Text(IntegerToString(m_value)))


Reason: