mql4 dragging event on chart
Try this , its commented out , if you use a translator it may mess up the code so be careful .
Cheers .
#property version "1.00" #property strict #property indicator_chart_window /* from what i understand you want the rectangle to be on the chart . where else would it be though so you need : a.a trigger to let the system know the next click is the drawing start */ bool drawArmed=false; /* b.an indication that you are drawing which means you have the first point and you are moving around to find the next point */ bool drawingNow=false; /* the datetime and price of the first point */ datetime time1=0; double price1=0; /* and right about now we start considering what its like for the user. They click the button to "arm" the drawer . okay but then they click . That click the chart will translate it to a drag of the x axis. So , we need an additional indication for whether or not the mouse scroll was on because we will turn it off when the user draws . */ bool drawerMemoryMouseScroll=false;//this will become true if its on before we draw /* and then what else might happen while we draw ? a new bar may form so we also need to cancel autoscroll while we are at it */ bool drawerMemoryAutoScroll=false;//this will become true if its on before we draw /* and we could go deeper and have the chart autonavigate gradually to the right if we hit the right edge and the opposite , but let's leave that ninja stuff for later. What did we forget ? time 2 and price 2 of course */ datetime time2=0; double price2=0; /* ready to start . But could we store it in a better way blabla bla and would this crash the apollo 1 cpu if it was under space radiation? we don't care . We just want to draw a rectangle in a civilized beautiful tasty easy flowing way. Sco (let's go) */ string SystemTag="TEST_";//our objects will have this name prefix int OnInit() { //we pull a reset of everything - could it be done better ? always time1=0;time2=0; price1=0.0;price2=0.0; drawArmed=false; drawingNow=false; drawerMemoryAutoScroll=false; drawerMemoryMouseScroll=false; //we delete all objects of this system because this is a test ObjectsDeleteAll(ChartID(),SystemTag); //and we create a button to press which arms the drawer ObjectCreate(ChartID(),SystemTag+"_ARM",OBJ_BUTTON,0,0,0); ObjectSetString(ChartID(),SystemTag+"_ARM",OBJPROP_TEXT,"ARM"); ObjectSetInteger(ChartID(),SystemTag+"_ARM",OBJPROP_XDISTANCE,10); ObjectSetInteger(ChartID(),SystemTag+"_ARM",OBJPROP_YDISTANCE,50); /* again we are sloppy because we are testing out a recipe right ? we are not inviting the prince of england for dinner .When we have all working components then we'll clean up , but above all we enjoy it. So all is ready , now , let's start the tricks . We will be using the mouse move to track down clicks and mouse location So , we reset the previous mouse values and these are explained in chart event function. */ prex=-1;prey=-1;prec=0; //and we light up the mouse move tracker , almost forgot ChartSetInteger(ChartID(),CHART_EVENT_MOUSE_MOVE,true); return(INIT_SUCCEEDED); } //We create a "memory" of the previous x y and click states for the mouse int prex,prey,prec; void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { /* now let's remember what we want to do . There are 3 states in our program : 1.drawer inactive drawing inactive 2.drawer armed drawing inactive 3.drawer armed and drawing in 1 we have the button visible in 2 we hide the button and tell the user to place the first point in 3 we have deployed the rectangle which the user is stretching around So , let's follow these states Simple , is the drawer active or not ?(armed) let's start from not active (not armed) because its easier */ if(drawArmed==false){ /* only one thing can happen here that we are interested in a click on the button ! */ if(id==CHARTEVENT_OBJECT_CLICK&&sparam==SystemTag+"_ARM"){ //self explanatory , if user clicks our button //a.hide the button ObjectSetInteger(ChartID(),SystemTag+"_ARM",OBJPROP_TIMEFRAMES,OBJ_NO_PERIODS); //b.place a message on the chart Comment("Click+HOLD to start drawing box"); //c.arm the drawer drawArmed=true; //d.delete the previous rectangle because this is a test ObjectDelete(ChartID(),SystemTag+"_RECT"); } }else{ /* this block , if the drawer is armed only 2 cases we are drawing or we are not so , again the easy first , if we are not drawing */ if(drawingNow==false){ /* what are we interested in here ? a new click and its location so mousemove */ if(id==CHARTEVENT_MOUSE_MOVE){ //we grab x , y and click states int x=(int)lparam; int y=(int)dparam; int c=(int)StringToInteger(sparam); //so , if the mouse click was 0 (no clicks) and its now 1 (left click) //we can start drawing //so if the previous state of click , the prec , was 0 and the current (c) is 1 if(prec==0&&c==1){ //remember we must first deactivate 2 switches and grab them as well //grab mouse scroll drawerMemoryMouseScroll=(bool)ChartGetInteger(ChartID(),CHART_MOUSE_SCROLL); //deactivate mouse scroll ChartSetInteger(ChartID(),CHART_MOUSE_SCROLL,false); //grab auto scroll drawerMemoryAutoScroll=(bool)ChartGetInteger(ChartID(),CHART_AUTOSCROLL); //deactivate auto scroll ChartSetInteger(ChartID(),CHART_AUTOSCROLL,false); //then get price 1 and time 1 int sub=0; //we ask the chart to turn the x and y of the mouse to time and price for our first point ! ChartXYToTimePrice(ChartID(),x,y,sub,time1,price1); //create the rectangle ObjectCreate(ChartID(),SystemTag+"_RECT",OBJ_RECTANGLE,0,time1,price1,time1,price1); //and activate the drawing indication drawingNow=true; //and update our message on the top left Comment("Drag to point 2 and release the mouse when done"); } //we also pass the x ,y and c of the mouse to the previous holders prex=x;prey=y;prec=c; }//mouse move for if not drawing ends here }//if not drawing ends here else{//if we are drawing /* if we are drawing we still need the mouse move event so if mouse move */ if(id==CHARTEVENT_MOUSE_MOVE){ //and we get x,y, and c again int x=(int)lparam; int y=(int)dparam; int c=(int)StringToInteger(sparam); //and if anything has changed since the previous event we care if(x!=prex||y!=prey||c!=prec){ //what do we need ? //price 2 time 2 int sub=0;//the sub is a result too if you are wondering not an instruction ChartXYToTimePrice(ChartID(),x,y,sub,time2,price2); //and we update our rectangle ObjectSetInteger(ChartID(),SystemTag+"_RECT",OBJPROP_TIME2,time2); ObjectSetDouble(ChartID(),SystemTag+"_RECT",OBJPROP_PRICE2,price2); //that is done now we need to know when this stops and that moment //will be when the mouse click becomes 0 again if(c==0){ //first we bring back mouse scroll if it was on ! ChartSetInteger(ChartID(),CHART_MOUSE_SCROLL,drawerMemoryMouseScroll); //and auto scroll ChartSetInteger(ChartID(),CHART_AUTOSCROLL,drawerMemoryAutoScroll); //and we kill the drawing switch and the draw arm drawArmed=false; drawingNow=false; //we remove the user message Comment(""); //we show the button again ObjectSetInteger(ChartID(),SystemTag+"_ARM",OBJPROP_TIMEFRAMES,OBJ_ALL_PERIODS); }//cancel drawing ends here //we pass the mouse parameters to the previous holders prex=x;prey=y;prec=c; //and we are done }//if anything changed in mouse ends here }//mouse move for if drawing ends here }//if we are drawing ends here }//if drawer is armed ends here } 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); }
mql4 dragging event on chart
Try this , its commented out , if you use a translator it may mess up the code so be careful .
Cheers .
Hello Lorentzos!
Thanks a lot. I am going to study your code, I also thank you for the comments since they will help me a lot to understand the code more. This idea of the box is to implement it to the code of the Indicator that you had already helped me with before, thank you very much again.
When I go to your land, if possible this summer, you have a couple of paid Mythos. ;-)
All the best
Hello Lorentzos!
Thanks a lot. I am going to study your code, I also thank you for the comments since they will help me a lot to understand the code more. This idea of the box is to implement it to the code of the Indicator that you had already helped me with before, thank you very much again.
When I go to your land, if possible this summer, you have a couple of paid Mythos. ;-)
All the best
Anytime ,cheers
Hello Lorentzos!
A question?. The button, once the rectangle is made and finished, remains pressed, it is possible to leave it as it was at the beginning without pressing it and for them to change color when pressed and without pressing.
Regards, and thank you very much.
Hello Lorentzos!
A question?. The button, once the rectangle is made and finished, remains pressed, it is possible to leave it as it was at the beginning without pressing it and for them to change color when pressed and without pressing.
Regards, and thank you very much.
Yes , instead of hiding and showing you can alter the color and state .
I marked where it changes .
#property version "1.00" #property strict #property indicator_chart_window /* from what i understand you want the rectangle to be on the chart . where else would it be though so you need : a.a trigger to let the system know the next click is the drawing start */ bool drawArmed=false; /* b.an indication that you are drawing which means you have the first point and you are moving around to find the next point */ bool drawingNow=false; /* the datetime and price of the first point */ datetime time1=0; double price1=0; /* and right about now we start considering what its like for the user. They click the button to "arm" the drawer . okay but then they click . That click the chart will translate it to a drag of the x axis. So , we need an additional indication for whether or not the mouse scroll was on because we will turn it off when the user draws . */ bool drawerMemoryMouseScroll=false;//this will become true if its on before we draw /* and then what else might happen while we draw ? a new bar may form so we also need to cancel autoscroll while we are at it */ bool drawerMemoryAutoScroll=false;//this will become true if its on before we draw /* and we could go deeper and have the chart autonavigate gradually to the right if we hit the right edge and the opposite , but let's leave that ninja stuff for later. What did we forget ? time 2 and price 2 of course */ datetime time2=0; double price2=0; /* ready to start . But could we store it in a better way blabla bla and would this crash the apollo 1 cpu if it was under space radiation? we don't care . We just want to draw a rectangle in a civilized beautiful tasty easy flowing way. Sco (let's go) */ string SystemTag="TEST_";//our objects will have this name prefix int OnInit() { //we pull a reset of everything - could it be done better ? always time1=0;time2=0; price1=0.0;price2=0.0; drawArmed=false; drawingNow=false; drawerMemoryAutoScroll=false; drawerMemoryMouseScroll=false; //we delete all objects of this system because this is a test ObjectsDeleteAll(ChartID(),SystemTag); //and we create a button to press which arms the drawer ObjectCreate(ChartID(),SystemTag+"_ARM",OBJ_BUTTON,0,0,0); ObjectSetString(ChartID(),SystemTag+"_ARM",OBJPROP_TEXT,"ARM"); ObjectSetInteger(ChartID(),SystemTag+"_ARM",OBJPROP_XDISTANCE,10); ObjectSetInteger(ChartID(),SystemTag+"_ARM",OBJPROP_YDISTANCE,50); //first state of button - color - text color - border color set_inactive_style(SystemTag+"_ARM"); /* again we are sloppy because we are testing out a recipe right ? we are not inviting the prince of england for dinner .When we have all working components then we'll clean up , but above all we enjoy it. So all is ready , now , let's start the tricks . We will be using the mouse move to track down clicks and mouse location So , we reset the previous mouse values and these are explained in chart event function. */ prex=-1;prey=-1;prec=0; //and we light up the mouse move tracker , almost forgot ChartSetInteger(ChartID(),CHART_EVENT_MOUSE_MOVE,true); return(INIT_SUCCEEDED); } //set a button to the active style void set_active_style(string name){ ObjectSetInteger(ChartID(),name,OBJPROP_STATE,false); ObjectSetInteger(ChartID(),name,OBJPROP_BGCOLOR,clrForestGreen); ObjectSetInteger(ChartID(),name,OBJPROP_COLOR,clrWhite); ObjectSetInteger(ChartID(),name,OBJPROP_BORDER_COLOR,clrDarkGreen); } //set a button to the inactive style void set_inactive_style(string name){ ObjectSetInteger(ChartID(),name,OBJPROP_STATE,false); ObjectSetInteger(ChartID(),name,OBJPROP_BGCOLOR,clrCrimson); ObjectSetInteger(ChartID(),name,OBJPROP_COLOR,clrGoldenrod); ObjectSetInteger(ChartID(),name,OBJPROP_BORDER_COLOR,clrDarkRed); } //We create a "memory" of the previous x y and click states for the mouse int prex,prey,prec; void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { /* now let's remember what we want to do . There are 3 states in our program : 1.drawer inactive drawing inactive 2.drawer armed drawing inactive 3.drawer armed and drawing in 1 we have the button visible in 2 we hide the button and tell the user to place the first point in 3 we have deployed the rectangle which the user is stretching around So , let's follow these states Simple , is the drawer active or not ?(armed) let's start from not active (not armed) because its easier */ if(drawArmed==false){ /* only one thing can happen here that we are interested in a click on the button ! */ if(id==CHARTEVENT_OBJECT_CLICK&&sparam==SystemTag+"_ARM"){ //self explanatory , if user clicks our button //a.hide the button //ObjectSetInteger(ChartID(),SystemTag+"_ARM",OBJPROP_TIMEFRAMES,OBJ_NO_PERIODS); //second state of button - color - text color - border color set_active_style(SystemTag+"_ARM"); //b.place a message on the chart Comment("Click+HOLD to start drawing box"); //c.arm the drawer drawArmed=true; //d.delete the previous rectangle because this is a test ObjectDelete(ChartID(),SystemTag+"_RECT"); } }else{ /* this block , if the drawer is armed only 2 cases we are drawing or we are not so , again the easy first , if we are not drawing */ if(drawingNow==false){ /* what are we interested in here ? a new click and its location so mousemove */ if(id==CHARTEVENT_MOUSE_MOVE){ //we grab x , y and click states int x=(int)lparam; int y=(int)dparam; int c=(int)StringToInteger(sparam); //so , if the mouse click was 0 (no clicks) and its now 1 (left click) //we can start drawing //so if the previous state of click , the prec , was 0 and the current (c) is 1 if(prec==0&&c==1){ //remember we must first deactivate 2 switches and grab them as well //grab mouse scroll drawerMemoryMouseScroll=(bool)ChartGetInteger(ChartID(),CHART_MOUSE_SCROLL); //deactivate mouse scroll ChartSetInteger(ChartID(),CHART_MOUSE_SCROLL,false); //grab auto scroll drawerMemoryAutoScroll=(bool)ChartGetInteger(ChartID(),CHART_AUTOSCROLL); //deactivate auto scroll ChartSetInteger(ChartID(),CHART_AUTOSCROLL,false); //then get price 1 and time 1 int sub=0; //we ask the chart to turn the x and y of the mouse to time and price for our first point ! ChartXYToTimePrice(ChartID(),x,y,sub,time1,price1); //create the rectangle ObjectCreate(ChartID(),SystemTag+"_RECT",OBJ_RECTANGLE,0,time1,price1,time1,price1); //and activate the drawing indication drawingNow=true; //and update our message on the top left Comment("Drag to point 2 and release the mouse when done"); } //we also pass the x ,y and c of the mouse to the previous holders prex=x;prey=y;prec=c; }//mouse move for if not drawing ends here }//if not drawing ends here else{//if we are drawing /* if we are drawing we still need the mouse move event so if mouse move */ if(id==CHARTEVENT_MOUSE_MOVE){ //and we get x,y, and c again int x=(int)lparam; int y=(int)dparam; int c=(int)StringToInteger(sparam); //and if anything has changed since the previous event we care if(x!=prex||y!=prey||c!=prec){ //what do we need ? //price 2 time 2 int sub=0;//the sub is a result too if you are wondering not an instruction ChartXYToTimePrice(ChartID(),x,y,sub,time2,price2); //and we update our rectangle ObjectSetInteger(ChartID(),SystemTag+"_RECT",OBJPROP_TIME2,time2); ObjectSetDouble(ChartID(),SystemTag+"_RECT",OBJPROP_PRICE2,price2); //that is done now we need to know when this stops and that moment //will be when the mouse click becomes 0 again if(c==0){ //first we bring back mouse scroll if it was on ! ChartSetInteger(ChartID(),CHART_MOUSE_SCROLL,drawerMemoryMouseScroll); //and auto scroll ChartSetInteger(ChartID(),CHART_AUTOSCROLL,drawerMemoryAutoScroll); //and we kill the drawing switch and the draw arm drawArmed=false; drawingNow=false; //we remove the user message Comment(""); //we show the button again //ObjectSetInteger(ChartID(),SystemTag+"_ARM",OBJPROP_TIMEFRAMES,OBJ_ALL_PERIODS); set_inactive_style(SystemTag+"_ARM"); }//cancel drawing ends here //we pass the mouse parameters to the previous holders prex=x;prey=y;prec=c; //and we are done }//if anything changed in mouse ends here }//mouse move for if drawing ends here }//if we are drawing ends here }//if drawer is armed ends here } 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); }
Yes , instead of hiding and showing you can alter the color and state .
I marked where it changes .
But this is exactly like the one already provided on the platform … same … click, drag, let go… I am working on something that will draw the rectangle with 2 clicks … no dragging… like…
It is , but , he controls the process :)
You mean what is the purpose since the x axis is only per bar and not "flexible" ?
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
Hello everyone!
I am trying to make an indicator that allows me to draw a rectangle with two clicks and later with this rectangle perform other functions with buttons; My problem is that when I use the CHARTEVENT_CLICK it only does the CHARTEVENT_CLICK thing and cancels the rest. In this code I have carried out a test with the CHARTEVENT_CLICK that when pressed gives me the coordinates of the Click with a "Comment" but when I press the Pink button that is to delete the "comment" it gives me the coordinate of the Click of the button. Can you help me?