В статье пересмотрим структуру индикаторного буфера в мультисимвольных мультипериодных индикаторах и организуем вывод на график цветных буферов этих индикаторов.
//--- Если панель по высоте не больше размера окна по высотеif(!this.m_higher_wnd)
{
if(y+h>this.m_chart_h-2)
y=this.m_chart_h-h-2;
if(y<1)
y=1;
}
//--- Если панель по высоте не входит в размер окна по высотеelse
{
//--- Не даём панели опускаться ниже верхней грани окна с зазором в 1 пиксельif(y>1)
y=1;
//--- Не даём панели провалиться ниже нижней грани окна с зазором в 1 пиксельif(y<this.m_chart_h-h-2)
y=this.m_chart_h-h-2;
}
//+------------------------------------------------------------------+//| Обработчик событий |//+------------------------------------------------------------------+void CDashboard::OnChartEvent(constint id,constlong &lparam,constdouble &dparam,conststring &sparam)
{
//--- Если создан графический объектif(id==CHARTEVENT_OBJECT_CREATE)
{
this.BringToTop();
::ObjectSetInteger(this.m_chart_id,sparam,OBJPROP_SELECTED,true);
}
//--- Если график изменёнif(id==CHARTEVENT_CHART_CHANGE)
{
//--- Получаем номер подокна графика, если это не главное окно (номер может измениться при удалении окна какого-либо индикатора)if(this.m_wnd!=0)
this.m_wnd=this.GetSubWindow();
//--- Получаем новые размеры графикаint w=(int)::ChartGetInteger(this.m_chart_id,CHART_WIDTH_IN_PIXELS,this.m_wnd);
int h=(int)::ChartGetInteger(this.m_chart_id,CHART_HEIGHT_IN_PIXELS,this.m_wnd);
//--- Определяем выход размеров панели за пределы окна графикаthis.m_higher_wnd=this.HigherWnd();this.m_wider_wnd=this.WiderWnd();//--- Если высота графика изменилась - корректируем расположение панели по вертикалиif(this.m_chart_h!=h)
{
this.m_chart_h=h;
int y=this.m_y;
if(this.m_y+this.m_h>h-1)
y=h-this.m_h-1;
if(y<1)
y=1;
this.Move(this.m_x,y);
}
//--- Если ширина графика изменилась - корректируем расположение панели по горизонталиif(this.m_chart_w!=w)
{
this.m_chart_w=w;
int x=this.m_x;
if(this.m_x+this.m_w>w-1)
x=w-this.m_w-1;
if(x<1)
x=1;
this.Move(x,this.m_y);
}
}
//--- Если график изменёнif(id == CHARTEVENT_CHART_CHANGE)
{
//--- Получаем номер подокна графика, если это не главное окно (номер может измениться при удалении окна какого-либо индикатора)if(m_wnd != 0)
m_wnd = GetSubWindow();
//long value;
// сбросим значение ошибки
::ResetLastError();
// получим значение свойстваif(!::ChartGetInteger(m_chart_id, CHART_BRING_TO_TOP, m_wnd, value))
{
//--- выведем сообщение об ошибке в журнал "Эксперты"Print(__FUNCTION__ + ", Error Code = ", ::GetLastError());
return;
}
// если это не показ графика поверх всех других - выходимif(value == 0)
return;
//--- Получаем новые размеры графикаint w = (int)::ChartGetInteger(m_chart_id, CHART_WIDTH_IN_PIXELS, m_wnd);
int h = (int)::ChartGetInteger(m_chart_id, CHART_HEIGHT_IN_PIXELS, m_wnd);
//--- Определяем выход размеров панели за пределы окна графика//m_higher_wnd = HigherWnd();//m_wider_wnd = WiderWnd();//--- Если высота графика изменилась - корректируем расположение панели по вертикалиif(m_chart_h != h)
{
m_chart_h = h;
m_higher_wnd = HigherWnd(); // addedint y = m_y;
if(m_y + m_h > h - 1)
y = h - m_h - 1;
if(y < 1)
y = 1;
Move(m_x, y);
}
//--- Если ширина графика изменилась - корректируем расположение панели по горизонталиif(m_chart_w != w)
{
m_chart_w = w;
m_wider_wnd = WiderWnd(); // addedint x = m_x;
if(m_x + m_w > w - 1)
x = w - m_w - 1;
if(x < 1)
x = 1;
Move(x, m_y);
}
}
我浏览了论坛。这个问题已经被讨论过了。举个例子。我在代码中 添加了这样一个检查:
错误似乎消失了。
谢谢。我稍后会把这个面板类添加到我的代码中。顺便说一下,在使用该面板的每一篇文章中,都有各种各样的改进。我想这是 使用该面板的最后一篇文章。但我不记得是否已经改进过了。
我在这里附上了面板类的代码。
关于交易、自动交易系统和交易策略测试的论坛
讨论文章 "制作用于在指标和智能交易系统中显示数据的信息面板"
Denis Kirichenko, 2024.09.23 22:26
另一个问题。当指标从图表中移除,面板最小化,然后在图表....,它无法处理 面板 窗口的展开。
是的,在最新版本的 Dashboard.mqh 中没有这个错误。它可以正常工作。
是的,在最新版本的 Dashboard.mqh 中没有这样的错误。它可以运行。
新的围兜还有一个错误。如果在图表上启动面板,然后调整图表窗口大小,当窗口恢复时,面板会粘在底部。而且它不想离开那里((
Artem,我有一个问题。在 void CDashboard::Move(int x, int y) 方法中有这样一个东西:
我尤其对这个 模块感兴趣。也就是说,如果面板高度小于图表窗口高度,并且其 Y 点(左上角)低于窗口高度与面板高度之差(修正 2 个像素),那么面板的上端点将被赋予 该差值。为什么会这样,重点是什么?
简而言之,这是因为CDashboard::Move(int x, int y) 方法导致了粘连。当您尝试在更改图表尺寸后移动面板时,它会不断纠正坐标,不允许您自由移动面板窗口...
Move(int x, int y)
有一个错误。您需要打印(或在调试器中查看,但通常不起作用)坐标和大小值。
下面是注释中的逻辑:
当改变图表尺寸后尝试移动面板时,它会不断修正坐标,而不允许您自由移动面板窗口...
在 Move() 方法中,this.m_higher_wnd 变量的值很可能与此无关。这些值是在事件处理程序中设置的:
很有可能在图表窗口展开时,超大标记没有在此处正确设置。
如果将这几行
在 Move() 方法的开头强制设置每次鼠标移动时的正确值,那么错误是否会消失?如果是这样,那就说明问题出在这些变量的值上,您需要在事件处理程序中查找为什么它们在窗口展开时没有得到它们的值。如果一切正常,那么你就需要打印 Move() 方法来查找错误。
错误消失了。我对 CDashboard::OnChartEvent() 方法做了这些 更改:
为了避免不断加载CDashboard:: Move() 方法,我在直接更改图表窗口宽度和高度的块中添加了超大标志检查。
错误消失了。我对 CDashboard::OnChartEvent() 方法做了这些 更改:
为了避免不断加载CDashboard:: Move() 方法,我在直接更改图表窗口宽度和高度的块中添加了超大标志检查。