1786 lines
142 KiB
MQL5
1786 lines
142 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| WndEvents.mqh |
|
|
//| Copyright 2015, MetaQuotes Software Corp. |
|
|
//| http://www.mql5.com |
|
|
//+------------------------------------------------------------------+
|
|
#include "Defines.mqh"
|
|
#include "WndContainer.mqh"
|
|
//+------------------------------------------------------------------+
|
|
//| Класс для обработки событий |
|
|
//+------------------------------------------------------------------+
|
|
class CWndEvents : public CWndContainer {
|
|
protected:
|
|
//--- Экземпляр класса для управления графиком
|
|
CChart m_chart;
|
|
//--- Идентификатор и номер окна графика
|
|
long m_chart_id;
|
|
int m_subwin;
|
|
//--- Имя программы
|
|
string m_program_name;
|
|
//--- Короткое имя индикатора
|
|
string m_indicator_shortname;
|
|
//--- Индекс активного окна
|
|
int m_active_window_index;
|
|
//--- Хэндл подокна эксперта
|
|
int m_subwindow_handle;
|
|
//--- Имя подокна эксперта
|
|
string m_subwindow_shortname;
|
|
//--- Количество подокон на графике после установки подокна эксперта
|
|
int m_subwindows_total;
|
|
//---
|
|
private:
|
|
//--- Параметры событий
|
|
int m_id;
|
|
long m_lparam;
|
|
double m_dparam;
|
|
string m_sparam;
|
|
//---
|
|
public:
|
|
CWndEvents(void);
|
|
~CWndEvents(void);
|
|
//--- Виртуальный обработчик события графика
|
|
virtual void OnEvent(const int id, const long &lparam, const double &dparam, const string &sparam) {}
|
|
//--- Таймер
|
|
void OnTimerEvent(void);
|
|
//---
|
|
public:
|
|
//--- Обработчики событий графика
|
|
void ChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam);
|
|
//---
|
|
public:
|
|
//--- Возвращает индекс активированного окна
|
|
int GetActiveWindowIndex(void) {
|
|
return(m_active_window_index);
|
|
}
|
|
//---
|
|
private:
|
|
void ChartEventCustom(void);
|
|
void ChartEventClick(void);
|
|
void ChartEventMouseMove(void);
|
|
void ChartEventObjectClick(void);
|
|
void ChartEventEndEdit(void);
|
|
void ChartEventChartChange(void);
|
|
//--- Проверка событий в элементах управления
|
|
void CheckElementsEvents(void);
|
|
|
|
//--- Определение номера подокна
|
|
void DetermineSubwindow(void);
|
|
//--- Удалить подокно эксперта
|
|
void DeleteExpertSubwindow(void);
|
|
//--- Проверка и обновление номера окна эксперта
|
|
void CheckExpertSubwindowNumber(void);
|
|
//--- Проверка и обновление номера окна индикатора
|
|
void CheckSubwindowNumber(void);
|
|
//--- Изменение размеров заблокированной главной формы
|
|
void ResizeLockedWindow(void);
|
|
|
|
//--- Инициализация параметров событий
|
|
void InitChartEventsParams(const int id, const long lparam, const double dparam, const string sparam);
|
|
//--- Перемещение окна
|
|
void MovingWindow(const bool moving_mode = false);
|
|
//--- Проверка событий всех элементов по таймеру
|
|
void CheckElementsEventsTimer(void);
|
|
//--- Установка состояния графика
|
|
void SetChartState(void);
|
|
//---
|
|
protected:
|
|
//--- Удаление интерфейса
|
|
void Destroy(void);
|
|
//--- Перерисовка окна
|
|
void ResetWindow(void);
|
|
//---
|
|
public:
|
|
//--- Инициализация ядра
|
|
void InitializeCore(void);
|
|
//--- Завершение создания GUI
|
|
void CompletedGUI(void);
|
|
//--- Обновление положения элементов
|
|
void Moving(void);
|
|
//---
|
|
protected:
|
|
//--- Скрытие всех элементов
|
|
void Hide(void);
|
|
//--- Показ элементов указанного окна
|
|
void Show(const uint window_index);
|
|
//--- Восстановление приоритетов на нажатие левой кнопкой мыши
|
|
void SetZorders(void);
|
|
//--- Перерисовка элементов
|
|
void Update(const bool redraw = false);
|
|
|
|
//--- Перемещает всплывающие подсказки на верхний слой
|
|
void ResetTooltips(void);
|
|
//--- Показывает элементы только выделенных вкладок
|
|
void ShowTabElements(const uint window_index);
|
|
//--- Устанавливает состояние доступности элементов
|
|
void SetAvailable(const uint window_index, const bool state);
|
|
|
|
//--- Формирует массив элементов с таймером
|
|
void FormTimerElementsArray(void);
|
|
//--- Формирует массив доступных элементов
|
|
void FormAvailableElementsArray(void);
|
|
//--- Формирует массив элементов с авто-ресайзом (X)
|
|
void FormAutoXResizeElementsArray(void);
|
|
//--- Формирует массив элементов с авто-ресайзом (Y)
|
|
void FormAutoYResizeElementsArray(void);
|
|
//---
|
|
private:
|
|
//--- Перетаскивание формы завершено
|
|
bool OnWindowEndDrag(void);
|
|
//--- Сворачивание/разворачивание формы
|
|
bool OnWindowCollapse(void);
|
|
bool OnWindowExpand(void);
|
|
//--- Обработка изменения размеров окна
|
|
bool OnWindowChangeXSize(void);
|
|
bool OnWindowChangeYSize(void);
|
|
//--- Включение/отключение всплывающих подсказок
|
|
bool OnWindowTooltips(void);
|
|
//--- Скрытие всех контекстных меню от пункта инициатора
|
|
bool OnHideBackContextMenus(void);
|
|
//--- Скрытие всех контекстных меню
|
|
bool OnHideContextMenus(void);
|
|
//--- Открытие диалогового окна
|
|
bool OnOpenDialogBox(void);
|
|
//--- Закрытие диалогового окна
|
|
bool OnCloseDialogBox(void);
|
|
//--- Определение доступных элементов
|
|
bool OnSetAvailable(void);
|
|
//--- Определение заблокированных элементов
|
|
bool OnSetLocked(void);
|
|
//--- Изменения в графическом интерфейсе
|
|
bool OnChangeGUI(void);
|
|
//---
|
|
private:
|
|
//--- Возвращает индекс активированного окна
|
|
int ActivatedWindowIndex(void);
|
|
//--- Возвращает индекс активированного главного меню
|
|
int ActivatedMenuBarIndex(void);
|
|
//--- Возвращает индекс активированного пункта меню
|
|
int ActivatedMenuItemIndex(void);
|
|
//--- Возвращает индекс активированной сдвоенной кнопки
|
|
int ActivatedSplitButtonIndex(void);
|
|
//--- Возвращает индекс активированного комбо-бокса
|
|
int ActivatedComboBoxIndex(void);
|
|
//--- Возвращает индекс активированного выпадающего календаря
|
|
int ActivatedDropCalendarIndex(void);
|
|
//--- Возвращает индекс активированной полосы прокрутки
|
|
int ActivatedScrollIndex(void);
|
|
//--- Возвращает индекс активированной таблицы
|
|
int ActivatedTableIndex(void);
|
|
//--- Возвращает индекс активированного слайдера
|
|
int ActivatedSliderIndex(void);
|
|
//--- Возвращает индекс активированного древовидного списка
|
|
int ActivatedTreeViewIndex(void);
|
|
//--- Возвращает индекс активированного стандартного графика
|
|
int ActivatedSubChartIndex(void);
|
|
|
|
//--- Проверяет и делает контекстное меню доступным
|
|
void CheckContextMenu(CMenuItem &object);
|
|
};
|
|
//+------------------------------------------------------------------+
|
|
//| Constructor |
|
|
//+------------------------------------------------------------------+
|
|
CWndEvents::CWndEvents(void) : m_chart_id(::ChartID()),
|
|
m_subwin(0),
|
|
m_active_window_index(0),
|
|
m_indicator_shortname(""),
|
|
m_program_name(PROGRAM_NAME),
|
|
m_subwindow_handle(INVALID_HANDLE),
|
|
m_subwindow_shortname(""),
|
|
m_subwindows_total(1) {
|
|
|
|
//--- Выйти, если это не реал-тайм
|
|
if(::MQLInfoInteger(MQL_TESTER) || ::MQLInfoInteger(MQL_FRAME_MODE))
|
|
return;
|
|
//--- Инициализация ядра
|
|
InitializeCore();
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Destructor |
|
|
//+------------------------------------------------------------------+
|
|
CWndEvents::~CWndEvents(void) {
|
|
//--- Выйти, если это не реал-тайм
|
|
if(::MQLInfoInteger(MQL_TESTER))
|
|
return;
|
|
//--- Удалить таймер
|
|
::EventKillTimer();
|
|
//--- Включим управление
|
|
m_chart.MouseScroll(true);
|
|
m_chart.SetInteger(CHART_DRAG_TRADE_LEVELS, true);
|
|
//--- Отключим слежение за событиями мыши
|
|
m_chart.EventMouseMove(false);
|
|
//--- Включим вызов командной строки для клавиш Space и Enter
|
|
m_chart.SetInteger(CHART_QUICK_NAVIGATION, true);
|
|
//--- Отсоединиться от графика
|
|
m_chart.Detach();
|
|
//--- Удалим подокно индикатора
|
|
DeleteExpertSubwindow();
|
|
//--- Стереть коммент
|
|
::Comment("");
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Инициализация ядра |
|
|
//+------------------------------------------------------------------+
|
|
void CWndEvents::InitializeCore(void) {
|
|
//--- Включим таймер, если вне тестера
|
|
if(!::MQLInfoInteger(MQL_TESTER)) {
|
|
::ResetLastError();
|
|
bool is_timer =::EventSetMillisecondTimer(TIMER_STEP_MSC);
|
|
}
|
|
//--- Получим ID текущего графика
|
|
m_chart.Attach();
|
|
//--- Включим слежение за событиями мыши
|
|
m_chart.EventMouseMove(true);
|
|
//--- Отключим вызов командной строки для клавиш Space и Enter
|
|
m_chart.SetInteger(CHART_QUICK_NAVIGATION, false);
|
|
//--- Определение номера подокна
|
|
DetermineSubwindow();
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Инициализация событийных переменных |
|
|
//+------------------------------------------------------------------+
|
|
void CWndEvents::InitChartEventsParams(const int id, const long lparam, const double dparam, const string sparam) {
|
|
m_id = id;
|
|
m_lparam = lparam;
|
|
m_dparam = dparam;
|
|
m_sparam = sparam;
|
|
//--- Получим параметры мыши
|
|
m_mouse.OnEvent(id, lparam, dparam, sparam);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Обработка событий программы |
|
|
//+------------------------------------------------------------------+
|
|
void CWndEvents::ChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) {
|
|
//--- Если массив пуст, выйдем
|
|
if(CWndContainer::WindowsTotal() < 1) {
|
|
//--- Направление события в файл приложения
|
|
OnEvent(id, lparam, dparam, sparam);
|
|
return;
|
|
}
|
|
//--- Инициализация полей параметров событий
|
|
InitChartEventsParams(id, lparam, dparam, sparam);
|
|
//--- Пользовательские события
|
|
ChartEventCustom();
|
|
//--- Проверка событий элементов интерфейса
|
|
CheckElementsEvents();
|
|
//--- Событие перемещения мыши
|
|
ChartEventMouseMove();
|
|
//--- Событие изменения свойств графика
|
|
ChartEventChartChange();
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Проверка событий элементов управления |
|
|
//+------------------------------------------------------------------+
|
|
void CWndEvents::CheckElementsEvents(void) {
|
|
//--- Обработка события перемещения курсора мыши
|
|
if(m_id == CHARTEVENT_MOUSE_MOVE) {
|
|
//--- Выйти, если форма находится в другом подокне графика
|
|
if(!m_windows[m_active_window_index].CheckSubwindowNumber())
|
|
return;
|
|
//--- Проверяем только доступные элементы
|
|
int available_elements_total = CWndContainer::AvailableElementsTotal(m_active_window_index);
|
|
for(int e = 0; e < available_elements_total; e++) {
|
|
CElement *el = m_wnd[m_active_window_index].m_available_elements[e];
|
|
//--- Проверка фокуса над элементами
|
|
el.CheckMouseFocus();
|
|
//--- Обработка события
|
|
el.OnEvent(m_id, m_lparam, m_dparam, m_sparam);
|
|
}
|
|
}
|
|
//--- Все события, кроме перемещения курсора мыши
|
|
else {
|
|
int elements_total = CWndContainer::ElementsTotal(m_active_window_index);
|
|
for(int e = 0; e < elements_total; e++) {
|
|
//--- Проверяем только доступные элементы
|
|
CElement *el = m_wnd[m_active_window_index].m_elements[e];
|
|
if(!el.IsVisible() || !el.CElementBase::IsAvailable() || el.CElementBase::IsLocked())
|
|
continue;
|
|
//--- Обработка события в обработчике элемента
|
|
el.OnEvent(m_id, m_lparam, m_dparam, m_sparam);
|
|
}
|
|
}
|
|
//--- Направление события в файл приложения
|
|
OnEvent(m_id, m_lparam, m_dparam, m_sparam);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Проверка пользовательских событий (CHARTEVENT_CUSTOM) |
|
|
//+------------------------------------------------------------------+
|
|
void CWndEvents::ChartEventCustom(void) {
|
|
//--- Если сигнал на определение доступных элементов
|
|
if(OnSetAvailable())
|
|
return;
|
|
//--- Если сигнал об изменении в графическом интерфейсе
|
|
if(OnChangeGUI())
|
|
return;
|
|
//--- Если сигнал на определение заблокированных элементов
|
|
if(OnSetLocked())
|
|
return;
|
|
//--- Если сигнал об окончании перетаскивания формы
|
|
if(OnWindowEndDrag())
|
|
return;
|
|
//--- Если сигнал свернуть форму
|
|
if(OnWindowCollapse())
|
|
return;
|
|
//--- Если сигнал развернуть форму
|
|
if(OnWindowExpand())
|
|
return;
|
|
//--- Если сигнал изменить размер элементов по оси X
|
|
if(OnWindowChangeXSize())
|
|
return;
|
|
//--- Если сигнал изменить размер элементов по оси Y
|
|
if(OnWindowChangeYSize())
|
|
return;
|
|
//--- Если сигнал включить/выключить всплывающие подсказки
|
|
if(OnWindowTooltips())
|
|
return;
|
|
//--- Если сигнал на скрытие контекстных меню от пункта инициатора
|
|
if(OnHideBackContextMenus())
|
|
return;
|
|
//--- Если сигнал на скрытие всех контекстных меню
|
|
if(OnHideContextMenus())
|
|
return;
|
|
//--- Если сигнал на открытие диалогового окна
|
|
if(OnOpenDialogBox())
|
|
return;
|
|
//--- Если сигнал на закрытие диалогового окна
|
|
if(OnCloseDialogBox())
|
|
return;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Событие CHARTEVENT CLICK |
|
|
//+------------------------------------------------------------------+
|
|
void CWndEvents::ChartEventClick(void) {
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Событие CHARTEVENT MOUSE MOVE |
|
|
//+------------------------------------------------------------------+
|
|
void CWndEvents::ChartEventMouseMove(void) {
|
|
//--- Выйти, если это не событие перемещения курсора
|
|
if(m_id != CHARTEVENT_MOUSE_MOVE)
|
|
return;
|
|
//--- Перемещение окна
|
|
MovingWindow();
|
|
//--- Установка состояния графика
|
|
SetChartState();
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Событие CHARTEVENT OBJECT CLICK |
|
|
//+------------------------------------------------------------------+
|
|
void CWndEvents::ChartEventObjectClick(void) {
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Событие CHARTEVENT OBJECT ENDEDIT |
|
|
//+------------------------------------------------------------------+
|
|
void CWndEvents::ChartEventEndEdit(void) {
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Событие CHARTEVENT CHART CHANGE |
|
|
//+------------------------------------------------------------------+
|
|
void CWndEvents::ChartEventChartChange(void) {
|
|
//--- Событие изменения свойств графика
|
|
if(m_id != CHARTEVENT_CHART_CHANGE)
|
|
return;
|
|
//--- Проверка и обновление номера окна эксперта
|
|
CheckExpertSubwindowNumber();
|
|
//--- Проверка и обновление номера окна индикатора
|
|
CheckSubwindowNumber();
|
|
//--- Перемещение окна
|
|
MovingWindow(true);
|
|
//--- Изменение размеров заблокированного главного окна
|
|
ResizeLockedWindow();
|
|
//--- Перерисуем график
|
|
m_chart.Redraw();
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Таймер |
|
|
//+------------------------------------------------------------------+
|
|
void CWndEvents::OnTimerEvent(void) {
|
|
//--- Выйти, если курсор мыши в состоянии покоя (разница между вызовами > 300 ms) и левая кнопка мыши отжата
|
|
if(m_mouse.GapBetweenCalls() > 300 && !m_mouse.LeftButtonState()) {
|
|
int text_boxes_total = CWndContainer::ElementsTotal(m_active_window_index, E_TEXT_BOX);
|
|
for(int e = 0; e < text_boxes_total; e++)
|
|
m_wnd[m_active_window_index].m_text_boxes[e].OnEventTimer();
|
|
//---
|
|
return;
|
|
}
|
|
//--- Если массив пуст, выйдем
|
|
if(CWndContainer::WindowsTotal() < 1)
|
|
return;
|
|
//--- Проверка событий всех элементов по таймеру
|
|
CheckElementsEventsTimer();
|
|
//--- Перерисуем график, если окно в режиме перемещения
|
|
if(m_windows[m_active_window_index].ClampingAreaMouse() == PRESSED_INSIDE_HEADER)
|
|
m_chart.Redraw();
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Событие окончания перетаскивания формы |
|
|
//+------------------------------------------------------------------+
|
|
bool CWndEvents::OnWindowEndDrag(void) {
|
|
//--- Если сигнал свернуть форму
|
|
if(m_id != CHARTEVENT_CUSTOM + ON_WINDOW_DRAG_END)
|
|
return(false);
|
|
//--- Если идентификатор окна и номер подокна совпадают
|
|
if(m_lparam == m_windows[0].Id() && (int)m_dparam == m_subwin) {
|
|
//--- Установить режим показа во всех главных элементах
|
|
int main_total = MainElementsTotal(m_active_window_index);
|
|
for(int e = 0; e < main_total; e++) {
|
|
CElement *el = m_wnd[m_active_window_index].m_main_elements[e];
|
|
el.Moving(false);
|
|
}
|
|
}
|
|
//--- Обновить расположение всех элементов
|
|
m_chart.Redraw();
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Событие свёртывания формы |
|
|
//+------------------------------------------------------------------+
|
|
bool CWndEvents::OnWindowCollapse(void) {
|
|
//--- Если сигнал свернуть форму
|
|
if(m_id != CHARTEVENT_CUSTOM + ON_WINDOW_COLLAPSE)
|
|
return(false);
|
|
//--- Если идентификатор окна и номер подокна совпадают
|
|
if(m_lparam == m_windows[0].Id() && (int)m_dparam == m_subwin) {
|
|
int elements_total = CWndContainer::ElementsTotal(0);
|
|
for(int e = 0; e < elements_total; e++) {
|
|
CElement *el = m_wnd[0].m_elements[e];
|
|
//--- Скрыть все элементы кроме формы
|
|
if(el.Id() > 0)
|
|
el.Hide();
|
|
}
|
|
//--- Сбросить цвета формы
|
|
m_windows[0].ResetColors();
|
|
}
|
|
//--- Обновить расположение всех элементов
|
|
m_chart.Redraw();
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Событие развёртывания формы |
|
|
//+------------------------------------------------------------------+
|
|
bool CWndEvents::OnWindowExpand(void) {
|
|
//--- Если сигнал "Развернуть форму"
|
|
if(m_id != CHARTEVENT_CUSTOM + ON_WINDOW_EXPAND)
|
|
return(false);
|
|
//--- Индекс активного окна
|
|
int awi = m_active_window_index;
|
|
//--- Если идентификатор окна и номер подокна совпадают
|
|
if(m_lparam != m_windows[awi].Id() || (int)m_dparam != m_subwin)
|
|
return(true);
|
|
//--- Изменить высоту окна, если включен режим
|
|
if(m_windows[awi].AutoYResizeMode())
|
|
m_windows[awi].ChangeWindowHeight(m_chart.HeightInPixels(m_subwin) - 3);
|
|
//---
|
|
int y_resize_total = CWndContainer::AutoYResizeElementsTotal(awi);
|
|
for(int e = 0; e < y_resize_total; e++) {
|
|
CElement *el = m_wnd[awi].m_auto_y_resize_elements[e];
|
|
//--- Если включен режим, то подогнать высоту
|
|
if(el.AutoYResizeMode()) {
|
|
el.ChangeHeightByBottomWindowSide();
|
|
el.Update();
|
|
}
|
|
}
|
|
//--- Показать элементы
|
|
Show(awi);
|
|
//--- Показать элементы только выделенных вкладок
|
|
ShowTabElements(awi);
|
|
//--- Обновить для отображения всех изменений
|
|
int elements_total = CWndContainer::ElementsTotal(awi);
|
|
for(int e = 0; e < elements_total; e++) {
|
|
CElement *el = m_wnd[awi].m_elements[e];
|
|
if(el.IsVisible())
|
|
el.Update();
|
|
}
|
|
//--- Обновить расположение всех элементов
|
|
m_chart.Redraw();
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Событие изменения размеров элементов по оси X |
|
|
//+------------------------------------------------------------------+
|
|
bool CWndEvents::OnWindowChangeXSize(void) {
|
|
//--- Если сигнал "Изменить размер элементов"
|
|
if(m_id != CHARTEVENT_CUSTOM + ON_WINDOW_CHANGE_XSIZE)
|
|
return(false);
|
|
//--- Выйти, если идентификаторы окна не совпадают
|
|
if(m_lparam != m_windows[m_active_window_index].Id())
|
|
return(true);
|
|
//--- Обновить положение элементов
|
|
Moving();
|
|
//--- Обновить окно
|
|
m_windows[m_active_window_index].Update();
|
|
//--- Изменить ширину
|
|
int x_resize_total = CWndContainer::AutoXResizeElementsTotal(m_active_window_index);
|
|
for(int e = 0; e < x_resize_total; e++) {
|
|
CElement *el = m_wnd[m_active_window_index].m_auto_x_resize_elements[e];
|
|
el.ChangeWidthByRightWindowSide();
|
|
//el.Update();
|
|
}
|
|
//--- Обновить положение элементов
|
|
Moving();
|
|
//---
|
|
for(int e = 0; e < x_resize_total; e++) {
|
|
CElement *el = m_wnd[m_active_window_index].m_auto_x_resize_elements[e];
|
|
el.Moving(false);
|
|
}
|
|
m_chart.Redraw();
|
|
for(int e = 0; e < x_resize_total; e++) {
|
|
CElement *el = m_wnd[m_active_window_index].m_auto_x_resize_elements[e];
|
|
el.Update();
|
|
}
|
|
//--- Обновить для отображения всех изменений в древовидных списках
|
|
int treeviews_total = ElementsTotal(m_active_window_index, E_TREE_VIEW);
|
|
for(int t = 0; t < treeviews_total; t++) {
|
|
CTreeView *tv = m_wnd[m_active_window_index].m_treeview_lists[t];
|
|
tv.RedrawContentList();
|
|
tv.UpdateContentList();
|
|
}
|
|
//--- Показать указатель курсора, если в режиме ручного изменения ширины
|
|
if(m_windows[m_active_window_index].ResizeState())
|
|
m_windows[m_active_window_index].GetResizePointer().Reset();
|
|
//--- Обновить расположение всех элементов
|
|
m_chart.Redraw();
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Событие изменения размеров элементов по оси Y |
|
|
//+------------------------------------------------------------------+
|
|
bool CWndEvents::OnWindowChangeYSize(void) {
|
|
//--- Если сигнал "Изменить размер элементов"
|
|
if(m_id != CHARTEVENT_CUSTOM + ON_WINDOW_CHANGE_YSIZE)
|
|
return(false);
|
|
//--- Выйти, если идентификаторы окна не совпадают
|
|
if(m_lparam != m_windows[m_active_window_index].Id())
|
|
return(true);
|
|
//--- Обновить положение элементов
|
|
Moving();
|
|
//--- Обновить окно
|
|
m_windows[m_active_window_index].Update();
|
|
//--- Изменить высоту
|
|
int y_resize_total = CWndContainer::AutoYResizeElementsTotal(m_active_window_index);
|
|
for(int e = 0; e < y_resize_total; e++) {
|
|
CElement *el = m_wnd[m_active_window_index].m_auto_y_resize_elements[e];
|
|
el.ChangeHeightByBottomWindowSide();
|
|
//el.Update();
|
|
}
|
|
//--- Обновить положение элементов
|
|
Moving();
|
|
//---
|
|
for(int e = 0; e < y_resize_total; e++) {
|
|
CElement *el = m_wnd[m_active_window_index].m_auto_y_resize_elements[e];
|
|
el.Moving(false);
|
|
}
|
|
m_chart.Redraw();
|
|
for(int e = 0; e < y_resize_total; e++) {
|
|
CElement *el = m_wnd[m_active_window_index].m_auto_y_resize_elements[e];
|
|
el.Update();
|
|
}
|
|
//--- Показать указатель курсора, если в режиме ручного изменения высоты
|
|
if(m_windows[m_active_window_index].ResizeState())
|
|
m_windows[m_active_window_index].GetResizePointer().Reset();
|
|
//--- Обновить расположение всех элементов
|
|
m_chart.Redraw();
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Событие включения/отключения всплывающих подсказок |
|
|
//+------------------------------------------------------------------+
|
|
bool CWndEvents::OnWindowTooltips(void) {
|
|
//--- Если сигнал "Включить/отключить всплывающие подсказки"
|
|
if(m_id != CHARTEVENT_CUSTOM + ON_WINDOW_TOOLTIPS)
|
|
return(false);
|
|
//--- Вытий, если идентификаторы окна не совпадают
|
|
if(m_lparam != m_windows[0].Id())
|
|
return(true);
|
|
//--- Синхронизировать режим всплывающих подсказок между всеми окнами
|
|
int windows_total = WindowsTotal();
|
|
for(int w = 0; w < windows_total; w++) {
|
|
bool state = m_windows[0].TooltipButtonState();
|
|
m_windows[w].IsTooltip(state);
|
|
//--- Показать всплывающие подсказки в кнопках окон
|
|
int window_elements_total = m_windows[w].ElementsTotal();
|
|
for(int e = 0; e < window_elements_total; e++) {
|
|
CElement *el = m_windows[w].Element(e);
|
|
el.ShowTooltip(state);
|
|
}
|
|
//--- Установить режим показа во всех элементах
|
|
int elements_total = ElementsTotal(w);
|
|
for(int e = 0; e < elements_total; e++) {
|
|
CElement *el = m_wnd[w].m_elements[e];
|
|
el.ShowTooltip(state);
|
|
}
|
|
}
|
|
//--- Переместить всплывающие подсказки на верхний слой
|
|
ResetTooltips();
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Событие скрытия контектсных меню от пункта инициатора |
|
|
//+------------------------------------------------------------------+
|
|
bool CWndEvents::OnHideBackContextMenus(void) {
|
|
//--- Если сигнал на скрытие контекстных меню от пункта инициатора
|
|
if(m_id != CHARTEVENT_CUSTOM + ON_HIDE_BACK_CONTEXTMENUS)
|
|
return(false);
|
|
//--- Пройдём по всем меню от последнего вызванного
|
|
int awi = m_active_window_index;
|
|
int context_menus_total = CWndContainer::ElementsTotal(awi, E_CONTEXT_MENU);
|
|
for(int i = context_menus_total - 1; i >= 0; i--) {
|
|
//--- Указатели контекстного меню и его предыдущего узла
|
|
CContextMenu *cm = m_wnd[awi].m_context_menus[i];
|
|
CMenuItem *mi = cm.PrevNodePointer();
|
|
//--- Если дальше этого пункта больше ничего нет, то...
|
|
if(::CheckPointer(mi) == POINTER_INVALID)
|
|
continue;
|
|
//--- Если дошли до пункта инициатора сигнала, то...
|
|
if(mi.Id() == m_lparam) {
|
|
//--- ...в случае, если его контекстное меню без фокуса, скроем его
|
|
if(!cm.MouseFocus()) {
|
|
cm.Hide();
|
|
mi.IsPressed(false);
|
|
mi.Update(true);
|
|
}
|
|
//--- Завершим цикл
|
|
break;
|
|
} else {
|
|
cm.Hide();
|
|
mi.IsPressed(false);
|
|
mi.Update(true);
|
|
}
|
|
}
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Событие скрытия всех контекстных меню |
|
|
//+------------------------------------------------------------------+
|
|
bool CWndEvents::OnHideContextMenus(void) {
|
|
//--- Если сигнал на скрытие всех контекстных меню
|
|
if(m_id != CHARTEVENT_CUSTOM + ON_HIDE_CONTEXTMENUS)
|
|
return(false);
|
|
//--- Скрыть все контекстные меню
|
|
int awi = m_active_window_index;
|
|
int cm_total = CWndContainer::ElementsTotal(awi, E_CONTEXT_MENU);
|
|
for(int i = 0; i < cm_total; i++) {
|
|
m_wnd[awi].m_context_menus[i].Hide();
|
|
//---
|
|
if(CheckPointer(m_wnd[awi].m_context_menus[i].PrevNodePointer()) != POINTER_INVALID) {
|
|
CMenuItem *mi = m_wnd[awi].m_context_menus[i].PrevNodePointer();
|
|
mi.IsPressed(false);
|
|
mi.Update(true);
|
|
}
|
|
}
|
|
//--- Отключить главные меню
|
|
int menu_bars_total = CWndContainer::ElementsTotal(awi, E_MENU_BAR);
|
|
for(int i = 0; i < menu_bars_total; i++)
|
|
m_wnd[awi].m_menu_bars[i].State(false);
|
|
//---
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Событие открытия диалогового окна |
|
|
//+------------------------------------------------------------------+
|
|
bool CWndEvents::OnOpenDialogBox(void) {
|
|
//--- Если сигнал на открытие диалогового окна
|
|
if(m_id != CHARTEVENT_CUSTOM + ON_OPEN_DIALOG_BOX)
|
|
return(false);
|
|
//--- Выйти, если сообщение от другой программы
|
|
if(m_sparam != m_program_name)
|
|
return(true);
|
|
//--- Пройдёмся по массиву окон
|
|
int window_total = CWndContainer::WindowsTotal();
|
|
for(int w = 0; w < window_total; w++) {
|
|
//--- Если идентификатор открытого окна
|
|
if(m_windows[w].Id() == m_lparam) {
|
|
//--- Запомним в этой форме индекс окна, с которого она была вызвана
|
|
m_windows[w].PrevActiveWindowIndex(m_active_window_index);
|
|
//--- Активируем форму
|
|
m_windows[w].State(true);
|
|
//--- Восстановим объектам формы приоритеты на нажатие левой кнопкой мыши
|
|
m_windows[w].SetZorders();
|
|
//--- Запомним индекс активированного окна
|
|
m_active_window_index = w;
|
|
//--- Показать окно
|
|
Show(m_active_window_index);
|
|
}
|
|
//--- Другие формы будут заблокированы, пока не закроется активированное окно
|
|
else {
|
|
//--- Заблокируем форму
|
|
m_windows[w].State(false);
|
|
//--- Обнулим приоритеты элементов формы на нажатие левой кнопкой мыши
|
|
int elements_total = CWndContainer::ElementsTotal(w);
|
|
for(int e = 0; e < elements_total; e++)
|
|
m_wnd[w].m_elements[e].ResetZorders();
|
|
}
|
|
}
|
|
//--- Скрытие всплывающих подсказок в предыдущем окне
|
|
int prev_window_index = m_windows[m_active_window_index].PrevActiveWindowIndex();
|
|
int tooltips_total = CWndContainer::ElementsTotal(prev_window_index, E_TOOLTIP);
|
|
for(int t = 0; t < tooltips_total; t++)
|
|
m_wnd[prev_window_index].m_tooltips[t].FadeOutTooltip();
|
|
//--- Показать элементы только выделенных вкладок
|
|
ShowTabElements(m_active_window_index);
|
|
//--- Сформируем массив видимых и при этом доступных элементов
|
|
FormAvailableElementsArray();
|
|
//--- Восстановление приоритетов на нажатие левой кнопкой мыши у активированного окна
|
|
SetZorders();
|
|
//--- Переместить всплывающие подсказки на верхний слой
|
|
ResetTooltips();
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Событие закрытия диалогового окна |
|
|
//+------------------------------------------------------------------+
|
|
bool CWndEvents::OnCloseDialogBox(void) {
|
|
//--- Если сигнал на закрытие диалогового окна
|
|
if(m_id != CHARTEVENT_CUSTOM + ON_CLOSE_DIALOG_BOX)
|
|
return(false);
|
|
//--- Пройдёмся по массиву окон
|
|
int window_total = CWndContainer::WindowsTotal();
|
|
for(int w = 0; w < window_total; w++) {
|
|
//--- Если идентификатор открытого окна
|
|
if(m_windows[w].Id() == m_lparam) {
|
|
//--- Заблокируем форму
|
|
m_windows[w].State(false);
|
|
//--- Спрячем форму
|
|
int elements_total = CWndContainer::ElementsTotal(w);
|
|
for(int e = 0; e < elements_total; e++)
|
|
m_wnd[w].m_elements[e].Hide();
|
|
//--- Активируем предыдущую форму
|
|
m_windows[int(m_dparam)].State(true);
|
|
//--- Перерисовка графика
|
|
m_chart.Redraw();
|
|
break;
|
|
}
|
|
}
|
|
//--- Установка индекса предыдущего окна
|
|
m_active_window_index = int(m_dparam);
|
|
//--- Восстановление приоритетов на нажатие левой кнопкой мыши у активированного окна
|
|
SetZorders();
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Событие для определения доступных элементов управления |
|
|
//+------------------------------------------------------------------+
|
|
bool CWndEvents::OnSetAvailable(void) {
|
|
//--- Если сигнал об изменении доступности элементов
|
|
if(m_id != CHARTEVENT_CUSTOM + ON_SET_AVAILABLE)
|
|
return(false);
|
|
//--- Сигнал на установку/восстановление
|
|
bool is_restore = (bool)m_dparam;
|
|
//--- Определим активные элементы
|
|
int ww_index = ActivatedWindowIndex();
|
|
int mb_index = ActivatedMenuBarIndex();
|
|
int mi_index = ActivatedMenuItemIndex();
|
|
int sb_index = ActivatedSplitButtonIndex();
|
|
int cb_index = ActivatedComboBoxIndex();
|
|
int dc_index = ActivatedDropCalendarIndex();
|
|
int sc_index = ActivatedScrollIndex();
|
|
int tl_index = ActivatedTableIndex();
|
|
int sd_index = ActivatedSliderIndex();
|
|
int tv_index = ActivatedTreeViewIndex();
|
|
int ch_index = ActivatedSubChartIndex();
|
|
//--- Если сигнал на определение доступных элементов, сначала отключаем доступ
|
|
if(!is_restore)
|
|
SetAvailable(m_active_window_index, false);
|
|
//--- Восстанавливаем, только если нет активированных элементов
|
|
else {
|
|
if(ww_index == WRONG_VALUE && mb_index == WRONG_VALUE && mi_index == WRONG_VALUE &&
|
|
sb_index == WRONG_VALUE && dc_index == WRONG_VALUE && cb_index == WRONG_VALUE &&
|
|
sc_index == WRONG_VALUE && tl_index == WRONG_VALUE && sd_index == WRONG_VALUE &&
|
|
tv_index == WRONG_VALUE && ch_index == WRONG_VALUE) {
|
|
SetAvailable(m_active_window_index, true);
|
|
return(true);
|
|
}
|
|
}
|
|
//--- Если (1) сигнал на определение доступных элементов или (2) на восстановление для выпадающего календаря
|
|
if(!is_restore || (is_restore && dc_index != WRONG_VALUE)) {
|
|
CElement *el = NULL;
|
|
//--- Окно
|
|
if(ww_index != WRONG_VALUE) {
|
|
el = m_windows[m_active_window_index];
|
|
}
|
|
//--- Главное меню
|
|
else if(mb_index != WRONG_VALUE) {
|
|
el = m_wnd[m_active_window_index].m_menu_bars[mb_index];
|
|
}
|
|
//--- Пункт меню
|
|
else if(mi_index != WRONG_VALUE) {
|
|
el = m_wnd[m_active_window_index].m_menu_items[mi_index];
|
|
}
|
|
//--- Сдвоенная кнопка
|
|
else if(sb_index != WRONG_VALUE) {
|
|
el = m_wnd[m_active_window_index].m_split_buttons[sb_index];
|
|
}
|
|
//--- Выпадающий календарь без выпадающего списка
|
|
else if(dc_index != WRONG_VALUE && cb_index == WRONG_VALUE) {
|
|
el = m_wnd[m_active_window_index].m_drop_calendars[dc_index];
|
|
}
|
|
//--- Выпадающий список
|
|
else if(cb_index != WRONG_VALUE) {
|
|
el = m_wnd[m_active_window_index].m_combo_boxes[cb_index];
|
|
}
|
|
//--- Полоса прокрутки
|
|
else if(sc_index != WRONG_VALUE) {
|
|
el = m_wnd[m_active_window_index].m_scrolls[sc_index];
|
|
}
|
|
//--- Таблица
|
|
else if(tl_index != WRONG_VALUE) {
|
|
el = m_wnd[m_active_window_index].m_tables[tl_index];
|
|
}
|
|
//--- Слайдер
|
|
else if(sd_index != WRONG_VALUE) {
|
|
el = m_wnd[m_active_window_index].m_sliders[sd_index];
|
|
}
|
|
//--- Древовидный список
|
|
else if(tv_index != WRONG_VALUE) {
|
|
el = m_wnd[m_active_window_index].m_treeview_lists[tv_index];
|
|
}
|
|
//--- Стандартный график
|
|
else if(ch_index != WRONG_VALUE) {
|
|
el = m_wnd[m_active_window_index].m_sub_charts[ch_index];
|
|
}
|
|
//--- Выйти, если указатель на элемент не получен
|
|
if(::CheckPointer(el) == POINTER_INVALID) {
|
|
return(true);
|
|
}
|
|
//--- Блок для главного меню
|
|
if(mb_index != WRONG_VALUE) {
|
|
//--- Сделать доступными главное меню и его видимые контекстные меню
|
|
el.IsAvailable(true);
|
|
//---
|
|
CMenuBar *mb = dynamic_cast<CMenuBar*>(el);
|
|
int items_total = mb.ItemsTotal();
|
|
for(int i = 0; i < items_total; i++) {
|
|
CMenuItem *mi = mb.GetItemPointer(i);
|
|
mi.IsAvailable(true);
|
|
//--- Проверяет и делает контекстное меню доступным
|
|
CheckContextMenu(mi);
|
|
}
|
|
}
|
|
//--- Блок для пункта меню
|
|
if(mi_index != WRONG_VALUE) {
|
|
CMenuItem *mi = dynamic_cast<CMenuItem*>(el);
|
|
mi.IsAvailable(true);
|
|
//--- Проверяет и делает контекстное меню доступным
|
|
CheckContextMenu(mi);
|
|
}
|
|
//--- Блок для полос прокрутки
|
|
else if(sc_index != WRONG_VALUE) {
|
|
//--- Сделать доступным начиная от главного узла
|
|
el.MainPointer().IsAvailable(true);
|
|
}
|
|
//--- Блок для древовидного списка
|
|
else if(tv_index != WRONG_VALUE) {
|
|
//--- Заблокировать все элементы, кроме главного
|
|
CTreeView *tv = dynamic_cast<CTreeView*>(el);
|
|
tv.IsAvailable(true, true);
|
|
int total = tv.ElementsTotal();
|
|
for(int i = 0; i < total; i++)
|
|
tv.Element(i).IsAvailable(false);
|
|
} else {
|
|
//--- Сделать элемент доступным
|
|
el.IsAvailable(true);
|
|
}
|
|
}
|
|
//---
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Событие ON_SET_LOCKED |
|
|
//+------------------------------------------------------------------+
|
|
bool CWndEvents::OnSetLocked(void) {
|
|
//--- Если сигнал о блокировке элементов
|
|
if(m_id != CHARTEVENT_CUSTOM + ON_SET_LOCKED)
|
|
return(false);
|
|
//---
|
|
bool find_flag = false;
|
|
//---
|
|
int elements_total = CWndContainer::MainElementsTotal(m_active_window_index);
|
|
for(int e = 0; e < elements_total; e++) {
|
|
CElement *el = m_wnd[m_active_window_index].m_main_elements[e];
|
|
//---
|
|
if(m_lparam != el.Id()) {
|
|
if(find_flag)
|
|
break;
|
|
//---
|
|
continue;
|
|
}
|
|
//---
|
|
find_flag = true;
|
|
//---
|
|
int total = el.ElementsTotal();
|
|
for(int i = 0; i < total; i++)
|
|
el.Element(i).Update(true);
|
|
//---
|
|
el.Update(true);
|
|
}
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Событие изменений в графическом интерфейсе |
|
|
//+------------------------------------------------------------------+
|
|
bool CWndEvents::OnChangeGUI(void) {
|
|
//--- Если сигнал об изменении в графическом интерфейсе
|
|
if(m_id != CHARTEVENT_CUSTOM + ON_CHANGE_GUI)
|
|
return(false);
|
|
//--- Сформируем массив видимых и при этом доступных элементов
|
|
FormAvailableElementsArray();
|
|
//--- Переместить всплывающие подсказки на верхний слой
|
|
ResetTooltips();
|
|
//--- Перерисовать график
|
|
m_chart.Redraw();
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Возвращает индекс активированного окна |
|
|
//+------------------------------------------------------------------+
|
|
int CWndEvents::ActivatedWindowIndex(void) {
|
|
int index = WRONG_VALUE;
|
|
//---
|
|
int total = WindowsTotal();
|
|
for(int i = 0; i < total; i++) {
|
|
if(m_windows[i].ResizeState()) {
|
|
index = i;
|
|
break;
|
|
}
|
|
}
|
|
return(index);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Возвращает индекс активированного главного меню |
|
|
//+------------------------------------------------------------------+
|
|
int CWndEvents::ActivatedMenuBarIndex(void) {
|
|
int index = WRONG_VALUE;
|
|
//---
|
|
int total = ElementsTotal(m_active_window_index, E_MENU_BAR);
|
|
for(int i = 0; i < total; i++) {
|
|
CMenuBar *el = m_wnd[m_active_window_index].m_menu_bars[i];
|
|
if(el.State()) {
|
|
index = i;
|
|
break;
|
|
}
|
|
}
|
|
return(index);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Возвращает индекс активированного пункта меню |
|
|
//+------------------------------------------------------------------+
|
|
int CWndEvents::ActivatedMenuItemIndex(void) {
|
|
int index = WRONG_VALUE;
|
|
//---
|
|
int total = ElementsTotal(m_active_window_index, E_MENU_ITEM);
|
|
for(int i = 0; i < total; i++) {
|
|
CMenuItem *el = m_wnd[m_active_window_index].m_menu_items[i];
|
|
if(el.GetContextMenuPointer().IsVisible()) {
|
|
index = i;
|
|
break;
|
|
}
|
|
}
|
|
return(index);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Возвращает индекс активированной сдвоенной кнопки |
|
|
//+------------------------------------------------------------------+
|
|
int CWndEvents::ActivatedSplitButtonIndex(void) {
|
|
int index = WRONG_VALUE;
|
|
//---
|
|
int total = ElementsTotal(m_active_window_index, E_SPLIT_BUTTON);
|
|
for(int i = 0; i < total; i++) {
|
|
CSplitButton *el = m_wnd[m_active_window_index].m_split_buttons[i];
|
|
if(el.GetContextMenuPointer().IsVisible()) {
|
|
index = i;
|
|
break;
|
|
}
|
|
}
|
|
return(index);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Возвращает индекс активированного комбо-бокса |
|
|
//+------------------------------------------------------------------+
|
|
int CWndEvents::ActivatedComboBoxIndex(void) {
|
|
int index = WRONG_VALUE;
|
|
//---
|
|
int total = ElementsTotal(m_active_window_index, E_COMBO_BOX);
|
|
for(int i = 0; i < total; i++) {
|
|
CComboBox *el = m_wnd[m_active_window_index].m_combo_boxes[i];
|
|
if(el.GetListViewPointer().IsVisible()) {
|
|
index = i;
|
|
break;
|
|
}
|
|
}
|
|
return(index);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Возвращает индекс активированного выпадающего календаря |
|
|
//+------------------------------------------------------------------+
|
|
int CWndEvents::ActivatedDropCalendarIndex(void) {
|
|
int index = WRONG_VALUE;
|
|
//---
|
|
int total = ElementsTotal(m_active_window_index, E_DROP_CALENDAR);
|
|
for(int i = 0; i < total; i++) {
|
|
CDropCalendar *el = m_wnd[m_active_window_index].m_drop_calendars[i];
|
|
if(el.GetCalendarPointer().IsVisible()) {
|
|
index = i;
|
|
break;
|
|
}
|
|
}
|
|
return(index);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Возвращает индекс активированной полосы прокрутки |
|
|
//+------------------------------------------------------------------+
|
|
int CWndEvents::ActivatedScrollIndex(void) {
|
|
int index = WRONG_VALUE;
|
|
//---
|
|
int total = ElementsTotal(m_active_window_index, E_SCROLL);
|
|
for(int i = 0; i < total; i++) {
|
|
CScroll *el = m_wnd[m_active_window_index].m_scrolls[i];
|
|
if(el.State()) {
|
|
index = i;
|
|
break;
|
|
}
|
|
}
|
|
return(index);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Возвращает индекс активированной таблицы |
|
|
//+------------------------------------------------------------------+
|
|
int CWndEvents::ActivatedTableIndex(void) {
|
|
int index = WRONG_VALUE;
|
|
//---
|
|
int total = ElementsTotal(m_active_window_index, E_TABLE);
|
|
for(int i = 0; i < total; i++) {
|
|
CTable *el = m_wnd[m_active_window_index].m_tables[i];
|
|
if(el.ColumnResizeControl()) {
|
|
index = i;
|
|
break;
|
|
}
|
|
}
|
|
return(index);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Возвращает индекс активированного слайдера |
|
|
//+------------------------------------------------------------------+
|
|
int CWndEvents::ActivatedSliderIndex(void) {
|
|
int index = WRONG_VALUE;
|
|
//---
|
|
int total = ElementsTotal(m_active_window_index, E_SLIDER);
|
|
for(int i = 0; i < total; i++) {
|
|
CSlider *el = m_wnd[m_active_window_index].m_sliders[i];
|
|
if(el.State()) {
|
|
index = i;
|
|
break;
|
|
}
|
|
}
|
|
return(index);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Возвращает индекс активированного древовидного списка |
|
|
//+------------------------------------------------------------------+
|
|
int CWndEvents::ActivatedTreeViewIndex(void) {
|
|
int index = WRONG_VALUE;
|
|
//---
|
|
int total = ElementsTotal(m_active_window_index, E_TREE_VIEW);
|
|
for(int i = 0; i < total; i++) {
|
|
CTreeView *el = m_wnd[m_active_window_index].m_treeview_lists[i];
|
|
//--- Перейти к следующему, если включен режим вкладок
|
|
if(el.TabItemsMode())
|
|
continue;
|
|
//--- Если процесс изменения ширины списков
|
|
if(el.GetMousePointer().State()) {
|
|
index = i;
|
|
break;
|
|
}
|
|
}
|
|
return(index);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Возвращает индекс активированного стандартного графика |
|
|
//+------------------------------------------------------------------+
|
|
int CWndEvents::ActivatedSubChartIndex(void) {
|
|
int index = WRONG_VALUE;
|
|
//---
|
|
int total = ElementsTotal(m_active_window_index, E_SUB_CHART);
|
|
for(int i = 0; i < total; i++) {
|
|
CStandardChart *el = m_wnd[m_active_window_index].m_sub_charts[i];
|
|
if(el.GetMousePointer().IsVisible()) {
|
|
index = i;
|
|
break;
|
|
}
|
|
}
|
|
return(index);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Рекурсивно проверяет и делает контекстные меню доступными |
|
|
//+------------------------------------------------------------------+
|
|
void CWndEvents::CheckContextMenu(CMenuItem &object) {
|
|
//--- Получим указатель контекстного меню
|
|
CContextMenu *cm = object.GetContextMenuPointer();
|
|
//--- Выйти, если контекстного меню нет в пункте
|
|
if(::CheckPointer(cm) == POINTER_INVALID)
|
|
return;
|
|
//--- Выйти, если контекстное меню есть, но скрыто
|
|
if(!cm.IsVisible())
|
|
return;
|
|
//--- Установить признаки доступного элемента
|
|
cm.IsAvailable(true);
|
|
//---
|
|
int items_total = cm.ItemsTotal();
|
|
for(int i = 0; i < items_total; i++) {
|
|
//--- Установить признаки доступного элемента
|
|
CMenuItem *mi = cm.GetItemPointer(i);
|
|
mi.IsAvailable(true);
|
|
//--- Проверим, есть ли в этом пункте контекстное меню
|
|
CheckContextMenu(mi);
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Перемещение окна |
|
|
//+------------------------------------------------------------------+
|
|
void CWndEvents::MovingWindow(const bool moving_mode = false) {
|
|
//--- Если управление передано окну, определим его положение
|
|
if(!moving_mode)
|
|
if(m_windows[m_active_window_index].ClampingAreaMouse() != PRESSED_INSIDE_HEADER)
|
|
return;
|
|
//--- Перемещение окна
|
|
int x = m_windows[m_active_window_index].X();
|
|
int y = m_windows[m_active_window_index].Y();
|
|
m_windows[m_active_window_index].Moving(x, y);
|
|
//--- Перемещение элементов управления
|
|
int main_total = MainElementsTotal(m_active_window_index);
|
|
for(int e = 0; e < main_total; e++) {
|
|
CElement *el = m_wnd[m_active_window_index].m_main_elements[e];
|
|
el.Moving();
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Проверка событий всех элементов по таймеру |
|
|
//+------------------------------------------------------------------+
|
|
void CWndEvents::CheckElementsEventsTimer(void) {
|
|
int awi = m_active_window_index;
|
|
int timer_elements_total = CWndContainer::TimerElementsTotal(awi);
|
|
for(int e = 0; e < timer_elements_total; e++) {
|
|
CElement *el = m_wnd[awi].m_timer_elements[e];
|
|
if(el.IsVisible())
|
|
el.OnEventTimer();
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Определение номера подокна |
|
|
//+------------------------------------------------------------------+
|
|
void CWndEvents::DetermineSubwindow(void) {
|
|
//--- Выйдем, если тип программы "Скрипт"
|
|
if(PROGRAM_TYPE == PROGRAM_SCRIPT)
|
|
return;
|
|
//--- Сброс последней ошибки
|
|
::ResetLastError();
|
|
//--- Если тип программы эксперт
|
|
if(PROGRAM_TYPE == PROGRAM_EXPERT) {
|
|
//--- Выйти, если графический интерфейс эксперта нужен в главном окне
|
|
if(!EXPERT_IN_SUBWINDOW)
|
|
return;
|
|
//--- Получим хэндл индикатора-пустышки (пустое подокно)
|
|
m_subwindow_handle = iCustom(::Symbol(), ::Period(), "::Indicators\\SubWindow.ex5");
|
|
//--- Если такого индикатор нет, сообщить об ошибке в журнал
|
|
if(m_subwindow_handle == INVALID_HANDLE)
|
|
::Print(__FUNCTION__, " > Ошибка при получении хэндла индикатора в директории ::Indicators\\SubWindow.ex5 !");
|
|
//--- Если хэндл получен, значит индикатор есть, подключен к приложению в качестве ресурса,
|
|
// а это значит, что графический интерфейс приложения нужно поместить в подокно
|
|
else {
|
|
//--- Получим количество подокон на графике
|
|
int subwindows_total = (int)::ChartGetInteger(m_chart_id, CHART_WINDOWS_TOTAL);
|
|
//--- Установим подокно для графического интерфейса эксперта
|
|
if(::ChartIndicatorAdd(m_chart_id, subwindows_total, m_subwindow_handle)) {
|
|
//--- Сохраним номер подокна и текущее количество подокон на графике
|
|
m_subwin = subwindows_total;
|
|
m_subwindows_total = subwindows_total + 1;
|
|
//--- Получим и сохраним короткое имя подокна эксперта
|
|
m_subwindow_shortname =::ChartIndicatorName(m_chart_id, m_subwin, 0);
|
|
}
|
|
//--- Если подокно не установилось
|
|
else
|
|
::Print(__FUNCTION__, " > Ошибка при установке подокна эксперта! Номер ошибки: ", ::GetLastError());
|
|
}
|
|
//---
|
|
return;
|
|
}
|
|
//--- Определение номера окна индикатора
|
|
m_subwin =::ChartWindowFind();
|
|
//--- Если не получилось определить номер, выйдем
|
|
if(m_subwin < 0) {
|
|
::Print(__FUNCTION__, " > Ошибка при определении номера подокна: ", ::GetLastError());
|
|
return;
|
|
}
|
|
//--- Если это не главное окно графика
|
|
if(m_subwin > 0) {
|
|
//--- Получим общее количество индикаторов в указанном подокне
|
|
int total =::ChartIndicatorsTotal(m_chart_id, m_subwin);
|
|
//--- Получим короткое имя последнего индикатора в списке
|
|
string indicator_name =::ChartIndicatorName(m_chart_id, m_subwin, total - 1);
|
|
//--- Если в подокне уже есть индикатор, то удалить программу с графика
|
|
if(total != 1) {
|
|
::Print(__FUNCTION__, " > В этом подокне уже есть индикатор.");
|
|
::ChartIndicatorDelete(m_chart_id, m_subwin, indicator_name);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Удаляет подокно эксперта |
|
|
//+------------------------------------------------------------------+
|
|
void CWndEvents::DeleteExpertSubwindow(void) {
|
|
//--- Выйти, если это не эксперт
|
|
if(PROGRAM_TYPE != PROGRAM_EXPERT)
|
|
return;
|
|
//--- Выйти, если хэндл невалиден
|
|
if(m_subwindow_handle == INVALID_HANDLE)
|
|
return;
|
|
//--- Получим количество окон на графике
|
|
int windows_total = (int)::ChartGetInteger(m_chart_id, CHART_WINDOWS_TOTAL);
|
|
//--- Найдём подокно эксперта
|
|
for(int w = 0; w < windows_total; w++) {
|
|
//--- Получим короткое имя подокна эксперта (индикатор SubWindow.ex5)
|
|
string indicator_name =::ChartIndicatorName(m_chart_id, w, 0);
|
|
//--- Перейти к следующему, если это не подокно эксперта
|
|
if(indicator_name != m_subwindow_shortname || w != m_subwin)
|
|
continue;
|
|
//--- Удалить подокно эксперта
|
|
if(!::ChartIndicatorDelete(m_chart_id, m_subwin, indicator_name))
|
|
::Print(__FUNCTION__, " > Ошибка при удалении подокна эксперта! Номер ошибки: ", ::GetLastError());
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Проверка и обновление номера окна эксперта |
|
|
//+------------------------------------------------------------------+
|
|
void CWndEvents::CheckExpertSubwindowNumber(void) {
|
|
//--- Выйти, если (1) это не эксперт или (2) графический интерфейс эксперта в главном окне
|
|
if(PROGRAM_TYPE != PROGRAM_EXPERT || !EXPERT_IN_SUBWINDOW)
|
|
return;
|
|
//--- Получим количество подокон на графике
|
|
int subwindows_total = (int)::ChartGetInteger(m_chart_id, CHART_WINDOWS_TOTAL);
|
|
//--- Выйти, если количество подокон и количество индикаторов не изменилось
|
|
if(subwindows_total == m_subwindows_total)
|
|
return;
|
|
//--- Сохраним текущее количество подокон
|
|
m_subwindows_total = subwindows_total;
|
|
//--- Для проверки наличия подокна эксперта
|
|
bool is_subwindow = false;
|
|
//--- Найдём подокно эксперта
|
|
for(int sw = 0; sw < subwindows_total; sw++) {
|
|
//--- Остановить цикл, если подокно эксперта есть
|
|
if(is_subwindow)
|
|
break;
|
|
//--- Сколько индикаторов в данном окне/подокне
|
|
int indicators_total =::ChartIndicatorsTotal(m_chart_id, sw);
|
|
//--- Переберём все индикаторы в окне
|
|
for(int i = 0; i < indicators_total; i++) {
|
|
//--- Получим короткое имя индикатора
|
|
string indicator_name =::ChartIndicatorName(m_chart_id, sw, i);
|
|
//--- Если это не подокно эксперта, перейти к следующему
|
|
if(indicator_name != m_subwindow_shortname)
|
|
continue;
|
|
//--- Отметим, что подокно эксперта есть
|
|
is_subwindow = true;
|
|
//--- Если номер подокна изменился, то
|
|
// нужно сохранить новый номер во всех элементах главной формы
|
|
if(sw != m_subwin) {
|
|
//--- Сохраним номер подокна
|
|
m_subwin = sw;
|
|
//--- Сохраним его также во всех элементах главной формы интерфейса
|
|
int elements_total = CWndContainer::ElementsTotal(0);
|
|
for(int e = 0; e < elements_total; e++)
|
|
m_wnd[0].m_elements[e].SubwindowNumber(m_subwin);
|
|
}
|
|
//---
|
|
break;
|
|
}
|
|
}
|
|
//--- Если подокно эксперта не обнаружено, удалим эксперта
|
|
if(!is_subwindow) {
|
|
::Print(__FUNCTION__, " > Удаление подокна эксперта приводит к удалению эксперта!");
|
|
//--- Удаление эксперта с графика
|
|
::ExpertRemove();
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Проверка и обновление номера окна программы |
|
|
//+------------------------------------------------------------------+
|
|
void CWndEvents::CheckSubwindowNumber(void) {
|
|
//--- Выйти, если это не индикатор
|
|
if(PROGRAM_TYPE != PROGRAM_INDICATOR)
|
|
return;
|
|
//--- Если программа в подокне и номера не совпадают
|
|
if(m_subwin != 0 && m_subwin !=::ChartWindowFind()) {
|
|
//--- Определить номер подокна
|
|
DetermineSubwindow();
|
|
//--- Сохранить во всех элементах
|
|
int windows_total = CWndContainer::WindowsTotal();
|
|
for(int w = 0; w < windows_total; w++) {
|
|
int elements_total = CWndContainer::ElementsTotal(w);
|
|
for(int e = 0; e < elements_total; e++)
|
|
m_wnd[w].m_elements[e].SubwindowNumber(m_subwin);
|
|
}
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Изменение размеров заблокированного главного окна |
|
|
//+------------------------------------------------------------------+
|
|
void CWndEvents::ResizeLockedWindow(void) {
|
|
//--- Сохранить во всех элементах
|
|
int windows_total = CWndContainer::WindowsTotal();
|
|
//--- Выйти, если интерфейс не создан
|
|
if(windows_total < 1)
|
|
return;
|
|
//--- Изменить размер всех элементов заблокированной формы, если включен один из режимов
|
|
if(m_windows[0].CElementBase::IsLocked() && (m_windows[0].AutoXResizeMode() || m_windows[0].AutoXResizeMode())) {
|
|
int elements_total = CWndContainer::ElementsTotal(0);
|
|
for(int e = 0; e < elements_total; e++) {
|
|
CElement *el = m_wnd[0].m_elements[e];
|
|
//--- Если это форма
|
|
if(dynamic_cast<CWindow*>(el) != NULL) {
|
|
el.OnEvent(m_id, m_lparam, m_dparam, m_sparam);
|
|
continue;
|
|
}
|
|
//--- Изменить ширину элементов, где включен такой режим
|
|
if(el.AutoXResizeMode())
|
|
el.ChangeWidthByRightWindowSide();
|
|
//--- Изменить ширину элементов, где включен такой режим
|
|
if(el.AutoYResizeMode())
|
|
el.ChangeHeightByBottomWindowSide();
|
|
//--- Обновить положение объектов
|
|
el.Moving();
|
|
}
|
|
//--- Обновим (сохраним) свойства графика у других форм
|
|
for(int w = 1; w < windows_total; w++)
|
|
m_windows[w].SetWindowProperties();
|
|
//--- Перерисовка активированного окна
|
|
ResetWindow();
|
|
//--- Обновить
|
|
Update();
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Перерисовка окна |
|
|
//+------------------------------------------------------------------+
|
|
void CWndEvents::ResetWindow(void) {
|
|
//--- Выйти, если ещё нет ни одного окна
|
|
if(CWndContainer::WindowsTotal() < 1)
|
|
return;
|
|
//--- Перерисовка окна и его элементов
|
|
Hide();
|
|
Show(m_active_window_index);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Удаление всех объектов |
|
|
//+------------------------------------------------------------------+
|
|
void CWndEvents::Destroy(void) {
|
|
//--- Установим индекс главного окна
|
|
m_active_window_index = 0;
|
|
//--- Получим количество окон
|
|
int window_total = CWndContainer::WindowsTotal();
|
|
//--- Пройдёмся по массиву окон
|
|
for(int w = 0; w < window_total; w++) {
|
|
//--- Активируем главное окно
|
|
if(m_windows[w].WindowType() == W_MAIN)
|
|
m_windows[w].State(true);
|
|
//--- Заблокируем диалоговые окна
|
|
else
|
|
m_windows[w].State(false);
|
|
}
|
|
//--- Освободим массивы элементов
|
|
for(int w = 0; w < window_total; w++) {
|
|
int elements_total = CWndContainer::ElementsTotal(w);
|
|
for(int e = 0; e < elements_total; e++) {
|
|
//--- Если указатель невалидный, перейти к следующему
|
|
if(::CheckPointer(m_wnd[w].m_elements[e]) == POINTER_INVALID)
|
|
continue;
|
|
//--- Удалить объекты элемента
|
|
m_wnd[w].m_elements[e].Delete();
|
|
m_wnd[w].m_elements[e].Id(WRONG_VALUE);
|
|
}
|
|
//--- Освободить массивы элементов
|
|
::ArrayFree(m_wnd[w].m_elements);
|
|
::ArrayFree(m_wnd[w].m_main_elements);
|
|
::ArrayFree(m_wnd[w].m_timer_elements);
|
|
::ArrayFree(m_wnd[w].m_auto_x_resize_elements);
|
|
::ArrayFree(m_wnd[w].m_auto_y_resize_elements);
|
|
::ArrayFree(m_wnd[w].m_available_elements);
|
|
::ArrayFree(m_wnd[w].m_menu_bars);
|
|
::ArrayFree(m_wnd[w].m_menu_items);
|
|
::ArrayFree(m_wnd[w].m_context_menus);
|
|
::ArrayFree(m_wnd[w].m_combo_boxes);
|
|
::ArrayFree(m_wnd[w].m_split_buttons);
|
|
::ArrayFree(m_wnd[w].m_drop_lists);
|
|
::ArrayFree(m_wnd[w].m_scrolls);
|
|
::ArrayFree(m_wnd[w].m_tables);
|
|
::ArrayFree(m_wnd[w].m_tabs);
|
|
::ArrayFree(m_wnd[w].m_calendars);
|
|
::ArrayFree(m_wnd[w].m_drop_calendars);
|
|
::ArrayFree(m_wnd[w].m_sub_charts);
|
|
::ArrayFree(m_wnd[w].m_pictures_slider);
|
|
::ArrayFree(m_wnd[w].m_time_edits);
|
|
::ArrayFree(m_wnd[w].m_text_boxes);
|
|
::ArrayFree(m_wnd[w].m_tooltips);
|
|
::ArrayFree(m_wnd[w].m_treeview_lists);
|
|
::ArrayFree(m_wnd[w].m_file_navigators);
|
|
::ArrayFree(m_wnd[w].m_frames);
|
|
}
|
|
//--- Освободить массивы форм
|
|
::ArrayFree(m_wnd);
|
|
::ArrayFree(m_windows);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Завершение создания GUI |
|
|
//+------------------------------------------------------------------+
|
|
void CWndEvents::CompletedGUI(void) {
|
|
//--- Выйти, если ещё нет ни одного окна
|
|
int windows_total = CWndContainer::WindowsTotal();
|
|
if(windows_total < 1) {
|
|
return;
|
|
}
|
|
//--- Показать комментарий информирующий пользователя
|
|
::Comment("Update. Please wait...");
|
|
//--- Скрыть элементы
|
|
Hide();
|
|
//--- Нарисовать элементы
|
|
Update(true);
|
|
//--- Показать элементы активированного окна
|
|
Show(m_active_window_index);
|
|
//--- Сформируем массив элементов с таймером
|
|
FormTimerElementsArray();
|
|
//--- Сформируем массив видимых и при этом доступных элементов
|
|
FormAvailableElementsArray();
|
|
//--- Сформируем массивы элементов с авто-ресайзом
|
|
FormAutoXResizeElementsArray();
|
|
FormAutoYResizeElementsArray();
|
|
//--- Перерисовать график
|
|
m_chart.Redraw();
|
|
//--- Очистить комментарий
|
|
::Comment("");
|
|
//--- Отправим событие завершения создания GUI
|
|
::EventChartCustom(m_chart_id, ON_END_CREATE_GUI, 0, 0.0, "");
|
|
|
|
//CWndEvents::PrintContainer();
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Перемещение элементов |
|
|
//+------------------------------------------------------------------+
|
|
void CWndEvents::Moving(void) {
|
|
//--- Обновить положение элементов
|
|
int main_total = MainElementsTotal(m_active_window_index);
|
|
for(int e = 0; e < main_total; e++) {
|
|
CElement *el = m_wnd[m_active_window_index].m_main_elements[e];
|
|
el.Moving(false);
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Скрытие элементов |
|
|
//+------------------------------------------------------------------+
|
|
void CWndEvents::Hide(void) {
|
|
int windows_total = CWndContainer::WindowsTotal();
|
|
for(int w = 0; w < windows_total; w++) {
|
|
m_windows[w].Hide();
|
|
int main_total = MainElementsTotal(w);
|
|
for(int e = 0; e < main_total; e++) {
|
|
CElement *el = m_wnd[w].m_main_elements[e];
|
|
el.Hide();
|
|
}
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Показ элементов указанного окна |
|
|
//+------------------------------------------------------------------+
|
|
void CWndEvents::Show(const uint window_index) {
|
|
//--- Показать элементы указанного окна
|
|
m_windows[window_index].Show();
|
|
//--- Если окно не свёрнуто
|
|
if(!m_windows[window_index].IsMinimized()) {
|
|
int main_total = MainElementsTotal(window_index);
|
|
for(int e = 0; e < main_total; e++) {
|
|
CElement *el = m_wnd[window_index].m_main_elements[e];
|
|
//--- Показать элемент, если он (1) не выпадающий и (2) его главный элемент не вкладки
|
|
if(!el.IsDropdown() && dynamic_cast<CTabs*>(el.MainPointer()) == NULL)
|
|
el.Show();
|
|
}
|
|
//--- Показать элементы только выделенных вкладок
|
|
ShowTabElements(window_index);
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Восстановление приоритетов на нажатие левой кнопкой мыши |
|
|
//| у активного окна |
|
|
//+------------------------------------------------------------------+
|
|
void CWndEvents::SetZorders(void) {
|
|
int elements_total = CWndContainer::ElementsTotal(m_active_window_index);
|
|
for(int e = 0; e < elements_total; e++) {
|
|
CElement *el = m_wnd[m_active_window_index].m_elements[e];
|
|
//---
|
|
if(el.ClassName() != "CGraph")
|
|
el.SetZorders();
|
|
else {
|
|
CGraph *graph = dynamic_cast<CGraph*>(el);
|
|
graph.SetZorders();
|
|
}
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Перерисовка элементов |
|
|
//+------------------------------------------------------------------+
|
|
void CWndEvents::Update(const bool redraw = false) {
|
|
int windows_total = CWndContainer::WindowsTotal();
|
|
for(int w = 0; w < windows_total; w++) {
|
|
//--- Перерисовка элементов
|
|
int elements_total = CWndContainer::ElementsTotal(w);
|
|
for(int e = 0; e < elements_total; e++) {
|
|
CElement *el = m_wnd[w].m_elements[e];
|
|
el.Update(redraw);
|
|
}
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Перемещает всплывающие подсказки на верхний слой |
|
|
//+------------------------------------------------------------------+
|
|
void CWndEvents::ResetTooltips(void) {
|
|
//--- Переместить всплывающие подсказки на верхний слой
|
|
int window_total = CWndContainer::WindowsTotal();
|
|
for(int w = 0; w < window_total; w++) {
|
|
int tooltips_total = CWndContainer::ElementsTotal(w, E_TOOLTIP);
|
|
for(int t = 0; t < tooltips_total; t++)
|
|
m_wnd[w].m_tooltips[t].Reset();
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Устанавливает состояние доступности элементов |
|
|
//+------------------------------------------------------------------+
|
|
void CWndEvents::SetAvailable(const uint window_index, const bool state) {
|
|
//--- Получим количество главных элементов
|
|
int main_total = MainElementsTotal(window_index);
|
|
//--- Если нужно сделать элементы недоступными
|
|
if(!state) {
|
|
m_windows[window_index].IsAvailable(state);
|
|
for(int e = 0; e < main_total; e++) {
|
|
CElement *el = m_wnd[window_index].m_main_elements[e];
|
|
el.IsAvailable(state);
|
|
}
|
|
} else {
|
|
m_windows[window_index].IsAvailable(state);
|
|
for(int e = 0; e < main_total; e++) {
|
|
CElement *el = m_wnd[window_index].m_main_elements[e];
|
|
//--- Если это древовидный список
|
|
if(dynamic_cast<CTreeView*>(el) != NULL) {
|
|
CTreeView *tv = dynamic_cast<CTreeView*>(el);
|
|
tv.IsAvailable(true);
|
|
continue;
|
|
}
|
|
//--- Если это файловый навигатор
|
|
if(dynamic_cast<CFileNavigator*>(el) != NULL) {
|
|
CFileNavigator *fn = dynamic_cast<CFileNavigator*>(el);
|
|
CTreeView *tv = fn.GetTreeViewPointer();
|
|
fn.IsAvailable(state);
|
|
tv.IsAvailable(state);
|
|
continue;
|
|
}
|
|
//--- Сделать элемент доступным
|
|
el.IsAvailable(state);
|
|
}
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Показывает элементы только выделенных вкладок |
|
|
//+------------------------------------------------------------------+
|
|
void CWndEvents::ShowTabElements(const uint window_index) {
|
|
//--- Простые вкладки
|
|
int tabs_total = CWndContainer::ElementsTotal(window_index, E_TABS);
|
|
for(int t = 0; t < tabs_total; t++) {
|
|
CTabs *el = m_wnd[window_index].m_tabs[t];
|
|
if(el.IsVisible())
|
|
el.ShowTabElements();
|
|
}
|
|
//--- Вкладки древовидных списков
|
|
int treeview_total = CWndContainer::ElementsTotal(window_index, E_TREE_VIEW);
|
|
for(int tv = 0; tv < treeview_total; tv++)
|
|
m_wnd[window_index].m_treeview_lists[tv].ShowTabElements();
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Формирует массив элементов с таймером |
|
|
//+------------------------------------------------------------------+
|
|
void CWndEvents::FormTimerElementsArray(void) {
|
|
int windows_total = CWndContainer::WindowsTotal();
|
|
for(int w = 0; w < windows_total; w++) {
|
|
int elements_total = CWndContainer::ElementsTotal(w);
|
|
for(int e = 0; e < elements_total; e++) {
|
|
CElement *el = m_wnd[w].m_elements[e];
|
|
//---
|
|
if(dynamic_cast<CCalendar *>(el) != NULL ||
|
|
dynamic_cast<CColorPicker *>(el) != NULL ||
|
|
dynamic_cast<CListView *>(el) != NULL ||
|
|
dynamic_cast<CTable *>(el) != NULL ||
|
|
dynamic_cast<CTextBox *>(el) != NULL ||
|
|
dynamic_cast<CTextEdit *>(el) != NULL ||
|
|
dynamic_cast<CTreeView *>(el) != NULL) {
|
|
CWndContainer::AddTimerElement(w, el);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Формирует массив доступных элементов |
|
|
//+------------------------------------------------------------------+
|
|
void CWndEvents::FormAvailableElementsArray(void) {
|
|
//--- Индекс окна
|
|
int awi = m_active_window_index;
|
|
//--- Общее количество элементов
|
|
int elements_total = CWndContainer::ElementsTotal(awi);
|
|
//--- Очистим массив
|
|
::ArrayFree(m_wnd[awi].m_available_elements);
|
|
//---
|
|
for(int e = 0; e < elements_total; e++) {
|
|
CElement *el = m_wnd[awi].m_elements[e];
|
|
//--- Добавляем только видимые и доступные для обработки элементы
|
|
if(!el.IsVisible() || !el.CElementBase::IsAvailable() || el.CElementBase::IsLocked())
|
|
continue;
|
|
//--- Исключить элементы не требующие обработки по наведению курсора мыши
|
|
if(dynamic_cast<CButtonsGroup *>(el) == NULL &&
|
|
dynamic_cast<CFileNavigator *>(el) == NULL &&
|
|
dynamic_cast<CPicture *>(el) == NULL &&
|
|
dynamic_cast<CPicturesSlider *>(el) == NULL &&
|
|
dynamic_cast<CProgressBar *>(el) == NULL &&
|
|
dynamic_cast<CSeparateLine *>(el) == NULL &&
|
|
dynamic_cast<CStatusBar *>(el) == NULL &&
|
|
dynamic_cast<CTabs *>(el) == NULL &&
|
|
dynamic_cast<CTextLabel *>(el) == NULL) {
|
|
AddAvailableElement(awi, el);
|
|
//Print(__FUNCTION__," > class: ",el.ClassName(),"; id: ",el.Id());
|
|
}
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Формирует массив элементов с авто-ресайзом (X) |
|
|
//+------------------------------------------------------------------+
|
|
void CWndEvents::FormAutoXResizeElementsArray(void) {
|
|
int windows_total = CWndContainer::WindowsTotal();
|
|
for(int w = 0; w < windows_total; w++) {
|
|
int elements_total = CWndContainer::ElementsTotal(w);
|
|
for(int e = 0; e < elements_total; e++) {
|
|
CElement *el = m_wnd[w].m_elements[e];
|
|
//--- Добавляем только те, у которых включен режим авто-ресайза
|
|
if(!el.AutoXResizeMode())
|
|
continue;
|
|
//---
|
|
if(dynamic_cast<CButton *>(el) != NULL ||
|
|
dynamic_cast<CFileNavigator *>(el) != NULL ||
|
|
dynamic_cast<CGraph *>(el) != NULL ||
|
|
dynamic_cast<CListView *>(el) != NULL ||
|
|
dynamic_cast<CMenuBar *>(el) != NULL ||
|
|
dynamic_cast<CProgressBar *>(el) != NULL ||
|
|
dynamic_cast<CStandardChart *>(el) != NULL ||
|
|
dynamic_cast<CStatusBar *>(el) != NULL ||
|
|
dynamic_cast<CTable *>(el) != NULL ||
|
|
dynamic_cast<CTabs *>(el) != NULL ||
|
|
dynamic_cast<CTextBox *>(el) != NULL ||
|
|
dynamic_cast<CTextEdit *>(el) != NULL ||
|
|
dynamic_cast<CTreeView *>(el) != NULL ||
|
|
dynamic_cast<CFrame *>(el) != NULL) {
|
|
CWndContainer::AddAutoXResizeElement(w, el);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Формирует массив элементов с авто-ресайзом (Y) |
|
|
//+------------------------------------------------------------------+
|
|
void CWndEvents::FormAutoYResizeElementsArray(void) {
|
|
int windows_total = CWndContainer::WindowsTotal();
|
|
for(int w = 0; w < windows_total; w++) {
|
|
int elements_total = CWndContainer::ElementsTotal(w);
|
|
for(int e = 0; e < elements_total; e++) {
|
|
CElement *el = m_wnd[w].m_elements[e];
|
|
//--- Добавляем только те, у которых включен режим авто-ресайза
|
|
if(!el.AutoYResizeMode())
|
|
continue;
|
|
//---
|
|
if (dynamic_cast<CGraph *>(el) != NULL ||
|
|
dynamic_cast<CListView *>(el) != NULL ||
|
|
dynamic_cast<CStandardChart *>(el) != NULL ||
|
|
dynamic_cast<CTable *>(el) != NULL ||
|
|
dynamic_cast<CTabs *>(el) != NULL ||
|
|
dynamic_cast<CTextBox *>(el) != NULL ||
|
|
dynamic_cast<CFrame *>(el) != NULL) {
|
|
CWndContainer::AddAutoYResizeElement(w, el);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Устанавливает состояние графика |
|
|
//+------------------------------------------------------------------+
|
|
void CWndEvents::SetChartState(void) {
|
|
int awi = m_active_window_index;
|
|
//--- Для определения события, когда нужно отключить управление
|
|
bool condition = false;
|
|
//--- Проверим окна
|
|
int windows_total = CWndContainer::WindowsTotal();
|
|
for(int i = 0; i < windows_total; i++) {
|
|
//--- Перейти к следующей, если эта форма скрыта
|
|
if(!m_windows[i].IsVisible())
|
|
continue;
|
|
//--- Проверить условия во внутреннем обработчике формы
|
|
m_windows[i].OnEvent(m_id, m_lparam, m_dparam, m_sparam);
|
|
//--- Если есть фокус, отметим это
|
|
if(m_windows[i].MouseFocus())
|
|
condition = true;
|
|
}
|
|
|
|
//--- Проверим фокус выпадающих списков
|
|
if(!condition) {
|
|
//--- Получим общее количество выпадающих списков
|
|
int drop_lists_total = CWndContainer::ElementsTotal(awi, E_DROP_LIST);
|
|
for(int i = 0; i < drop_lists_total; i++) {
|
|
//--- Получим указатель на выпадающий список
|
|
CListView *lv = m_wnd[awi].m_drop_lists[i];
|
|
//--- Если список активирован (открыт)
|
|
if(lv.IsVisible()) {
|
|
//--- Проверим фокус над списком и состояние его полосы прокрутки
|
|
if(m_wnd[awi].m_drop_lists[i].MouseFocus() || lv.ScrollState()) {
|
|
condition = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//--- Проверим фокус выпадающих календарей
|
|
if(!condition) {
|
|
int drop_calendars_total = CWndContainer::ElementsTotal(awi, E_DROP_CALENDAR);
|
|
for(int i = 0; i < drop_calendars_total; i++) {
|
|
if(m_wnd[awi].m_drop_calendars[i].GetCalendarPointer().MouseFocus()) {
|
|
condition = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
//--- Проверим фокус контекстных меню
|
|
if(!condition) {
|
|
//--- Получим общее количество выпадающих контекстных меню
|
|
int context_menus_total = CWndContainer::ElementsTotal(awi, E_CONTEXT_MENU);
|
|
for(int i = 0; i < context_menus_total; i++) {
|
|
//--- Если фокус над контексным меню
|
|
if(m_wnd[awi].m_context_menus[i].MouseFocus()) {
|
|
condition = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
//--- Проверим состояние полос прокрутки
|
|
if(!condition) {
|
|
int scrolls_total = CWndContainer::ElementsTotal(awi, E_SCROLL);
|
|
for(int i = 0; i < scrolls_total; i++) {
|
|
if(((CScroll*)m_wnd[awi].m_scrolls[i]).State()) {
|
|
condition = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//--- Устанавливаем состояние графика во всех формах
|
|
for(int i = 0; i < windows_total; i++)
|
|
m_windows[i].CustomEventChartState(condition);
|
|
}
|
|
//+------------------------------------------------------------------+
|