Discussion de l'article "Contrôles graphiques personnalisés. Partie 3. Formulaires"

 

Un nouvel article Contrôles graphiques personnalisés. Partie 3. Formulaires a été publié :

Ceci est le dernier des trois articles consacrés aux contrôles graphiques. Il couvre la création du composant principal de l'interface graphique - le formulaire - et son utilisation en combinaison avec d'autres contrôles. En plus des classes de formulaire, les classes CFrame, CButton, CLabel ont été ajoutées à la bibliothèque de contrôle.

Le formulaire est basé sur les objets graphiques « Etiquette rectangulaire » OBJ_RECTANGLE_LABEL avec utilisation de plusieurs boutons OBJ_BUTTON. Visuellement, le formulaire représente un rectangle (Fig. 1) avec une barre dans la partie supérieure du formulaire où sont affichés le nom du formulaire et les boutons de contrôle.

Un bouton de défilement du formulaire (avec une image en forme de main) est situé à gauche, un bouton de minimisation (avec une image rectangulaire) et un bouton d’arrêt (avec une image en forme de croix) sont situés à droite.

Fig. 1. Formulaire

Fig. 1. Formulaire

Pour déplacer le formulaire, appuyez sur le bouton de défilement (le bouton se mettra en position enfoncée) et cliquez n'importe où dans le graphique pour déplacer le formulaire où que vous souhaitez. En conséquence, le bouton de défilement le bouton de déplacement relâchera et le formulaire se déplacera à l'endroit indiqué (son coin supérieur gauche se retrouvera sur le point cliqué).

Auteur : Dmitry Fedoseev

 

Un travail de qualité et utile, Dimitri. Il y a une suggestion pour la quatrième partie : "Form Wizard" ou "Visual Form Editor" : "Form Wizard" ou "Visual Form Editor", qu'en pensez-vous ?

 

Respect, Dimitri. Vous avez fait un excellent travail.

Je vous prie d'accepter quelques critiques pour la prochaine version des classes v4.

1. il n'y a pas assez d'abstraction dans le projet de base. Il s'est avéré que chaque contrôle que vous avez agit comme une unité indépendante. Par conséquent, vous ne pouvez pas les combiner dans un tableau, par exemple.

2. Chaque classe d'un élément possède désormais, dans l'ensemble, son propre ensemble de fonctions. Ce n'est pas une bonne chose. Il devrait y avoir un ancêtre commun dont les fonctions sont simplement remplacées par les descendants. D'autant plus qu'il existe de nombreuses fonctions portant le même nom dans les classes actuelles. Qu'est-ce qui vous empêche de créer un ancêtre commun ?

3. si une classe de base apparaît, il sera possible de cacher la gestion des événements à l'intérieur des descendants, au lieu de les placer tous à l'extérieur dans le formulaire. de faire une cascade d'événements à l'intérieur des objets (similaire à CSS dans le web).


Mais en général, les trois parties de l'article méritent d'être récompensées, en particulier j'ai aimé les "nudges" lorsque l'on appuie sur les boutons et leurs réponses interactives aux pressions en fonction de l'état de l'élément.

PS.
Et le menu multi-niveaux que vous finissez toujours, un article séparé sur lui n'est pas nécessaire, trop gros pour une si petite tâche d'écrire un nouvel article. Qu'il s'agisse simplement d'une mise à jour dans la version 4.
La classe d'arbre CTreeCtrl peut être tirée de l'article https://www.mql5.com/ru/article s/272 ou CTreeNode proposé dans le kit MT.

Трассировка, отладка и структурный анализ кода
Трассировка, отладка и структурный анализ кода
  • 2011.03.16
  • o_O
  • www.mql5.com
Весь комплекс задач создания структуры работающего кода и его трассировки можно решить без особых сложностей. Эта возможность появилась в MetaTrader 5 благодаря новому свойству языка MQL5 - автоматическое создание переменных сложного типа данных (структуры и классы) и их уничтожение при выходе из локальной области видимости. В статье описана методика и предоставлен готовый инструмент.
 
Lizar:

Un travail de qualité et utile, Dimitri. Il y a une suggestion pour la quatrième partie : "Form Wizard" ou "Visual Form Editor" : "Form Wizard" ou "Visual Form Editor". Qu'en pensez-vous ?

Personnellement, je la vois d'un bon œil. Visual ne fait que simplifier le placement des objets. Si vous le faites correctement, vous devez lier la génération de code pour les objets créés, la liaison des variables ou des classes à l'objet. Et surtout, la gestion des événements.

Mais dans ces classes non abstraites, ce n'est pas possible. Elles sont très manuelles. En de nombreux endroits, il est nécessaire d'écrire les objets nouvellement créés et leur traitement.
Pour les événements, par exemple, il n'y a pas de division entre le système et l'utilisateur - comme Draw (système de base) et OnDraw - ajout de l'utilisateur avec son propre dessin.

Dans d'autres structures (par exemple Joomla !), il n'y a pas qu'une seule fonction personnalisée OnDraw. Elle est divisée en deux : BeforDraw et AfterDraw. En d'autres termes, le programmeur peut gérer l'événement système EVENT_DRAW - à la fois avant le début du dessin du système et après sa fin.

 
sergeev:

Respect, Dimitri. Vous avez fait un excellent travail.

Je vous prie d'accepter quelques critiques pour la prochaine version des classes v4.

1. il n'y a pas assez d'abstraction dans le projet de base. Il s'est avéré que chaque contrôle que vous avez agit comme une unité indépendante. Par conséquent, vous ne pouvez pas les combiner dans un tableau, par exemple.

2. Chaque classe d'un élément possède désormais, dans l'ensemble, son propre ensemble de fonctions. Ce n'est pas une bonne chose. Il devrait y avoir un ancêtre commun dont les fonctions sont simplement remplacées par les descendants. D'autant plus qu'il existe de nombreuses fonctions portant le même nom dans les classes actuelles. Qu'est-ce qui vous empêche de créer un ancêtre commun ?

3. si une classe de base apparaît, il sera possible de cacher la gestion des événements dans les descendants, au lieu de les placer tous à l'extérieur dans le formulaire. de faire une cascade d'événements à l'intérieur des objets (similaire à CSS dans le web).


Mais en général, les trois parties de l'article méritent d'être récompensées, en particulier j'ai aimé les "nudges" lorsque l'on appuie sur les boutons et leurs réponses interactives aux pressions en fonction de l'état de l'élément.

PS.
4. Un menu multi-niveaux est toujours en cours de finition, un article séparé à ce sujet n'est pas nécessaire, trop gros pour une si petite tâche d'écrire un nouvel article. Que ce soit juste une mise à jour de la version v4.
La classe d'arbre CTreeCtrl peut être tirée de l'article https://www.mql5.com/ru/article s/272 ou CTreeNode proposé dans le kit MT.

1- Vous pouvez assembler des contrôles de type unique dans un tableau. Pourquoi voudriez-vous rassembler des contrôles dissemblables dans un tableau ?

2. Si vous utilisez une classe de base (une pour tous les contrôles), cela signifie qu'elle doit avoir toutes les méthodes que n'importe quelle sous-classe peut avoir. Avec les classes indépendantes, dans la liste déroulante des méthodes (pendant le développement), nous n'avons que les méthodes qui existent réellement dans la classe. À mon avis, il s'agit là d'un point très important. J'imagine quelqu'un s'asseoir et essayer d'appeler la méthode SetWidth() pour une barre de défilement verticale.

Le deuxième argument - toutes les classes sont commentées pour doxygen, s'il y a une classe de base et des sous-classes, il n'y aura pas de structuration aussi évidente dans la documentation.

J'essaie de créer des solutions prêtes à l'emploi afin qu'elles puissent être utilisées "les yeux fermés". Pour accélérer le processus de création d'un nouveau contrôle, vous pouvez utiliser un modèle contenant toutes les méthodes obligatoires.

3) Je ne comprends pas très bien. Si un contrôle contient un autre contrôle, sa gestion des événements est cachée. Dans tous les cas, vous devrez appeler Event() pour chaque contrôle.

4. Je ne sais pas, peut-être... J'ai ma propre classe spécialement conçue pour la création de menus, il n'est pas nécessaire d'appeler AddNode(), c'est AddItem() qui est appelé, et le niveau est déterminé par le nombre d'espaces par lesquels commence le nom de l'élément. Le processus de création d'un arbre est très clair. Jusqu'à présent, il fonctionne avec l'affichage dans le commentaire et le contrôle des touches. En général, vous pouvez créer plusieurs menus arborescents : 1) comme un menu principal normal avec des onglets déroulants, 2) affichant les éléments d'un onglet et le chemin vers le sommet, 3) avec affichage de l'arbre (comme l'explorateur Windos).

 
sergeev:

1) Personnellement, je la vois d'un bon œil. La visualisation ne fait que simplifier le placement des objets. Si vous le faites correctement, vous devez lier la génération de code pour les objets créés, en liant des variables ou des classes à l'objet. Et surtout, le traitement des événements.

2. Mais dans ces classes non abstraites, ce n'est pas possible. Elles sont très manuelles. Il est nécessaire d'écrire en de nombreux endroits les objets nouvellement créés et leur traitement.
Pour les événements, par exemple, il n'y a pas de division entre le système et l'utilisateur - comme Draw (système de base) et OnDraw - un ajout de l'utilisateur avec son propre dessin.

Dans d'autres structures (par exemple Joomla !), il n'y a pas qu'une seule fonction personnalisée OnDraw. Elle est divisée en deux : BeforDraw et AfterDraw. En d'autres termes, le programmeur peut gérer l'événement système EVENT_DRAW - à la fois avant le début du dessin du système et après sa fin.


1. Il sera possible de générer automatiquement le code de gestion des événements des contrôles et d'obtenir des fonctions d'événement pour tous les contrôles, comme HScrollBar1_OnChange().....

2. Il n'y a pas encore d'événements, par exemple, lorsque des valeurs sont définies par programme, les événements ne sont générés que lorsque les valeurs sont saisies par l'utilisateur. Il s'agit d'un minimum suffisant, rien de plus. Sinon, quelqu'un qui apprend la programmation par lui-même sera submergé d'événements.

 
Lizar:

Un travail de qualité et utile, Dimitri. Il y a une suggestion pour la quatrième partie : "Form Wizard" ou "Visual Form Editor" : "Form Wizard" ou "Visual Form Editor". Qu'en pensez-vous ?

Positivement. J'ai déjà compris comment le faire avec peu de sueur et sans artillerie lourde. Ce n'est que dans un avenir proche que je suis en vacances. Après les vacances, ce sera possible, si Rosh n'y voit pas d'inconvénient.
 
Lizar:

... Il y a une suggestion pour la partie 4 : "Form Wizard" ou "Visual Form Editor". Qu'en pensez-vous ?

"Tout a déjà été volé avant nous" (Opération Y).
 
Integer:

1. Les contrôles de type unique peuvent être assemblés en un réseau. Pourquoi rassembler différents types de contrôles dans un tableau ?

Pour tout rassembler dans une seule boucle et se débarrasser des types spécifiques dans la gestion des événements.

2. Si vous utilisez une classe de base (une pour tous les contrôles), cela signifie qu'elle doit avoir toutes les méthodes que n'importe quelle sous-classe peut avoir. Avec les classes indépendantes, dans la liste déroulante des méthodes (pendant le développement), nous n'avons que les méthodes qui existent réellement dans la classe. À mon avis, il s'agit là d'un point très important. J'imagine quelqu'un assis et essayant d'appeler la méthode SetWidth() pour une barre de défilement verticale.

Toutes les fonctions de la classe de base sont des bouchons vides avec une fonctionnalité générale minimale. Même si quelqu'un appelle sans le savoir une fonction sans rapport avec un élément, il ne se passera absolument rien de grave. Le polymorphisme.

Le deuxième argument - toutes les classes sont commentées pour doxygen, s'il y a une classe de base et des sous-classes, il n'y aura pas une structuration aussi évidente dans la documentation.

Il y en aura une, mais elle sera différente... :)

Когда нужно использовать указатели в MQL5
Когда нужно использовать указатели в MQL5
  • 2010.03.25
  • MetaQuotes Software Corp.
  • www.mql5.com
Все объекты в MQL5 по умолчанию передаются по ссылке, но есть возможность использовать и указатели объектов. При этом есть опасность получить в качестве параметра функции указатель неинициализированного объекта. В этом случае работа программы будет завершена критически с последующей выгрузкой. Автоматически создаваемые объекты как правило такой ошибки не вызывают, и в этом отношении они достаточно безопасны. В этой статье мы попробуем разобраться в чем разница между ссылкой и указателей, когда оправдано использование указателей и как написать безопасный код с использованием указателей.
 
sergeev:

1. tout regrouper dans une seule boucle et se débarrasser des types spécifiques dans la gestion des événements.

2. le point est que la classe de base n'a pas d'implémentation de fonctions d'actions spécifiques. toutes les fonctions de la classe de base sont des bouchons vides avec une fonctionnalité générale minimale. Même si quelqu'un appelle sans le savoir une fonction sans rapport avec un élément, il ne se passera absolument rien de grave. Le polymorphisme, cependant.

3. cela arrivera. mais ce sera différent.... :)

1. c'est tout ? Pour le bien de cette question, je vais m'amuser avec le point 2 - le dumping de méthode ?

Alternatives :

1) La nécessité d'ajouter manuellement un appel Event() pour chaque classe (ce qui consiste à copier avec la souris une ligne et à changer quelques lettres à gauche du point) et en même temps, dans la liste des méthodes de chaque classe nous n'avons que les méthodes de travail correspondant à cette classe, cliqué sur le point, la liste s'est affichée et tout est clair.

2) Traitement automatique de Event() de toutes les classes, alors qu'une fonction devra encore être appelée à partir de OnChartEvent(), et d'autre part : un vidage des méthodes dans la liste. De plus, vous devrez détruire les pointeurs dans le deinit.

Cherchez un peu plus loin, pourquoi tous les Event() devraient être traités dans une boucle, chaque contrôle devrait avoir ses propres actions pour son Event(), les contrôles ne servent pas seulement à entrer une valeur et pas seulement à faire bouger et scintiller tout ce qui est à l'écran, mais aussi (et surtout) à utiliser les valeurs entrées dans le programme.

3. Vous devrez lire environ la moitié des méthodes d'un contrôle à un endroit de la documentation et l'autre moitié à un autre.

 
Integer:

1. c'est tout ? Pour l'amour de la chose, pour toucher au point 2 - le dumping des méthodes ?

Autres solutions :

1) La nécessité d'ajouter manuellement un appel Event() pour chaque classe (ce qui consiste à copier avec la souris une ligne et à changer quelques lettres à gauche du point) et en même temps, dans la liste des méthodes de chaque classe on n'a que les méthodes de travail correspondant à cette classe, on clique sur le point, la liste tombe et tout est clair.

2) Traitement automatique de Event() de toutes les classes, alors qu'une fonction devra encore être appelée à partir de OnChartEvent(), et d'autre part : un vidage des méthodes dans la liste. De plus, nous devrons détruire les pointeurs dans le deinit.

Cherchez un peu plus loin, pourquoi tous les Event() devraient être traités dans une boucle, chaque contrôle devrait avoir ses propres actions pour son Event(), les contrôles ne servent pas seulement à entrer une valeur et pas seulement à faire bouger et scintiller tout ce qui est à l'écran, mais aussi (et surtout) à utiliser les valeurs entrées dans le programme.

3. Vous devrez lire environ la moitié des méthodes d'un contrôle à un endroit de la documentation et l'autre moitié à un autre.


Vous avez fait tout ce qu'il fallait.

Vu les possibilités de ME, c'est assez pratique, le minimalisme japonais à l'ère du kitsch total, tout est là, rien n'est superflu.

Ceux qui veulent faire des boucles dans les objets peuvent implémenter un shell postfix où ils peuvent écrire ce qu'ils veulent.