183 lines
No EOL
15 KiB
MQL5
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);
|
|
} |