Test_ChartEvent

Author: WU Tao
Test_ChartEvent
0 Views
0 Downloads
0 Favorites
Test_ChartEvent
//tao.wu. Create(2017-03-14)Modify(2017-04-18)..file:Test_ChartEvent.mq45 (mt45: same file for mql4 & mql5)
//=============================================================================================================
// WU Tao - http://forex.simula.fr/temp/
//=======================================================================================
// Test the various Chart Events.
// In this EA, I test the key event, mouse event, custom event.
// and I created a class to handle the objects.
// Finally, the OnTimer () function randomly generates the custom event.
// Press the "h" key to get help.
// To use the MouseMove event, press the 'm' key to activate the mode.
//=======================================================================================

#property copyright "WU Tao"
#property link      "http://forex.simula.fr/temp/"
#property version   "1.00"
#ifdef __MQL4__
#property strict
#endif

//--- input parameters
input int iLogLevel=0;   // LogLevel: 0: no log message, 1: a little, 2: more message

                         //========== prototype of function ================
bool Obj_Create();
bool Obj_Delete();
bool Obj_Move(int hSens,int vSens);
void Print_Info();
//
void MouseEventUse(bool bUseMouse);
int MouseMove(int aXX,int aYY,string sState);

//========= global variables =====================
int gChartNo=0;
int gSubWinNo=0;
string gsObj_Name_selected="";

//======== Custom event ===========================
#define cMyEvent_1 0
#define cMyEvent_2 1
#define cMyEvent_3_broadcast 2
//CHARTEVENT_CUSTOM= 1000 et CHARTEVENT_CUSTOM_LAST= 66534

//========== variable of MouseMoveEvent =======================
bool ggmMouseOn;   //Enable or Disable
int ggmLogLevel;   //DebugLevel
int ggmXX;         //X_Coordonne
int ggmYY;         //Y_Coordonne
int ggmStateMouse; //mouse button state
int ggmStateAct;   //mouse action state
uint ggmTimeTop;   //Start
//+------------------------------------------------------------------+
//| a sample of class to manager the button object                   |
//+------------------------------------------------------------------+
class CObjectMan //Object Manager
  {
public:
   string            m_name;
   color             m_color;
   int               m_step;
   //=====================================
   void              CObjectMan(string aName,color aColor=clrRed);
   void             ~CObjectMan();
   bool              f_Create();
   bool              f_Delete();
   bool              f_Move(int hSens,int vSens);
   void              f_print();
  }
gObjectMan1("Green button",clrGreen),gObjectMan2("Yellow button",clrChocolate);
//
//
//======================= initialization function ====================================
//
int OnInit()
  {
   if(iLogLevel)
      Print("CHARTEVENT_CUSTOM=",CHARTEVENT_CUSTOM,", CHARTEVENT_CUSTOM_LAST=",CHARTEVENT_CUSTOM_LAST); //(5000, 66534)
   Obj_Create();
   EventSetTimer(60);
   return(INIT_SUCCEEDED);
  }//int OnInit()
//
//
//
//================================== deinitialization function ==================================
//
void OnDeinit(const int reason)
  {
   Obj_Delete();
   EventKillTimer();
  }
//
//
//================================== Expert tick function ==================================
//
void OnTick()
  {
  }
//
//
//================================== Timer function ==================================
//
void OnTimer()
  {
   int ii=MathRand()%3;
   long lparam=0;
   double dparam= 0.0;
   string sparam= "by "+_Symbol+StringSubstr(EnumToString((ENUM_TIMEFRAMES)_Period), 6);

   if(ii==0)
      EventChartCustom(gChartNo,cMyEvent_1,lparam,dparam,sparam);
   if(ii==1)
      EventChartCustom(gChartNo,cMyEvent_2,lparam,dparam,sparam);
   if(ii==2)
     {
      BroadcastEvent(lparam,dparam,sparam);
     }
  }//void OnTimer()
//
//
//================================== ChartEvent function ==================================
//
//
//See exemple in Help for: OnChartEvent()
#define KEY_NUMPAD_5 12
#define KEY_LEFT 37
#define KEY_UP 38
#define KEY_RIGHT 39
#define KEY_DOWN 40
#define KEY_NUMLOCK_DOWN 98 //2 (De-Select Objet)
#define KEY_NUMLOCK_LEFT 100 //4
#define KEY_NUMLOCK_5 101 //5
#define KEY_NUMLOCK_RIGHT 102 //6
#define KEY_NUMLOCK_UP 104 //8 (Select Objet)
//
void OnChartEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
  {
   bool bRet=false;

   if(id==CHARTEVENT_KEYDOWN)
     {
      //
      bRet=false;
      int vSens=0,hSens=0;
      switch((int)lparam)
        {
         case KEY_NUMLOCK_LEFT: //Print("The KEY_NUMLOCK_LEFT has been pressed");
            hSens=-1;   break;
         case KEY_LEFT: //Print("The KEY_LEFT has been pressed");
            hSens=-1;   break;
         case KEY_NUMLOCK_UP: //bRet= false;
            vSens=-1;   break;
         case KEY_UP: //Print("The KEY_UP has been pressed");
            vSens=-1;   break;
         case KEY_NUMLOCK_RIGHT: //Print("The KEY_NUMLOCK_RIGHT has been pressed");
            hSens=1;   break;
         case KEY_RIGHT: //Print("The KEY_RIGHT has been pressed");
            hSens=1;   break;
         case KEY_NUMLOCK_DOWN: //Print("The KEY_NUMLOCK_DOWN has been pressed (Objet de-select= ", bRet);
            vSens=1;   break;
         case KEY_DOWN: //Print("The KEY_DOWN has been pressed");
            vSens=1;   break;
         case KEY_NUMPAD_5: //Print("The KEY_NUMPAD_5 has been pressed");
            break;
         case KEY_NUMLOCK_5: //Print("The KEY_NUMLOCK_5 has been pressed");
            break;
         case 'H':            //Print("'h' has been pressed");
            Print("Help: use mouse click at an object to select it for moving");
            Print("Help: use direction key or numlock direction key to move the Object");
            Print("Help: use mouse to grag the object");
            Print("Help: Press 'm' to activate mouse move event");
            break;
         case 'I':            //Print("'i' has been pressed");
            Print_Info();
            break;
         case 'M':            //Print("'i' has been pressed");
            MouseEventUse(true);
            if(iLogLevel)
               Print("MouseMoveEvent is activated");
            break;
         default: //Print("Some not listed key has been pressed");
            break;
        }
      if(vSens!=0 || hSens!=0)
        {
         Obj_Move(hSens,vSens);
        }
      //	Print("lparam= ", lparam, ", dparam= ", dparam, ", sparam= ", sparam, ", 'd'= ", 'd');
      //	printf("lparam= %ld, dparam= %g, sparam= %s, %X, %X, %c", lparam, dparam, sparam, StringToInteger(sparam), 'd', 'd');
      //bRet= true;
      //Print("Objet= " , sparam, " is Clicked");
     }//	if(id==CHARTEVENT_KEYDOWN){
//
//
   if(id>=CHARTEVENT_CUSTOM && id<CHARTEVENT_CUSTOM_LAST)
     {
      int custom_id=id-CHARTEVENT_CUSTOM;
      if(iLogLevel)
         Print("Here Custom event: custom_id=",custom_id," ::::: lparam= ",lparam,", dparam= ",dparam,", sparam= ",sparam);
      if(custom_id==cMyEvent_1)
        {
         if(iLogLevel)
            Print("Custom Event #1");
        }
      if(custom_id==cMyEvent_2)
        {
         if(iLogLevel)
            Print("Custom Event #2");
        }
      if(custom_id==cMyEvent_3_broadcast)
        {
         if(iLogLevel)
            Print("Custom Event #3");
        }
     }

//
   bRet=false;
//
   if(id==CHARTEVENT_OBJECT_CHANGE)
     {
      bRet=true;
      if(iLogLevel)
         Print("Objet '",sparam,"' is Changed");
     }
   if(id==CHARTEVENT_OBJECT_DRAG)
     {
      bRet=true;
      if(iLogLevel)
         Print("Objet '",sparam,"' is Draged");
     }
   if(id==CHARTEVENT_OBJECT_DELETE)
     {
      bRet=true;
      if(iLogLevel)
         Print("Objet '",sparam,"' is Deleted");
     }
//
   if(id==CHARTEVENT_OBJECT_CLICK)
     {
      bRet=true;
      if(iLogLevel)
         Print("Objet '",sparam,"' is Clicked");
      if(sparam==gObjectMan1.m_name)
         gsObj_Name_selected=gObjectMan1.m_name;
      else if(sparam==gObjectMan2.m_name)
         gsObj_Name_selected=gObjectMan2.m_name;
      else
         gsObj_Name_selected="";
     }
   if(bRet==true)
     {
/*
		if(iOption==0)
			//Rect_Maj_Change();
		if(iOption==1)
			//Trend_Maj_Change();
		*/
      ChartRedraw();
     }
//
   if(id==CHARTEVENT_MOUSE_MOVE)
     { //See: CHART_EVENT_MOUSE_MOVE
      //Print("Mouse is moving ...");
      MouseMove((int)lparam,(int)dparam,sparam);
      //if(ggMouse.ggmStateAct==3){
      //	ret= 65;
      //}
     }
//
   if(id==CHARTEVENT_CLICK)
     {
      if(!IsMoved((int)lparam,(int)dparam))
        {
         datetime aTime;
         double aPrice;
         //MqlRates bRates[1]; //Give error, why ?
         MqlRates bRates[];
         int ret=0;
         aTime=ChartTimeOnDropped();
         ChartXYToTimePrice(gChartNo,(int)lparam,(int)dparam,gSubWinNo,aTime,aPrice);
         if(iLogLevel)
            Print("Mouse clicked at XX= ",lparam,", YY= ",(int)dparam,", Time= ",aTime,", Price= ",aPrice);
         if(iLogLevel>=2)
           {
            ret=CopyRates(_Symbol,_Period,aTime,1,bRates);
            Print("Bar: Open= ",DoubleToString(bRates[0].open,(int)SymbolInfoInteger(_Symbol,SYMBOL_DIGITS)),
                  ", Close= ",DoubleToString(bRates[0].close,(int)SymbolInfoInteger(_Symbol,SYMBOL_DIGITS)),
                  ", Time= ",bRates[0].time);
           }
         bRet=false;
         //MouseEventUse(false);
         //
         //ggMouse.MouseClick((int)lparam, (int)dparam);
         //if(gMouseEvent.ggmStateAct==1){
         //	ret= 87;
         //}
        }
     }
  }//void OnChartEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
//

//+------------------------------------------------------------------+
//| Print the info about the two objects                             |
//+------------------------------------------------------------------+
void Print_Info()
  {
   gObjectMan1.f_print();
   gObjectMan2.f_print();
  }
//
//+------------------------------------------------------------------+
//| Create the two button objects (at random position                |
//+------------------------------------------------------------------+
bool Obj_Create()
  {
   gObjectMan1.f_Create();
   gObjectMan2.f_Create();
   gsObj_Name_selected=gObjectMan1.m_name;
//
   return true;
  }//bool Obj_Create()
//
//+------------------------------------------------------------------+
//| Delete the two objects                                           |
//+------------------------------------------------------------------+
bool Obj_Delete()
  {
   gObjectMan1.f_Delete();
   gObjectMan2.f_Delete();
//ChartRedraw(0);
   return true;
  }//bool Obj_Delete()
//
//+----------------------------------------------------------------------------------+
//| Move the selected object: hSens: horizontal direction, vSens: vertical direction |
//+----------------------------------------------------------------------------------+
bool Obj_Move(int hSens,int vSens)
  {
   if(gsObj_Name_selected==gObjectMan1.m_name)
      gObjectMan1.f_Move(hSens,vSens);
   if(gsObj_Name_selected==gObjectMan2.m_name)
      gObjectMan2.f_Move(hSens,vSens);
//
   return true;
  }//bool Obj_Move()
//
//+------------------------------------------------------------------+
//| Send the message of broardcast to opened graphiques              |
//+------------------------------------------------------------------+
void BroadcastEvent(long lparam,double dparam,string sparam)
  {
   long currChart=ChartFirst();   //the first Window
   int ii=0;

   while(ii<CHARTS_MAX)
     {
      EventChartCustom(currChart,cMyEvent_3_broadcast,lparam,dparam,sparam);
      currChart=ChartNext(currChart); // from precedent window to the next window
      if(currChart==-1) break;        // we are at the end of the list of windows
      ii++;                           // Increase the compter
     }
  }//void BroadcastEvent()
//+------------------------------------------------------------------+

//=========== an exemple of class: class CObjectMan =====================
//Object Manager
//
//+------------------------------------------------------------------+
//| Constructor (with label and color                                |
//+------------------------------------------------------------------+
void CObjectMan::CObjectMan(string aName,color aColor=clrRed)
  {
   m_name=aName;
   m_color=aColor;
   m_step=10;
  }
//
//+------------------------------------------------------------------+
//| destructor                                                       |
//+------------------------------------------------------------------+
void CObjectMan::~CObjectMan()
  {
   f_Delete();
  }
//
//+------------------------------------------------------------------+
//| Create the object                                                |
//+------------------------------------------------------------------+
bool CObjectMan::f_Create()
  {
//
   bool bRet;
   int XX,YY;
   int Large,Haut;
   color aCouleur=clrWhite;
   ENUM_OBJECT oType;

   XX= 180+MathRand()%300;
   YY= 90+MathRand()%200;
   Large=120;
   Haut=50;
//
   oType= OBJ_LABEL;
   oType= OBJ_BUTTON;
//
   bRet= ObjectCreate(0, m_name, oType, 0, 0, 0);
   bRet= ObjectSetInteger(0, m_name, OBJPROP_XDISTANCE, XX);
   bRet= ObjectSetInteger(0, m_name, OBJPROP_YDISTANCE, YY);
//
   bRet= ObjectSetInteger(0, m_name, OBJPROP_XSIZE, Large);
   bRet= ObjectSetInteger(0, m_name, OBJPROP_YSIZE, Haut);
//
   bRet= ObjectSetString(0, m_name, OBJPROP_TEXT, m_name);
   bRet= ObjectSetInteger(0, m_name, OBJPROP_FONTSIZE, 12);
   bRet=ObjectSetString(0,m_name,OBJPROP_FONT,"Times New Roman");      //"Arial"
   bRet= ObjectSetInteger(0, m_name, OBJPROP_COLOR, aCouleur);
//
   bRet=ObjectSetInteger(0,m_name,OBJPROP_BGCOLOR,m_color);
//bRet= ObjectSetInteger(0, m_name, OBJPROP_BORDER_TYPE, BORDER_SUNKEN);
   bRet= ObjectSetInteger(0, m_name, OBJPROP_BORDER_COLOR, clrAzure);
   bRet= ObjectSetInteger(0, m_name, OBJPROP_WIDTH, 4);

   bRet=ObjectSetInteger(0,m_name,OBJPROP_STATE,false);

   bRet= ObjectSetInteger(0, m_name, OBJPROP_ZORDER, 1);
   bRet= ObjectSetInteger(gChartNo, m_name, OBJPROP_SELECTABLE, true);
   bRet= ObjectSetInteger(gChartNo, m_name, OBJPROP_SELECTED, true);
   return true;
  }
//+------------------------------------------------------------------+
//| Delete the object                                                |
//+------------------------------------------------------------------+
bool CObjectMan::f_Delete()
  {
   if(ObjectFind(0,m_name)==0)
      ObjectDelete(0,m_name);
   return true;
  }
//+---------------------------------------------------------------------------+
//| Move the object: hSens (horizontal direction), vSens (vertical direction) |
//+---------------------------------------------------------------------------+
bool CObjectMan::f_Move(int hSens,int vSens)
  {
   int XX,YY,XX2,YY2;
   int Large,Haut;
   int winWidth,winHight;
   bool bRet=false;

   if(iLogLevel==2)
      Print("Obj_Move(",hSens,", ",vSens,")");

   if(ObjectFind(0,m_name)!=0)
      return false;
//
   if(hSens==0 && vSens==0)
      return false;
//
   XX2= XX= (int)ObjectGetInteger(0, m_name, OBJPROP_XDISTANCE);
   YY2= YY= (int)ObjectGetInteger(0, m_name, OBJPROP_YDISTANCE);
//
   Large=(int)ObjectGetInteger(0,m_name,OBJPROP_XSIZE);
   Haut=(int)ObjectGetInteger(0,m_name,OBJPROP_YSIZE);
//
   winWidth= (int)ChartGetInteger(0, CHART_WIDTH_IN_PIXELS);
   winHight= (int)ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS);
//
   if(hSens>0) XX+= m_step;
   if(hSens<0) XX-= m_step;
   if(vSens>0) YY+= m_step;
   if(vSens<0) YY-= m_step;
   if(XX<0) XX= 0;
   if(YY<0) YY= 0;
   if(XX>winWidth-Large) XX=winWidth-Large;
   if(YY>winHight-Haut) YY=winHight-Haut;
//
   if(XX==XX2 && YY==YY2)
      return false;
//
   if(XX!=XX2)
     {
      bRet=ObjectSetInteger(0,m_name,OBJPROP_XDISTANCE,XX);
     }
   if(YY!=YY2)
     {
      bRet=ObjectSetInteger(0,m_name,OBJPROP_YDISTANCE,YY);
     }
   ChartRedraw(0);
   return true;
  }
//
//+---------------------------------------------------------------------------+
//| Print the object's info: color, position, name                            |
//+---------------------------------------------------------------------------+
void CObjectMan::f_print()
  {
   int XX= (int)ObjectGetInteger(0, m_name, OBJPROP_XDISTANCE);
   int YY= (int)ObjectGetInteger(0, m_name, OBJPROP_YDISTANCE);
   if(iLogLevel)
      Print("Object name=",m_name,", color=",m_color,", position: (",XX,", ",YY,")");
  }
//
//+---------------------------------------------------------------------------+
//| Active/Desactive the MOUSE_MOVE event mode                                |
//+---------------------------------------------------------------------------+
void MouseEventUse(bool bUseMouse)
  {
   ChartSetInteger(ChartID(),CHART_EVENT_MOUSE_MOVE,bUseMouse);
   ggmMouseOn=bUseMouse;
   if(bUseMouse)
     {
      ggmXX=ggmYY=0;
      ggmStateMouse=0;
      ggmStateAct=0;
      ggmTimeTop=0;
     }
  }//void MouseEventUse(bool bUseMouse)
//
//+---------------------------------------------------------------------------+
//| Handle of the Mouse move event : show the move info                       |
//+---------------------------------------------------------------------------+
int MouseMove(int aXX,int aYY,string sState)
  {
   int StateMouse=0;
   string lSS="";

   if(sState=="16"){ lSS="Wheel"; StateMouse=3; }
   if(sState=="1"){ lSS= "Left"; StateMouse= 1; }
   if(sState=="2"){ lSS= "Right"; StateMouse= 2; }
   if(sState=="0"){ lSS= "Non"; StateMouse= 0; }

//Print("Mouse is moving ... lSS= ",lSS);

   if(ggmStateMouse==0 && StateMouse!=0)
     {
      //Memorize
      ggmXX=aXX; ggmYY=aYY;
      ggmStateMouse=StateMouse;
      ggmStateAct=2; //Move Started
      ggmTimeTop=GetTickCount();
     }
   else if(ggmStateMouse!=0 && StateMouse==0)
     {
      if(IsMoved(aXX,aYY))
        {
         if(iLogLevel)
           {
            double pr1,pr2;
            datetime tm1,tm2;
            ChartXYToTimePrice(gChartNo,ggmXX,ggmYY,gSubWinNo,tm1,pr1);
            ChartXYToTimePrice(gChartNo,aXX,aYY,gSubWinNo,tm2,pr2);
            PrintFormat("==> Mouse move from (%d, %d) to (%d, %d) state=%s (%s)",ggmXX,ggmYY,aXX,aYY,sState,lSS);
            PrintFormat("==> from (tm=%s, pr=%G) to (tm=%s, pr=%G)",TimeToString(tm1),pr1,TimeToString(tm2),pr2);
           }
         //
         //CheckAction(1,aXX,aYY);
         ggmXX=aXX; ggmYY=aYY;
         ggmStateMouse=0;
         ggmStateAct=3; //Move to be traited
         ggmTimeTop=0;
         //optional
         //Press the key board 'm' for re-enable
         //TraitMouse(3, aXX, bRates[ii].time, aShift);
         MouseEventUse(false);
        }
      else
        {
         //MyInit(); //Cette mouvement n'est pas vraiment Move : donc annuler'
         ggmXX=ggmYY=0;
         ggmStateMouse=0;
         ggmStateAct=0;
         ggmTimeTop=0;
        }
     }
   else
     {
      //Ne fait rien
     }
//

   return 0;
  }//int MouseMove()
//
//+---------------------------------------------------------------------------+
//| Check if the mouse is monving                                             |
//+---------------------------------------------------------------------------+
bool IsMoved(int aXX,int aYY)
  {
   if(!ggmMouseOn) return false;
//
   if(ggmTimeTop==0 || ggmStateMouse==0)
      return false;
//
//Duration at least one seconde and deplace at least 3 points
//If not, it is considered as "MouseClick"
//
//PrintFormat("Mouse move from (%d, %d) to (%d, %d) state=%s (%s)", mXX, mYY, aXX, aYY, sState, lSS);
   if(ggmTimeTop+460<GetTickCount() && (MathAbs(aXX-ggmXX)>2 || MathAbs(aYY-ggmYY)>2))
     {
      return true;
     }
   return false;
  }
//+------------------------------------------------------------------+
//| Show the mouse moving info                                       |
//+------------------------------------------------------------------+
int CheckAction(int aOption,int aXX,int aYY)
  {
   if(iLogLevel)
      Print("Mouse has moved from (",ggmXX,", ",ggmYY,") to (",aXX,", ",aYY,")");
   return 0;
  }//int CMouseEvent::CheckAction(int aOption, int aXX, int aYY)

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

Comments