EA-Setka-2/Libs/MQL5Trace/View/PropertyView.mqh
super.admin a4b861dd93 convert
2025-05-30 14:50:44 +02:00

183 lines
No EOL
15 KiB
MQL5

//+------------------------------------------------------------------+
//| PropertyView |
//| Copyright 2006-2011, www.FXmaster.de |
//| www.FXmaster.de |
//+------------------------------------------------------------------+
#property copyright "Copyright 2006-2011, www.FXmaster.de"
#property link "www.FXmaster.de"
#property version "1.00"
#include "TreeView.mqh"
#ifndef REPORT_BROWSER
#import "shell32.dll"
int ShellExecuteW(int hwnd, string &lpOperation, string &lpFile, string &lpParameters, string &lpDirectory, int nShowCmd);
#import
#endif
#define SW_SHOWNORMAL 1
#define SW_SHOWMINIMIZED 2
#define ERROR_BAD_FORMAT 11
#define ERROR_FILE_NOT_FOUND 2
#define ERROR_PATH_NOT_FOUND 3
//------------------------------------------------------------------ class CPropertyView
class CPropertyView: public CTreeView
{
//--- базовые функции
public:
CPropertyView(); // конструктор
~CPropertyView(); // деструктор
virtual void Create(long chart, string name, int wnd, color clr, color bgclr, color selclr, int x, int y, int dx, int dy, int corn=0, int fontsize=8, string font="Arial");
//--- функции обработки состояния
public:
virtual int OnClick(string name); // обработка события клика на объекте
//--- функции отображения
public:
virtual void Draw(); // обновить вид
virtual void DrawTree(CNode *root, int xpos, int &ypos, int &up, int &dn);
virtual void DrawNode(CNode *node, int x, int y); // отрисовать узел
virtual void DeleteView(CNode *root=NULL, bool delparent=true); // удаляем отображение
};
//------------------------------------------------------------------ CPropertyView
void CPropertyView::CPropertyView() { }
//------------------------------------------------------------------ ~CPropertyView
void CPropertyView::~CPropertyView()
{
ObjectDelete(m_chart, m_name+".open");
DeleteView();
}
//------------------------------------------------------------------ Create
void CPropertyView::Create(long achart, string name, int wnd, color clr, color bgclr, color selclr, int x, int y, int dx, int dy, int corn=0, int fontsize=8, string font="Arial")
{
CTreeView::Create(achart, name, wnd, clr, bgclr, selclr, x, y, dx, dy, corn, fontsize, font);
}
//------------------------------------------------------------------ OnClick
int CPropertyView::OnClick(string name) // имя объекта на который кликнули
{
int start=StringLen(m_name); int len=StringFind(name, ".")-start;
int id=(int)StringToInteger(StringSubstr(name, start, len));
if (StringFind(name, ".open")>=0)
{
ObjectSetInteger(m_chart, name, OBJPROP_STATE, false);
string path=m_tree.m_root.m_path;
string cmd="open"; string nil="";
int hWnd=(int)ChartGetInteger(m_chart, CHART_WINDOW_HANDLE);
int rez=ShellExecuteW(hWnd, cmd, path, nil, nil, SW_SHOWNORMAL);
if (rez==0) MessageBox("Нехватает ресурсов для открытия \n"+path);
else if (rez==ERROR_BAD_FORMAT) MessageBox("Не \'exe\' файл ");
else if (rez==ERROR_FILE_NOT_FOUND) MessageBox("Файл не найден \n"+path);
else if (rez==ERROR_PATH_NOT_FOUND) MessageBox("Путь не найден \n"+path);
else if (rez<=31) MessageBox("Ошибка запуска \n"+path);
return(BTN_OPEN);
}
else return(CTreeView::OnClick(name));
}
//------------------------------------------------------------------ Draw
void CPropertyView::Draw()
{
if (!IsOpenView()) return; // если не создан просмотр, то выходим
SetRectLbl(m_chart, m_name+".rect", m_wnd, "", m_clr, m_bgclr, m_x, m_y, m_dx, m_dy, m_corn, m_fontsize, m_font, true);
int ax=int(m_x+m_dx-1.5*m_bdx); int adx=int(1.2*m_bdx); int i=-1;
i++; SetButton(m_chart, m_name+".collaps", 0, "-", m_bgclr, m_selclr, ax-i*adx, int(m_y+0.5*m_bdy), m_bdx, m_bdy, 0, 7, "Tahoma", false);
i++; SetButton(m_chart, m_name+".expand", 0, "+", m_bgclr, m_selclr, ax-i*adx, int(m_y+0.5*m_bdy), m_bdx, m_bdy, 0, 7, "Tahoma", false);
i++; SetButton(m_chart, m_name+".open", 0, "...", m_bgclr, clrDarkOliveGreen, ax-i*adx, int(m_y+0.5*m_bdy), m_bdx, m_bdy, 0, 7, "Tahoma", false);
int show=0, up=0, dn=0;
DrawTree(m_tree.m_root, 1, show, up, dn); // нарисовали дерево
if (up<=0 && dn<=0) m_scroll.DeleteView(); // убрали полосу прокрутки для перерисовки
else
{
m_scroll.m_max=up+dn; m_scroll.m_value=up;
m_scroll.m_x=m_x+m_dx-20; m_scroll.m_dx=16;
m_scroll.m_y=m_y+2*m_bdy; m_scroll.m_dy=m_dy-3*m_bdy+8;
m_scroll.Draw(); // отрисовали полосу прокрутки
}
}
//------------------------------------------------------------------ DrawTree
void CPropertyView::DrawTree(CNode *root, int xpos, int &ypos, int &up, int &dn)
{
if (xpos==1) { root=m_tree.m_root; ypos=0; } // если начали с первого элемента, то берем корень и левое положение
if (root==NULL) { root=m_tree.m_root; xpos=1; } // если не указан первый узел, то берем корень и верхнее положение
if (NIL(root)) return; // правильность указателя
string name=m_name+string(root.m_id);
if (!IsOpenView()) return; // если не создан просмотр, то выходим
int x=m_x0+m_x+5+(xpos-1)*m_bdx;
int y=m_y0+m_y+5+ypos*m_ndy;
bool ishide=(y<=m_y || y>=m_y+m_dy-m_ndy);
if (root.m_break && ishide)
{
while (y<m_y) { m_y0+=m_ndy; y=m_y0+m_y+5+ypos*m_ndy; }// подвинули вниз
while (y>m_y+m_dy-m_ndy) { m_y0-=m_ndy; y=m_y0+m_y+5+ypos*m_ndy; }// подвинули вверх
up=0; dn=0;
DrawTree(m_tree.m_root, 1, ypos, up, dn); // отрисовали снова все дерево
}
if (!ishide) DrawNode(root, x, y); // если не уходит за область видимости
else
{
ObjectDelete(m_chart, name+".lbl"); ObjectDelete(m_chart, name+".btn");
ObjectDelete(m_chart, name+".prop");
if (y<m_y) up++; else dn++;
}
if (!root.m_expand) return; // если не раскрыт, то пропускаем
for (int i=0; i<ArraySize(root.m_next); i++)
{
if (NIL(root.m_next[i])) continue;
ypos++; // увеличили положение
DrawTree(root.m_next[i], xpos+1, ypos, up, dn); // отрисовали следующую ветку
}
}
//------------------------------------------------------------------ DrawNode
void CPropertyView::DrawNode(CNode *node, int x, int y)
{
if (NIL(node)) return;
int ndx=m_ndx-m_bdx;
string name=m_name+string(node.m_id);
string txt=node.m_text;
// определяем цвет
bool bgroup=false;
if (!NIL(node.m_prev)) if (node.m_prev.m_id==0) bgroup=true;
color clr=bgroup ? m_selclr : m_clr;
clr=node.m_id==0 ? clrDarkOliveGreen : clr;
// выводим текст для узла
SetLabel(m_chart, name+".lbl", m_wnd, txt, clr, x+ndx, y-1, m_corn, m_fontsize, m_font);
if (node.m_desc=="" || node.m_id==0 || !node.m_expand)
ObjectDelete(m_chart, name+".prop");
else
{
if (node.m_edit) SetEdit(m_chart, name+".prop", m_wnd, node.m_desc, clr, m_bgclr, int(m_x+150), y, m_ndx*2, m_ndy+1, m_corn, m_fontsize, m_font, false);
else SetLabel(m_chart, name+".prop", m_wnd, node.m_desc, clr, int(m_x+150), y, m_corn, m_fontsize, m_font);
}
// кнопку раскрытости узла
string state=node.m_expand ? "-" : "+";
if (ArraySize(node.m_next)>0) // если есть подмассив, то ставим раскрытие
SetButton(m_chart, name+".btn", m_wnd, state, m_clr, m_bgclr, x, y, m_bdx, m_bdy, m_corn, m_fontsize, m_font, node.m_expand);
else ObjectDelete(m_chart, name+".btn");
}
//------------------------------------------------------------------ DeleteView
void CPropertyView::DeleteView(CNode *root=NULL, bool delparent=true)
{
CTreeView::DeleteView(root, delparent); // метод базового
if (root==NULL) root=m_tree.m_root; if (NIL(root)) return;
if(delparent) // удаляем узел родителя
ObjectDelete(m_chart, m_name+string(root.m_id)+".prop");
for (int i=0; i<ArraySize(root.m_next); i++)
if (!NIL(root.m_next[i])) DeleteView(root.m_next[i], true);
}