OBJ_EDIT focus

 

Hello,

I have two similar questions related to OBJ_EDIT:

1) Can I find out if the object (OBJ_EDIT) has focus (the cursor blinks inside the box) in MQL?

2) Can I set focus to an object (OBJ_EDIT) in MQL?

 
Petr Nosek:

Hello,

I have two similar questions related to OBJ_EDIT:

1) Can I find out if the object (OBJ_EDIT) has focus (the cursor blinks inside the box) in MQL?

2) Can I set focus to an object (OBJ_EDIT) in MQL?


1. Not sure, but my guess is the editable object won't accept any new value while being edited in the GUI.

2. No.

 
Ex Ovo Omnia:

1. Not sure, but my guess is the editable object won't accept any new value while being edited in the GUI.

2. No.

Thank you for your effort

Maybe we don't understand to each other. I'm not sure but I think the answer to my both questions are unfortunately "NO", but maybe I'm wrong.

To my first question:

I don't need an object to accept a new value while being edited in the GUI. I just need to find out programmatically if the object has focus or not.

To my second question:

If I create object (OBJ_EDIT) in MQL by ObjectCreate() first I have to click by mouse in this box, because the object doesn't have focus and then I can type text in the box. I would like to type text directly after creating object (without mouse clicking). Maybe the way is using function EventChartCustom(), but it won't work in Script (just in Experts and Indicators).

 
Petr Nosek:

Thank you for your effort

Maybe we don't understand to each other. I'm not sure but I think the answer to my both questions are unfortunately "NO", but maybe I'm wrong.

To my first question:

I don't need an object to accept a new value while being edited in the GUI. I just need to find out programmatically if the object has focus or not.

To my second question:

If I create object (OBJ_EDIT) in MQL by ObjectCreate() first I have to click by mouse in this box, because the object doesn't have focus and then I can type text in the box. I would like to type text directly after creating object (without mouse clicking). Maybe the way is using function EventChartCustom(), but it won't work in Script (just in Experts and Indicators).

You will need to use the WINAPI for that.

 
Alain Verleyen:

You will need to use the WINAPI for that.

It was my nightmare :D

It will be hard job without MetaTrader API documentation. I can imagine the solution of my second question this way, but not the first one.

In any case, thank you.

 
Petr Nosek:

I would like to type text directly after creating object (without mouse clicking). 


#property strict
#property indicator_chart_window
#include <Arrays\ArrayChar.mqh>
#include <ChartObjects\ChartObjectsTxtControls.mqh>
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
class CharList : public CArrayChar
{
public:
   string ToString() const { return (m_data_total <= 0 ? "" : CharArrayToString(m_data,0,m_data_total));}

   bool Add(const char element)
   {
      if(Allowed(element))
         return CArrayChar::Add(element);
      return false;
   }
protected:
   bool Allowed(char character)
   {
      static string allow = "1234567890.";
      string in = CharToString(character);
      if(in =="." && StringFind(ToString(),in) >=0 )
         return false;
      return (StringFind(allow,in) >=0);
   }
};
//+------------------------------------------------------------------+
CharList          chars;
CChartObjectEdit  edit;
//+------------------------------------------------------------------+
int OnInit()
{
   edit.Create(0,"EDIT",0,50,50,500,50);  
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
{
//---
   if(id == CHARTEVENT_KEYDOWN)
   {
      //printf("id= %d, lparam= %d, dparam= %f, sparam= %s",id,lparam,dparam,sparam);
      if(lparam == 46)//delete
         chars.Delete(chars.Total()-1);
      else
         chars.Add((char)TranslateKey(int(lparam))); 
      edit.Description(chars.ToString());     
   }
}
//+------------------------------------------------------------------+
int start(){   return(0);}
 
nicholishen:

Hi nicholishen,

Your code unfortunately does not solve my problem because object "edit" does not have focus after creating (I have to click into "edit" and then I can write text).

 
Petr Nosek:

Hi nicholishen,

Your code unfortunately does not solve my problem because object "edit" does not have focus after creating (I have to click into "edit" and then I can write text).

This code example allows you to edit the object (with rules) without focus just by typing. In this example you can only type numbers and a single decimal point...
 

Maybe I have found a solution. Below is a sample code included. This code is a script and has some limitations.

First limitation: Because of using Sleep() you can't use it in indicator.

Second limitation: If you have multiple monitors with different resolutions you have to open your MetaTrader on the primary display monitor. The function GetSystemMetrics() (used in function ConvertXY) calculates resolution of primary display monitor.

#property strict

struct POINT
  {
   int posX;   // x position
   int posY;   // y position
  };

#import "user32.dll"
   void  mouse_event(int dwFlags,int dx,int dy,int dwData,int dwExtraInfo);
   bool  ClientToScreen(int hWnd,POINT &lpPoint);
   int   GetSystemMetrics(int nIndex);
#import

#define NAME   "TMP_EDIT_FOCUS"
#define X      (50)
#define Y      (50)
#define WIDTH  (300)
#define HEIGHT (20)

void OnStart()
  {
   ObjectDelete(0,NAME);
   ResetLastError();
   if(!ObjectCreate(0,NAME,OBJ_EDIT,0,0,0))
     {
      Print(__FUNCTION__,
            ": failed to create \"Edit\" object! Error code = ",GetLastError());
      return;
     }
   ObjectSetInteger(0,NAME,OBJPROP_XDISTANCE,X);
   ObjectSetInteger(0,NAME,OBJPROP_YDISTANCE,Y);
   ObjectSetInteger(0,NAME,OBJPROP_XSIZE,WIDTH);
   ObjectSetInteger(0,NAME,OBJPROP_YSIZE,HEIGHT);
   ObjectSetInteger(0,NAME,OBJPROP_HIDDEN,false);
   ObjectSetString(0,NAME,OBJPROP_TEXT,"Object Edit with focus after creating");
   ChartRedraw();
   Sleep(100); // Wait for 0.1 second becauce of finishing Object
//--- Simulate a click inside the OBJ_EDIT to get focus
   POINT Inside=ConvertXY(int ((2*X+WIDTH)/2),int((2*Y+HEIGHT)/2));
   mouse_event(0x8007,Inside.posX,Inside.posY,0,0);
//---
   Sleep(10000); // Wait for 10 seconds
//--- Simulate a click outside the OBJ_EDIT to lose focus
   POINT Outside=ConvertXY(int ((2*X+WIDTH)/2)+WIDTH,int((2*Y+HEIGHT)/2)+HEIGHT);
   mouse_event(0x8007,Outside.posX,Outside.posY,0,0);
//---
   ChartRedraw();
   Sleep(100); // Wait for 0.1 second becauce of finishing click
   ObjectSetString(0,NAME,OBJPROP_TEXT,"In 10 seconds the object Edit will be deleted");
   ChartRedraw();
   Sleep(10000); // Wait for 10 seconds
   ObjectDelete(0,NAME);
   ChartRedraw();
  }

POINT ConvertXY(const int x,const int y)
  {
   POINT ClientPoint,AbsolutePoint;
   int screenX=GetSystemMetrics(0);
   int screenY=GetSystemMetrics(1);
   ClientToScreen(WindowHandle(_Symbol,_Period),ClientPoint);
   AbsolutePoint.posX=int ((x+ClientPoint.posX)*65535/screenX);
   AbsolutePoint.posY=int ((y+ClientPoint.posY)*65535/screenY);
   return(AbsolutePoint);
  }
 
nicholishen:
This code example allows you to edit the object (with rules) without focus just by typing. In this example you can only type numbers and a single decimal point...

I know what your code does, but this is not what I want. If you run my script you will know what I mean.

BTW You can't use your code in scripts and if you have multiple edit objects it doesn't work properly (IMHO).

 
Petr Nosek:

Maybe I have found a solution. Below is a sample code included. This code is a script and has some limitations.

First limitation: Because of using Sleep() you can't use it in indicator.

Second limitation: If you have multiple monitors with different resolutions you have to open your MetaTrader on the primary display monitor. The function GetSystemMetrics() (used in function ConvertXY) calculates resolution of primary display monitor.

It doesn't click inside the EDIT object on my side.

Reason: