How can I use two chart events at the same time (CHARTEVENT_KEYDOWN and CHARTEVENT_CLICK)?

 

Hi forum,

I want a vertical line to be drawn if I press (and hold) the s-key and click on a candle. But that doesn't work the way I tried it. I know that this is not correct because there can't be a CHARTEVENT_KEYDOWN and a CHARTEVENT_CLICK at the same time. But how can I check if the s-key was and is still pressed when the CHARTEVENT_CLICK occurs? I guess it has to do with the bit mask describing the status of keyboard buttons (SPARAM) but I have no idea how to handle it. When I print the SPARAM value after pressing the key, it is always 31. I don't know what that means and there is no description of this parameter how to use it.

Can someone help me with that? Thanks in advance! 

//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//---
   if (id==CHARTEVENT_KEYDOWN) {
      if (lparam == 'S' || lparam == 's') {
         if (id==CHARTEVENT_CLICK) {
            int x=(int)lparam; 
            int y=(int)dparam;
            datetime dt=0; 
            double price=0; 
            int window=0; 
            if(ChartXYToTimePrice(0,x,y,window,dt,price)) {
               if (price<=High[iBarShift(NULL, 0, dt)] && price>=Low[iBarShift(NULL, 0, dt)]) {
                  ObjectCreate(0, "VLINE", OBJ_VLINE, 0, dt, 0);
               }
            }
         }
      }
   }
  }
 

I just found out that if I keep on pressing the s-key that the sparam changes after a short while to 16415. So I guess the bit mask changed and this means that the key was pressed and is still hold. But nevertheless I can't use CHARTEVENT_CLICK to determine the mouse-position because the CHARTEVENT_KEYDOWN is still active. So I am sure that I have to check one after the other but how? I tried this version but it still has no effect:

//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//---
   if (id==CHARTEVENT_KEYDOWN) {
      if (lparam == 'S' || lparam == 's') {
         if (sparam==16415) keyPressed=true;
         else keyPressed=false;
      }
   }
   if (id==CHARTEVENT_CLICK && keyPressed) {
      int x=(int)lparam; 
      int y=(int)dparam;
      datetime dt=0; 
      double price=0; 
      int window=0; 
      if(ChartXYToTimePrice(0,x,y,window,dt,price)) {
         if (price<=High[iBarShift(NULL, 0, dt)] && price>=Low[iBarShift(NULL, 0, dt)]) {
            ObjectCreate(0, "VLINE", OBJ_VLINE, 0, dt, 0);
         }
      }
   }
  }
 
   static bool keyPressed=false
   
   if (id==CHARTEVENT_KEYDOWN) {
      if (lparam == 'S' || lparam == 's') {
         if (!keyPressed) keyPressed=true;
         else keyPressed=false;
      }
   }

I think that you just need to change as highlighted

Edit: I should have said that by pressing and releasing the s key once , you can then click on the chart to draw the line.

Then press s again to prevent new lines being drawn at every click on the chart.

You may decide to add an extra bit of code to put a label on the chart to warn that the key has been pressed and delete it with the second key press 

 
GumRai:
I think that you just need to change as highlighted
I am afraid he is rather missing a key up event.
 

Unfortunately, it doesn't work this way, GumRai. I think Ovo is correct. There is no key up event and I have no idea how to handle that because there is no such function in MT4.

Right now I found another solution. I use CHARTEVENT_MOUSE_MOVE first, store the data and if a key is pressed then, the lines are printed. So exactly vice versa. Works very good.

But nevertheless I am very interested how to program it by first pressing and holding a key and then check for a click. 

 

Sorry, I have edited my post as the code won't work with a press and hold.

More a press - click - press 

 

No problem :)

I think to do it correctly, the Win32 functions have to be used. Like I wrote, I solved it the other way round and it works pretty good for me.

Reason: