164 lines
15 KiB
MQL5
164 lines
15 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| Mouse.mqh |
|
|
//| Copyright 2016, MetaQuotes Software Corp. |
|
|
//| http://www.mql5.com |
|
|
//+------------------------------------------------------------------+
|
|
#include "Defines.mqh"
|
|
#include "Objects.mqh"
|
|
#include <Charts\Chart.mqh>
|
|
//+------------------------------------------------------------------+
|
|
//| Класс для получения параметров мыши |
|
|
//+------------------------------------------------------------------+
|
|
class CMouse
|
|
{
|
|
private:
|
|
//--- Экземпляр класса для управления графиком
|
|
CChart m_chart;
|
|
//--- Координаты
|
|
int m_x;
|
|
int m_y;
|
|
//--- Номер окна, в котором находится курсор
|
|
int m_subwin;
|
|
//--- Время соответствующее координате X
|
|
datetime m_time;
|
|
//--- Уровень (цена) соответствующий координате Y
|
|
double m_level;
|
|
//--- Состояние левой кнопки мыши (зажата/отжата)
|
|
bool m_left_button_state;
|
|
//--- Счётчик вызовов
|
|
ulong m_call_counter;
|
|
//--- Пауза между кликами левой кнопкой мыши (для определения двойного нажатия)
|
|
uint m_pause_between_clicks;
|
|
//---
|
|
public:
|
|
CMouse(void);
|
|
~CMouse(void);
|
|
//--- Обработчик событий
|
|
void OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
|
|
|
|
//--- Возвращает абсолютные координаты курсора мыши
|
|
int X(void) const { return(m_x); }
|
|
int Y(void) const { return(m_y); }
|
|
//--- (1) Возвращает номер окна, в котором находится курсор, (2) время соответствующее координате X,
|
|
// (3) уровень (цена) соответствующий координате Y
|
|
int SubWindowNumber(void) const { return(m_subwin); }
|
|
datetime Time(void) const { return(m_time); }
|
|
double Level(void) const { return(m_level); }
|
|
//--- Возвращает состояние левой кнопки мыши (зажата/отжата)
|
|
bool LeftButtonState(void) const { return(m_left_button_state); }
|
|
|
|
//--- Возвращает (1) сохранённое при последнем вызове значение счётчика (ms) и
|
|
// (2) разницу (ms) между вызовами обработчика события перемещения курсора мыши
|
|
ulong CallCounter(void) const { return(m_call_counter); }
|
|
ulong GapBetweenCalls(void) const { return(::GetTickCount()-m_call_counter); }
|
|
|
|
//--- Возвращает относительные координаты курсора мыши от переданного объекта-холста для рисования
|
|
int RelativeX(CRectCanvas &object);
|
|
int RelativeY(CRectCanvas &object);
|
|
//---
|
|
private:
|
|
//--- Проверка изменения состояния левой кнопки мыши
|
|
bool CheckChangeLeftButtonState(const string mouse_state);
|
|
//--- Проверка двойного нажатия левой кнопки мыши
|
|
void CheckDoubleClick(void);
|
|
};
|
|
//+------------------------------------------------------------------+
|
|
//| Constructor |
|
|
//+------------------------------------------------------------------+
|
|
CMouse::CMouse(void) : m_x(0),
|
|
m_y(0),
|
|
m_subwin(WRONG_VALUE),
|
|
m_time(NULL),
|
|
m_level(0.0),
|
|
m_left_button_state(false),
|
|
m_call_counter(::GetTickCount()),
|
|
m_pause_between_clicks(300)
|
|
{
|
|
//--- Получим ID текущего графика
|
|
m_chart.Attach();
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Destructor |
|
|
//+------------------------------------------------------------------+
|
|
CMouse::~CMouse(void)
|
|
{
|
|
//--- Отсоединиться от графика
|
|
m_chart.Detach();
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Обработка событий мыши |
|
|
//+------------------------------------------------------------------+
|
|
void CMouse::OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
|
|
{
|
|
//--- Обработка события перемещения курсора
|
|
if(id==CHARTEVENT_MOUSE_MOVE)
|
|
{
|
|
//--- Координаты и состояние левой кнопки мыши
|
|
m_x =(int)lparam;
|
|
m_y =(int)dparam;
|
|
m_left_button_state =CheckChangeLeftButtonState(sparam);
|
|
//--- Сохраним значение счётчика вызовов
|
|
m_call_counter=::GetTickCount();
|
|
//--- Получим местоположение курсора
|
|
if(!::ChartXYToTimePrice(m_chart.ChartId(),m_x,m_y,m_subwin,m_time,m_level))
|
|
return;
|
|
//--- Получим относительную координату Y
|
|
if(m_subwin>0)
|
|
m_y=m_y-m_chart.SubwindowY(m_subwin);
|
|
return;
|
|
}
|
|
//--- Обработка события нажатия на графике
|
|
if(id==CHARTEVENT_CLICK)
|
|
{
|
|
//--- Проверим двойное нажатие левой кнопкой мыши
|
|
CheckDoubleClick();
|
|
return;
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Возвращает относительную X-координату курсора мыши |
|
|
//| от переданного объекта-холста для рисования |
|
|
//+------------------------------------------------------------------+
|
|
int CMouse::RelativeX(CRectCanvas &object)
|
|
{
|
|
return(m_x-object.X()+(int)ObjectGetInteger(0,object.ChartObjectName(),OBJPROP_XOFFSET));
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Возвращает относительную Y-координату курсора мыши |
|
|
//| от переданного объекта-холста для рисования |
|
|
//+------------------------------------------------------------------+
|
|
int CMouse::RelativeY(CRectCanvas &object)
|
|
{
|
|
return(m_y-object.Y()+(int)ObjectGetInteger(0,object.ChartObjectName(),OBJPROP_YOFFSET));
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Проверка изменения состояния левой кнопки мыши |
|
|
//+------------------------------------------------------------------+
|
|
bool CMouse::CheckChangeLeftButtonState(const string mouse_state)
|
|
{
|
|
bool left_button_state=(bool)int(mouse_state);
|
|
//--- Отправим сообщение об изменении состояния левой кнопки мыши
|
|
if(m_left_button_state!=left_button_state)
|
|
::EventChartCustom(m_chart.ChartId(),ON_CHANGE_MOUSE_LEFT_BUTTON,0,0.0,"");
|
|
//--- Вернуть текущее состояние левой кнопки мыши
|
|
return(left_button_state);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Проверка двойного нажатия левой кнопки мыши |
|
|
//+------------------------------------------------------------------+
|
|
void CMouse::CheckDoubleClick(void)
|
|
{
|
|
static uint prev_depressed =0;
|
|
static uint curr_depressed =::GetTickCount();
|
|
//--- Обновим значения
|
|
prev_depressed =curr_depressed;
|
|
curr_depressed =::GetTickCount();
|
|
//--- Определим время между нажатиями
|
|
uint counter = curr_depressed - prev_depressed;
|
|
//--- Если между кликами прошло меньше времени, чем указано, отправим сообщение о двойном нажатии
|
|
if(counter < m_pause_between_clicks)
|
|
{
|
|
::EventChartCustom(m_chart.ChartId(),ON_DOUBLE_CLICK,counter,0.0,"");
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|