How to get a text value of the SpinEdit after the text has been modified by the user? The documentation don’t provide any function for that.
What about Value() ?
Thanks. I have solved this question making some changes in the SpinEdit class. Here is the changes with marked text.
//+------------------------------------------------------------------+
//| SpinEdit.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include "WndContainer.mqh"
#include "Edit.mqh"
#include "BmpButton.mqh"
//+------------------------------------------------------------------+
//| Resources |
//+------------------------------------------------------------------+
#resource "res\\SpinInc.bmp"
#resource "res\\SpinDec.bmp"
//+------------------------------------------------------------------+
//| Class CSpinEdit |
//| Usage: class that implements the "Up-Down" control |
//+------------------------------------------------------------------+
class CSpinEdit : public CWndContainer
{
private:
//--- dependent controls
CEdit m_edit; // the entry field object
CBmpButton m_inc; // the "Increment button" object
CBmpButton m_dec; // the "Decrement button" object
//--- adjusted parameters
int m_min_value; // minimum value
int m_max_value; // maximum value
//--- state
int m_value; // current value
public:
CSpinEdit(void);
~CSpinEdit(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);
//--- set up
int MinValue(void) const { return(m_min_value); }
void MinValue(const int value);
int MaxValue(void) const { return(m_min_value); }
void MaxValue(const int value);
//--- state
int Value(void) const { return(m_value); }
bool Value(int value);
//--- methods for working with files
virtual bool Save(const int file_handle);
virtual bool Load(const int file_handle);
protected:
//--- create dependent controls
virtual bool CreateEdit(void);
virtual bool CreateInc(void);
virtual bool CreateDec(void);
//--- handlers of the dependent controls events
virtual bool OnClickInc(void);
virtual bool OnClickDec(void);
virtual bool OnChangeText(void);
//--- internal event handlers
virtual bool OnChangeValue(void);
};
//+------------------------------------------------------------------+
//| Common handler of chart events |
//+------------------------------------------------------------------+
EVENT_MAP_BEGIN(CSpinEdit)
ON_EVENT(ON_CLICK,m_inc,OnClickInc)
ON_EVENT(ON_CLICK,m_dec,OnClickDec)
ON_EVENT(ON_END_EDIT,m_edit,OnChangeText)
EVENT_MAP_END(CWndContainer)
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CSpinEdit::CSpinEdit(void) : m_min_value(0),
m_max_value(0),
m_value(0)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CSpinEdit::~CSpinEdit(void)
{
}
//+------------------------------------------------------------------+
//| Create a control |
//+------------------------------------------------------------------+
bool CSpinEdit::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
{
//--- check height
if(y2-y1<CONTROLS_SPIN_MIN_HEIGHT)
return(false);
//--- call method of the parent class
if(!CWndContainer::Create(chart,name,subwin,x1,y1,x2,y2))
return(false);
//--- create dependent controls
if(!CreateEdit())
return(false);
if(!CreateInc())
return(false);
if(!CreateDec())
return(false);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Set current value |
//+------------------------------------------------------------------+
bool CSpinEdit::Value(int value)
{
//--- check value
if(value<m_min_value)
value=m_min_value;
if(value>m_max_value)
value=m_max_value;
//--- if value was changed
if(m_value!=value)
{
m_value=value;
//--- call virtual handler
return(OnChangeValue());
}
//--- value has not been changed
return(false);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CSpinEdit::Save(const int file_handle)
{
//--- check
if(file_handle==INVALID_HANDLE)
return(false);
//---
FileWriteInteger(file_handle,m_value);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CSpinEdit::Load(const int file_handle)
{
//--- check
if(file_handle==INVALID_HANDLE)
return(false);
//---
if(!FileIsEnding(file_handle))
Value(FileReadInteger(file_handle));
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Set minimum value |
//+------------------------------------------------------------------+
void CSpinEdit::MinValue(const int value)
{
//--- if value was changed
if(m_min_value!=value)
{
m_min_value=value;
//--- adjust the edit value
Value(m_value);
}
}
//+------------------------------------------------------------------+
//| Set maximum value |
//+------------------------------------------------------------------+
void CSpinEdit::MaxValue(const int value)
{
//--- if value was changed
if(m_max_value!=value)
{
m_max_value=value;
//--- adjust the edit value
Value(m_value);
}
}
//+------------------------------------------------------------------+
//| Create the edit field |
//+------------------------------------------------------------------+
bool CSpinEdit::CreateEdit(void)
{
//--- create
if(!m_edit.Create(m_chart_id,m_name+"Edit",m_subwin,0,0,Width(),Height()))
return(false);
if(!m_edit.Text(""))
return(false);
if(!m_edit.ReadOnly(false))
return(false);
if(!Add(m_edit))
return(false);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Create the "Increment" button |
//+------------------------------------------------------------------+
bool CSpinEdit::CreateInc(void)
{
//--- right align button (try to make equal offsets from top and bottom)
int x1=Width()-(CONTROLS_BUTTON_SIZE+CONTROLS_SPIN_BUTTON_X_OFF);
int y1=(Height()-2*CONTROLS_SPIN_BUTTON_SIZE)/2;
int x2=x1+CONTROLS_BUTTON_SIZE;
int y2=y1+CONTROLS_SPIN_BUTTON_SIZE;
//--- create
if(!m_inc.Create(m_chart_id,m_name+"Inc",m_subwin,x1,y1,x2,y2))
return(false);
if(!m_inc.BmpNames("::res\\SpinInc.bmp"))
return(false);
if(!Add(m_inc))
return(false);
//--- property
m_inc.PropFlags(WND_PROP_FLAG_CLICKS_BY_PRESS);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Create the "Decrement" button |
//+------------------------------------------------------------------+
bool CSpinEdit::CreateDec(void)
{
//--- right align button (try to make equal offsets from top and bottom)
int x1=Width()-(CONTROLS_BUTTON_SIZE+CONTROLS_SPIN_BUTTON_X_OFF);
int y1=(Height()-2*CONTROLS_SPIN_BUTTON_SIZE)/2+CONTROLS_SPIN_BUTTON_SIZE;
int x2=x1+CONTROLS_BUTTON_SIZE;
int y2=y1+CONTROLS_SPIN_BUTTON_SIZE;
//--- create
if(!m_dec.Create(m_chart_id,m_name+"Dec",m_subwin,x1,y1,x2,y2))
return(false);
if(!m_dec.BmpNames("::res\\SpinDec.bmp"))
return(false);
if(!Add(m_dec))
return(false);
//--- property
m_dec.PropFlags(WND_PROP_FLAG_CLICKS_BY_PRESS);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Handler of click on the "increment" button |
//+------------------------------------------------------------------+
bool CSpinEdit::OnClickInc(void)
{
//--- try to increment current value
return(Value(m_value+1));
}
//+------------------------------------------------------------------+
//| Handler of click on the "decrement" button |
//+------------------------------------------------------------------+
bool CSpinEdit::OnClickDec(void)
{
//--- try to decrement current value
return(Value(m_value-1));
}
//+------------------------------------------------------------------+
//| Handler of changing current state |
//+------------------------------------------------------------------+
bool CSpinEdit::OnChangeValue(void)
{
//--- copy text to the edit field edit
m_edit.Text(IntegerToString(m_value));
//--- send notification
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_CHANGE,m_id,0.0,m_name);
//--- handled
return(true);
}
//+------------------------------------------------------------------+
bool CSpinEdit::OnChangeText(void)
{
//--- copy text to the edit field edit
m_value = StringToInteger(ObjectGetString(m_chart_id,m_name+"Edit",OBJPROP_TEXT));
Value(m_value);
m_edit.Text(IntegerToString(m_value));
//--- send notification
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_CHANGE,m_chart_id,0.0,m_name+"Edit");
//--- handled
return(true);
}
//+------------------------------------------------------------------+
Not a good idea to change a class from the standard library directly. It will be erased with the next update.
It’s ok. Thank you for warning me. So I’ll save it as a new class.
Saved as CSpinEdit_Modified. More later i’ll modified all standar library and save to make my custom library. For now i’m only studing and trying to understand how to use controls.
Thank you all.
//+------------------------------------------------------------------+
//| SpinEdit_Modified.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include "WndContainer.mqh"
#include "Edit.mqh"
#include "BmpButton.mqh"
//+------------------------------------------------------------------+
//| Resources |
//+------------------------------------------------------------------+
#resource "res\\SpinInc.bmp"
#resource "res\\SpinDec.bmp"
//+------------------------------------------------------------------+
//| Class CSpinEdit_Modified |
//| Usage: class that implements the "Up-Down" control |
//+------------------------------------------------------------------+
class CSpinEdit_Modified : public CWndContainer
{
private:
//--- dependent controls
CEdit m_edit; // the entry field object
CBmpButton m_inc; // the "Increment button" object
CBmpButton m_dec; // the "Decrement button" object
//--- adjusted parameters
int m_min_value; // minimum value
int m_max_value; // maximum value
//--- state
int m_value; // current value
public:
CSpinEdit_Modified(void);
~CSpinEdit_Modified(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);
//--- set up
int MinValue(void) const { return(m_min_value); }
void MinValue(const int value);
int MaxValue(void) const { return(m_min_value); }
void MaxValue(const int value);
//--- state
int Value(void) const { return(m_value); }
bool Value(int value);
//--- methods for working with files
virtual bool Save(const int file_handle);
virtual bool Load(const int file_handle);
protected:
//--- create dependent controls
virtual bool CreateEdit(void);
virtual bool CreateInc(void);
virtual bool CreateDec(void);
//--- handlers of the dependent controls events
virtual bool OnClickInc(void);
virtual bool OnClickDec(void);
virtual bool OnChangeText(void);
//--- internal event handlers
virtual bool OnChangeValue(void);
};
//+------------------------------------------------------------------+
//| Common handler of chart events |
//+------------------------------------------------------------------+
EVENT_MAP_BEGIN(CSpinEdit_Modified)
ON_EVENT(ON_CLICK,m_inc,OnClickInc)
ON_EVENT(ON_CLICK,m_dec,OnClickDec)
ON_EVENT(ON_END_EDIT,m_edit,OnChangeText)
EVENT_MAP_END(CWndContainer)
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CSpinEdit_Modified::CSpinEdit_Modified(void) : m_min_value(0),
m_max_value(0),
m_value(0)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CSpinEdit_Modified::~CSpinEdit_Modified(void)
{
}
//+------------------------------------------------------------------+
//| Create a control |
//+------------------------------------------------------------------+
bool CSpinEdit_Modified::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
{
//--- check height
if(y2-y1<CONTROLS_SPIN_MIN_HEIGHT)
return(false);
//--- call method of the parent class
if(!CWndContainer::Create(chart,name,subwin,x1,y1,x2,y2))
return(false);
//--- create dependent controls
if(!CreateEdit())
return(false);
if(!CreateInc())
return(false);
if(!CreateDec())
return(false);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Set current value |
//+------------------------------------------------------------------+
bool CSpinEdit_Modified::Value(int value)
{
//--- check value
if(value<m_min_value)
value=m_min_value;
if(value>m_max_value)
value=m_max_value;
//--- if value was changed
if(m_value!=value)
{
m_value=value;
//--- call virtual handler
return(OnChangeValue());
}
//--- value has not been changed
return(false);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CSpinEdit_Modified::Save(const int file_handle)
{
//--- check
if(file_handle==INVALID_HANDLE)
return(false);
//---
FileWriteInteger(file_handle,m_value);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CSpinEdit_Modified::Load(const int file_handle)
{
//--- check
if(file_handle==INVALID_HANDLE)
return(false);
//---
if(!FileIsEnding(file_handle))
Value(FileReadInteger(file_handle));
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Set minimum value |
//+------------------------------------------------------------------+
void CSpinEdit_Modified::MinValue(const int value)
{
//--- if value was changed
if(m_min_value!=value)
{
m_min_value=value;
//--- adjust the edit value
Value(m_value);
}
}
//+------------------------------------------------------------------+
//| Set maximum value |
//+------------------------------------------------------------------+
void CSpinEdit_Modified::MaxValue(const int value)
{
//--- if value was changed
if(m_max_value!=value)
{
m_max_value=value;
//--- adjust the edit value
Value(m_value);
}
}
//+------------------------------------------------------------------+
//| Create the edit field |
//+------------------------------------------------------------------+
bool CSpinEdit_Modified::CreateEdit(void)
{
//--- create
if(!m_edit.Create(m_chart_id,m_name+"Edit",m_subwin,0,0,Width(),Height()))
return(false);
if(!m_edit.Text(""))
return(false);
if(!m_edit.ReadOnly(false))
return(false);
if(!Add(m_edit))
return(false);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Create the "Increment" button |
//+------------------------------------------------------------------+
bool CSpinEdit_Modified::CreateInc(void)
{
//--- right align button (try to make equal offsets from top and bottom)
int x1=Width()-(CONTROLS_BUTTON_SIZE+CONTROLS_SPIN_BUTTON_X_OFF);
int y1=(Height()-2*CONTROLS_SPIN_BUTTON_SIZE)/2;
int x2=x1+CONTROLS_BUTTON_SIZE;
int y2=y1+CONTROLS_SPIN_BUTTON_SIZE;
//--- create
if(!m_inc.Create(m_chart_id,m_name+"Inc",m_subwin,x1,y1,x2,y2))
return(false);
if(!m_inc.BmpNames("::res\\SpinInc.bmp"))
return(false);
if(!Add(m_inc))
return(false);
//--- property
m_inc.PropFlags(WND_PROP_FLAG_CLICKS_BY_PRESS);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Create the "Decrement" button |
//+------------------------------------------------------------------+
bool CSpinEdit_Modified::CreateDec(void)
{
//--- right align button (try to make equal offsets from top and bottom)
int x1=Width()-(CONTROLS_BUTTON_SIZE+CONTROLS_SPIN_BUTTON_X_OFF);
int y1=(Height()-2*CONTROLS_SPIN_BUTTON_SIZE)/2+CONTROLS_SPIN_BUTTON_SIZE;
int x2=x1+CONTROLS_BUTTON_SIZE;
int y2=y1+CONTROLS_SPIN_BUTTON_SIZE;
//--- create
if(!m_dec.Create(m_chart_id,m_name+"Dec",m_subwin,x1,y1,x2,y2))
return(false);
if(!m_dec.BmpNames("::res\\SpinDec.bmp"))
return(false);
if(!Add(m_dec))
return(false);
//--- property
m_dec.PropFlags(WND_PROP_FLAG_CLICKS_BY_PRESS);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Handler of click on the "increment" button |
//+------------------------------------------------------------------+
bool CSpinEdit_Modified::OnClickInc(void)
{
//--- try to increment current value
return(Value(m_value+1));
}
//+------------------------------------------------------------------+
//| Handler of click on the "decrement" button |
//+------------------------------------------------------------------+
bool CSpinEdit_Modified::OnClickDec(void)
{
//--- try to decrement current value
return(Value(m_value-1));
}
//+------------------------------------------------------------------+
//| Handler of changing current state |
//+------------------------------------------------------------------+
bool CSpinEdit_Modified::OnChangeValue(void)
{
//--- copy text to the edit field edit
m_edit.Text(IntegerToString(m_value));
//--- send notification
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_CHANGE,m_id,0.0,m_name);
//--- handled
return(true);
}
//+------------------------------------------------------------------+
bool CSpinEdit_Modified::OnChangeText(void)
{
//--- copy text to the edit field edit
m_value = StringToInteger(ObjectGetString(m_chart_id,m_name+"Edit",OBJPROP_TEXT));
Value(m_value);
m_edit.Text(IntegerToString(m_value));
//--- send notification
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_CHANGE,m_chart_id,0.0,m_name+"Edit");
//--- handled
return(true);
}
//+------------------------------------------------------------------+
Tangentially related to this thread.
I wanted CSpinEdit to increment/decrement by a step value.
This is fairly straightforward to do.
I will leave this lying around in case anyone wants to use it.
/**
* Extends functionality of CSpitEdit to inc/dec by a step amount
*/
class CSpinEditIncr : public CSpinEdit
{
public:
int m_step;
CSpinEditIncr(void):m_step(10){} // Set step amount to 10
virtual bool OnClickInc(void)
{
return(Value(Value()+m_step));
}
virtual bool OnClickDec(void)
{
return(Value(Value()-m_step));
}
};
I realized there were some other features I wanted from CSpinEdit, so I created my own class.
Features:
-
I added the OnChangeText() code that you supplied (above). I also added a ReadOnly() flag with getter/setter for the embedded CEdit control.
-
I added the ability to specify a step amount (as I mentioned above).
-
Ability to turn the “fast spin” off. This basically means that a button click up or down only increments or decrements one step.
Put the file in \MQL5\Include\Controls.
Oh, if you are going to call SpinFast() or ReadOnly(), do so before calling Create().