393 lines
30 KiB
MQL5
393 lines
30 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| ConsoleDialog.mqh |
|
|
//| Copyright 2025, Yuriy Bykov |
|
|
//| https://www.mql5.com/ru/users/antekov |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "Copyright 2025, Yuriy Bykov"
|
|
#property link "https://www.mql5.com/ru/users/antekov"
|
|
#property version "1.00"
|
|
|
|
#include "Include/Adwizard/Utils/Macros.mqh"
|
|
#include <Canvas/Canvas.mqh>
|
|
#include <Controls/Dialog.mqh>
|
|
|
|
#define DIALOG_VERTICAL_MARGIN (17) // Отступ верхнего края диалогового окна от края графика
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Класс диалогового окна на весь экран |
|
|
//| для вывода многострочного текста |
|
|
//+------------------------------------------------------------------+
|
|
class CConsoleDialog : public CAppDialog {
|
|
protected:
|
|
CCanvas m_canvas; // Объект холста для вывода текста
|
|
|
|
string m_lines[]; // Массив строк текста
|
|
string m_text; // Текст для вывода в диалоговом окне
|
|
|
|
int m_startRow; // Начальная строка видимого текста
|
|
int m_startCol; // Начальный столбец (символ) видимого текста
|
|
|
|
int m_totalRows; // Общее число строк текста
|
|
int m_totalCols; // Общее число символов в самой длинной строке текста
|
|
|
|
int m_visibleRows; // Максимальное количество видимых строк
|
|
int m_visibleCols; // Максимальное количество видимых символов в строке
|
|
|
|
string m_fontName; // Название шрифта для текста
|
|
int m_fontSize; // Размер шрифта
|
|
uint m_fontColor; // Цвет шрифта
|
|
|
|
int m_fontSymbolWidth; // Ширина одного символа в пикселях
|
|
int m_fontSymbolHeight; // Высота строки текста в пикселях
|
|
|
|
uint m_backgroundColor; // Цвет фона
|
|
|
|
bool m_mouseWheel; // Предыдущее состояние отслеживания событий прокрутки мышью
|
|
|
|
bool CreateCanvas(); // Создание холста
|
|
void UpdateCanvas(); // Вывод текста на холсте
|
|
void UpdateCanvasFont(); // Изменение шрифта холста
|
|
|
|
public:
|
|
CConsoleDialog(); // Конструктор
|
|
~CConsoleDialog(void); // Деструктор
|
|
|
|
// Методы создания диалогового окна
|
|
bool Create(string name);
|
|
virtual bool Create(const long chart, const string name, const int subwin,
|
|
const int x1, const int y1, const int x2, const int y2);
|
|
// Обработка событий
|
|
virtual void ChartEvent(const int id, const long &lparam,
|
|
const double &dparam, const string &sparam);
|
|
|
|
virtual void Minimize(); // Минимизация диалогового окна
|
|
virtual void Maximize(); // Максимизация диалогового окна
|
|
|
|
virtual void Text(string text); // Установка нового текста
|
|
|
|
virtual void FontName(string p_fontName); // Установка названия шрифта
|
|
virtual bool FontSize(int p_fontSize); // Установка размера шрифта
|
|
virtual void FontColor(uint p_fontColor); // Установка цвета шрифта
|
|
|
|
// Установка цвета фона
|
|
virtual void BackgroundColor(uint p_backgroundColor);
|
|
};
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Конструктор |
|
|
//+------------------------------------------------------------------+
|
|
CConsoleDialog::CConsoleDialog() :
|
|
m_fontName("Consolas"),
|
|
m_fontSize(13),
|
|
m_fontColor(ColorToARGB(clrBlack, 240)),
|
|
m_backgroundColor(ColorToARGB(clrBlack, 0)) {
|
|
FontSize(m_fontSize);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Деструктор |
|
|
//+------------------------------------------------------------------+
|
|
CConsoleDialog::~CConsoleDialog() {
|
|
// Удаляем холст
|
|
m_canvas.Destroy();
|
|
|
|
// Возвращаем прежнюю настройку обработки событий прокрутки мышью
|
|
ChartSetInteger(m_chart_id, CHART_EVENT_MOUSE_WHEEL, (long)m_mouseWheel);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Метод создания диалогового окна только по имени |
|
|
//+------------------------------------------------------------------+
|
|
bool CConsoleDialog::Create(string name) {
|
|
// Устанавливаем положение угла и размеры окна
|
|
int x1 = 0;
|
|
int y1 = DIALOG_VERTICAL_MARGIN;
|
|
int y2 = (int) ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS, 0);
|
|
int x2 = (int) ChartGetInteger(0, CHART_WIDTH_IN_PIXELS, 0);
|
|
|
|
// Вызываем метод создания по заданным размерам
|
|
return Create(0, name, 0, x1, y1, x2, y2);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Метод создания диалогового окна |
|
|
//+------------------------------------------------------------------+
|
|
bool CConsoleDialog::Create(const long chart, const string name, const int subwin, const int x1, const int y1, const int x2, const int y2) {
|
|
// Вызов родительского метода создания диалога
|
|
if(!CAppDialog::Create(chart, name, subwin, x1, y1, x2, y2)) {
|
|
return false;
|
|
}
|
|
|
|
// Устновка размеров минимизированного окна диалога
|
|
m_min_rect.SetBound(0, DIALOG_VERTICAL_MARGIN,
|
|
250, DIALOG_VERTICAL_MARGIN + CONTROLS_DIALOG_MINIMIZE_HEIGHT);
|
|
|
|
// Создание холста
|
|
if(!CreateCanvas()) {
|
|
return false;
|
|
}
|
|
|
|
// Запоминаем прежнюю настройку обработки событий прокрутки мышью
|
|
m_mouseWheel = ChartGetInteger(0, CHART_EVENT_MOUSE_WHEEL);
|
|
|
|
// Устанавливаем отслеживание событий прокрутки мышью
|
|
ChartSetInteger(chart, CHART_EVENT_MOUSE_WHEEL, 1);
|
|
|
|
// Устанавливаем начальное положение текста в окне
|
|
m_startRow = 0;
|
|
m_startCol = 0;
|
|
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Обработка событий |
|
|
//+------------------------------------------------------------------+
|
|
void CConsoleDialog::ChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) {
|
|
// Обработка события прокрутки колёсика мыши
|
|
if(id == CHARTEVENT_MOUSE_WHEEL) {
|
|
// Если окно диалога минимизировано, то не обрабатываем это событие
|
|
if(m_minimized) {
|
|
return;
|
|
}
|
|
|
|
// Разбираем состояние кнопок и колесика мышки для этого события
|
|
int flg_keys = (int)(lparam >> 32); // флаг состояний клавиш Ctrl, Shift и кнопок мышки
|
|
int delta = (int)dparam; // суммарное значение прокрутки колесика,
|
|
// срабатывает при достижении +120 или -120
|
|
|
|
// Если нажата клавиша SHIFT, то
|
|
if((flg_keys & 0x0004) != 0) {
|
|
// Если количество символов в строке больше количества видимых
|
|
// символов в диалоге, то выполняем горизонтальное смещение
|
|
if(m_totalCols > m_visibleCols) {
|
|
// На одно событие прокрутки будем смещаться на 2 символа (120 / 60 = 2)
|
|
delta /= 60;
|
|
|
|
// Если новая начальная позиция попадает в допустимый диапазон, то
|
|
if(m_startCol - delta >= 0
|
|
&& m_startCol - delta <= m_totalCols - m_visibleCols + 2) {
|
|
// Запоминаем новую начальную позицию
|
|
m_startCol -= delta;
|
|
|
|
// Обновляем холст
|
|
UpdateCanvas();
|
|
}
|
|
}
|
|
} else if (flg_keys == 0) {
|
|
// Иначе если количество строк текста больше количества видимых
|
|
// строк в диалоге, то выполняем вертикальное смещение
|
|
if(m_totalRows > m_visibleRows) {
|
|
// На одно событие прокрутки будем смещаться на 1 строку (120 / 120 = 1)
|
|
delta /= 120;
|
|
|
|
// Если новая начальная позиция попадает в допустимый диапазон, то
|
|
if(m_startRow - delta >= 0
|
|
&& m_startRow - delta <= m_totalRows - m_visibleRows + 1) {
|
|
// Запоминаем новую начальную позицию
|
|
m_startRow -= delta;
|
|
|
|
// Обновляем холст
|
|
UpdateCanvas();
|
|
}
|
|
}
|
|
} else if((flg_keys & 0x0008) != 0) {
|
|
// Иначе если нажата клавиша CTRL, то пробуем установить новый размер шрифта
|
|
if(FontSize(m_fontSize + delta / 120)) {
|
|
// Обновляем холст
|
|
UpdateCanvas();
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
// Обработка события изменения графика
|
|
if(id == CHARTEVENT_CHART_CHANGE) {
|
|
// Если размеры отображаемой области изменились
|
|
if(m_chart.HeightInPixels(m_subwin) != Height() + DIALOG_VERTICAL_MARGIN
|
|
|| m_chart.WidthInPixels() != Width()) {
|
|
// Установить для диалогового окна новые размеры
|
|
m_norm_rect.SetBound(0, DIALOG_VERTICAL_MARGIN, m_chart.WidthInPixels(), m_chart.HeightInPixels(m_subwin));
|
|
|
|
// Если окно диалога не минимизировано, то
|
|
if(!m_minimized) {
|
|
// Разворачивем его на полный экран графика с новыми размерами
|
|
Maximize();
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Обработка отсальных событий в вышестоящем классе
|
|
CAppDialog::ChartEvent(id, lparam, dparam, sparam);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Минмизация диалогового окна |
|
|
//+------------------------------------------------------------------+
|
|
void CConsoleDialog::Minimize() {
|
|
// Удаляем холст
|
|
m_canvas.Destroy();
|
|
|
|
// Вызываем родительский метод минимизации
|
|
CAppDialog::Minimize();
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Максимизация диалогового окна |
|
|
//+------------------------------------------------------------------+
|
|
void CConsoleDialog::Maximize() {
|
|
// Вызываем родительский метод максимизации
|
|
CAppDialog::Maximize();
|
|
|
|
// Создаём холст
|
|
CreateCanvas();
|
|
|
|
// Выводим текст на холсте
|
|
UpdateCanvas();
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Установка текста |
|
|
//+------------------------------------------------------------------+
|
|
void CConsoleDialog::Text(string text) {
|
|
// Если текст изменяется, то
|
|
if(text != m_text) {
|
|
// Запомним новый тект
|
|
m_text = text;
|
|
|
|
// Делим текст на строки
|
|
StringSplit(m_text, '\n', m_lines);
|
|
|
|
// Запоминаем количество строк
|
|
m_totalRows = ArraySize(m_lines);
|
|
|
|
// Определяем максимальную длину строк
|
|
m_totalCols = 0;
|
|
FOREACH(m_lines) {
|
|
m_totalCols = MathMax(m_totalCols, StringLen(m_lines[i]));
|
|
}
|
|
|
|
// Выводим текст на холсте
|
|
UpdateCanvas();
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Установка названия шрифта |
|
|
//+------------------------------------------------------------------+
|
|
void CConsoleDialog::FontName(string p_fontName) {
|
|
// Запоминаем новое имя шрифта
|
|
m_fontName = p_fontName;
|
|
|
|
// Обновляем шрифт холста
|
|
UpdateCanvasFont();
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Установка размера шрифта |
|
|
//+------------------------------------------------------------------+
|
|
bool CConsoleDialog::FontSize(int p_fontSize) {
|
|
// Если размер находится в разумных пределах, то
|
|
if (p_fontSize >= 8 && p_fontSize <= 72) {
|
|
// Запоминаем новый размер шрифта
|
|
m_fontSize = p_fontSize;
|
|
|
|
// Сбрасываем начальную строку и столбец
|
|
m_startRow = 0;
|
|
m_startCol = 0;
|
|
|
|
// Обновляем шрифт холста
|
|
UpdateCanvasFont();
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Установка цвета шрифта |
|
|
//+------------------------------------------------------------------+
|
|
void CConsoleDialog::FontColor(uint p_fontColor) {
|
|
m_fontColor = p_fontColor;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Установка цвета фона |
|
|
//+------------------------------------------------------------------+
|
|
void CConsoleDialog::BackgroundColor(uint p_backgroundColor) {
|
|
m_backgroundColor = p_backgroundColor;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Создание холста |
|
|
//+------------------------------------------------------------------+
|
|
bool CConsoleDialog::CreateCanvas() {
|
|
// Получаем размеры клиентской области диалогового окна
|
|
int height = ClientAreaHeight();
|
|
int width = ClientAreaWidth();
|
|
|
|
// Если размеры ненулевые
|
|
if(height > 0 && width > 0) {
|
|
// Если при создании холста возникла ошибка, то выходим
|
|
if(!m_canvas.CreateBitmapLabel("display",
|
|
ClientAreaLeft(),
|
|
ClientAreaTop(),
|
|
ClientAreaWidth(),
|
|
ClientAreaHeight(),
|
|
COLOR_FORMAT_ARGB_NORMALIZE)) {
|
|
PrintFormat(__FUNCTION__" | ERROR: Creating canvas %d", GetLastError());
|
|
return false;
|
|
}
|
|
|
|
UpdateCanvasFont();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Вывод текста на холсте |
|
|
//+------------------------------------------------------------------+
|
|
void CConsoleDialog::UpdateCanvas() {
|
|
// Стираем холст цветом фона
|
|
m_canvas.Erase(m_backgroundColor);
|
|
|
|
// Для каждой строки, попадающей в видимый диапазон
|
|
for (int i = m_startRow; i < MathMin(m_totalRows, m_startRow + m_visibleRows); i++) {
|
|
// Берём очередную строку текста
|
|
string line = m_lines[i];
|
|
|
|
// Если её надо показывать не с первого символа, то
|
|
if (m_startCol > 0) {
|
|
// Вырезаем начальные символы
|
|
line = StringSubstr(line, m_startCol);
|
|
}
|
|
|
|
// Выводим строку на холст
|
|
m_canvas.TextOut(5, 5 + (i - m_startRow) * m_fontSymbolHeight, line, m_fontColor, TA_LEFT | TA_TOP);
|
|
}
|
|
|
|
// Вызываем метод отрисовки холста на экране
|
|
m_canvas.Update(true);
|
|
}
|
|
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Изменение шрифта холста |
|
|
//+------------------------------------------------------------------+
|
|
void CConsoleDialog::UpdateCanvasFont() {
|
|
// Установка параметров шрифта для вывода текста на холст
|
|
m_canvas.FontSet(m_fontName, m_fontSize);
|
|
|
|
// Установка новых размеров одного символа
|
|
m_canvas.TextSize("M", m_fontSymbolWidth, m_fontSymbolHeight);
|
|
|
|
// Определяем количество видимых строк и символов в строке (столбцов)
|
|
m_visibleRows = ClientAreaHeight() / m_fontSymbolHeight;
|
|
m_visibleCols = ClientAreaWidth() / m_fontSymbolWidth;
|
|
}
|
|
//+------------------------------------------------------------------+
|