Есть ли способ выполнить событие Click на кнопке, не нажимая кнопку?

 

У меня есть следующий код:

#define name_append "abc_"
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int Buy_Coords[2][2];

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
  {
   Panel();
   EventSetMillisecondTimer(50);
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   EventKillTimer();
   ObjectsDeleteAll(0, name_append, 0);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   Panel();
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnTimer()
  {
   if(ObjectGetInteger(0, name_append + "buy", OBJPROP_STATE) == true)
     {
      Print("Buy Clicked");
      ObjectSetInteger(0, name_append + "buy", OBJPROP_STATE, false);
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnChartEvent(const int       id,       // event ID
                  const long&     lparam,   // long type event parameter
                  const double&   dparam,   // double type event parameter
                  const string&   sparam    // string type event parameter
                 )
  {
   if(id == CHARTEVENT_OBJECT_CLICK)
     {
      if(sparam == name_append + "buy")
        {
         Print("Buy Clicked");
         ObjectSetInteger(0, name_append + "buy", OBJPROP_STATE, false);
        }
     }
   else
     {
      if(
         Buy_Coords[0][0] <= lparam && lparam <= Buy_Coords[1][0] &&
         Buy_Coords[0][1] <= dparam && dparam <= Buy_Coords[1][1]
      )
        {
	 Print("Buy Clicked");
        }

     }
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void Panel()
  {
   int X = int(ChartGetInteger(0, CHART_WIDTH_IN_PIXELS) - 150),
       Y = 30;
   Edit(0, name_append + "Lotsize", 0, X, Y, 50, 18, "0.1", "Arial", 10, ALIGN_CENTER, false, CORNER_LEFT_UPPER, clrBlack, clrWhite, clrWhite, false, false, false, 1);
   Y = Y + 20;
   Button(0, name_append + "buy", 0, X, Y, 50, 18, CORNER_LEFT_UPPER, "BUY", "Arial", 10, clrWhite, clrDodgerBlue, clrDodgerBlue, false, false, false, false, 1);
   Buy_Coords[0][0] = X;
   Buy_Coords[1][0] = Buy_Coords[0][0] + 50;
   Buy_Coords[0][1] = Y;
   Buy_Coords[1][1] = Buy_Coords[0][1] + 18;
  }
//+------------------------------------------------------------------+
bool Edit(const long             chart_ID=0,               // chart's ID
          const string           name="Edit",              // object name
          const int              sub_window=0,             // subwindow index
          const int              x=0,                      // X coordinate
          const int              y=0,                      // Y coordinate
          const int              width=50,                 // width
          const int              height=18,                // height
          const string           text="Text",              // text
          const string           font="Arial",             // font
          const int              font_size=10,             // font size
          const ENUM_ALIGN_MODE  align=ALIGN_CENTER,       // alignment type
          const bool             read_only=false,          // ability to edit
          const ENUM_BASE_CORNER corner=CORNER_LEFT_UPPER, // chart corner for anchoring
          const color            clr=clrBlack,             // text color
          const color            back_clr=clrWhite,        // background color
          const color            border_clr=clrNONE,       // border color
          const bool             back=false,               // in the background
          const bool             selection=false,          // highlight to move
          const bool             hidden=true,              // hidden in the object list
          const long             z_order=0)                // priority for mouse click
  {
//--- reset the error value
   ResetLastError();

   if(ObjectFind(chart_ID, name) < 0)
     {
      if(!ObjectCreate(chart_ID,name,OBJ_EDIT,sub_window,0,0))
        {
         Print(__FUNCTION__,
               ": failed to create \"Edit\" object! Error code = ",GetLastError());
         return(false);
        }
      //--- set object coordinates
      ObjectSetInteger(chart_ID,name,OBJPROP_XDISTANCE,x);
      ObjectSetInteger(chart_ID,name,OBJPROP_YDISTANCE,y);
      //--- set object size
      ObjectSetInteger(chart_ID,name,OBJPROP_XSIZE,width);
      ObjectSetInteger(chart_ID,name,OBJPROP_YSIZE,height);
      //--- set the text
      ObjectSetString(chart_ID,name,OBJPROP_TEXT,text);
      //--- set text font
      ObjectSetString(chart_ID,name,OBJPROP_FONT,font);
      //--- set font size
      ObjectSetInteger(chart_ID,name,OBJPROP_FONTSIZE,font_size);
      //--- set the type of text alignment in the object
      ObjectSetInteger(chart_ID,name,OBJPROP_ALIGN,align);
      //--- enable (true) or cancel (false) read-only mode
      ObjectSetInteger(chart_ID,name,OBJPROP_READONLY,read_only);
      //--- set the chart's corner, relative to which object coordinates are defined
      ObjectSetInteger(chart_ID,name,OBJPROP_CORNER,corner);
      //--- set text color
      ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
      //--- set background color
      ObjectSetInteger(chart_ID,name,OBJPROP_BGCOLOR,back_clr);
      //--- set border color
      ObjectSetInteger(chart_ID,name,OBJPROP_BORDER_COLOR,border_clr);
      //--- display in the foreground (false) or background (true)
      ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
      //--- enable (true) or disable (false) the mode of moving the label by mouse
      ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
      ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
      //--- hide (true) or display (false) graphical object name in the object list
      ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
      //--- set the priority for receiving the event of a mouse click in the chart
      ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
     }
   else //--- reset the error value
     {
      ResetLastError();
      //--- move the object
      if(!ObjectSetInteger(chart_ID,name,OBJPROP_XDISTANCE,x))
        {
         Print(__FUNCTION__,
               ": failed to move X coordinate of the object! Error code = ",GetLastError());
         return(false);
        }
      if(!ObjectSetInteger(chart_ID,name,OBJPROP_YDISTANCE,y))
        {
         Print(__FUNCTION__,
               ": failed to move Y coordinate of the object! Error code = ",GetLastError());
         return(false);
        }
     }
   return(true);
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool Button(const long              chart_ID=0,               // chart's ID
            const string            name="Button",            // button name
            const int               sub_window=0,             // subwindow index
            const int               x=0,                      // X coordinate
            const int               y=0,                      // Y coordinate
            const int               width=50,                 // button width
            const int               height=18,                // button height
            const ENUM_BASE_CORNER  corner=CORNER_LEFT_UPPER, // chart corner for anchoring
            const string            text="Button",            // text
            const string            font="Arial",             // font
            const int               font_size=10,             // font size
            const color             clr=clrBlack,             // text color
            const color             back_clr=C'236,233,216',  // background color
            const color             border_clr=clrNONE,       // border color
            const bool              state=false,              // pressed/released
            const bool              back=false,               // in the background
            const bool              selection=false,          // highlight to move
            const bool              hidden=true,              // hidden in the object list
            const long              z_order=0)                // priority for mouse click
  {
//--- reset the error value
   ResetLastError();
   if(ObjectFind(chart_ID, name) < 0)
     {
      if(!ObjectCreate(chart_ID,name,OBJ_BUTTON,sub_window,0,0))
        {
         Print(__FUNCTION__,
               ": failed to create the button! Error code = ",GetLastError());
         return(false);
        }
      //--- set button coordinates
      ObjectSetInteger(chart_ID,name,OBJPROP_XDISTANCE,x);
      ObjectSetInteger(chart_ID,name,OBJPROP_YDISTANCE,y);
      //--- set button size
      ObjectSetInteger(chart_ID,name,OBJPROP_XSIZE,width);
      ObjectSetInteger(chart_ID,name,OBJPROP_YSIZE,height);
      //--- set the chart's corner, relative to which point coordinates are defined
      ObjectSetInteger(chart_ID,name,OBJPROP_CORNER,corner);
      //--- set the text
      ObjectSetString(chart_ID,name,OBJPROP_TEXT,text);
      //--- set text font
      ObjectSetString(chart_ID,name,OBJPROP_FONT,font);
      //--- set font size
      ObjectSetInteger(chart_ID,name,OBJPROP_FONTSIZE,font_size);
      //--- set text color
      ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
      //--- set background color
      ObjectSetInteger(chart_ID,name,OBJPROP_BGCOLOR,back_clr);
      //--- set border color
      ObjectSetInteger(chart_ID,name,OBJPROP_BORDER_COLOR,border_clr);
      //--- display in the foreground (false) or background (true)
      ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
      //--- set button state
      ObjectSetInteger(chart_ID,name,OBJPROP_STATE,state);
      //--- enable (true) or disable (false) the mode of moving the button by mouse
      ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
      ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
      //--- hide (true) or display (false) graphical object name in the object list
      ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
      //--- set the priority for receiving the event of a mouse click in the chart
      ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
     }
   else //--- reset the error value
     {
      ResetLastError();
      //--- move the object
      if(!ObjectSetInteger(chart_ID,name,OBJPROP_XDISTANCE,x))
        {
         Print(__FUNCTION__,
               ": failed to move X coordinate of the object! Error code = ",GetLastError());
         return(false);
        }
      if(!ObjectSetInteger(chart_ID,name,OBJPROP_YDISTANCE,y))
        {
         Print(__FUNCTION__,
               ": failed to move Y coordinate of the object! Error code = ",GetLastError());
         return(false);
        }
     }
   return(true);
  }
//+------------------------------------------------------------------+

Выход =

Я нажал кнопку, и она работала хорошо. Но когда я нажимаю на поле редактирования, иногда оно вызывает событие кнопки и печатает сообщение «Купить кликнул». Но я не нажимал.

Я обнаружил, что есть некоторые проблемы с кодом, когда я пытаюсь поймать событие кнопки в функции OnChartEvent() в другой части. Координаты, которые я использую, могут не совпадать.

Пожалуйста, помогите мне пройти через это. Я добавил это еще, потому что есть время, когда много линейных объектов перекрываются с кнопкой, и события не могут быть выполнены, поэтому я подумал об использовании координат диаграммы кнопки, если что-то нажато. Если координаты являются координатами кнопки покупки, то это должно вызвать событие покупки. Но иногда срабатывает кнопка, когда я нажимаю на поле редактирования.

Я хочу знать, есть ли способ получить событие щелчка на кнопке «Купить», не нажимая ее, если есть объект, перекрывающий кнопку. Нажатие кнопки не выполняется при наличии перекрывающихся объектов в тестере или в реальном режиме.

Помогите мне исправить это, пожалуйста.

 
jaffer wilson:

Я нажал кнопку, и она работала хорошо. Но когда я нажимаю на поле редактирования, иногда оно вызывает событие кнопки и печатает сообщение «Купить кликнул». Но я не нажимал.

Проблема в этом участке кода:

if(id == CHARTEVENT_OBJECT_CLICK)
     {
      if(sparam == name_append + "buy")
        {
         Print("Buy Clicked");
         ObjectSetInteger(0, name_append + "buy", OBJPROP_STATE, false);
        }
     }
   else
     {
      if(
         Buy_Coords[0][0] <= lparam && lparam <= Buy_Coords[1][0] &&
         Buy_Coords[0][1] <= dparam && dparam <= Buy_Coords[1][1]
      )
        {
         Print("Buy Clicked");
        }

     }

Во-первых, блок else будет срабатывать при любом событии графика, отличном от CHARTEVENT_OBJECT_CLICK. То есть уже на этом этапе следует еще раз определить тип полученного события. В данном случае это CHARTEVENT_CLICK.

Во-вторых, проверка координат клика неправильная. Там везде знаки <=. Половина из них должна быть >=.

 
Ihor Herasko # :

Проблема в этом участке кода:

Во-первых, блок else будет срабатывать при любом событии графика, отличном от CHARTEVENT_OBJECT_CLICK. То есть уже на этом этапе следует еще раз определить тип полученного события. В данном случае это CHARTEVENT_CLICK .

Во-вторых, проверка координат клика неправильная. Там везде знаки <=. Половина из них должна быть >=.

Пожалуйста, не могли бы вы изменить мой пример и проверить его один раз. Потому что я думаю, что знаки верны.

 
Есть ли решение моей проблемы? Я все еще жду.
 
jaffer wilson #:
Есть ли решение моей проблемы? Я все еще жду.

Я ведь указал на вариант решения...

Сделал вот так и никаких проблем нет:

void OnTimer()
  {
   if(ObjectGetInteger(0, name_append + "buy", OBJPROP_STATE) == true)
     {
           Print(__FUNCTION__, ", Buy Clicked");
      ObjectSetInteger(0, name_append + "buy", OBJPROP_STATE, false);
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnChartEvent(const int       id,       // event ID
                  const long&     lparam,   // long type event parameter
                  const double&   dparam,   // double type event parameter
                  const string&   sparam    // string type event parameter
                 )
  {
   if(id == CHARTEVENT_OBJECT_CLICK)
     {
      if(sparam == name_append + "buy")
        {
              Print(__FUNCTION__, ", Buy Clicked, id: ", id);
         ObjectSetInteger(0, name_append + "buy", OBJPROP_STATE, false);
        }
     }
     
   if(id == CHARTEVENT_CLICK)
     {
      Print("lparam: ", lparam, ", dparam: ", dparam, ", x0: ", Buy_Coords[0][0], ", x1: ", Buy_Coords[1][0], ", y0: ", Buy_Coords[0][1], ", y1: ", Buy_Coords[1][1]);
      if(
         Buy_Coords[0][0] <= lparam && lparam <= Buy_Coords[1][0] &&
         Buy_Coords[0][1] <= dparam && dparam <= Buy_Coords[1][1]
      )
              Print(__FUNCTION__, ", Buy Clicked, id: ", id);

     }
  }

Заметьте, что еще добавил в распечатку имя функции, из которой происходит вывод сообщения в лог. Это поможет понять, где именно происходит ложное срабатывание, если оно все еще имеет место быть. По крайней мере, мне не удается вызвать ложное сообщение о клике на кнопку.

P. S. Скорее всего, в полном коде Вы используете слежение за перемещением мыши (CHART_EVENT_MOUSE_MOVE=true). В этом случае как раз и происходит ложное срабатывание, т. к. тип события дополнительно не проверен.
 
Ihor Herasko # :

Я ведь указал на вариант решения...

Сделал вот так и никаких проблем нет:

Заметьте, что еще добавил в распечатку имя функции, из которой происходит вывод сообщения в лог. Это поможет понять, где именно происходит ложное срабатывание, если оно все еще имеет место быть. По крайней мере, мне не удается вызвать ложное сообщение о клике на кнопку.

P. S. Скорее всего, в полном коде Вы используете слежение за перемещением мыши (CHART_EVENT_MOUSE_MOVE=true). В этом случае как раз и происходит ложное срабатывание, т. к. тип события дополнительно не проверен.

Спасибо за обновление. Я обязательно отмечу это и применю к своему коду.