文章 "MQL5 初学者: 图形对象的防破坏保护"

 

新文章 MQL5 初学者: 图形对象的防破坏保护已发布:

1. 简介

MQL5编程语言的一个优点是, 使用MQL5的标准函数, 您可以在使用MetaTrader 5交易终端时使用代码完成各种任务以及达到各种目标.

这篇文章使用简明的语言, 易懂的实例, 使用两种不同方式来实现控制面板在其图形对象被删除或者修改时的回应. 我们将会发现, 您如何确认在应用程序退出之后, 在图表上不会出现无主的对象, 这样的对象可能是某人或者程序把它们重新命名而使得程序对之失去了控制.

控制面板在对象属性被人工修改前后的实例

图 1. 控制面板在其对象属性被人工修改前后的外观实例

在本文中描述的, 构造对来自外界干扰的回应的代码, 对于其他情况也并非是多余的. 举例来说, 在图表上运行的第三方程序没有准备做清除的, 使用某些参数调用一个函数来删除对象(ObjectsDeleteAll () 或者您自己创建的函数):

  • 在同一个窗口/子窗口中删除人工或者其他程序创建的全部类型的图形对象;
  • 或者在您程序的控制面板上完全删除某种类型的对象;
  • 或者根据前缀的匹配删除您程序中的对象.
这些选项在一定条件下都是合理的, 包括程序正确运行中, 在意外或者有意删除了控制面板对象时, 或者在代码中人工修改了它们的属性时提供可以执行的操做.

本文对刚刚开始学习OnChartEvent()函数的事件处理的开发者也会有所帮助.

我想直接提醒您, 本文不包括创建"强硬"的回应代码, 就是那种对象会在未经授权的条件下修改或者删除的代码. 终端程序的主要目的是解决交易者可能遇到的问题, 所以武断地干预是不可接受的.

对于喜欢强硬行动的人, 我建议您在考虑这样做之前做一个下面的类比. 假如有个办公室的清洁工, 在用抹布擦桌子的时碰掉了桌上的电脑, 或者在某人画出漂亮的作品时弄脏了他/她的桌子或者电脑. 所以如果被毁坏财物的主人的反应是, 在大庭广众之下把电脑, 家具连同清洁工一起扔出窗外, 他的行为显然是不当的. 另外, 做出这种激进行为的人也得不到什么好处.

在继续进行对蓄意破坏对象回应的两种(从更多选择中选出的)可能的方法之前, 我相信有必要提一下在MQL5/MQL4编程语言中的一种对象保护方法.

作者:Dina Paches

 

这篇文章写得很好,我用一种略微不同的方法来保护程序不受此类破坏...

我使用 CREATE_OBJECTS()这样的特殊函数创建所有必要的对象,并在图表可见性之外添加前缀、

然后检查错误 4202 ERR_OBJECT_DOES_NOT_EXIST 对象是否不存在,如果存在,则再次调用 CREATE_OBJECTS()函数

图表中的其他对象属性将根据需要进行更改。

 

干得好文章不错。示例也不错。

但似乎有一种简单的方法可以检查对象是否存在,而且在必要时可以随时恢复它。

 
Victor Nikolaev:

但似乎有一种简单的方法可以检查对象是否存在,而且在必要时可以随时恢复。

诀窍在于将检查次数减少到最低限度,而不是不间断地检查。为此,可以将它们与特定事件绑定。如果我理解正确的话。遗憾的是,所有这些都没有绑定到标准库中
 

感谢大家的反馈!

Victor Nikolaev:

干得好。文章不错。示例也不错。

但似乎有一种简单的方法可以检查对象是否存在,而且必要时可以随时恢复。

谢谢你,维克多!

为了以防万一,我想说的是,给出的变体与通常的习惯方法(简单或不那么简单)并不对立。

只是,通常熟悉的方式(简单或不那么简单)不一定总是 "及时 "的。尤其是同样的各种 "顽皮的手 "并没有被取消。包括,也许在某些情况下是我们自己或用户的。

例如,如果程序控制面板中的对象通过"对象 列表 "与其他选择一起被 Shift 或第三方程序意外删除,这时可以使用删除对象的函数(ObjectsDeleteAll() 或独立创建的函数),该函数根据设置的参数执行:

  • 在手动或借助其他程序创建的对象所在的同一窗口/子窗口中,全部删除所有类型的图形对象;
  • 或完全删除程序控制面板中的同类型对象;
  • 或删除与程序中对象前缀一致的前缀、

那么本文中描述的选项就会派上用场,根据实际情况做出相应调整。在某些情况下,还能让你摆脱不必要的 "移动"。我相信,这些方案可以通用,必要时还可以与其他方案 "无痛无冲突 "地结合起来。

不知何故。

也就是说,为了 "保护 "程序对象,当然可以采用不同的方案、方法及其组合。

文章中描述的这些并不是每个代码都必须使用的,但在某些情况下可能并不是多余的。

Alexander Puzanov:
诀窍在于尽量减少检查次数,而不是不间断检查。为此,它们与特定事件绑定。如果我理解正确的话。

是的,谢谢,没错,减少检查过程中的处理次数是其中的一个窍门。

 

本文已完全过时。

1.绝对不适合初学者

2.这不是 MQL5 - 这是 MQL4!

3.编码方式非常复杂,而且从 MQL5 的角度来看,完全是错误的。

如果您认为另一个 EA 或指标会破坏对象是个问题,这可以做得更有效、更优雅:

- 为每个图表对象 定义一个 MQL 对象,如标准 Control 库已经做的那样。每个这样的 MQL 对象代表一个图表对象,并保存其所有数据 - 正常的 MQL5 风格。

- 将所有对象打包到一个主容器中

- 只有主容器才会检查图表对象是否已被删除,无论是不时删除还是通过 OnChartEvent() 期间的相应图表事件删除。

- 为 CWnd 添加 .ReCreate() 成员函数,并为所有实现此功能的对象添加 OnRecreate() 虚拟函数

- 如果主容器检测到某种 "破坏 "行为,它将向所有子对象发送 .ReCreate() 函数。

完成。

 

我对英语知之甚少。 我没读过这篇文章的英文版

对不起,但是......你读过这篇文章的全文吗?

你会说俄语吗?

如果你会俄语,那么我们可以在本文俄语版讨论 中进行更有建设性的交流。


Doerk Hilger:

这篇文章已经完全过时了。

您错了。

Doerk Hilger:

1.绝对不适合初学者

您为什么这么认为?请详细告诉我。

Doerk Hilger

2.不是 MQL5,而是 MQL4!

错了。

但本文中描述的方案不仅可用于 MQL5,也可用于 MQL4。

Doerk Hilger

3.这种编码方式非常复杂,而且从 MQL5 的角度来看,完全是错误的。

Пожалуйстапрочитайте эту статью "MQL5 для начинающих: Антивандальная защита графических объектов" ещё раз внимательно.И пожалуйста не торопитесь с выводами.Если и после этого ваше мнение не изменится, то напишите более конкретно непонятные для вас моменты.

请阅读本文 "MQL5 入门":图形对象的防破坏保护"一文。请不要匆忙下结论。如果在此之后您的观点仍未改变,请写下更多对您来说特别困难的时刻。


Doerk Hilger

如果您认为另一个 EA 或指标会破坏对象是个问题,那么我们可以做得更有效、更优雅:

- 为每个图表对象 定义一个 MQL 对象,如标准 Control 库已经做的那样。每个这样的 MQL 对象代表一个图表对象,并保存其所有数据 - 正常的 MQL5 风格。

- 将所有对象打包到一个主容器中

- 只有主容器才会检查图表对象是否已被删除,无论是不时删除还是通过 OnChartEvent() 期间的相应图表事件删除。

- 为 CWnd 添加 .ReCreate() 成员函数,并为所有实现此功能的对象添加 OnRecreate() 虚拟函数

- 如果主容器检测到某种 "破坏 "行为,它将向所有子对象发送 .ReCreate() 函数。

完成。

Встатье "MQL5 для начинающих: Антивандальная защита графических объектов" рассматриваются схемы только двух вариантов (способов) из множества возможных.在此基础上,我们还将继续努力,在全球范围内提供更多的信息。
Применять или не применять схемы из этой статьи - это зависит только от ваших решений.


Скажутолько, что эти две схемы из статьи "MQL5 для начинающих: Антивандальная защита графических объектов" обладают следующими положительными качествами:

  • экономно используют ресурсы компьютера и торгового терминала;
  • (не вседругиеобычные привычные способы могутбыть своевременными);
  • могутбыть применены совместно со многими другими вариантами (способами).

Эти схемы из данной статьи сконструированы в процедурном стиле.В том числе, чтобы они были более понятны, наглядны и могли послужить идеями для каких-то других вариантов.

Если вам не нравятся эти схемы или они не подходят вам по каким-то другим причинам, вы конечно можете использовать другие схемы. И, естественно, в том стиле программирования, что для вас привычен.

Применять эти схемы из статьи или не применять - это ваше личное дело и право.


在文章"MQL5 入门:图形对象的防破坏保护"一文中,只考虑了许多可能的方案(方法)中的两个选项。
使用或不使用本文中的方案 - 这取决于您的决定。

我只能说,"MQL5 入门"一文中的这两个方案是可行的:图形对象的防破坏保护"一文中的这两个方案具有以下优点:
  • 经济地使用计算机和交易终端的资源;
  • 具有较高的响应及时性(并非所有其他惯用方法都能及时响应);
  • 可与许多其他方式结合使用。

本文的这些方案是以程序化的方式提出的。特别是为了使它们更容易理解、更清晰可见,并可作为一些其他方案的思路。

如果你不喜欢这些方案,或者由于其他原因它们不适合你,你当然可以使用其他方案。当然,也可以使用自己喜欢的编程风格。

使用或不使用本文中的方案--这取决于你的决定。


对不起,我的英语说得不好。


P./S..Пожалуйста прочитайте эту статью ещё раз внимательно.在此,我们建议您使用 "Ипожалуйста не торопитесь с выводами. Если у вас затем будут конструктивные вопросы или предложения, то пишите, пожалуйста.请注意,您在使用时可能会遇到一些问题,例如,您的计算机在使用时可能会出现 "眩晕"、"疲劳"、"倦怠"、"眩晕"、"疲劳"、"眩晕"、"疲劳"、"倦怠 "等。请再次仔细阅读本文。

请再次仔细阅读这篇文章。请不要匆忙下结论。如果您有任何具体问题和建议,请写信给我。我可能只有在新年假期之后才能给您答复。还有五天。

P./S.: Сегодня у нас праздник Нового года.Поэтому и вас поздравляю с наступающим новым 2016-м годом!

今天是 新年假期 祝大家 2016 年 新年快乐

 

MetaEditor Version 5.00 build 1241编译时 ,文章中附带的测试代码名称如下:

  • test_count_click_0.mq5
  • test_count_click_1.mq5
  • test_count_click_2.mq5

和以前一样,就防破坏功能而言,它们工作正常。但是,在新版本中编译时,我发现一个不属于 文章中的防破坏措施的函数出现了问题。我向服务台 Service Desk 提出了请求(#1379624),但现在是假期,所以我自然不指望从那里得到答复或解决方案。

下面是对问题的描述、解决问题的方法以及包含问题解决方案的文件,而不是文章的附件:

但首先我想再次强调,在新版本中编译时,与破坏行为有关的功能是 正常 工作的。

已命名测试代码的不正确性表现在,当点击这些测试代码的控制面板对象时,除了最先 点击的按钮,不再显示点击次数。也就是说,无论点击多少个按钮,数字都是一样的:

不过,如果这些 测试代码不是在1241 版本中编译的,那么在 早期版本编译这些 测试代码在新 版本中仍能 正常工作。也就是说,当点击这些测试代码的对象时,点击次数的计算是正常的:

发现 检测到的 问题与OnChartEvent()CHARTEVENT_OBJECT_CLICK 事件处理块中ArrayFill () 函数的应用有关。

               count=countClick[index]+count;
               int summ=countClick[NUMBER_ALL]+1;
               //---
               ArrayFill(countClick,index,1,count);
               ArrayFill(countClick,NUMBER_ALL,1,summ)

但是,如果将数据打印输出或ChartRedraw() 放在该函数之前,文章中命名的代码就会在编译后开始正常工作:

               count=countClick[index]+count;
               int summ=countClick[NUMBER_ALL]+1;
               //---
               //TEST_PRINT_TWO(count,summ);
               ChartRedraw();
               //---
               ArrayFill(countClick,index,1,count);
               ArrayFill(countClick,NUMBER_ALL,1,summ);

在下面附带修复的三个文件中,以及在文章附带的同名版本中,这些部分以及修复下面代码中的问题都是相同的。也就是说

  • 在 test_count_click_0.mq5 文件中 - 未应用防破坏保护措施;
  • 在 test_count_click_1.mq5 文件中 - 如果图表上的程序对象受到未经授权的干扰,程序会从图表中 "自删除";
  • 在 test_count_click_2.mq5 文件中 - 在程序对象被擅自修改或删除的情况下 "自我恢复 "的变体。

附/附注:要正确使用下面所附的代码,必须在 "Include "文件夹下有 本文 所附的 objectcreateandset.mqh 文件 ,其中附有代码,我就是根据这些代码发现所命名的函数工作不正确的。该文件也可从代码库 下载

附加的文件:
 
顺便说一下,既然已经发生了,我想为那些刚刚开始研究MQL5 OnChartEvent() 函数中事件处理的人补充一点,文章中给出的保护变体方案会节约使用计算机和交易终端资源。因此,如果您阅读了这篇文章,请在其中给出的示例方案中注意其中提供的检查过滤器,以减少处理次数。

例如,熟悉文章示例方案中基于StringFind() 函数的检查过滤器可能会有所帮助。因为当应用该函数的程序收到有关图表中对象的任何事件的通知时,必要时借助该函数的筛选器可以大大减少对象名称的搜索次数。也就是说,必要时,它们不仅在构建防破坏变体时有用,在其他情况下也很有用。 为了以防万一,我还想补充一点,如果有必要,还可以通过使用第三个输入参数 来扩展基于该功能的检查过滤器的应用范围。

 
Dina Paches:

我对英语知之甚少。 我没读过这篇文章的英文版

对不起,但是......你读过这篇文章的全文吗?


+1

回答得很好。

 
Doerk Hilger:

- 为每个图表对象 定义一个 MQL 对象,如标准 Control 库已经做的那样。每个这样的 MQL 对象代表一个图表对象,并保存其所有数据 - 正常的 MQL5 风格。

- 将所有对象打包到一个主容器中

- 只有主容器才会检查图表对象是否已被删除,无论是不时删除还是通过 OnChartEvent() 期间的相应图表事件删除。

- 为 CWnd 添加 .ReCreate() 成员函数,并为所有实现此功能的对象添加 OnRecreate() 虚拟函数

- 如果主容器检测到某种 "破坏行为",它将向所有子对象发送 .ReCreate() 函数。

本文提供了一个现成的解决方案示例,可以在任何源代码(OOP 或过程式)中实现。因此,任务是:找到一条与西装相匹配的领带

你的解决方案是:买一套新的 OOP 西装。对了,别忘了给你的新西装买条领带

PS 至于标准库:不幸的是,控制库是这个库中最糟糕的部分--太多的错误和未实现或不可用的选项。因此,有时这个库会成为问题的根源(图表上的垃圾),本文中提到了这一点