OnClick Event does not work in CAPPDialog

 

I am trying to create a Dialog with two CBmpButtons. The UX works fine BUT when the programs needs to handle the button clicks just detects the first button and no the other one. Am I doing something wrong in here? I have made another Panel using CAppDialog and the code handles all the button clicks perfectly but not in this one. Thanks in advance.

This is my code:

Class

#include <Controls\Dialog.mqh>
#include <Controls\BmpButton.mqh>

class Tester : public CAppDialog
{
   private:
      CBmpButton btn_trendline;
      CBmpButton btn_crosshair;
      
   public:
      Tester(void) {};
      ~Tester(void) {}
      
      virtual bool Create(const long chart, const string name, const int subwin, const int x1, const int y1, const int x2, const int y2);
      virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
      
   protected:
      bool CreateTLBtn();
      bool CreateCHBtn();
      
      void OnClickedTLBtn();
      void OnClickedCHBtn();
};
EVENT_MAP_BEGIN(Tester)
ON_EVENT(ON_CLICK,btn_crosshair,OnClickedCHBtn)
ON_EVENT(ON_CLICK,btn_trendline,OnClickedTLBtn)
EVENT_MAP_END(CAppDialog)

bool Tester::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;
   
   if ( !CreateCHBtn() )
      return false;
      
   if ( !CreateTLBtn() )
      return false;
      
    return true;
}

bool Tester::CreateCHBtn(void)
{
   if ( !btn_crosshair.Create(0, "crosshair_btn", 0, 5, 3, 15, 15) )
      return false;
   
   btn_crosshair.BmpNames("\\Images\\ic_test_off.bmp","\\Images\\ic_test_on.bmp");
   btn_trendline.Locking(true);
   if ( !Add(btn_crosshair) )
      return false;
   
   return true;
}

bool Tester::CreateTLBtn(void)
{
   if ( !btn_trendline.Create(0, "trendline_btn", 0, 40, 3, 15, 15) )
      return false;
   
   btn_trendline.BmpNames("\\Images\\ic_test_off.bmp","\\Images\\ic_test_on.bmp");
   btn_trendline.Locking(true);
   if ( !Add(btn_trendline) )
      return false;
   
   return true;
}

void Tester::OnClickedCHBtn(void)
{
   Print("CH");
}

void Tester::OnClickedTLBtn(void)
{
   Print("TL");
}

Indicator to handle the class

#include <@indicesGodd\Test.mqh>
Tester tester;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
   if (!tester.Create(0, "Probando", 0, 5, 5, 300, 150))
      return(INIT_FAILED);
   if ( !tester.Run() )
      return(INIT_FAILED);
//---
   return(INIT_SUCCEEDED);
}

void OnDeinit(const int reason)
{
   tester.Destroy(reason);
}
//+------------------------------------------------------------------+
//| 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);
  }

void OnChartEvent(const int id,const long& lparam,const double& dparam,const string& sparam)
{
   tester.ChartEvent(id, lparam, dparam, sparam);
}
//+------------------------------------------------------------------+
 
Hm. Looks pretty good, maybe some spelling mistake... You could print messages in case a button was not created or added to the dialog successfully.
 
bool Tester::CreateCHBtn(void)
{
   if ( !btn_crosshair.Create(0, "crosshair_btn", 0, 5, 3, 15, 15) )
      return false;
   
   btn_crosshair.BmpNames("\\Images\\ic_test_off.bmp","\\Images\\ic_test_on.bmp");
   btn_trendline.Locking(true);
   if ( !Add(btn_crosshair) )
      return false;
   
   return true;
}

I guess you made a mistake here.

 
Tobias Johannes Zimmer #:
Hm. Looks pretty good, maybe some spelling mistake... You could print messages in case a button was not created or added to the dialog successfully.

I'll do that because I am driving myself crazy about this lol.

But all the buttons draws perfectly, the problem is when I have to handle the clicks of each button.

 
Samuel Manoel De Souza #:

I guess you made a mistake here.

I deleted my old class and indicator to create a new one thinking that maybe something was wrong with the class itself or indicator file.

So, I made another one.

bool DrawingPanel::CreateCrosshairBtn(void)
{
   if ( !btn_crosshair.Create(0, "Crosshair_Btn", 0, 8, 8, 8+7, 8+7) )
      return false;
      
   btn_crosshair.BmpNames("\\Images\\ic_test_off.bmp", "\\Images\\ic_crosshair_on.bmp");
   btn_crosshair.Locking(true);
   ObjectSetString(0, "Crosshair_Btn", OBJPROP_TOOLTIP, "Show Crosshair");
   
   if ( !Add(btn_crosshair) )
      return false;
      
   return true;
}
This is the code to create the BmpButton. It works well but it works so well that when I click another place inside the panel, it detects the click and handle the function that should be working for the button only.
 

I'd a similar setup to solve recently. I'll post my code, hoping it's usefull in your application.

My solution for toggling between two buttons looks as follows:


#include <buttons.mqh>//+------------------------------------------------------------------+

if(ObjectGetInteger(0,my_name+"Button1",OBJPROP_STATE,0)){
POS_function();
if(del_obj_==0){
ObjectSetInteger(0,"DASHBOARD_Label_Swap",OBJPROP_TIMEFRAMES,OBJ_NO_PERIODS);
ObjectSetInteger(0,"DASHBOARD_Label_SwapDetail",OBJPROP_TIMEFRAMES,OBJ_NO_PERIODS);
ObjectSetInteger(0,"DASHBOARD_Label_SwapDetailLong",OBJPROP_TIMEFRAMES,OBJ_NO_PERIODS);
ObjectSetInteger(0,"DASHBOARD_Label_SwapDetailShort",OBJPROP_TIMEFRAMES,OBJ_NO_PERIODS);
ObjectSetInteger(0,"DASHBOARD_Label_PosCumSwap",OBJPROP_TIMEFRAMES,OBJ_NO_PERIODS);
for(i2=0;i2<integer_Instrument && !IsStopped(); i2++) {
ObjectSetInteger(0,"DASHBOARD_6_"+IntegerToString(i2),OBJPROP_TIMEFRAMES,OBJ_NO_PERIODS);
   }
   GUI_function();
   del_obj_++;
      }
      GUI_function_REDRAW(true);
         }

if(ObjectGetInteger(0,my_name+"Button2",OBJPROP_STATE,0)){
Symbol_Swaps_function();
if(del_obj_==0){
ObjectSetInteger(0,"DASHBOARD_Label_Vol",OBJPROP_TIMEFRAMES,OBJ_NO_PERIODS);
ObjectSetInteger(0,"DASHBOARD_Label_Swap",OBJPROP_TIMEFRAMES,OBJ_NO_PERIODS);
ObjectSetInteger(0,"DASHBOARD_Label_PosCumSwap",OBJPROP_TIMEFRAMES,OBJ_NO_PERIODS);
for(i2=0;i2<integer_Instrument && !IsStopped(); i2++) {
ObjectSetInteger(0,"DASHBOARD_1_"+IntegerToString(i2),OBJPROP_TIMEFRAMES,OBJ_NO_PERIODS);
   }
   SWAP_DETAIL_GUI_function();
   del_obj_++;
      }
      SWAP_DETAIL_GUI_function_REDRAW(true);
         }
//+------------------------------------------------------------------+
//|                                                      buttons.mqh |
//|                           Copyright 2019-2022, Bünyamin Tasdelen |
//|                                  https://mumblefx.com/impressum/ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019-2022, Bünyamin Tasdelen"
#property link      "https://mumblefx.com/impressum/"
//+------------------------------------------------------------------+
//|                                               ControlsButton.mq5 |
//|                        Copyright 2017, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property description "Control Panels and Dialogs. Demonstration class CButton"
#include <Controls\Dialog.mqh>
#include <Controls\Button.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

string my_name  ="tzeek";
//+------------------------------------------------------------------+
//| Class CControlsDialog                                            |
//| Usage: main dialog of the Controls application                   |
//+------------------------------------------------------------------+
class CControlsDialog : public CAppDialog
  {
private:
protected:

 
public:
   CButton           m_button1;                       // the button object
   CButton           m_button2;                       // the button object
   CButton           m_button3;                       // the fixed button object
   


                     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);
 
   //--- create dependent controls
   bool              CreateButton1(void);
   bool              CreateButton2(void);
   bool              CreateButton3(void);
         //--- handlers of the dependent controls events
   void              OnClickButton1(void);
   void              OnClickButton2(void);
   void              OnClickButton3(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)
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,my_name,subwin,x1,y1,x2,y2))
      return(false);
//--- create dependent controls
   if(!CreateButton1())
      return(false);
   if(!CreateButton2())
      return(false);
   if(!CreateButton3())
      return(false);
//--- succeed
   return(true);
  }
CControlsDialog ExtDialog;
//+------------------------------------------------------------------+
//| 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,my_name+"Button1",m_subwin,x1,y1,x2,y2))
      return(false);
   if(!m_button1.Text("Positions"))
      return(false);
   if(!Add(m_button1))
      return(false);
      
   m_button1.Locking(true);
//--- 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,my_name+"Button2",m_subwin,x1,y1,x2,y2))
      return(false);
   if(!m_button2.Text("Swaps"))
      return(false);
   if(!Add(m_button2))
      return(false);
      
   m_button2.Locking(true);
//--- 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,my_name+"Button3",m_subwin,x1,y1,x2,y2))
      return(false);
   if(!m_button3.Text("Net/Detail"))
      return(false);
   if(!Add(m_button3))
      return(false);
   m_button3.Locking(true);
//--- succeed
   return(true);
  }
//+------------------------------------------------------------------+
//| Event handler                                                    |
//+------------------------------------------------------------------+
void CControlsDialog::OnClickButton1(void)
  {
   //if(m_button1.Pressed()){   m_button1.Text("Display Positions");   }
   //else{   m_button1.Text("off");  }
   if(m_button1.Pressed()){
   ObjectSetInteger(0,my_name+"Button1",OBJPROP_STATE,true);del_obj_=0;
   m_button2.Pressed(false);
   }else{
   ObjectSetInteger(0,my_name+"Button1",OBJPROP_STATE,false);
         }
   }
//+------------------------------------------------------------------+
//| Event handler                                                    |
//+------------------------------------------------------------------+
void CControlsDialog::OnClickButton2(void)
  {
   //if(m_button2.Pressed()){   m_button2.Text("Display Swaps");   }
   //else{   m_button2.Text("off");  }
   if(m_button2.Pressed()){
   ObjectSetInteger(0,my_name+"Button2",OBJPROP_STATE,true);del_obj_=0;
   m_button1.Pressed(false);
   }else{
   ObjectSetInteger(0,my_name+"Button2",OBJPROP_STATE,false);
      }

  }
//+------------------------------------------------------------------+
//| Event handler                                                    |
//+------------------------------------------------------------------+
void CControlsDialog::OnClickButton3(void)
  {

  }
Files:
MumbleFX.com.png  168 kb
 
Bünyamin Tasdelen #:

I'd a similar setup to solve recently. I'll post my code, hoping it's usefull in your application.

My solution for toggling between two buttons looks as follows:


Thanks a lot to share your code in here. I'll try it. I guess my problem is with the x1, y1, x2, y2 when I create the buttons. Don't know if the buttons overlaps and that's why the other buttons can not work.
I'll let you know what happens.

Thanks, Bünyamin, for your time.

 
Genaro Cancino:

I am trying to create a Dialog with two CBmpButtons. The UX works fine BUT when the programs needs to handle the button clicks just detects the first button and no the other one. Am I doing something wrong in here? I have made another Panel using CAppDialog and the code handles all the button clicks perfectly but not in this one. Thanks in advance.

This is my code:

Class

Indicator to handle the class

The initial class you wrote, that is the Tester class works well, similar to the example in the reference guide. There are numerous ways to solve the problem.

bool Tester::CreateCHBtn(void)
{
   if ( !btn_crosshair.Create(0, "crosshair_btn", 0, 5, 3, 0 ,0 ))
      return false;
   
   btn_crosshair.BmpNames("\\Images\\ic_test_off.bmp","\\Images\\ic_test_on.bmp");
   btn_crosshair.Locking(true);
   btn_crosshair.Size(32, 32);	
   if ( !Add(btn_crosshair) )
      return false;
   
   return true;
}

You could also use

      btn_crosshair.Height(32);
      btn_crosshair.Width(32);

while declaring the height and the width of the BmpButton. its important to note that if the size declared is bigger than that of the bmp image, then clicking outside the bmp image would act like clicking the button.

Reason: