程序库: Easy Canvas - 页 12

 
Nikolai Semko:

这适用于正常模式还是测试仪?

正常模式,尼古拉。

 
Nikolai Semko:

谢谢!

这个功能不合适吗?

很遗憾不合适。它移动的是位图对象本身,我需要的是一个可以移动内容 x 点的函数。我知道内存内部由 x、y 数组组成,但 mql 中没有 memmove 或其他东西。我不知道如何快速移动内存。

 
Владислав Качило :

正常模式,尼古拉

我通常采用以下方案:

  1. 我在一个函数中执行与柱状图或时间相关的所有绘制,例如 void Draw()
  2. 在 OnChartEvent 中 添加行
    if (id == CHARTEVENT_CHART_CHANGE ) Draw (); 
    跟踪图表变化事件(新条形图也是图表变化事件)。
  3. 在测试模式的 OnCalculate 中,我添加了一条重绘线,例如当出现新条形图时,因为 OnChartEvent 不工作:
     if(rate_total-prev_calculated == 1) if (Canvas.tester) {ChartChanged (); Draw ();}

如果在 MT4 中不起作用,那么 CHARTEVENT_CHART_CHANGE 事件就有问题。我现在无法检查,因为还没有报价。

 
Nikolai Semko:

我通常会这样做

  1. 我在一个函数中完成与柱状图或时间相关的所有绘制,例如 void Draw()
  2. 在 OnChartEvent 中 添加一行 来跟踪图表变化事件(新条形图也是图表变化事件)。
  3. 在测试模式的 OnCalculate 中,我添加了一行用于重新绘制,例如当出现新的条形图时,因为 OnChartEvent 不工作:

如果在 MT4 中不起作用,那么 CHARTEVENT_CHART_CHANGE 事件就有问题。我现在无法检查,因为还没有报价。

尼古拉斯,为了不耽误您的时间,我在上面写了一个解决方案,解决了我的问题,即,正如您正确注意到的,在 OnCalcucate() 中插入以下代码:

if(rates_total - prev_calculated == 1)ChartChanged();

 
Mighty7:

可惜不行。它移动的是位图对象本身,我需要的是一个可以移动内容 x 点的函数。我知道内存内部由 x、y 数组组成,但 mql 中没有 memmove 或其他东西。我不知道如何快速移动内存。

我不明白,你需要在整个画布内移动矩形区域吗?

 
Vladyslav Katsylo:

尼古拉斯,为了不浪费你的时间,我在上面写了一个解决我的问题的方法,即,正如你正确注意到的,在 OnCalcucate() 中插入以下代码:

在正常的非测试模式下,你不应该这样做,因为 ChartChanged() 函数会被连续执行两次,这是不太合理的。毕竟,它是在 iCanvas.mqh 文件中发生 CHARTEVENT_CHART_CHANGE 事件时执行的。
在不使用 ChartChanged() 的情况下,当窗口更改事件(CHARTEVENT_CHART_CHANGE)发生时,在OnChartEvent 中重新绘制与条形图或时间绑定的画布是正确的。

 
Vladyslav Katsylo:

尼古拉斯,为了不浪费你的时间,我在上面写了一个解决我的问题的方法,即,正如你正确注意到的,在 OnCalcucate() 中插入以下代码:

你需要考虑以下几点:

  • 每次在 iCanvas 类内的OnChartEvent 中发生CHARTEVENT_CHART_CHANGE 事件时,都会执行 ChartChanged()
  • 先执行 iCanvas 类中的 OnChartEvent,然后再 执行 您代码 中的 OnChartEvent。

您的问题显然是因为 OnCalculate 在OnChartEvent 执行 之前执行,因此 ChartChanged() 尚未处理。
这就是为什么在OnChartEvent 而不是 OnCalculate 中实现重绘处理程序是合理的
。尤其是用户可以随时改变窗口的大小,所以应该这样做。CHARTEVENT_CHART_CHANGE 事件负责这一切

 
Nikolai Semko:

我不明白,是否需要在整个画布内移动矩形区域?

是的。例如:我在全屏画布的中间画了一个圆,并想将圆向左移动,但我不想删除整个区域并在每次移动时重新绘制圆,而只想将内存向左滚动。

CCanvas 只是一个 x/y 点数组。

   uint              m_pixels[];               // 像素数组
//+------------------------------------------------------------------+
//| 获取像素颜色|
//+------------------------------------------------------------------+
uint CCanvas::PixelGet(const int x,const int y) const
  {
//--- 检查坐标
   if(x>=0 && x<m_width && y>=0 && y<m_height)
      return(m_pixels[y*m_width+x]);
//--- 错误
   return(0);
  }

我需要的是一个可以将 m_pixels 向左、右、上、下移动的函数

 
Mighty7:

可以。例如:我在全屏画布的中间画了一个圆,想将圆向左移动,但我不想删除整个区域并在每次移动时重新绘制圆,而只想将内存向左滚动。

CCanvas 只是一个 x/y 点数组。

我需要的是一个可以将 m_pixels 向左、右、上、下移动的函数

是的,这是一个合理的愿望。
而且实现起来并不困难。
我考虑过这个问题,但得出的结论是,如果需要移动普通画布的矩形部分,有一种更简单的方法可以实现:

  • 创建一个新的较小画布。在这种情况下,您就不必担心要填充要移动部分的背景了。

是的,这是一个有充分理由的愿望。
而且,实现起来也不难。
我想了想,得出的结论是,如果需要移动普通画布的矩形部分,那么有一种更简单的方法可以实现:
  • 创建一个新的、更小的画布。在这种情况下,您不必担心移动部分的背景填充问题。
 
Nikolai Semko:

是的,这是很合理的愿望。
而且实现起来并不困难。
我考虑过这个问题,但得出的结论是,如果需要移动一般画布的矩形部分,有一种更简单的方法可以实现:

  • 创建一个新的较小画布。在这种情况下,您不必担心要填充要移动部分的背景。

是的,这是一个有充分理由的愿望。
而且,实现起来也不难。
我想了想,得出的结论是,如果需要移动普通画布的矩形部分,那么有一种更简单的方法可以实现:
  • 创建一个新的、更小的画布。在这种情况下,您不必担心移动部分的背景填充问题。

这行不通,因为我的画布是全屏的。这就像一个刻度线图,但要擦除整个背景并重新构建和绘制所有内容需要花费大量时间,因此我需要将内容向左移动(例如 8 像素),然后只在新的 8 像素(X 方向 8 px,全高)上绘制新数据。我试着用 MoveCanvas 将画布向左移动 8 像素,这样做是可行的,但我无法按照从左侧移除 8 像素宽度并在右侧添加 8 像素的方式调整画布大小。希望您能理解...