//+------------------------------------------------------------------+ //| ControlsDialog.mqh | //| Copyright 2009-2013, MetaQuotes Software Corp. | //| http://www.mql5.com | //+------------------------------------------------------------------+ #include <Controls\Dialog.mqh> #include <Controls\Button.mqh> #include <Controls\Edit.mqh> #include <Controls\DatePicker.mqh> #include <Controls\ListView.mqh> #include <Controls\ComboBox.mqh> #include <Controls\SpinEdit.mqh> #include <Controls\RadioGroup.mqh> #include <Controls\CheckGroup.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: CEdit m_edit; // the display field object CButton m_button1; // the button object CButton m_button2; // the button object CButton m_button3; // the fixed button object CSpinEdit m_spin_edit; // the up-down object CDatePicker m_date; // the datepicker object CListView m_list_view; // the list object CComboBox m_combo_box; // the dropdown list object CRadioGroup m_radio_group; // the radio buttons group object CCheckGroup m_check_group; // the check box group 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 CreateEdit(void); bool CreateButton1(void); bool CreateButton2(void); bool CreateButton3(void); bool CreateSpinEdit(void); bool CreateDate(void); bool CreateListView(void); bool CreateComboBox(void); bool CreateRadioGroup(void); bool CreateCheckGroup(void); //--- handlers of the dependent controls events void OnClickButton1(void); void OnClickButton2(void); void OnClickButton3(void); void OnChangeSpinEdit(void); void OnChangeDate(void); void OnChangeListView(void); void OnChangeComboBox(void); void OnChangeRadioGroup(void); void OnChangeCheckGroup(void); }; //+------------------------------------------------------------------+ //| Event Handling | //+------------------------------------------------------------------+ EVENT_MAP_BEGIN(CControlsDialog) ON_EVENT(ON_CLICK,m_button1,OnClickButton1) ON_EVENT(ON_CLICK,m_button2,OnClickButton2) ON_EVENT(ON_CLICK,m_button3,OnClickButton3) ON_EVENT(ON_CHANGE,m_spin_edit,OnChangeSpinEdit) ON_EVENT(ON_CHANGE,m_date,OnChangeDate) ON_EVENT(ON_CHANGE,m_list_view,OnChangeListView) ON_EVENT(ON_CHANGE,m_combo_box,OnChangeComboBox) ON_EVENT(ON_CHANGE,m_radio_group,OnChangeRadioGroup) ON_EVENT(ON_CHANGE,m_check_group,OnChangeCheckGroup) 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(!CreateEdit()) return(false); if(!CreateButton1()) return(false); if(!CreateButton2()) return(false); if(!CreateButton3()) return(false); if(!CreateSpinEdit()) return(false); if(!CreateListView()) return(false); if(!CreateDate()) return(false); if(!CreateRadioGroup()) return(false); if(!CreateCheckGroup()) return(false); if(!CreateComboBox()) return(false); //--- succeed return(true); } //+------------------------------------------------------------------+ //| Create the display field | //+------------------------------------------------------------------+ bool CControlsDialog::CreateEdit(void) { //--- coordinates int x1=INDENT_LEFT; int y1=INDENT_TOP; int x2=ClientAreaWidth()-INDENT_RIGHT; int y2=y1+EDIT_HEIGHT; //--- create if(!m_edit.Create(m_chart_id,m_name+GetID(),m_subwin,x1,y1,x2,y2)) return(false); if(!m_edit.ReadOnly(true)) return(false); if(!Add(m_edit)) return(false); //--- succeed return(true); } //+------------------------------------------------------------------+ //| Create the "Button1" button | //+------------------------------------------------------------------+ bool CControlsDialog::CreateButton1(void) { //--- coordinates int x1=INDENT_LEFT; int y1=INDENT_TOP+(EDIT_HEIGHT+CONTROLS_GAP_Y); int x2=x1+BUTTON_WIDTH; int y2=y1+BUTTON_HEIGHT; //--- create if(!m_button1.Create(m_chart_id,m_name+GetID(),m_subwin,x1,y1,x2,y2)) return(false); if(!m_button1.Text("Button1")) return(false); if(!Add(m_button1)) return(false); //--- succeed return(true); } //+------------------------------------------------------------------+ //| Create the "Button2" button | //+------------------------------------------------------------------+ bool CControlsDialog::CreateButton2(void) { //--- coordinates int x1=INDENT_LEFT+(BUTTON_WIDTH+CONTROLS_GAP_X); int y1=INDENT_TOP+(EDIT_HEIGHT+CONTROLS_GAP_Y); int x2=x1+BUTTON_WIDTH; int y2=y1+BUTTON_HEIGHT; //--- create if(!m_button2.Create(m_chart_id,m_name+GetID(),m_subwin,x1,y1,x2,y2)) return(false); if(!m_button2.Text("Button2")) return(false); if(!Add(m_button2)) return(false); //--- succeed return(true); } //+------------------------------------------------------------------+ //| Create the "Button3" fixed button | //+------------------------------------------------------------------+ bool CControlsDialog::CreateButton3(void) { //--- coordinates int x1=INDENT_LEFT+2*(BUTTON_WIDTH+CONTROLS_GAP_X); int y1=INDENT_TOP+(EDIT_HEIGHT+CONTROLS_GAP_Y); int x2=x1+BUTTON_WIDTH; int y2=y1+BUTTON_HEIGHT; //--- create if(!m_button3.Create(m_chart_id,m_name+GetID(),m_subwin,x1,y1,x2,y2)) return(false); if(!m_button3.Text("Locked")) return(false); if(!Add(m_button3)) return(false); m_button3.Locking(true); //--- succeed return(true); } //+------------------------------------------------------------------+ //| Create the "SpinEdit" element | //+------------------------------------------------------------------+ bool CControlsDialog::CreateSpinEdit(void) { //--- coordinates int x1=INDENT_LEFT; int y1=INDENT_TOP+(EDIT_HEIGHT+CONTROLS_GAP_Y)+(BUTTON_HEIGHT+CONTROLS_GAP_Y); int x2=x1+GROUP_WIDTH; int y2=y1+EDIT_HEIGHT; //--- create if(!m_spin_edit.Create(m_chart_id,m_name+GetID(),m_subwin,x1,y1,x2,y2)) return(false); if(!Add(m_spin_edit)) return(false); m_spin_edit.MinValue(10); m_spin_edit.MaxValue(1000); m_spin_edit.Value(100); //--- succeed return(true); } //+------------------------------------------------------------------+ //| Create the "DatePicker" element | //+------------------------------------------------------------------+ bool CControlsDialog::CreateDate(void) { //--- coordinates int x1=INDENT_LEFT+GROUP_WIDTH+2*CONTROLS_GAP_X; int y1=INDENT_TOP+(EDIT_HEIGHT+CONTROLS_GAP_Y)+(BUTTON_HEIGHT+CONTROLS_GAP_Y); int x2=x1+GROUP_WIDTH; int y2=y1+EDIT_HEIGHT; //--- create if(!m_date.Create(m_chart_id,m_name+GetID(),m_subwin,x1,y1,x2,y2)) return(false); if(!Add(m_date)) return(false); m_date.Value(TimeCurrent()); //--- succeed return(true); } //+------------------------------------------------------------------+ //| Create the "ListView" element | //+------------------------------------------------------------------+ bool CControlsDialog::CreateListView(void) { //--- coordinates int x1=INDENT_LEFT+GROUP_WIDTH+2*CONTROLS_GAP_X; int y1=INDENT_TOP+(EDIT_HEIGHT+CONTROLS_GAP_Y)+ (BUTTON_HEIGHT+CONTROLS_GAP_Y)+ (EDIT_HEIGHT+2*CONTROLS_GAP_Y); int x2=x1+GROUP_WIDTH; int y2=y1+LIST_HEIGHT-CONTROLS_GAP_Y; //--- create if(!m_list_view.Create(m_chart_id,m_name+GetID(),m_subwin,x1,y1,x2,y2)) return(false); if(!Add(m_list_view)) return(false); //--- fill out with strings for(int i=0;i<16;i++) if(!m_list_view.AddItem("Item "+IntegerToString(i))) return(false); //--- succeed return(true); } //+------------------------------------------------------------------+ //| Create the "ComboBox" element | //+------------------------------------------------------------------+ bool CControlsDialog::CreateComboBox(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); int x2=x1+GROUP_WIDTH; int y2=y1+EDIT_HEIGHT; //--- create if(!m_combo_box.Create(m_chart_id,m_name+GetID(),m_subwin,x1,y1,x2,y2)) return(false); if(!Add(m_combo_box)) return(false); //--- fill out with strings for(int i=0;i<16;i++) if(!m_combo_box.ItemAdd("Item "+IntegerToString(i))) return(false); //--- succeed return(true); } //+------------------------------------------------------------------+ //| Create the "RadioGroup" element | //+------------------------------------------------------------------+ bool CControlsDialog::CreateRadioGroup(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); int x2=x1+GROUP_WIDTH; int y2=y1+RADIO_HEIGHT; //--- create if(!m_radio_group.Create(m_chart_id,m_name+GetID(),m_subwin,x1,y1,x2,y2)) return(false); if(!Add(m_radio_group)) return(false); //--- fill out with strings for(int i=0;i<3;i++) if(!m_radio_group.AddItem("Item "+IntegerToString(i),1<<i)) return(false); //--- succeed return(true); } //+------------------------------------------------------------------+ //| Create the "CheckGroup" element | //+------------------------------------------------------------------+ bool CControlsDialog::CreateCheckGroup(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+CHECK_HEIGHT; //--- create if(!m_check_group.Create(m_chart_id,m_name+GetID(),m_subwin,x1,y1,x2,y2)) return(false); if(!Add(m_check_group)) return(false); //--- fill out with strings for(int i=0;i<5;i++) if(!m_check_group.AddItem("Item "+IntegerToString(i),1<<i)) return(false); //--- succeed return(true); } //+------------------------------------------------------------------+ //| Event handler | //+------------------------------------------------------------------+ void CControlsDialog::OnClickButton1(void) { m_edit.Text(__FUNCTION__); } //+------------------------------------------------------------------+ //| Event handler | //+------------------------------------------------------------------+ void CControlsDialog::OnClickButton2(void) { m_edit.Text(__FUNCTION__); } //+------------------------------------------------------------------+ //| Event handler | //+------------------------------------------------------------------+ void CControlsDialog::OnClickButton3(void) { if(m_button3.Pressed()) m_edit.Text(__FUNCTION__+"On"); else m_edit.Text(__FUNCTION__+"Off"); } //+------------------------------------------------------------------+ //| Event handler | //+------------------------------------------------------------------+ void CControlsDialog::OnChangeSpinEdit() { m_edit.Text(__FUNCTION__+" : Value="+IntegerToString(m_spin_edit.Value())); } //+------------------------------------------------------------------+ //| Event handler | //+------------------------------------------------------------------+ void CControlsDialog::OnChangeDate(void) { m_edit.Text(__FUNCTION__+" \""+TimeToString(m_date.Value(),TIME_DATE)+"\""); } //+------------------------------------------------------------------+ //| Event handler | //+------------------------------------------------------------------+ void CControlsDialog::OnChangeListView(void) { m_edit.Text(__FUNCTION__+" \""+m_list_view.Select()+"\""); } //+------------------------------------------------------------------+ //| Event handler | //+------------------------------------------------------------------+ void CControlsDialog::OnChangeComboBox(void) { m_edit.Text(__FUNCTION__+" \""+m_combo_box.Select()+"\""); } //+------------------------------------------------------------------+ //| Event handler | //+------------------------------------------------------------------+ void CControlsDialog::OnChangeRadioGroup(void) { m_edit.Text(__FUNCTION__+" : Value="+IntegerToString(m_radio_group.Value())); } //+------------------------------------------------------------------+ //| Event handler | //+------------------------------------------------------------------+ void CControlsDialog::OnChangeCheckGroup(void) { m_edit.Text(__FUNCTION__+" : Value="+IntegerToString(m_check_group.Value())); } //+------------------------------------------------------------------+ //=============================================================================================================================== // GetID() - returns unique ID to pass to Create() //=============================================================================================================================== // Variable outside the class static int __id_counter = 0; // Function inside the class string GetID() { __id_counter++; Print(__id_counter); // Check it return ("#" + string(__id_counter)); }
Hello,
If you want to be read by Metaquotes developpers, you should write to ServiceDesk.

- www.mql5.com
I am not sure if Service Desk has already replied to your issue, but I encountered a similar problem before.
The problem has something to do with the Run() function of CAppDialog. Each control (including CAppDialog) creates a unique ID for itself, based on the subwindow. This ID is then passed down to any other controls they contain, so that all controls within the dialog window will have a unique ID. However, in your case, you have two separate CAppDialog instances, and both instances do not know that the other exists. As a result, they create the basically the same IDs for each of their controls, despite the controls having different names. This explains why clicking on one control on one dialog window triggers the same event on the other.
One solution to the problem is this:
- Create a static class member that counts the number of instances of the class
- Replace/add the value of the static member to the only argument of the Id() function (under Run())
- Increment the static member
Here is a screen shot of the result:
https://www.mql5.com/en/charts/3823800/eurusd-h1-international-capital-markets

- www.mql5.com
Hi Enrico,
thank you very much, this will help.
During my "investigations" I also figured out, that the processing of the ChartEvent is very ineffective, the reason for this is just the same: No instance managing, no saving of processing time is possible. This means, if you have several charts with several dialogues with several objects - each member of the dialog processes MOUSE_MOVE no matter if it can handle it or not - processes this. As a result, you will end up in performance problems. You see this already when you enter some text into an CEdit() an move the mouse, the input starts to flicker.
I think one can do better.
For what it's worth, I'm also having a massive headache trying to do anything remotely complex with these controls.
It seems they work fine provided you create them once, and then don't want to do anything like dynamically removing or recreating them. As soon as you start doing this however, all sorts of weird behaviour starts cropping up, elements shifting position, invalid pointer exceptions getting thrown. And, as you mentioned, it's something of a nightmare to debug.
It's a shame, because these are potentially a huge time-saving set of standard controls which I could use for many applications, but they are indeed in a very "beta" state at present.
Hello,
Someone try to use the Enrico exemple and with the EA in the chart, change more than two times the TF?
Here was totally denconfigured! :(
Someone can help me?
I am not sure if Service Desk has already replied to your issue, but I encountered a similar problem before.
The problem has something to do with the Run() function of CAppDialog. Each control (including CAppDialog) creates a unique ID for itself, based on the subwindow. This ID is then passed down to any other controls they contain, so that all controls within the dialog window will have a unique ID. However, in your case, you have two separate CAppDialog instances, and both instances do not know that the other exists. As a result, they create the basically the same IDs for each of their controls, despite the controls having different names. This explains why clicking on one control on one dialog window triggers the same event on the other.
One solution to the problem is this:
- Create a static class member that counts the number of instances of the class
- Replace/add the value of the static member to the only argument of the Id() function (under Run())
- Increment the static member
Here is a screen shot of the result:
https://www.mql5.com/en/charts/3823800/eurusd-h1-international-capital-markets

- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
Dear MQL5 developers,
at least I hope you guys read this.
I started to create a set of classes to develop a trading environment on a visual basis. Everything fine so far, until I found a very odd behaviour when using the control classes. First I thought I´ve overseen something, but then I found out, that there must be very huge bug in the classes, somewhere behind CWndContainer/CWnd. What I saw first was, that after resizing a CWndContainer object, it dropped added/bound elements. Just like that. Or when resizing a CWndClient object, the positions started to shift.
Then I tried something very simple, I took a sample from you which I found here, which creates a floating dialog window. That works, as it seems. BUT ... when I define just two instead of one class object, the whole thing goes crazy! When Im typing something into the edit fields and so on, the other window is affected. When I click on one listbox, the other reacts. Well, theses are classes and there is not static data in between. This behaviour is definitely buggy and the classes are not seriously usable.
Of course I´ve installed the newest version of Metatrader and tested it again. Same results. It´s not possible to create multiple instances of nested control objects. Now I don´t know if this is a problem of Metatrader or "just" a problem of the classes, which are kinda complex and are not so easy to debug. I´d be very unhappy if it would stay like that because it would mean, I cannot finish my work which costed me already plenty of time.
Looking forward to anybodies reply who can really help.
EDIT: In the meanwhile I found out, that this sample is originally a part of Metatrader 5. I´ve tried it with the same changes in Metatrader 5 and still got the same results. In my opinion there is something hardly wrong with the memory management, probably (hopefully!) within the MQL5 classes. But what confuses me most, is, that it seems that I am the first person who tries to develop seriously visual tools on a higher lever for Metatrader. Well, that´s were I started programming on Assembler Basis and C almost 25 years ago, it´s what I always could best :) But i really don´t want to write all the classes that I need for what I am planning. I expected that the control classes are ready to use, but they´re kinda beta.