文章 "MQL5 细则手册:指标子窗口控件 - 按钮" - 页 4

 
DC2008:

而 "按钮功能放在 OnInit 函数中 "的说法非常可笑!

不过,也许你不明白我们在说什么?如果按下按钮,就会触发一些用户函数来执行一些微任务。

 
DC2008:

好吧,让我们笑一笑。文章是你写的,"没人扯你的舌头"。

所以,用引经据典的形式来解释无法解释的事情,至少是对读者的不尊重。回答问题时应举例说明,并提供原始资料 链接。

用不必要的函数混乱和超载代码只会误导 "初学者"。

而 "按钮函数放在 OnInit 函数中 "这一事实非常可笑!

没人拽你的舌头。你要给我证据吗?或者说,反驳我的说法?我想告诉你的是,手册中还没有描述所有的功能。我的意思是,手册的编写工作正在进行中,补充和更正也在进行中。您应该亲自检查所有内容。

请相信我,您文章中的代码不仅对初学者来说更 "令人困惑",从您文章的讨论中也可以看出这一点。

不过,也许您不明白我们在说什么?如果您点击一个按钮,就会触发一些用户函数来执行一些微任务。

是的,我是从字面上理解的。请把问题问得更准确一些。但我估计我的回答会被你嘲笑,因为你今天似乎就有这样的功能。

在这种情况下,"微任务 "就是改变按钮的颜色。我特意没有添加任何额外的功能,以免多余。只是为了避免代码超载。

实际上,这篇文章的主题并不仅限于按钮。大部分内容都与图表事件有关。这样的例子很少,所以我决定写一个。

 

亲爱的作者,你不是为我写的,而是为初学者写的。的确,我对你的解决方案不感兴趣,但我们谈论的是那些刚刚了解这门语言的人。我们在谈论什么 "其他程序"?一个程序的 OnDeinit 函数 如何影响其他程序的函数?

我们在讨论一篇文章,你为什么如此愤愤不平?

试着回答这些问题,不是为了我,而是为了初学者--让他们明白为什么和怎么做。

Документация по MQL5: Основы языка / Функции / Функции обработки событий
Документация по MQL5: Основы языка / Функции / Функции обработки событий
  • www.mql5.com
Основы языка / Функции / Функции обработки событий - Документация по MQL5
 
DC2008:

亲爱的作者,你不是为我写的,而是为初学者写的。

正是如此。

的确,我对你的解决方案不感兴趣,但我们谈论的是那些刚刚了解这门语言的人。

但你提出了问题。

我们在谈论什么 "其他方案"?

就是你之前提供链接的那些。你试图用暗示来反驳我的说法,却没有给出证据。

一个程序的 OnDeinit 函数 怎么会影响其他程序的函数?

确实会。我写过这篇文章。发表文章的编辑也证实了这一点。你也可以自己去查查看。

我们正在讨论这篇文章,你为什么这么反感?

没什么。我在等你反驳我的论断。)

试着回答问题,而不是回答我的问题,而是回答新人的问题--让他们明白为什么和怎么做。

到目前为止,新人还没有提出任何问题。也不可能有问题。一切都非常清楚,每一行代码都有详细的注释。

 

我们先解决这个问题:

void OnTimer()
  {
//--- 检查鼠标事件跟踪是否启用
   //CheckChartEventMouseMove();

  }

也就是说,现在我们不跟踪鼠标事件了,对吗?

在图表上运行代码:

现在我们运行 "另一个程序",让它再次成为你的代码:

我猜是出错了,还是这就是我们应该做的?

现在我们删除其中一个指示器,根据代码编写者的说法,我们失去了 "鼠标跟踪 "功能,但事实并非如此:

 
C-4:

如果你没有资格,那我不知道谁有资格?Danald Knuth?比尔-盖茨?

我只是想得到赞美。成功了)。

C-4:
我明白了。但不清楚的是,由你创造的市场领先产品并不属于你。这难道不是一种耻辱吗?

1.现在还不是晚上)

2.我的手工艺品也一直名列前茅,尽管它与面板没有任何可比性。

3.面板的成功在很大程度上归功于创意者的努力,因此说它是我的产品是不正确的。

4.我没有免费工作)

 
DC2008:

...

现在我们删除其中一个指标,根据代码编写者的说法,我们失去了 "鼠标跟踪 "功能,但这并没有发生:

现在检查指标是否触发了OnDeinit() 事件。这就是我之前提到的有趣之处。:)也就是说,在文章示例中的OnDeinit() 事件中,运动跟踪事件被禁用。这是一个错误,我们应该通知开发人员。

此外,为了确保我的说法是正确的,我们需要创建一个空白的智能交易系统(OnDeinit()函数在智能交易系统中起作用),在其中添加这行代码(高亮显示)即可:

//+------------------------------------------------------------------+
//|测试。mq5
//| 2013 年 MetaQuotes 软件公司版权所有。
//|http://www.mql5.com ||
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
//+------------------------------------------------------------------+
//| 自定义指示器初始化函数
//+------------------------------------------------------------------+
int OnInit()
  {
   return(0);
  }
//+------------------------------------------------------------------+
//| 专家的去初始化功能
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- 禁用鼠标事件跟踪
   ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,false);
  }
//+------------------------------------------------------------------+
//| OnTick|
//+------------------------------------------------------------------+
void OnTick()
  {
  }
//+------------------------------------------------------------------+

//---

现在,当文章中的指标出现在图表上时,如果移除智能交易系统,指标中的移动事件跟踪也将被禁用。

关于这一点:

一定是出了什么问题? 还是设计就是这样的?

众所周知。不是这样设计的,只是本文没有考虑到这一点。和往常一样,这篇文章只是举了一个简单的例子,并不是适用于所有情况的现成解决方案。)

 
谢尔盖,别大惊小怪。例如,我不清楚为什么要使用计时器。但过了一会儿,我在文章中找到了解释,立刻就明白了一切。我没有在实践中验证过这一说法,但在这一点上我相信作者,因为我意识到他写这篇文章是有原因的,如果引入了计时器,也是有原因的。
 
void OnDeinit(const int reason)
  {
//--- 禁用鼠标事件跟踪
   ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,false);
  }

总的来说,这段代码似乎很有问题。在禁用 "智能交易系统"/"指示器 "时,没有必要关闭鼠标移动跟踪功能。 如果要这么麻烦,应该恢复 "智能交易系统 "启动前的状态:

bool mouseStatus;
void OnInit()
  {
  mouseStatus = ChartGetInteger(0,CHART_EVENT_MOUSE_MOVE);
  }

void OnDeinit(const int reason)
  {
   //--- 禁用鼠标事件跟踪
   ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,mauseStatus);
  }
 
C-4:

总的来说,这段代码似乎很有问题。在禁用 "智能交易系统"/"指示器 "时关闭鼠标移动跟踪功能并没有真正的理由。

不,你错了。禁用鼠标移动跟踪是有真正原因的。我现在就证明给你看。)

例如,您有两个程序在图表上运行。一个是需要跟踪鼠标移动事件的 "智能交易系统",另一个是不需要跟踪鼠标移动事件的 "指标"。还有一个指标,您不需要跟踪鼠标移动事件,但需要跟踪其他一些图表事件。

现在运行 Expert Advisor 的代码:

#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
//+------------------------------------------------------------------+
//| 自定义指示器初始化函数
//+------------------------------------------------------------------+
int OnInit()
  {
//--- 启用鼠标事件跟踪
   ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,true);
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| 专家的去初始化功能
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- 禁用鼠标事件跟踪
   //ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,false);
  }
//+------------------------------------------------------------------+
//| OnTick|
//+------------------------------------------------------------------+
void OnTick()
  {
  }
//+------------------------------------------------------------------+
//| 图表事件函数|
//+------------------------------------------------------------------+
void OnChartEvent(const int    id,
                  const long   &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//--- 跟踪鼠标移动和按下鼠标左键的情况
   if(id==CHARTEVENT_MOUSE_MOVE)
     {
      static int count=1;
      Print("CHARTEVENT_MOUSE_MOVE; EXPERT; ",count);
      count++;
     }
  }
//+------------------------------------------------------------------+

在初始化过程中,OnInit()函数启用了鼠标移动事件跟踪。但在OnDeinit() 函数中,应该禁用跟踪功能的那一行却被故意注释掉了。

在图表上加载指标。下面是它的代码:

#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
//+------------------------------------------------------------------+
//| 自定义指示器初始化函数
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| 专家的去初始化功能
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
  }
//+------------------------------------------------------------------+
//| 自定义指标迭代函数
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   
//--- 为下一次调用返回 prev_calculated 的值
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| 图表事件函数|
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//--- 跟踪鼠标移动和按下鼠标左键的情况
   if(id==CHARTEVENT_MOUSE_MOVE)
     {
      static long count=1;
      Print("CHARTEVENT_MOUSE_MOVE; INDICATOR; ",count);
      count++;
     }
  }
//+------------------------------------------------------------------+

第一个和第二个程序都会在日志中打印收到事件的信息。现在从图表中移除智能交易系统。假设您已经在它的帮助下进行了一些计算,不再需要它了。移除后,由于鼠标移动跟踪事件没有被禁用,该指标会继续接收该事件。而您并不需要它。

您现在同意了吗?)