Hello Alberto .
You can manage those events separately ,they dont need to happen at the same time.
Here is an example :
//+------------------------------------------------------------------+ //| CTRL_AND_MOUSE.mq5 | //| 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" #define KEY_CTRL 17 //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ struct mouse_controller { bool LeftButtonIsPressed,RightButtonIsPressed,MouseScrollMemory,UseMouseScrollMemory,UseClickLimiter; bool LeftButtonWasPressed,RightButtonWasPressed; int x,y,pre_x,pre_y; string c,pre_c; uint last_click_event,last_event,ClickLimiterLimit; mouse_controller(void){ reset(true,true,true);UseMouseScrollMemory=false;UseClickLimiter=false; ClickLimiterLimit=0; } void reset(bool reset_coordinates, bool reset_strings, bool reset_buttons){ if(reset_coordinates){x=-1;y=-1;pre_x=-1;pre_y=-1;} if(reset_strings){c=NULL;pre_c=NULL;} if(reset_buttons){LeftButtonIsPressed=false;RightButtonIsPressed=false;MouseScrollMemory=false;LeftButtonWasPressed=false;RightButtonWasPressed=false;} } void propagate(){pre_x=x;pre_y=y;pre_c=c;RightButtonWasPressed=RightButtonIsPressed;LeftButtonWasPressed=LeftButtonIsPressed;} bool is_it_still_limited(uint now,uint last,uint limit,bool setting){ if(setting){ int elapsed=(int)(now-last); if(now<last){elapsed=(int)((UINT_MAX+now)-last);} if((uint)elapsed<=limit){return(false);} } return(true); } void set_scroll_memory(bool new_setting){UseMouseScrollMemory=new_setting;} void set_click_limiter(bool new_setting,uint new_limit){UseClickLimiter=new_setting;ClickLimiterLimit=new_limit;} void process_events(const int &id,const long &lparam,const double &dparam,const string &sparam){ if(id==CHARTEVENT_MOUSE_MOVE){ last_event=GetTickCount(); propagate(); x=(int)lparam; y=(int)dparam; c=sparam; if(c=="0"){LeftButtonIsPressed=false;RightButtonIsPressed=false;} else if(c=="1"){LeftButtonIsPressed=true;RightButtonIsPressed=false;} else if(c=="2"){LeftButtonIsPressed=false;RightButtonIsPressed=true;} else if(c=="3"){LeftButtonIsPressed=true;RightButtonIsPressed=true;} //if something new if(c!=pre_c){ last_click_event=GetTickCount(); //if new button and scroll memory if(UseMouseScrollMemory){ //release , release scroll memory if(c=="0"){if(MouseScrollMemory){ChartSetInteger(ChartID(),CHART_MOUSE_SCROLL,true);MouseScrollMemory=false;}} else {MouseScrollMemory=(bool)ChartGetInteger(ChartID(),CHART_MOUSE_SCROLL);if(MouseScrollMemory){ChartSetInteger(ChartID(),CHART_MOUSE_SCROLL,false);}} } //if new button and scroll memory ends here } //if something new ends here } } }; mouse_controller MC; int OnInit() { //--- create timer MC.set_scroll_memory(true); ChartSetInteger(ChartID(),CHART_EVENT_MOUSE_MOVE,true); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- } //+------------------------------------------------------------------+ //| ChartEvent function | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { //--- MC.process_events(id,lparam,dparam,sparam); if(id==CHARTEVENT_KEYDOWN) { if (int(lparam)==KEY_CTRL) { if(MC.LeftButtonIsPressed){Print("pundix is rising and you bought");} else if(!MC.LeftButtonIsPressed){Print("you forgot to buy pundix");} } } } //+------------------------------------------------------------------+there may be issues as im low on caffeinne
Simpliest way is via WinAPI GetAsyncKeyState() - see Ctrl + left click example:
#import "user32.dll" int GetKeyState(int nVirtKey); // GetKeyState() checks if the key was pressed at the same time as the WM_KEYDOWN message came, GetAsyncKeyState() checks if it is still down. short GetAsyncKeyState(int nVirtKey); #import int VK_CONTROL = 0x11; // https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes void OnChartEvent(const int id, // Event ID const long& lparam, // Parameter of type long event const double& dparam, // Parameter of type double event const string& sparam // Parameter of type string events ) { if (id==CHARTEVENT_CLICK) { PrintFormat("Mouse click: x = %d y = %.1f", lparam, dparam); datetime dt; double price; int window = 0; if (ChartXYToTimePrice(0, (int)lparam, (int)dparam, window, dt, price)) { // TerminalInfoInteger(TERMINAL_KEYSTATE_XXX) returns the same state code of a key as the GetKeyState() function in MSDN // not working properly after MessageBoax has been shown! double controlKeyState = TerminalInfoInteger(TERMINAL_KEYSTATE_CONTROL); short asyncKeyState = GetAsyncKeyState(VK_CONTROL); PrintFormat("Price = %s, date = %s, Control key state: %s, GetAsyncKeyState(): %d", DoubleToStr(price, _Digits), TimeToStr(dt), DoubleToStr(controlKeyState), asyncKeyState); if (asyncKeyState < 0) { //Print("Ctrl+Click"); // Warning! MessageBox(...) freezes control state! MessageBox("Ctrl+Click"); //OpenOrder(price); return; } } else { Print("ChartXYToTimePrice return error code: ", GetLastError()); } }

Virtual-Key Codes (Winuser.h) - Win32 apps
- 2020.12.12
- Karl-Bridge-Microsoft
- docs.microsoft.com
The following table shows the symbolic constant names, hexadecimal values, and mouse or keyboard equivalents for the virtual-key codes used by the system. The codes are listed in numeric order.

You are missing trading opportunities:
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
Registration
Log in
You agree to website policy and terms of use
If you do not have an account, please register
Hello,
i would like to do a specific action (like an OrderSend or others) when i press CONTROL with the LEFT MOUSE BUTTON down. I am able to use CHARTEVENT_KEYDOWN and CHARTEVENT_CLICK separatly but not togheter.
This doesn't works:
#define KEY_CTRL 17
if(id==CHARTEVENT_KEYDOWN)
{
if (int(lparam)==KEY_CTRL)
{
if (id==CHARTEVENT_CLICK) DO SOMETHING
I hope that what i wrote is clear enough (sry for my english)
Anyone wanna help me pls?
Thanks
Alberto