How to recognize ctrl+ Mouse left Click ?

 

Hi 
I'm trying to recognize the ctrl+mouse left click.

When I press ctrl the ID is CHARTEVENT_KEYDOWN and the sparam is 29

if I hold the ctrl down the ID remains the same but the sparam is 16413, which I think this is what I need to use.

I also know that the mouse left click id is CHARTEVEN_CLICK with no sparam (I guess). 


But as the events come one by one, I can't get ctrl+ Click.

Is there a way to recognize such action?


Regards

 

Well, by reading the links mql5 automatically added at the bottom of my post, I figured out that there is no direct answer for this question.
Then I will try to find another way to have the same result.
Maybe I measure the time difference between the last key-down (sparam 16413) and the click event, so if it was the minimum time interval like 20 millisecond or less + the event after the click was still the Ctrl, then I can do what I want to do.
Maybe some other idea.

Any suggestion would be appreciated.

BTW, if there is any 

 

Hello ,

there is a direct answer to your question . 

Let me know if you have any questions

//+------------------------------------------------------------------+
//|                                            control_and_mouse.mq4 |
//|                        Copyright 2020, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
struct keycode
{
long L;
double D;
string S;
bool Armed;
uint ArmedMS;
uint MSForValidHit;
keycode(void){L=0;D=0;S="Honolulu";Disarm();}
keycode(int l,double d,string s,uint milliseconds_delay){L=l;D=d;S=s;MSForValidHit=milliseconds_delay;Disarm();}
void Disarm(){Armed=false;ArmedMS=0;}
void Arm(){Armed=true;ArmedMS=GetTickCount();}
bool IsArmed(){if(Armed){CheckTimer();}return(Armed);}
void CheckTimer()
     {
     uint nowms=GetTickCount()-ArmedMS;
     if(nowms>MSForValidHit){Armed=false;Print("CTRL :: Disarmed");}
     }
void CheckMe(long lparam,double dparam,string sparam)
     {
     if(Armed&&(S!=sparam||D!=dparam||L!=lparam)){Disarm();Print("CTRL :: Disarmed");}
     if(S!="Honolulu"&&S==sparam&&D==dparam&&L==lparam){Arm();Print("CTRL :: Armed");}
     }
};
//setup a button 
keycode CTRL(17,1,"16413",1200);


int OnInit()
  {
  CTRL.Disarm();
  //ChartSetInteger(ChartID(),CHART_EVENT_MOUSE_MOVE,true); 

   return(INIT_SUCCEEDED);
  }

void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
  if(id==CHARTEVENT_KEYDOWN) CTRL.CheckMe(lparam,dparam,sparam);
  if(id==CHARTEVENT_CLICK&&CTRL.IsArmed()){Alert("CTRL + CLICK");CTRL.Disarm();}
  }

 
Lorentzos Roussos:

Hello ,

there is a direct answer to your question . 

Let me know if you have any questions

Thank you very much Lorentzos Roussos .


I'm happy you shared this interesting codes, not just because I can get the answer for my question, but also the way you wrote the code had a lot to learn for me. 

I understood all of it, and enjoyed learning your codes.


Thank you very much.

 
Reza nasimi:

Thank you very much Lorentzos Roussos .


I'm happy you shared this interesting codes, not just because I can get the answer for my question, but also the way you wrote the code had a lot to learn for me. 

I understood all of it, and enjoyed learning your codes.


Thank you very much.

Enjoy :) 

 
Lorentzos Roussos:

Enjoy :) 

very helpfull, how about shift+click or alt+click ? can you tell the the code here, thanks
 
arief ace:
very helpfull, how about shift+click or alt+click ? can you tell the the code here, thanks

Thank you , I have not tried Alt as it is enabling the menus on the title bar of MT

Compile this utility (expert advisor) ,plug it in the chart and it will give you all the codes for what you press.

#property strict
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
string system_tag="key_tests_";
long cLong=68,oLong=-1;
double cDouble=1,oDouble=-1;
string cString="32",oString="-1";
bool key_know_previous=false;
string key_previous_name="";
int OnInit()
  {
//---
  key_know_previous=false;
  ObjectsDeleteAll(0,system_tag);
  HS_Create_Rectangle_Label(0,0,system_tag+"_back",400,110,10,10,C'60,60,60',clrAliceBlue,BORDER_FLAT,false,false);
  HS_Create_Edit(0,0,system_tag+"_keyname",300,20,15,20,"Arial",10,clrBlack,clrBlack,BORDER_RAISED,clrOrange,ALIGN_CENTER,"L : 68",false,false,false);  
  HS_Create_Edit(0,0,system_tag+"_data",380,20,20,80,"Arial",8,clrDarkBlue,clrDarkBlue,BORDER_FLAT,clrYellow,ALIGN_CENTER,"data",false,true,false);
  UpdateSystem(-1,-1,"-1",false,"");
//---
   return(INIT_SUCCEEDED);
  }
  
void UpdateSystem(long hLong,double hDouble,string hString,bool know_previous,string previous_name)
{
  keyFinder Name=FindKeyName(hLong,hDouble,hString,know_previous,previous_name);
  if(Name.KeyName!="NOKEY"){key_know_previous=true;key_previous_name=Name.KeyName;}
  ObjectSetString(0,system_tag+"_keyname",OBJPROP_TEXT,Name.Display);  
  string data="L : "+hLong+" D : "+hDouble+" S : "+hString;
  ObjectSetString(0,system_tag+"_data",OBJPROP_TEXT,data);  
  oLong=hLong;
  oDouble=hDouble;
  oString=hString;
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
  ObjectsDeleteAll(0,system_tag); 
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   
  }
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//---
    if(id==CHARTEVENT_KEYDOWN)
    {
    UpdateSystem(lparam,dparam,sparam,key_know_previous,key_previous_name);
    } 
  }
//+------------------------------------------------------------------+
//CREATE RECTANGLE LABEL
  void HS_Create_Rectangle_Label(long cid,
                     int subw,
                     string name,
                     int sx,
                     int sy,
                     int px,
                     int py,
                     color bck_col,
                     color brd_col,
                     ENUM_BORDER_TYPE brd_type,
                     bool selectable,
                     bool back)  
  {
  bool obji=ObjectCreate(cid,name,OBJ_RECTANGLE_LABEL,subw,0,0);
  if(obji)
    {
    ObjectSetInteger(0,name,OBJPROP_XSIZE,sx);
    ObjectSetInteger(0,name,OBJPROP_YSIZE,sy);
    ObjectSetInteger(0,name,OBJPROP_XDISTANCE,px);
    ObjectSetInteger(0,name,OBJPROP_YDISTANCE,py);
    ObjectSetInteger(0,name,OBJPROP_BGCOLOR,bck_col);
    ObjectSetInteger(0,name,OBJPROP_BORDER_COLOR,brd_col);
    ObjectSetInteger(0,name,OBJPROP_COLOR,brd_col);
    ObjectSetInteger(0,name,OBJPROP_BORDER_TYPE,brd_type);
    ObjectSetInteger(0,name,OBJPROP_SELECTABLE,selectable);
    ObjectSetInteger(0,name,OBJPROP_BACK,back);
    }
  }                   
//CREATE RECTANGLE LABEL OBJECT ENDS HERE 




//CREATE BTN OBJECT
  void HS_Create_Btn(long cid,
                     int subw,
                     string name,
                     int sx,
                     int sy,
                     int px,
                     int py,
                     string font,
                     int fontsize,
                     color bck_col,
                     color brd_col,
                     ENUM_BORDER_TYPE brd_type,
                     color txt_col,
                     ENUM_ALIGN_MODE align,
                     string text,
                     bool selectable,
                     bool back)  
  {
  bool obji=ObjectCreate(cid,name,OBJ_BUTTON,subw,0,0);
  if(obji)
    {
    ObjectSetString(0,name,OBJPROP_FONT,font);
    ObjectSetInteger(0,name,OBJPROP_ALIGN,align);
    ObjectSetInteger(0,name,OBJPROP_FONTSIZE,fontsize);
    ObjectSetInteger(0,name,OBJPROP_XSIZE,sx);
    ObjectSetInteger(0,name,OBJPROP_YSIZE,sy);
    ObjectSetInteger(0,name,OBJPROP_XDISTANCE,px);
    ObjectSetInteger(0,name,OBJPROP_YDISTANCE,py);
    ObjectSetInteger(0,name,OBJPROP_BGCOLOR,bck_col);
    ObjectSetInteger(0,name,OBJPROP_BORDER_COLOR,brd_col);
    ObjectSetInteger(0,name,OBJPROP_COLOR,txt_col);
    ObjectSetInteger(0,name,OBJPROP_BORDER_TYPE,brd_type);
    ObjectSetInteger(0,name,OBJPROP_SELECTABLE,selectable);
    ObjectSetInteger(0,name,OBJPROP_BACK,back);
    ObjectSetString(0,name,OBJPROP_TEXT,text);
    }
  }                   
//CREATE BTN OBJECT ENDS HERE 

//CREATE INPUT OBJECT
  void HS_Create_Edit(long cid,
                     int subw,
                     string name,
                     int sx,
                     int sy,
                     int px,
                     int py,
                     string font,
                     int fontsize,
                     color bck_col,
                     color brd_col,
                     ENUM_BORDER_TYPE brd_type,
                     color txt_col,
                     ENUM_ALIGN_MODE align,
                     string text,
                     bool selectable,
                     bool readonly,
                     bool back)  
  {
  bool obji=ObjectCreate(cid,name,OBJ_EDIT,subw,0,0);
  if(obji)
    {
    ObjectSetString(0,name,OBJPROP_FONT,font);
    ObjectSetInteger(0,name,OBJPROP_ALIGN,align);
    ObjectSetInteger(0,name,OBJPROP_FONTSIZE,fontsize);
    ObjectSetInteger(0,name,OBJPROP_XSIZE,sx);
    ObjectSetInteger(0,name,OBJPROP_YSIZE,sy);
    ObjectSetInteger(0,name,OBJPROP_XDISTANCE,px);
    ObjectSetInteger(0,name,OBJPROP_YDISTANCE,py);
    ObjectSetInteger(0,name,OBJPROP_BGCOLOR,bck_col);
    ObjectSetInteger(0,name,OBJPROP_BORDER_COLOR,brd_col);
    ObjectSetInteger(0,name,OBJPROP_COLOR,txt_col);
    ObjectSetInteger(0,name,OBJPROP_BORDER_TYPE,brd_type);
    ObjectSetInteger(0,name,OBJPROP_SELECTABLE,selectable);
    ObjectSetInteger(0,name,OBJPROP_READONLY,readonly);
    ObjectSetInteger(0,name,OBJPROP_BACK,back);
    ObjectSetString(0,name,OBJPROP_TEXT,text);
    }
  }                   
//CREATE BTN OBJECT ENDS HERE 


//find key name based on code 
struct keyFinder
{
string KeyName;
string Display;
keyFinder(void){KeyName="NOKEY";Display="UNMAPPED";}
void set(string keyname,string display){KeyName=keyname;Display=display;}
};
keyFinder FindKeyName(long L,double D,string S,bool know_previous,string previous_name)
{
keyFinder result;
long SL=StringToInteger(S);
long hold_limit=10000;

if(L==17&&SL<100){result.set("LEFT CONTROL","LEFT CONTROL");return(result);}
if(L==17&&SL>100&&SL<hold_limit){result.set("RIGHT CONTROL","RIGHT CONTROL");return(result);}
if(L==16&&SL<50&&SL<hold_limit){result.set("LEFT SHIFT","LEFT SHIFT");return(result);}
if(L==16&&SL>50&&SL<hold_limit){result.set("RIGHT SHIFT","RIGHT SHIFT");return(result);}
if(L==32&&SL<hold_limit){result.set("SPACEBAR","SPACEBAR");return(result);}
if(L==13&&SL<hold_limit&&SL<100){result.set("ENTER","ENTER");return(result);}
if(L==9&&SL<hold_limit){result.set("TAB","TAB");return(result);}
if(L==20&&SL<hold_limit){result.set("CAPS LOCK","CAPS LOCK");return(result);}

if(L==45&&SL<hold_limit){result.set("INSERT","INSERT");return(result);}
if(L==36&&SL<hold_limit){result.set("HOME","HOME");return(result);}
if(L==33&&SL<hold_limit){result.set("PAGE UP","PAGE UP");return(result);}
if(L==34&&SL<hold_limit){result.set("PAGE DOWN","PAGE DOWN");return(result);}
if(L==35&&SL<hold_limit){result.set("END","END");return(result);}
if(L==46&&SL<hold_limit){result.set("DELETE","DELETE");return(result);}

if(L==38&&SL<hold_limit){result.set("UP","UP");return(result);}
if(L==40&&SL<hold_limit){result.set("DOWN","DOWN");return(result);}
if(L==37&&SL<hold_limit){result.set("LEFT","LEFT");return(result);}
if(L==39&&SL<hold_limit){result.set("RIGHT","RIGHT");return(result);}

if(L==144&&SL<hold_limit){result.set("NUM LOCK","NUM LOCK");return(result);}
if(L==111&&SL<hold_limit){result.set("NUM PAD /","NUM PAD /");return(result);}
if(L==106&&SL<hold_limit){result.set("NUM PAD *","NUM PAD *");return(result);}
if(L==109&&SL<hold_limit){result.set("NUM PAD -","NUM PAD -");return(result);}
if(L==107&&SL<hold_limit){result.set("NUM PAD +","NUM PAD +");return(result);}
if(L==13&&SL<hold_limit&&SL>100){result.set("NUM PAD ENTER","NUM PAD ENTER");return(result);}
if(L==110&&SL<hold_limit){result.set("NUM PAD ,","NUM PAD ,");return(result);}
if(L==96&&SL<hold_limit){result.set("NUM PAD 0","NUM PAD 0");return(result);}
if(L==97&&SL<hold_limit){result.set("NUM PAD 1","NUM PAD 1");return(result);}
if(L==98&&SL<hold_limit){result.set("NUM PAD 2","NUM PAD 2");return(result);}
if(L==99&&SL<hold_limit){result.set("NUM PAD 3","NUM PAD 3");return(result);}
if(L==100&&SL<hold_limit){result.set("NUM PAD 4","NUM PAD 4");return(result);}
if(L==101&&SL<hold_limit){result.set("NUM PAD 5","NUM PAD 5");return(result);}
if(L==102&&SL<hold_limit){result.set("NUM PAD 6","NUM PAD 6");return(result);}
if(L==103&&SL<hold_limit){result.set("NUM PAD 7","NUM PAD 7");return(result);}
if(L==104&&SL<hold_limit){result.set("NUM PAD 8","NUM PAD 8");return(result);}
if(L==105&&SL<hold_limit){result.set("NUM PAD 9","NUM PAD 9");return(result);}

if(L==145&&SL<hold_limit){result.set("SCROLL LOCK","SCROLL LOCK");return(result);}

if(L==188&&SL<hold_limit){result.set("<","<");return(result);}
if(L==190&&SL<hold_limit){result.set(">",">");return(result);}
if(L==191&&SL<hold_limit){result.set("?","?");return(result);}
if(L==186&&SL<hold_limit){result.set(":",":");return(result);}
if(L==222&&SL<hold_limit){result.set("'","'");return(result);}
if(L==220&&SL<hold_limit){result.set("\\","\\");return(result);}
if(L==219&&SL<hold_limit){result.set("[","[");return(result);}
if(L==221&&SL<hold_limit){result.set("]","]");return(result);}
if(L==189&&SL<hold_limit){result.set("-","-");return(result);}
if(L==187&&SL<hold_limit){result.set("+","+");return(result);}
if(L==192&&SL<hold_limit){result.set("~","~");return(result);}


//if it comes here none of the above were valid 
if(SL<hold_limit&&L>=0&&D>=0&&SL>=0)
{
string fi=CharToString((uchar)L);
result.set(fi,fi);return(result);
}

if(know_previous&&SL>hold_limit){result.set(previous_name,"HELD "+previous_name);return(result);}

return(result);
}
//find key name based on code ends here
 
Lorentzos Roussos:

Thank you , I have not tried Alt as it is enabling the menus on the title bar of MT

Compile this utility (expert advisor) ,plug it in the chart and it will give you all the codes for what you press.

wonderful job! thank very much Lorentzos..
 
arief ace:
wonderful job! thank very much Lorentzos..

Thank you Ace

 
Lorentzos Roussos:

Hello ,

there is a direct answer to your question . 

Let me know if you have any questions

Hi Lorentzos, can you tell me what styler you use please? if the you use any.

Thanks

 
Reza nasimi:

Hi Lorentzos, can you tell me what styler you use please? if the you use any.

Thanks

I dont use a styler actually

Reason: