如何动态地创建对象?(一些OOP的东西) - 页 5

 
Doerk Hilger:

2. Framework from scratch.

Similar here. When I started to go a bit deeper into the standard libraries I found many things, which I did not like. Not only the bad performance of those, but also lack of flexibility and also because of an incomplete architecture. I am missing for example a global CMouse class/object as well as a class between CWnd and CObject, because CWnd objects are childs of the chart as well as lines are, and there is no connection to such and no final implementation of any such objects at all like I described it above. And, there is no master object, which holds all such chart objects which makes it possible to show/hide all of them with one command, destroy them, whatever. CCanvas, same thing, a nice class but where is the implementation with CWnd which allows me to create interactive objects based on bitmaps that inherit from CWnd? And so on. 




全局CMouse的作用是什么?它是否只是作为一个独立的类为最终用户服务,以方便访问鼠标管理?它与框架有什么关系?
关于CWnd和CObject之间的类,我不明白你的解释,为什么你觉得需要它们。CWnd对象是图表的子对象,也是线条--我不明白这有什么问题,为什么没有联系?
你还说,根本就没有像你上面描述的那样对任何此类对象进行最终实现?(你在哪里描述的?)

 

至少在我的GUI中,全局鼠标对象的机会是保存关于鼠标的任何信息(位置、按压位置、位置价格等),可供每个处理这些信息的类使用。此外,鼠标对象还保存了关于鼠标专用的信息,例如拖动时的信息。这可以在东西被拖动或即将被点击时节省很多CPU时间。

最后但并非最不重要。在EA中使用标准库时,由于没有鼠标事件,所以在策略测试器中没有任何功能。如果你想在strategy tester中实现对鼠标的支持,你也会感谢这样一个鼠标类,因为这个类并不关心鼠标移动的信息来自哪里,但需要这些信息的对象仍然知道他们要去哪里寻找。

---

我所缺少的不仅仅是CWnd和CObject之间的类,实际上更多的是缺少一个主对象/容器,它容纳了基于像素的对象和基于时间/价格的对象。正如你所提到的,它们都是图表的对象,所以逻辑上的主对象应该是一个代表图表的对象,它可以容纳所有的对象。为了实现这一点,在CWnd和CObject之间必须有一个类。

这个想法的背景不仅是逻辑,它也是一个性能问题。在我的案例中,当图表发生某种变化时,主对象会检测到这一点,它会循环所有包含的对象,这些对象可以是线的容器,CWnd的容器,以及这些类型中的任何单一对象,并 "通知 "任何想被通知的对象。这意味着,在代码中只有一个单一的循环,而且由于使用了容器和子容器,这非常有效。

我还使用这个主程序来一次性冻结所有对象,并通过一行代码来防止任何物理更新。性能上的差别是非常大的。举个例子。当我为我的EA创建所有我需要的视觉对象时,在某些情况下,这些对象超过1000个,我预先冻结这个主对象,创建其他对象,然后 "解冻 "它,这导致图表的一次物理更新。如果不冻结,这个过程可能需要整整一分钟。有了冻结,则不到2秒。

在我开始自己创建GUI之前,我真的用标准的libs试过。后来,我试图至少保留一些部分。但问题是,我根本不可能实现我的想法,因为不完整的实现和架构是有点...让我们做一个能用的东西,但我们不知道。视觉性能是通过清晰的层次结构来实现的,但标准的libs在某种程度上是无政府主义的。

总之,我不是第一个认识到这一点的人。正如Alain所提到的,我不确定这是否真的有帮助,因为它太理论化了。我只能谈谈我对所有这些东西的经验,这不仅仅是基于MQL,但我的观点也只是我的观点,当然不是法律。

 
首先,我不同意它过于理论化。我认为它是非常有见地的。对于那些对建立框架不感兴趣,只需要用它们来建立一个界面面板的人来说,我可以同意它是理论性的。

但是对于第二类人来说,这里讨论的思维方式和考虑因素是非常有价值的,也是非常实用的。当然,一篇文章会更好,但尽管如此。
我不认为人们在读完这个主题后会建立框架,但它仍然有很好的信息和见解,即使对于已经建立了公共MQL框架的人来说,似乎也很缺乏。

所以,对于鼠标和测试器,如果我没听错的话,你是用::OnTester()来调用你的鼠标,而不是用户输入,如果我听懂了的话。

再次感谢,Doerk。
 
Doerk Hilger:

至少在我的GUI中,全局鼠标对象的机会是保存关于鼠标的任何信息(位置、按压位置、位置价格等),供每个处理这些信息的类访问。此外,鼠标对象还保存了关于鼠标专用的信息,例如拖动时的信息。这可以在东西被拖动或即将被点击时节省很多CPU时间。

最后但并非最不重要。在EA中使用标准库时,由于没有鼠标事件,所以在策略测试器中没有任何功能。如果你想在strategy tester中实现对鼠标的支持,你也会感谢这样一个鼠标类,因为这个类并不关心鼠标移动的信息来自哪里,但需要这些信息的对象仍然知道它们要去哪里寻找。

假设现在全局鼠标已经注意到了对一个对象的点击,从你的描述来看,对象本身必须在鼠标类中寻找这些信息--难道鼠标不需要通知对象(通过在事件上的移动)来通知对象?如果是这样,那么CPU的时间从哪里来?如果它不这样做,那么对象怎么会不缺少鼠标事件呢?例如,我点击了一个按钮,然后又点击了一个组合框,我的鼠标没有通知按钮它被点击了,现在鼠标把最后点击的对象作为组合框。所以,这一定是鼠标传递了一个对象被点击的事件。所以,对象被点击事件不是直接从MT5传给控件类,而是传给鼠标,然后再传给控件,这哪里是节省CPU?

还是我错过了什么?
 

鼠标对象不会自己看它是否在一个对象上,或者它是否正在被一个对象使用,这是由对象本身完成的。但鼠标对象是可以存储这些信息的中心 "场所"。

标准的控制类是这样工作的,在每次鼠标移动时,所有的对象都会被循环计算,如果这个动作与它们有关,这需要大量的CPU时间,当你启动任务管理器,当EA或指标被加载,CDialog对象是EA或指标的一部分时,就可以很容易地看到。对话框越复杂,CPU的使用率就越高。

在我的GUI中,由于存在一个全局性的鼠标对象,这是不一样的做法。你可以有10000个对象,而当鼠标移动时,CPU的使用率完全没有增长。它是这样做的,只有当鼠标按钮落在一个特定的对象上时,这个特定的对象才会通知鼠标对象,它拥有焦点,并且在这个按钮落下的事件之后,鼠标一移动,就没有其他对象需要照顾它了,任何进一步的鼠标移动/任何进一步的鼠标移动事件都直接被送到拥有焦点的对象--它总是独占的--通过使用它的指针。

由于所有的图表对象,不管是基于时间/价格的(趋势线等)还是基于像素坐标的(面板等)都有一个共同的基类,所有这些对象都可以使用一套共同的重载函数来处理。这也是我提到CWnd和CObject之间缺少一个类的原因,因为这个基类也是基于时间/价格的对象所使用的基类,只有这样才能有效地沟通,有效地处理这些事件。

 
所以实际上,你放弃了对鼠标运动的监听(除非是在对象点击之后直接监听),而只关注鼠标点击和鼠标拖动。至于鼠标点击,它的做法和标准lib一样,对象本身检测到了点击,但是它想为拖动做好准备,所以它通知了鼠标,而鼠标可能会保持它的位置,进一步的拖动会被唤回对象。如果鼠标碰巧在没有拖动的情况下抬起按钮,它只是通过删除对象指针来停止关注被点击的对象。所以对象听从点击,鼠标听从拖动。
所以,归根结底,鼠标移动实际上是被忽略的,因为它不重要,除非是在物体被点击之前?
 

是的。

尽管如此,我还是可以选择在点击或不点击的情况下捕捉任何动作,而且CPU性能更好,不使用对象 名称,但这不是这里的问题。

 
是的,我现在看到了你想表达的意思,肯定有办法让鼠标的移动也被鼠标本身所监听,而不需要对对象进行循环。它甚至可以在对象处于焦点时通知它们,只用它们的指针 作为监听器注册。