Comment créer des objets de manière dynamique ? (Quelques trucs de POO) - page 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. 




Quel est le rôle d'une CMouse globale ? Sert-elle à l'utilisateur final en tant que classe autonome uniquement, pour avoir un accès facile à la gestion de la souris ? Comment est-elle liée au framework ?
A propos de la classe entre CWnd et CObject, je ne suis pas votre explication sur la raison pour laquelle vous les avez trouvés nécessaires. Les objets CWnd sont des enfants du graphique, ainsi que les lignes - je ne comprends pas le problème et pourquoi il n'y a pas de connexion ?
Vous dites également qu'il n'y a pas d'implémentation finale de ces objets comme vous l'avez décrit ci-dessus ? (où avez-vous décrit ?)

 

L'opportunité d'un objet souris global est, au moins dans mon GUI, de sauvegarder toutes les informations sur la souris (position, position d'appui, prix de la position etc.) accessibles pour toutes les classes traitant de ces informations. En outre, l'objet souris contient des informations sur l'utilisation exclusive de la souris, par exemple lors du déplacement. Cela permet d'économiser beaucoup de temps CPU lorsque quelque chose est glissé ou est sur le point d'être cliqué, etc.

Dernier point, mais non le moindre : Aucun élément de la bibliothèque standard ne fonctionne dans StrategyTester lorsqu'il est utilisé dans des EA car il n'y a pas d'événements de souris. Et si vous voulez implémenter le support de la souris dans strategy tester, vous serez reconnaissant pour une telle classe de souris aussi, parce que la classe ne se soucie pas d'où l'information sur les mouvements de la souris provient, mais les objets qui ont besoin de l'information savent toujours où ils doivent chercher.

---

Ce n'est pas seulement la classe entre CWnd et CObject qui me manque, c'est plutôt l'objet maître/conteneur manquant qui contient les objets basés sur les pixels ainsi que les objets basés sur le temps/prix. Comme vous l'avez également mentionné, ils sont tous des objets du graphique, donc le maître logique devrait être un objet qui représente le graphique et qui contient tous les objets. Et pour réaliser cela, il doit y avoir une classe entre CWnd et CObject.

L'arrière-plan de cette idée n'est pas seulement la logique, c'est aussi une question de performance. Dans mon cas, lorsque le graphique change d'une manière ou d'une autre, l'objet maître le détecte, il boucle tous les objets contenus qui peuvent être des conteneurs de lignes, des conteneurs de CWnd ainsi que tout objet unique de n'importe lequel de ces types, et "informe" tout objet qui veut être informé par cela. Cela signifie simplement qu'il n'y a qu'une seule boucle à un seul endroit du code, et grâce à l'utilisation de conteneurs et de sous-conteneurs, c'est extrêmement efficace.

J'utilise également ce maître pour geler tous les objets en une fois et empêcher toute mise à jour physique par une seule ligne de code. La différence de performance est radicale. Exemple : Lorsque je crée tous les objets visuels dont j'ai besoin pour mon EA, et dans certains cas, il y en a plus de 1000, je gèle d'abord cet objet maître, crée les autres objets et le "dégèle" ensuite, ce qui permet une seule mise à jour physique du graphique. Sans gel, ce processus peut prendre une minute entière. Avec la congélation, c'est moins de 2 secondes.

Avant de commencer à créer l'interface graphique par moi-même, j'ai vraiment essayé avec les librairies standard. Plus tard, j'ai essayé de garder au moins certaines parties. Mais le problème était qu'il était tout simplement impossible de réaliser ce que j'avais en tête à cause d'une implémentation incomplète et d'une architecture qui est un peu ... Faisons quelque chose qui fonctionne d'une manière ou d'une autre pour que nous ne sachions pas. La performance visuelle est atteinte avec une hiérarchie claire, mais les librairies standard sont en quelque sorte anarchiques.

Quoi qu'il en soit, je ne suis pas la première personne à avoir reconnu cela. Et comme Alain l'a déjà mentionné, je ne suis pas sûr que cela aide vraiment, car c'est trop théorique. Je peux juste parler de mon expérience avec toutes ces choses qui ne sont pas seulement basées sur MQL, mais mon opinion reste néanmoins juste mon opinion et bien sûr pas une loi.

 
D'abord, je ne suis pas d'accord pour dire que c'est trop théorique. Je pense que c'est très perspicace. Je peux admettre que c'est théorique pour les personnes qui ne sont pas intéressées par la construction de frameworks et qui ont juste besoin de les utiliser pour construire un panneau d'interface.

Mais pour le deuxième type, la façon de penser et les considérations discutées ici sont très précieuses et très pratiques aussi. Bien sûr, un article serait mieux, mais néanmoins.
Je ne pense pas que les gens construiront des frameworks après avoir lu ce fil de discussion, mais il contient tout de même de bonnes informations et des idées, qui semblent manquer même pour les personnes qui ont déjà construit des frameworks MQL publics.

Donc, pour la souris et le testeur, si j'ai bien compris, vous utilisez le ::OnTester() pour appeler votre souris au lieu d'une entrée utilisateur, si je vous suis.

Merci encore, Doerk.
 
Doerk Hilger:

L'opportunité d'un objet souris global est, au moins dans mon GUI, de sauvegarder toutes les informations sur la souris (position, position d'appui, prix de la position etc.) accessibles pour toutes les classes traitant de ces informations. En outre, l'objet souris contient des informations sur l'utilisation exclusive de la souris, par exemple lors du déplacement. Cela permet d'économiser beaucoup de temps CPU lorsque quelque chose est glissé ou est sur le point d'être cliqué, etc.

Dernier point, mais non le moindre : Rien de la bibliothèque standard ne fonctionne dans StrategyTester lorsqu'elle est utilisée dans des EA, car il n'y a pas d'événements de souris. Et si vous voulez implémenter le support de la souris dans StrategyTester, vous serez reconnaissant pour une telle classe de souris aussi, parce que la classe ne se soucie pas d'où l'information sur les mouvements de la souris provient, mais les objets qui ont besoin de l'information savent toujours où ils doivent chercher.

Supposons que la souris globale a maintenant remarqué un clic sur un objet, d'après votre description, l'objet lui-même doit chercher cette information dans la classe de souris - la souris ne doit-elle pas notifier l'objet (en se déplaçant sur l'événement) à l'objet ? Si c'est le cas, alors où est le temps CPU économisé ? Si ce n'est pas le cas, alors comment l'objet peut-il ne pas manquer un événement de souris, par exemple, j'ai cliqué sur un bouton et ensuite sur une boîte combo, ma souris n'a pas notifié le bouton qu'elle a été cliquée et maintenant la souris a le dernier objet cliqué comme la boîte combo. Donc, il doit être que la souris passe sur un objet a été cliqué événement. Donc, au lieu que l'événement "objet cliqué" vienne directement de MT5 à la classe de contrôle, il vient à la souris et ensuite au contrôle, où est l'économie de CPU ?

Ou est-ce que quelque chose m'échappe ?
 

L'objet souris ne regarde pas lui-même s'il est au-dessus d'un objet ou s'il est actuellement utilisé par un objet, cela est fait par les objets eux-mêmes. Mais l'objet souris est le "lieu" central où ces informations peuvent être stockées.

Les classes de contrôle standard fonctionnent de la sorte : à chaque mouvement de souris, tous les objets sont mis en boucle pour déterminer si ce mouvement a quelque chose à voir avec eux, ce qui prend beaucoup de temps au CPU, ce qui peut être facilement constaté lorsque vous lancez le gestionnaire de tâches et que vous déplacez la souris lorsque l'EA ou l'indicateur est chargé et qu'un objet CDialog fait partie de l'EA ou de l'indicateur. Plus le dialogue est complexe, plus l'utilisation du CPU est élevée.

Dans mon interface graphique, avec l'existence d'un objet souris global, cela se fait différemment. Vous pouvez avoir 10000 objets et l'utilisation du CPU n'augmente pas du tout lorsque la souris est déplacée. C'est fait de telle manière que, dès que le bouton de la souris est enfoncé sur un objet spécifique, cet objet spécifique informe l'objet souris qu'il a le focus, et dès que la souris bouge après cet événement d'enfoncement du bouton, aucun autre objet n'a besoin de s'en occuper, et tout autre mouvement de la souris / tout autre événement de mouvement de la souris est acheminé directement vers l'objet qui a le focus - qui est toujours exclusif - en utilisant son pointeur.

Et comme tous les objets graphiques, qu'ils soient basés sur le temps/prix (lignes de tendance, etc.) ou sur les coordonnées des pixels (panneaux, etc.) ont une classe de base commune, tous ces objets peuvent utiliser un ensemble commun de fonctions surchargées pour gérer cela. C'est aussi une raison pour laquelle j'ai mentionné qu'il y a une classe manquante entre CWnd et CObject, parce que cette classe de base entre est la même classe de base qui est utilisée par les objets basés sur le temps/prix aussi et seulement cela permet de communiquer efficacement et de gérer de tels événements efficacement.

 
Donc, en fait, vous renoncez à écouter les mouvements de la souris (à moins qu'ils ne suivent directement le clic d'un objet), et ne prêtez attention qu'au clic et au déplacement de la souris. En ce qui concerne le clic de la souris, il est fait de la même manière que dans la librairie standard, l'objet lui-même détecte le clic, mais il veut ensuite être préparé pour le déplacement, donc il notifie la souris qui garde probablement sa position et le déplacement ultérieur est rappelé à l'objet. Si la souris lève le bouton sans glisser, elle arrête simplement de se concentrer sur l'objet cliqué en supprimant le pointeur de l'objet. Ainsi, les objets écoutent les clics et la souris écoute les déplacements.
Donc, cela revient à dire que les mouvements de la souris sont en fait ignorés comme n'étant pas importants, à moins que ce ne soit juste avant qu'un objet soit cliqué ?
 

Oui.

Néanmoins, j'ai la possibilité d'attraper tous les mouvements s'ils sont cliqués ou non, et aussi avec de meilleures performances CPU et sans utiliser les noms des objets, mais ce n'était pas la question ici.

 
Oui, je vois maintenant l'image que vous avez essayé de communiquer et il y a sûrement des moyens de faire écouter les mouvements de la souris par la souris elle-même, sans avoir besoin de boucler les objets. Et il est même possible de notifier les objets lorsqu'ils sont en focus avec juste leurs pointeurs utilisés pour s'enregistrer comme auditeurs.