Hotkey programming to turn on/off the indicator

 

Hi,

I found this link on how to use hotkey programming.  I further use the hotkey to turn on/off the display of VLINE for US/UK session on hourly or below chart.  See code:

It works but 2 issues:

a.  After pressing Ctrl-J, I have to shift the screen using mouse in order to view the vLine.

b1.  I have to press Ctrl-J two times to display all 5 vLines.  The 1st Ctrl-J displays only sTime[0-3] and the next Ctrl-J displays sTime[4].

b2.  likewise, I also have to press Ctrl-Q two times to turn off the 5 vlines.

Pls advise!

Regards,

Toyogo

//+------------------------------------------------------------------+

//|                                            DisplaySession.mq5 |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "2014"
#property link      "http://www.mql5.com"

#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots   1
#define   TimeSession       5

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+

static string name3[TimeSession];
static datetime sTime[TimeSession];

void OnInit() {
   datetime lTime = TimeCurrent();
   MqlDateTime ldate;
   TimeToStruct(lTime,ldate);

   name3[0] = "LNSessionStart";  // the server time is based on US close.  i.e. UTC+2
   name3[1] = "LNSessionEnd";
   name3[2] = "USSessionStart";
   name3[3] = "USSessionEnd";
   name3[4] = "MTSessionStart";
   sTime[0] = StringToTime(IntegerToString(ldate.year)+"."+IntegerToString(ldate.mon)+"."+IntegerToString(ldate.day)+" 10:00");  //LN start
   sTime[1] = StringToTime(IntegerToString(ldate.year)+"."+IntegerToString(ldate.mon)+"."+IntegerToString(ldate.day)+" 18:00");  //LN End 
   sTime[2] = StringToTime(IntegerToString(ldate.year)+"."+IntegerToString(ldate.mon)+"."+IntegerToString(ldate.day)+" 15:00");  //US start
   sTime[3] = StringToTime(IntegerToString(ldate.year)+"."+IntegerToString(ldate.mon)+"."+IntegerToString(ldate.day)+" 23:00");  //US End
   sTime[4] = StringToTime(IntegerToString(ldate.year)+"."+IntegerToString(ldate.mon)+"."+IntegerToString(ldate.day)+" 00:00");  //MT Start
}

void OnDeinit(const int reason) {
  int x;
  for (x=0; x<TimeSession; x++) {
    if (ObjectFind(0,name3[x]) != -1) ObjectDelete(0,name3[x]);
  }
}

static bool ctrl_pressed = false;

void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
{
   int x;
   ENUM_TIMEFRAMES cTime;

   if (id == CHARTEVENT_KEYDOWN) {
      if (ctrl_pressed == false && lparam == 17)  // Ctrl key pressed
         ctrl_pressed = true;
      else if (ctrl_pressed == true) {
         if (lparam == 74) {         //Ctrl-J to activate DispSession
            cTime=Period(); 
            if (cTime == PERIOD_H1 || cTime == PERIOD_M30 || cTime == PERIOD_M15 || cTime == PERIOD_M5) {
               for (x=0; x<TimeSession; x++) {
                  if (ObjectFind(0,name3[x]) != -1) ObjectDelete(0,name3[x]);
                  ObjectCreate(0,name3[x],OBJ_VLINE,0,sTime[x],0);          
                  ObjectSetInteger(0,name3[x],OBJPROP_COLOR,Aqua);
                  ObjectSetInteger(0,name3[x],OBJPROP_STYLE,STYLE_DOT);
                  ObjectSetInteger(0,name3[x],OBJPROP_WIDTH,1);
                  ObjectSetInteger(0,name3[x],OBJPROP_RAY,false);
                  ObjectSetInteger(0,name3[x],OBJPROP_BACK,true);
               }
            }
            ctrl_pressed = false;
         } else if (lparam == 81) {  //Ctrl-Q to deactivate DispSession
            for (x=0; x<TimeSession; x++) {
               if (ObjectFind(0,name3[x]) != -1) ObjectDelete(0,name3[x]);
            }
            ctrl_pressed = false;
         }
      }
   }
}

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(rates_total);
}

Automated Trading and Strategy Testing
Automated Trading and Strategy Testing
  • www.mql5.com
MQL5: language of trade strategies built-in the MetaTrader 5 Trading Platform, allows writing your own trading robots, technical indicators, scripts and libraries of functions
 

Next time, please use SRC button when you post code. I edited it for you.

From my experience CHARTEVENT_KEYDOWN isn't reliable to detect key combination inputs.

Your code works well if you press <Ctrl+J>, then release all, then press <Ctrl+Q>, then release all... But normal behavior (in any Windows program) like pressing <Ctrl> then <J>, releasing J key, then press <Q>, all of that keeping <Ctrl> pressed, doesn't work and can't be detected.

I already report this to ServiceDesk (#826140), but without success, their reply was :

You should analyze the value of the sparam for event CHARTEVENT_KEYDOWN as it said in MSDN (http://msdn.microsoft.com/en-us/library/983st27a%28v=vs.90%29.aspx)

Event

Value of the id parameter

Value of the lparam parameter

Value of the dparam parameter

Value of the sparam parameter

Event of a keystroke

CHARTEVENT_KEYDOWN

code of a pressed key

Repeat count (the number of times the keystroke is repeated as a result of the user holding down the key)

The string value of a bit mask describing the status of keyboard buttons

But I can't find a way to have it working well. So my opinion is that there is no reliable way to detect correctly combination of keys input. I would be happy if some can demonstrate that I am wrong.

CWnd::OnKeyDown
CWnd::OnKeyDown
  • msdn.microsoft.com
A nonsystem key is a keyboard key that is pressed when the ALT key is not pressed or a keyboard key that is pressed when CWnd has the input focus. Because of auto-repeat, more than one OnKeyDown call may occur before an OnKeyUp member function call is made. The bit that indicates the previous key state can be used to determine whether the...
 
angevoyageur:

Next time, please use SRC button when you post code. I edited it for you.

From my experience CHARTEVENT_KEYDOWN isn't reliable to detect key combination inputs.

Your code works well if you press <Ctrl+J>, then release all, then press <Ctrl+Q>, then release all... But normal behavior (in any Windows program) like pressing <Ctrl> then <J>, releasing J key, then press <Q>, all of that keeping <Ctrl> pressed, doesn't work and can't be detected.

I already report this to ServiceDesk (#826140), but without success, their reply was :

But I can't find a way to have it working well. So my opinion is that there is no reliable way to detect correctly combination of keys input. I would be happy if some can demonstrate that I am wrong.

Hi,

Noted on the SRC button.  The detection of <Ctrl+J> is quite reliable so far.  see the test program link .    The issue is the execution of code inside the <Ctrl+J> is not done properly.

Regards,

Toyogo

 
toyogo00:

Hi,

Noted on the SRC button.  The detection of <Ctrl+J> is quite reliable so far.  see the test program link .    The issue is the execution of code inside the <Ctrl+J> is not done properly.

Regards,

Toyogo

Nope. I tried your code and it's working well. If use press <Ctrl+J> all 5 lines are displayed, if I press <Ctrl+Q> all 5 lines are removed.

The detection of <Ctrl+J> isn't always reliable. If I press <Ctrl> and keep it pressed, then I press <Q>, lines are removed, if I then press <J>, lines are not displayed. <Ctrl+J> is not detected. Anyway, it's probably not related to your issue, and I understand that it's sufficiently reliable for your need.

Reason: