//+------------------------------------------------------------------+ //| Window.mqh | //| Copyright 2015, MetaQuotes Software Corp. | //| http://www.mql5.com | //+------------------------------------------------------------------+ #include "..\ElementBase.mqh" #include "Button.mqh" #include "Pointer.mqh" //+------------------------------------------------------------------+ //| Класс формы для элементов управления | //+------------------------------------------------------------------+ class CWindow : public CElement { private: //--- Объекты для создания формы CButton m_button_close; CButton m_button_fullscreen; CButton m_button_collapse; CButton m_button_tooltip; CPointer m_xy_resize; //--- Индекс предыдущего активного окна int m_prev_active_window_index; //--- Возможность перемещать окно на графике bool m_is_movable; //--- Статус свёрнутого окна bool m_is_minimized; //--- Статус окна в полноэкранном режиме bool m_is_fullscreen; //--- Последние координаты и размеры окна перед переводом в полноэкранный размер int m_last_x; int m_last_y; int m_last_x_size; int m_last_y_size; bool m_last_auto_xresize; bool m_last_auto_yresize; //--- Минимальные размеры окна int m_minimum_x_size; int m_minimum_y_size; //--- Тип окна ENUM_WINDOW_TYPE m_window_type; //--- Режим фиксированной высоты подокна (для индикаторов) bool m_height_subwindow_mode; //--- Режим сворачивания формы в подокне индикатора bool m_rollup_subwindow_mode; //--- Высота подокна индикатора int m_subwindow_height; //--- Полная высота формы int m_full_height; //--- Высота заголовка int m_caption_height; //--- Цвета заголовка color m_caption_color; color m_caption_color_hover; color m_caption_color_locked; //--- Включает прозрачность только у заголовка bool m_transparent_only_caption; //--- Наличие кнопки для (1) закрытия, (2) разворачивания в полноэкранный режим, (3) свёртывания окна bool m_close_button; bool m_fullscreen_button; bool m_collapse_button; //--- Наличие кнопки для режима показа всплывающих подсказок bool m_tooltips_button; bool m_tooltips_button_state; //--- Размеры графика int m_chart_width; int m_chart_height; //--- Для определения границ области захвата в заголовке окна int m_right_limit; //--- Переменные связанные с перемещением окна int m_prev_x; int m_prev_y; int m_size_fixing_x; int m_size_fixing_y; //--- Состояние кнопки мыши с учётом, где она была нажата ENUM_MOUSE_STATE m_clamping_area_mouse; //--- Режим изменения размеров окна bool m_xy_resize_mode; //--- Индекс границы для изменения размеров окна int m_resize_mode_index; //--- Переменные связанные с изменением размеров окна int m_x_fixed; int m_size_fixed; int m_point_fixed; //--- Для управления состоянием графика bool m_custom_event_chart_state; //--- Custom bool m_show_prints; public: CWindow(void); ~CWindow(void); //--- Методы для создания окна bool CreateWindow(const long chart_id,const int window,const string caption_text,const int x_gap,const int y_gap); //--- private: void InitializeProperties(const long chart_id,const int subwin,const string caption_text,const int x_gap,const int y_gap); bool CreateCanvas(void); bool CreateButtons(void); bool CreateResizePointer(void); //--- public: //--- Возвращает указатели CButton *GetCloseButtonPointer(void) { return(::GetPointer(m_button_close)); } CButton *GetFullscreenButtonPointer(void) { return(::GetPointer(m_button_fullscreen)); } CButton *GetCollapseButtonPointer(void) { return(::GetPointer(m_button_collapse)); } CButton *GetTooltipButtonPointer(void) { return(::GetPointer(m_button_tooltip)); } CPointer *GetResizePointer(void) { return(::GetPointer(m_xy_resize)); } //--- (1) Получение и сохранение индекса предыдущего активного окна int PrevActiveWindowIndex(void) const { return(m_prev_active_window_index); } void PrevActiveWindowIndex(const int index) { m_prev_active_window_index=index; } //--- (1) Тип окна, (2) ограничение области захвата заголовка ENUM_WINDOW_TYPE WindowType(void) const { return(m_window_type); } void WindowType(const ENUM_WINDOW_TYPE flag) { m_window_type=flag; } void RightLimit(const int value) { m_right_limit=value; } //--- Высота заголовка void CaptionHeight(const int height) { m_caption_height=height; } int CaptionHeight(void) const { return(m_caption_height); } //--- (1) Цвета заголовка, (2) включает режим прозрачности только у заголовка окна void CaptionColor(const color clr) { m_caption_color=clr; } color CaptionColor(void) const { return(m_caption_color); } void CaptionColorHover(const color clr) { m_caption_color_hover=clr; } color CaptionColorHover(void) const { return(m_caption_color_hover); } void CaptionColorLocked(const color clr) { m_caption_color_locked=clr; } color CaptionColorLocked(void) const { return(m_caption_color_locked); } void TransparentOnlyCaption(const bool state) { m_transparent_only_caption=state; } //--- (1) Использовать кнопку для закрытия окна, (2) использовать кнопку полноэкранного режима, // (3) использовать кнопку для сворачивания/разворачивания окна, (4) использовать кнопку подсказок void CloseButtonIsUsed(const bool state) { m_close_button=state; } bool CloseButtonIsUsed(void) const { return(m_close_button); } void FullscreenButtonIsUsed(const bool state) { m_fullscreen_button=state; } bool FullscreenButtonIsUsed(void) const { return(m_fullscreen_button); } void CollapseButtonIsUsed(const bool state) { m_collapse_button=state; } bool CollapseButtonIsUsed(void) const { return(m_collapse_button); } void TooltipsButtonIsUsed(const bool state) { m_tooltips_button=state; } bool TooltipsButtonIsUsed(void) const { return(m_tooltips_button); } //--- (1) Проверка режима показа всплывающих подсказок void TooltipButtonState(const bool state) { m_tooltips_button_state=state; } bool TooltipButtonState(void) const { return(m_tooltips_button_state); } //--- Возможность перемещения окна bool IsMovable(void) const { return(m_is_movable); } void IsMovable(const bool state) { m_is_movable=state; } //--- (1) Статус свёрнутого окна, (2) возвращает область, где была зажата левая кнопка мыши bool IsMinimized(void) const { return(m_is_minimized); } void IsMinimized(const bool state) { m_is_minimized=state; } ENUM_MOUSE_STATE ClampingAreaMouse(void) const { return(m_clamping_area_mouse); } //--- Установка минимальных размеров окна void MinimumXSize(const int x_size) { m_minimum_x_size=x_size; } void MinimumYSize(const int y_size) { m_minimum_y_size=y_size; } //--- Возможность изменения размеров окна bool ResizeMode(void) const { return(m_xy_resize_mode); } void ResizeMode(const bool state) { m_xy_resize_mode=state; } //--- Статус процесса изменения размеров окна bool ResizeState(void) const { return(m_resize_mode_index!=WRONG_VALUE && m_mouse.LeftButtonState()); } //--- Ярлык по умолчанию uint DefaultIcon(void); //--- Установка состояния окна void State(const bool flag); //--- Режим сворачивания подокна индикатора void RollUpSubwindowMode(const bool flag,const bool height_mode); //--- Управление размерами void ChangeWindowWidth(const int width); void ChangeWindowHeight(const int height); //--- Изменяет высоту подокна индикатора void ChangeSubwindowHeight(const int height); //--- Получение размеров графика void SetWindowProperties(void); //--- Проверка курсора в области заголовка bool CursorInsideCaption(const int x,const int y); //--- Обнуление переменных void ZeroMoveVariables(void); void ZeroResizeVariables(void); //--- Проверка состояния левой кнопки мыши void CheckMouseButtonState(void); //--- Установка режима графика void SetChartState(void); //--- Обновление координат формы void UpdateWindowXY(const int x,const int y); //--- Пользовательский флаг управления свойствами графика void CustomEventChartState(const bool state) { m_custom_event_chart_state=state; } //--- Открытие окна void OpenWindow(void); //--- Закрытие главного окна void CloseWindow(void); //--- Закрытие диалогового окна void CloseDialogBox(void); //--- Изменение состояния окна void ChangeWindowState(void); //--- Custom void ShowPrintsFlag(bool s) { this.m_show_prints = s; } bool ShowPrintFlag() { return this.m_show_prints; } //--- public: //--- Обработчик событий графика virtual void OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam); //--- Перемещение элемента virtual void Moving(const int x,const int y); //--- Показ, скрытие, сброс, удаление virtual void Show(void); virtual void Reset(void); virtual void Delete(void); //--- Рисует элемент virtual void Draw(void); //--- public: //--- Обработка нажатия на кнопке "Закрыть окно" bool OnClickCloseButton(const int id=WRONG_VALUE,const int index=WRONG_VALUE); //--- В полноэкранный размер или в предыдущий размер окна bool OnClickFullScreenButton(const int id=WRONG_VALUE,const int index=WRONG_VALUE); //--- Обработка нажатия на кнопке "Свернуть окно" bool OnClickCollapseButton(const int id=WRONG_VALUE,const int index=WRONG_VALUE); //--- Обработка нажатия на кнопке "Всплывающие подсказки" bool OnClickTooltipsButton(const uint id,const uint index); private: //--- Методы для (1) сворачивания и (2) разворачивания окна void Collapse(void); void Expand(void); //--- Управляет размерами окна void ResizeWindow(void); //--- Проверка готовности для изменения размеров окна bool CheckResizePointer(const int x,const int y); //--- Возвращает индекс режима для изменения размеров окна int ResizeModeIndex(const int x,const int y); //--- Обновление размеров окна void UpdateSize(const int x,const int y); //--- Проверка перетаскивания границы окна int CheckDragWindowBorder(const int x,const int y); //--- Расчёт и изменение размеров окна void CalculateAndResizeWindow(const int distance); //--- Рисует задний фон virtual void DrawBackground(void); //--- Рисует передний фон virtual void DrawForeground(void); }; //+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CWindow::CWindow(void) : m_right_limit(0), m_caption_height(20), m_caption_color(C'77,118,201'), m_caption_color_hover(C'77,118,201'), m_caption_color_locked(C'188,165,219'), m_transparent_only_caption(true), m_prev_active_window_index(0), m_subwindow_height(0), m_rollup_subwindow_mode(false), m_height_subwindow_mode(false), m_is_movable(false), m_x_fixed(0), m_size_fixed(0), m_point_fixed(0), m_xy_resize_mode(false), m_resize_mode_index(WRONG_VALUE), m_is_minimized(false), m_is_fullscreen(false), m_last_x(0), m_last_y(0), m_last_x_size(0), m_last_y_size(0), m_minimum_x_size(0), m_minimum_y_size(0), m_last_auto_xresize(false), m_last_auto_yresize(false), m_close_button(true), m_fullscreen_button(false), m_collapse_button(false), m_tooltips_button(false), m_tooltips_button_state(false), m_window_type(W_MAIN), m_clamping_area_mouse(NOT_PRESSED), m_show_prints(true) { //--- Сохраним имя класса элемента в базовом классе CElementBase::ClassName(CLASS_NAME); //--- Получим размеры окна графика SetWindowProperties(); } //+------------------------------------------------------------------+ //| Destructor | //+------------------------------------------------------------------+ CWindow::~CWindow(void) { } //+------------------------------------------------------------------+ //| Обработчик событий графика | //+------------------------------------------------------------------+ void CWindow::OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam) { //--- Обработка события перемещения курсора if(id==CHARTEVENT_MOUSE_MOVE) { //--- Выйти, если форма находится в другом подокне графика if(!CElementBase::CheckSubwindowNumber()) { //--- Если прокрутка графика отключена if(!m_chart.GetInteger(CHART_MOUSE_SCROLL)) { //--- Обнуление ZeroMoveVariables(); CElementBase::MouseFocus(false); //--- Установим состояние графика m_chart.MouseScroll(true); m_chart.SetInteger(CHART_DRAG_TRADE_LEVELS,true); } //--- return; } //--- Проверка фокуса мыши CElementBase::CheckMouseFocus(); //--- Проверим и запомним состояние кнопки мыши CheckMouseButtonState(); //--- Установим состояние графика SetChartState(); //--- Выйти, если эта форма заблокирована if(CElementBase::IsLocked()) return; //--- Перерисовать элемент, если (1) было пересечение границ и (2) цвета состояний различаются if(CElementBase::CheckCrossingBorder()) { if(m_caption_color!=m_caption_color_hover) Update(true); } //--- Если управление передано окну if(m_clamping_area_mouse==PRESSED_INSIDE_HEADER) { //--- Выйти, если номера подокон не совпадают if(CElementBase::m_subwin!=CElementBase::m_mouse.SubWindowNumber()) return; //--- Обновление координат окна UpdateWindowXY(m_mouse.X(),m_mouse.Y()); return; } //--- Изменение размеров окна ResizeWindow(); return; } //--- Обработка события нажатия на графике if(id==CHARTEVENT_CLICK) { //--- Получим размеры окна графика SetWindowProperties(); return; } //--- Обработка события двойного нажатия на объекте if(id==CHARTEVENT_CUSTOM+ON_DOUBLE_CLICK) { //--- Если событие генерировалось на заголовке окна if(CursorInsideCaption(m_mouse.X(),m_mouse.Y())) { OnClickFullScreenButton(m_button_fullscreen.Id(),m_button_fullscreen.Index()); } //--- return; } //--- Обработка события нажатия на кнопках формы if(id==CHARTEVENT_CUSTOM+ON_CLICK_BUTTON) { //--- Закрыть окно if(OnClickCloseButton((uint)lparam,(uint)dparam)) return; //--- Проверка полноэкранного режима if(OnClickFullScreenButton((uint)lparam,(uint)dparam)) return; //--- Свернуть/Развернуть окно if(OnClickCollapseButton((uint)lparam,(uint)dparam)) return; //--- Если нажатие на кнопке "Всплывающие подсказки" if(OnClickTooltipsButton((uint)lparam,(uint)dparam)) return; //--- return; } //--- Событие изменения свойств графика if(id==CHARTEVENT_CHART_CHANGE) { //--- Если кнопка отжата if(m_clamping_area_mouse==NOT_PRESSED) { //--- Получим размеры окна графика SetWindowProperties(); //--- Корректировка координат UpdateWindowXY(m_x,m_y); } //--- Изменить ширину, если включен режим if(CElementBase::AutoXResizeMode()) ChangeWindowWidth(m_chart.WidthInPixels()-2); //--- Изменить высоту, если включен режим if(CElementBase::AutoYResizeMode()) ChangeWindowHeight(m_chart.HeightInPixels(m_subwin)-3); //--- return; } //--- Обработка события изменения высоты подокна эксперта if(id==CHARTEVENT_CUSTOM+ON_SUBWINDOW_CHANGE_HEIGHT) { //--- Выйти, если (1) это сообщение было от эксперта или (2) это не эксперт if(sparam==PROGRAM_NAME || CElementBase::ProgramType()!=PROGRAM_EXPERT) return; //--- Выйти, если не установлен режим фиксированной высоты подокна if(!m_height_subwindow_mode) return; //--- Рассчитать и изменить высоту подокна m_subwindow_height=(m_is_minimized)? m_caption_height+3 : m_full_height+3; ChangeSubwindowHeight(m_subwindow_height); return; } } //+------------------------------------------------------------------+ //| Создаёт форму для элементов управления | //+------------------------------------------------------------------+ bool CWindow::CreateWindow(const long chart_id,const int subwin,const string caption_text,const int x,const int y) { //--- Выйти, если идентификатор не определён if(CElementBase::Id()==WRONG_VALUE) { if(this.m_show_prints) ::Print(__FUNCTION__," > Перед созданием окна его указатель нужно сохранить в базе: CWndContainer::AddWindow(CWindow &object)"); return(false); } //--- Сохраним указатели на себя CElement::WindowPointer(this); CElement::MainPointer(this); //--- Сохраним свойства окна графика SetWindowProperties(); //--- Инициализация свойств InitializeProperties(chart_id,subwin,caption_text,x,y); //--- Создание всех объектов окна if(!CreateCanvas()) return(false); if(!CreateButtons()) return(false); if(!CreateResizePointer()) return(false); //--- Значение последнего устрановленного идентификатора CElementBase::LastId(CElementBase::Id()); //--- Если эта программа индикатор if(CElementBase::ProgramType()==PROGRAM_INDICATOR) { //--- Если установлен режим фиксированной высоты подокна if(m_height_subwindow_mode) { m_subwindow_height=m_full_height+3; ChangeSubwindowHeight(m_subwindow_height); } } //--- return(true); } //+------------------------------------------------------------------+ //| Инициализация свойств | //+------------------------------------------------------------------+ void CWindow::InitializeProperties(const long chart_id,const int subwin,const string caption_text,const int x_gap,const int y_gap) { m_chart_id =chart_id; m_subwin =subwin; m_label_text =caption_text; //--- Координты и размеры m_x =x_gap; m_y =y_gap; m_x_size =(m_auto_xresize_mode)? m_chart_width-2 : m_x_size; m_y_size =(m_auto_yresize_mode)? m_chart_height-3 : m_y_size; m_x_size =(m_x_size<1)? 200 : m_x_size; m_y_size =(m_y_size<1)? 200 : m_y_size; m_full_height =m_y_size; m_last_x_size =m_x_size; m_last_y_size =m_y_size; m_minimum_x_size =(m_minimum_x_size<200)? m_x_size : m_minimum_x_size; m_minimum_y_size =(m_minimum_y_size<200)? m_y_size : m_minimum_y_size; //--- Свойства по умолчанию m_back_color =(m_back_color!=clrNONE)? m_back_color : clrWhiteSmoke; m_icon_x_gap =(m_icon_x_gap!=WRONG_VALUE)? m_icon_x_gap : 5; m_icon_y_gap =(m_icon_y_gap!=WRONG_VALUE)? m_icon_y_gap : 2; m_label_x_gap =(m_label_x_gap!=WRONG_VALUE)? m_label_x_gap : 24; m_label_y_gap =(m_label_y_gap!=WRONG_VALUE)? m_label_y_gap : 3; m_label_color =(m_label_color!=clrNONE)? m_label_color : clrWhite; m_label_color_hover =(m_label_color_hover!=clrNONE)? m_label_color_hover : clrWhite; m_label_color_locked =(m_label_color_locked!=clrNONE)? m_label_color_locked : clrBlack; //--- Отступы от крайней точки CElementBase::XGap(x_gap); CElementBase::YGap(y_gap); } //+------------------------------------------------------------------+ //| Создаёт объект для рисования | //+------------------------------------------------------------------+ bool CWindow::CreateCanvas(void) { //--- Формирование имени объекта string name=CElementBase::ElementName("window"); //--- Размер главного окна зависит от состояния (свёрнуто/развёрнуто) if(m_window_type==W_MAIN) m_y_size=(m_is_minimized)? m_caption_height : m_full_height; //--- Создание объекта if(!CElement::CreateCanvas(name,m_x,m_y,m_x_size,m_y_size)) return(false); //--- Установим свойства /* if(CElement::IconFile() == "") { CElement::IconFile((uint)DefaultIcon()); CElement::IconFileLocked((uint)DefaultIcon()); }*/ //--- return(true); } //+------------------------------------------------------------------+ //| Создаёт кнопки на форме | //+------------------------------------------------------------------+ bool CWindow::CreateButtons(void) { //--- Если тип программы "скрипт", выйдем if(CElementBase::ProgramType()==PROGRAM_SCRIPT) return(true); //--- Счётчик, размер, количество int i=0,x_size=20; int buttons_total=4; //--- Путь к файлу uint icon_index=INT_MAX; //--- Исключение в области захвата m_right_limit=0; //--- CButton *button_obj=NULL; //--- for(int b=0; b0) { //--- Если программа типа "Индикатор" if(CElementBase::m_program_type==PROGRAM_INDICATOR) { if(!::IndicatorSetInteger(INDICATOR_HEIGHT,height)) if(this.m_show_prints) ::Print(__FUNCTION__," > Не удалось изменить высоту подокна индикатора! Номер ошибки: ",::GetLastError()); } //--- Если программа типа "Эксперт" else { //--- Отправить сообщение индикатору SubWindow.ex5 о том, что размеры окна нужно изменить ::EventChartCustom(m_chart_id,ON_SUBWINDOW_CHANGE_HEIGHT,(long)height,0,PROGRAM_NAME); } } } //+------------------------------------------------------------------+ //| Изменяет ширину окна | //+------------------------------------------------------------------+ void CWindow::ChangeWindowWidth(const int width) { //--- Если ширина не изменилась, выйдем if(width==m_canvas.XSize()) return; //--- Обновим ширину для фона и заголовка CElementBase::XSize(width); m_canvas.XSize(width); m_canvas.Resize(width,m_y_size); //--- Перерисовать окно Draw(); //--- Сообщение о том, что размеры окна были изменены ::EventChartCustom(m_chart_id,ON_WINDOW_CHANGE_XSIZE,(long)CElementBase::Id(),0,""); } //+------------------------------------------------------------------+ //| Изменяет высоту окна | //+------------------------------------------------------------------+ void CWindow::ChangeWindowHeight(const int height) { //--- Если высота не изменилась, выйдем if(height==m_canvas.YSize()) return; //--- Выйти, если окно свёрнуто if(m_is_minimized) return; //--- Обновим высоту для фона CElementBase::YSize(height); m_canvas.YSize(height); m_canvas.Resize(m_x_size,height); m_full_height=m_last_y_size; //--- Перерисовать окно Draw(); //--- Сообщение о том, что размеры окна были изменены ::EventChartCustom(m_chart_id,ON_WINDOW_CHANGE_YSIZE,(long)CElementBase::Id(),0,""); } //+------------------------------------------------------------------+ //| Получение размеров графика | //+------------------------------------------------------------------+ void CWindow::SetWindowProperties(void) { //--- Получим ширину и высоту окна графика m_chart_width =m_chart.WidthInPixels(); m_chart_height =m_chart.HeightInPixels(m_subwin); } //+------------------------------------------------------------------+ //| Проверка положения курсора в области заголовка окна | //+------------------------------------------------------------------+ bool CWindow::CursorInsideCaption(const int x,const int y) { return(x>m_x && xm_y && y=0 && limit_right=0) { new_y_point =y+m_size_fixing_y; new_x_point =x+m_size_fixing_x; } //--- Если вышли из границ графика else { if(limit_bottom>m_chart_height) // > вниз { new_y_point =m_chart_height-m_caption_height; new_x_point =x+m_size_fixing_x; } else if(limit_top<0) // > вверх { new_y_point =0; new_x_point =x+m_size_fixing_x; } if(limit_right>m_chart_width) // > вправо { new_x_point =m_chart_width-m_x_size; new_y_point =y+m_size_fixing_y; } else if(limit_left<0) // > влево { new_x_point =0; new_y_point =y+m_size_fixing_y; } } //--- Обновим координаты, если было перемещение if(new_x_point>0 || new_y_point>0) { //--- Скорректируем координаты формы m_x =(new_x_point<=0)? 1 : new_x_point; m_y =(new_y_point<=0)? 1 : new_y_point; //--- if(new_x_point>0) m_x=(m_x>m_chart_width-m_x_size-1) ? m_chart_width-m_x_size-1 : m_x; if(new_y_point>0) m_y=(m_y>m_chart_height-m_caption_height-2) ? m_chart_height-m_caption_height-2 : m_y; //--- Обнулим точки фиксации m_prev_x=0; m_prev_y=0; } } //+------------------------------------------------------------------+ //| Открытие окна | //+------------------------------------------------------------------+ void CWindow::OpenWindow(void) { //--- Показать элемент CWindow::Show(); //--- Отправить сообщение об этом ::EventChartCustom(m_chart_id,ON_OPEN_DIALOG_BOX,CElementBase::Id(),0,m_program_name); } //+------------------------------------------------------------------+ //| Закрытие диалогового окна или программы | //+------------------------------------------------------------------+ void CWindow::CloseWindow(void) { OnClickCloseButton(); } //+------------------------------------------------------------------+ //| Закрытие диалогового окна | //+------------------------------------------------------------------+ void CWindow::CloseDialogBox(void) { //--- Отправить сообщение об этом ::EventChartCustom(m_chart_id,ON_CLOSE_DIALOG_BOX,CElementBase::Id(),m_prev_active_window_index,m_label_text); } //+------------------------------------------------------------------+ //| Изменение состояния окна на противополжное (свернуть/развернуть) | //+------------------------------------------------------------------+ void CWindow::ChangeWindowState(void) { OnClickCollapseButton(); } //+------------------------------------------------------------------+ //| Устанавливает состояние окна | //+------------------------------------------------------------------+ void CWindow::State(const bool flag) { int elements_total=CElement::ElementsTotal(); //--- Если нужно заблокировать окно if(!flag) { //--- Установим статус CElementBase::IsLocked(true); for(int i=0; i The program was removed from the chart with your consent!"); //--- Удаление эксперта с графика ::ExpertRemove(); return(true); // } //else // { // m_button_close.MouseFocus(false); // m_button_close.Update(true); // } } //--- Если программа типа "Индикатор" else if(CElementBase::ProgramType()==PROGRAM_INDICATOR) { //--- Удаление индикатора с графика if(::ChartIndicatorDelete(m_chart_id,::ChartWindowFind(),CElementBase::ProgramName())) { // if(this.m_show_prints) ::Print(__FUNCTION__," > The program was removed from the chart with your consent!"); return(true); } } } //--- Если это диалоговое окно, закроем его else if(m_window_type==W_DIALOG) CloseDialogBox(); //--- return(false); } //+------------------------------------------------------------------+ //| В полноэкранный размер или в предыдущий размер формы | //+------------------------------------------------------------------+ bool CWindow::OnClickFullScreenButton(const int id=WRONG_VALUE,const int index=WRONG_VALUE) { //--- Проверить идентификатор и индекс элемента, если был внешний вызов int check_id =(id!=WRONG_VALUE)? id : CElementBase::Id(); int check_index =(index!=WRONG_VALUE)? index : CElementBase::Index(); //--- Выйти, если индексы не совпадают if(check_id!=m_button_fullscreen.Id() || check_index!=m_button_fullscreen.Index()) return(false); //--- Если окно не в полноэкранном размере if(!m_is_fullscreen) { //--- Перевести в полноэкранный размер m_is_fullscreen=true; //--- Получим текущие размеры окна графика SetWindowProperties(); //--- Запомним текущие координаты и размеры формы m_last_x =m_x; m_last_y =m_y; m_last_x_size =m_x_size; m_last_y_size =m_full_height; m_last_auto_xresize =m_auto_xresize_mode; m_last_auto_yresize =m_auto_yresize_mode; //--- Включить автоизменение размеров формы m_auto_xresize_mode=true; m_auto_yresize_mode=true; //--- Развернуть форму на весь график ChangeWindowWidth(m_chart.WidthInPixels()-2); ChangeWindowHeight(m_chart.HeightInPixels(m_subwin)-3); //--- Обновить местоположение m_x=m_y=1; Moving(m_x,m_y); //--- Заменить изображение в кнопке m_button_fullscreen.IconFile((uint)RESOURCE_MINIMIZE_TO_WINDOW); m_button_fullscreen.IconFileLocked((uint)RESOURCE_MINIMIZE_TO_WINDOW); } //--- Если окно в полноэкранном размере else { //--- Перевести в предыдущий размер окна m_is_fullscreen=false; //--- Отключить автоизменение размеров m_auto_xresize_mode=m_last_auto_xresize; m_auto_yresize_mode=m_last_auto_yresize; //--- Если режим отключен, то установить прежний размер if(!m_auto_xresize_mode) ChangeWindowWidth(m_last_x_size); if(!m_auto_yresize_mode) ChangeWindowHeight(m_last_y_size); //--- Обновить местоположение m_x=m_last_x; m_y=m_last_y; Moving(m_x,m_y); //--- Заменить изображение в кнопке m_button_fullscreen.IconFile((uint)RESOURCE_FULL_SCREEN); m_button_fullscreen.IconFileLocked((uint)RESOURCE_FULL_SCREEN); } //--- Снять фокус с кнопки m_button_fullscreen.MouseFocus(false); m_button_fullscreen.Update(true); ChartRedraw(); return(true); } //+------------------------------------------------------------------+ //| Проверка на события сворачивания/разворачивания окна | //+------------------------------------------------------------------+ bool CWindow::OnClickCollapseButton(const int id=WRONG_VALUE,const int index=WRONG_VALUE) { //--- Проверить идентификатор и индекс элемента, если был внешний вызов int check_id =(id!=WRONG_VALUE)? id : CElementBase::Id(); int check_index =(index!=WRONG_VALUE)? index : CElementBase::Index(); //--- Выйти, если индексы не совпадают if(check_id!=m_button_collapse.Id() || check_index!=m_button_collapse.Index()) return(false); //--- Если окно развёрнуто if(!m_is_minimized) Collapse(); else Expand(); //--- Снять фокус с кнопки m_button_collapse.MouseFocus(false); m_button_collapse.Update(true); return(true); } //+------------------------------------------------------------------+ //| Сворачивает окно | //+------------------------------------------------------------------+ void CWindow::Collapse(void) { //--- Заменить кнопку m_button_collapse.IconFile((uint)RESOURCE_DOWN_THIN_WHITE); m_button_collapse.IconFileLocked((uint)RESOURCE_DOWN_THIN_WHITE); //--- Установить и запомнить размер CElementBase::YSize(m_caption_height); m_canvas.YSize(m_caption_height); m_canvas.Resize(m_x_size,m_canvas.YSize()); //--- Состояние формы "Свёрнуто" m_is_minimized=true; //--- Перерисовать окно Update(true); //--- Рассчитаем высоту подокна m_subwindow_height=m_caption_height+3; //--- Если эта программа в подокне с фиксированной высотой и с режимом сворачивания подокна, // установим размер для подокна программы if(m_height_subwindow_mode) if(m_rollup_subwindow_mode) ChangeSubwindowHeight(m_subwindow_height); //--- Получим номер подокна программы int subwin=(CElementBase::ProgramType()==PROGRAM_INDICATOR)? ::ChartWindowFind() : m_subwin; //--- Отправим сообщение об этом ::EventChartCustom(m_chart_id,ON_WINDOW_COLLAPSE,CElementBase::Id(),subwin,""); //--- Отправим сообщение об изменении в графическом интерфейсе ::EventChartCustom(m_chart_id,ON_CHANGE_GUI,CElementBase::Id(),0.0,""); } //+------------------------------------------------------------------+ //| Разворачивает окно | //+------------------------------------------------------------------+ void CWindow::Expand(void) { //--- Заменить кнопку m_button_collapse.IconFile((uint)RESOURCE_UP_THIN_WHITE); m_button_collapse.IconFileLocked((uint)RESOURCE_UP_THIN_WHITE); //--- Установить и запомнить размер CElementBase::YSize(m_full_height); m_canvas.YSize(m_full_height); m_canvas.Resize(m_x_size,m_canvas.YSize()); //--- Состояние формы "Развёрнуто" m_is_minimized=false; //--- Перерисовать окно Update(true); //--- Рассчитаем высоту подокна m_subwindow_height=m_full_height+3; //--- Если это индикатор в подокне с фиксированной высотой и с режимом сворачивания подокна, // установим размер для подокна программы if(m_height_subwindow_mode) if(m_rollup_subwindow_mode) ChangeSubwindowHeight(m_subwindow_height); //--- Получим номер подокна программы int subwin=(CElementBase::ProgramType()==PROGRAM_INDICATOR)? ::ChartWindowFind() : m_subwin; //--- Отправим сообщение об этом ::EventChartCustom(m_chart_id,ON_WINDOW_EXPAND,CElementBase::Id(),subwin,""); //--- Отправим сообщение об изменении в графическом интерфейсе ::EventChartCustom(m_chart_id,ON_CHANGE_GUI,CElementBase::Id(),0.0,""); } //+------------------------------------------------------------------+ //| Обработка нажатия на кнопке "Всплывающие подсказки" | //+------------------------------------------------------------------+ bool CWindow::OnClickTooltipsButton(const uint id,const uint index) { //--- Эта кнопка не нужна, если окно диалоговое if(m_window_type==W_DIALOG) return(false); //--- Выйти, если индексы не совпадают if(id!=m_button_tooltip.Id() || index!=m_button_tooltip.Index()) return(false); //--- Запомним состояние в поле класса m_tooltips_button_state=m_button_tooltip.IsPressed(); //--- Отправим сообщение об этом ::EventChartCustom(m_chart_id,ON_WINDOW_TOOLTIPS,CElementBase::Id(),CElementBase::Index(),""); return(true); } //+------------------------------------------------------------------+ //| Управляет размерами окна | //+------------------------------------------------------------------+ void CWindow::ResizeWindow(void) { //--- Выйти, если окно недоступно if(!CElementBase::IsAvailable()) return; //--- Выйти, если кнопка мыши была нажата не над границей формы if(m_clamping_area_mouse!=PRESSED_INSIDE_BORDER && m_clamping_area_mouse!=NOT_PRESSED) return; //--- Выйти, если (1) режим изменения размеров окна отключен или // (2) окно в полноэкранном размере или (3) окно минимизировано if(!m_xy_resize_mode || m_is_fullscreen || m_is_minimized) return; //--- Координаты int x =m_mouse.RelativeX(m_canvas); int y =m_mouse.RelativeY(m_canvas); //--- Проверка готовности для изменения ширины списков if(!CheckResizePointer(x,y)) return; //--- Обновление размеров окна UpdateSize(x,y); } //+------------------------------------------------------------------+ //| Проверка готовности для изменения размеров окна | //+------------------------------------------------------------------+ bool CWindow::CheckResizePointer(const int x,const int y) { //--- Определим текущий индекс режима m_resize_mode_index=ResizeModeIndex(x,y); //--- Если курсор скрыт if(!m_xy_resize.IsVisible()) { //--- Если режим определён if(m_resize_mode_index!=WRONG_VALUE) { //--- Для определения индекса отображаемой картинки указателя курсора мыши int index=WRONG_VALUE; //--- Если на вертикальных границах if(m_resize_mode_index==0 || m_resize_mode_index==1) index=0; //--- Если на горизонтальных границах else if(m_resize_mode_index==2) index=1; //--- Изменить картинку m_xy_resize.ChangeImage(0,index); //--- Переместить, перерисовать и показать m_xy_resize.Moving(m_mouse.X(),m_mouse.Y()); m_xy_resize.Update(true); m_xy_resize.Reset(); return(true); } } else { //--- Переместить указатель if(m_resize_mode_index!=WRONG_VALUE) m_xy_resize.Moving(m_mouse.X(),m_mouse.Y()); //--- Скрыть указатель else if(!m_mouse.LeftButtonState()) { //--- Скрыть указатель и обнулить переменные m_xy_resize.Hide(); ZeroResizeVariables(); } //--- Обновить график m_chart.Redraw(); return(true); } //--- return(false); } //+------------------------------------------------------------------+ //| Возвращает индекс режима для изменения размеров окна | //+------------------------------------------------------------------+ int CWindow::ResizeModeIndex(const int x,const int y) { //--- Вернуть индекс границы, если уже есть захват if(m_resize_mode_index!=WRONG_VALUE && m_mouse.LeftButtonState()) return(m_resize_mode_index); //--- Толщина, отступ и индекс границы int width =5; int offset =15; int index =WRONG_VALUE; //--- Проверка фокуса на левой границе if(x>0 && xm_caption_height+offset && ym_x_size-width && xm_caption_height+offset && ym_y_size-width && yoffset && x