Hi,
I try to use a button and a spinedit on a control panel (Dialog).
When the following code line in OnChartEvent() function is commented out, the button works, but not the spin edit.
On the other hand, when it is commented in, the button does not work, but the spin edit.
How can I correctly handle actions ?
Thanks in advance for any help.
The normal way to use a button is to perform some actions when it is clicked. Not to toggle it's state (for that, we use checkboxes).
As for spinedit, it's behavior when you call OnEvent() is expected. You call input_test2.Value() only when you need it's value.
So the behavior of both controls with OnEvent() call is expected, there is nothing wrong.
The normal way to use a button is to perform some actions when it is clicked. Not to toggle it's state (for that, we use checkboxes).
Thank you for your explanation. However in order to simplify the question, I just removed the business logic, (as you see the button is called as test).
So the behavior of both controls with OnEvent() call is expected, there is nothing wrong.
Actually, the first post explains what is the wrong pretty good.
If the code is executed, the wrong is easily observed.
Just try to click the button, it will not work.
Then comment out the mentioned line, execute code, at this time spinedit does not work.
Thank you.
Thank you for your explanation. However in order to simplify the question, I just removed the business logic, (as you see the button is called as test).
Actually, the first post explains what is the wrong pretty good.
If the code is executed, the wrong is easily observed.
Just try to click the button, it will not work.
Then comment out the mentioned line, execute code, at this time spinedit does not work.
Thank you.
Of course it won't work, because it wasn't designed to work that way - read my first reply again.
Here's what you could do if you want to use CButton as a toggle:
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { cpInterface.OnEvent(id, lparam, dparam, sparam); if (btn_test1.Pressed()) { switch (btn_test1.ColorBackground()) { case (clrGreen): { Print ("Color is Green, Spin Edit Value = ", input_test2.Value()); btn_test1.ColorBackground(clrRed); break; } default: { Print ("Color is Red, do nothing"); btn_test1.ColorBackground(clrGreen); break; } } } }
Here's what you could do if you want to use CButton as a toggle:
Thank you very much.
I was previously doing just like that.
The control mechanism in here is based on the background color which is not the intended way.
In other words, when I realized that the CButton class has a state() function, I wanted to utilize it.
From the definition of state() function , I understand that when I press the button it is state is changed to pressed.
When I again press it , the state is changed to unpressed.
I also confirmed this behavior with the following code.
Note: I do not want to use checkbox or radio button here.
//+------------------------------------------------------------------+ //| Tmp.mq4 | //| fxbender 2021 | //| https://www.google.com | //+------------------------------------------------------------------+ #property copyright "Fxbender 2021" #property link "https://www.google.com" #property version "1.00" #property strict #include <Controls/Dialog.mqh> #include <Controls/Button.mqh> #include <Controls/SpinEdit.mqh> #include <stdlib.mqh> #include <WinUser32.mqh> CAppDialog cpInterface; CButton btn_test1; const string btnID_test1="ButtonTest1"; CSpinEdit input_test2; const string inputID_test2="InputTest2"; static int a_x = int(ChartGetInteger(0,CHART_WIDTH_IN_PIXELS,0)-10); int OnInit() { const int sub_window = 0; // subwindow index int x = 10; // X coordinate int y = 10; // Y coordinate int width = 50; // object width int height = 20; // object height const int space = 3; // space between objects int left=0,top=0,right=0,bottom=0; left = x + (width + space) * 2.5; top = y; right = left + width * 3; bottom = top + height; btn_test1.Create(0, btnID_test1, sub_window, left, top, right, bottom); btn_test1.Text("Test"); btn_test1.FontSize(9); btn_test1.Color(clrWhite); btn_test1.ColorBackground(clrRed); btn_test1.ColorBorder(clrBlack); return(INIT_SUCCEEDED); } void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { if(id==CHARTEVENT_OBJECT_CLICK) { string clickedChartObjectID = sparam; if(clickedChartObjectID == btnID_test1) { // State of the button - pressed or not bool selected = ObjectGetInteger(0, btnID_test1, OBJPROP_STATE); Print("Test Button pressed = ", selected); string message; // If the button is pressed if(selected) { message = "Test Activated"; ObjectSetInteger(0, btnID_test1, OBJPROP_BGCOLOR, clrGreen); } else // Button is not pressed { message="Test Deactivated"; ObjectSetInteger(0, btnID_test1, OBJPROP_BGCOLOR, clrRed); } Print(message); } ChartRedraw(); } } void OnDeinit(const int reason) { cpInterface.Destroy(reason); }
When I use it within a Dialog control panel, it does not work.
Thank you very much.
I was previously doing just like that.
The control mechanism in here is based on the background color which is not the intended way.
In other words, when I realized that the CButton class has a state() function, I wanted to utilize it.
From the definition of state() function , I understand that when I press the button it is state is changed to pressed.
When I again press it , the state is changed to unpressed.
I also confirmed this behavior with the following code.
Note: I do not want to use checkbox or radio button here.
When I use it within a Dialog control panel, it does not work.
Don't use background color then. I used that just for convenience...
cpInterface.OnEvent(id, lparam, dparam, sparam); static bool btn_selected = false; if (btn_test1.Pressed()) { if (btn_selected) { btn_test1.ColorBackground(clrGreen); Print ("Color is Green, do nothing"); btn_selected = false; } else { btn_test1.ColorBackground(clrRed); Print ("Color is Red, Spin Edit Value = ", input_test2.Value()); btn_selected = true; } }
You need to decide whether to use OBJ_BUTTON of MQL4 (where OBJPROP_STATE plays a role), or switch to the CButton of MQL5 and make use of Pressed(), and work around it (use your own bool state) so that it serves as a toggle (which isn't it's intended role) rather than on per-click basis.
Thank you very much for the fast response.
I understand from the latest response that the MQL$ state() function does not behave as the same when not using Dialog panel.
Although I do not have the reasoning about that yet, I will follow your advise and design a circumventing logic.
Actually MQL4 is relatively simple than, that's why I tend to use this notion.
However I only want to leverage object oriented programming style when I create GUI elements.
Since assigning values to attributes is more clean with MQL5.
However class logic is not like that, it is more complicated and dirty.
Anyway, again thank you.
//+------------------------------------------------------------------+ //| SpinEdit.mq4 | //| Copyright 2021, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2021, MetaQuotes Software Corp." #property link "https://www.mql5.com" #property version "1.00" #property strict #property indicator_chart_window #include <Controls/SpinEdit.mqh> CSpinEdit MySpin; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { MySpin.Create(0,"MySpin",0,420,20,500,50); MySpin.MaxValue(30); MySpin.MinValue(20); MySpin.Value(25); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { //--- //--- return value of prev_calculated for next call return(rates_total); } //+------------------------------------------------------------------+ //| ChartEvent function | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { MySpin.OnEvent(id,lparam,dparam,sparam); } //+------------------------------------------------------------------+ void OnDeinit(const int reason) { MySpin.Destroy(reason); }
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
Hi,
I try to use a button and a spinedit on a control panel (Dialog).
When the following code line in OnChartEvent() function is commented out, the button works, but not the spin edit.
On the other hand, when it is commented in, the button does not work, but the spin edit.
How can I correctly handle actions ?
Thanks in advance for any help.