English Русский 中文 Español Deutsch 日本語 Português 한국어 Italiano Türkçe
Créez vos propres panneaux graphiques en MQL5

Créez vos propres panneaux graphiques en MQL5

MetaTrader 5Exemples | 22 décembre 2021, 16:58
287 0
MetaQuotes
MetaQuotes

Introduction

Un nouvel ensemble de classes est disponible dans la bibliothèque standard. Ces classes sont conçues pour le développement indépendant de dialogues de contrôle et de panneaux d'affichage dans les programmes MQL5.

Le nouvel ensemble de classes permet à chacun de créer des composants d'interface personnalisés en utilisant le modèle événementiel comme modèle sous-jacent. Tout est basé sur les objets cartographiques embarqués et les événements du Terminal.

Les classes développées peuvent être utilisées de manières suivantes :
  1. Panneau d'affichage dans une sous-fenêtre de graphique distincte ;
  2. Panneau de configuration pour un Expert Advisor ;
  3. Panneau de configuration d'affichage personnalisé.

Cet article montrera à quel point il est facile de créer vos propres panneaux d'affichage dans une sous-fenêtre de graphique distincte à l'aide des classes de la bibliothèque standard.


Qu'est-ce que la bibliothèque standard a à offrir ?

La bibliothèque standard fournit au développeur les commandes ci-dessous prêtes à l'emploi :

1. Commandes simples :

Contrôler Application Implémentation basée sur l'objet embarqué Bibliothèque Standard

Bouton avec texte

Assurer l'interaction entre la souris et le programme MQL

« Bouton »  <Controls\Button.mqh>

Bouton avec image

Assurer l'interaction entre la souris et le programme MQL

« Label graphique »  <Controls\BmpButton.mqh>

Édition

Saisie ou affichage d'informations textuelles (en mode « Lecture seule »)

« Éditer »  <Controls\Edit.mqh>

Sous-titre

Affichage des informations textuelles auxiliaires

« Label de texte »  <Controls\Label.mqh>

Panneau

Commande auxiliaire (regroupement visuel des commandes)

« Label rectangulaire »  <Controls\Panel.mqh>

Image

Contrôle décoratif

 « Label graphique »  <Controls\Picture.mqh>



2. Contrôles complexes :


Contrôler Application Mise en œuvre basée sur les contrôles Bibliothèque Standard

Liste

Affichage d'une liste

« Rectangle », « Bouton avec image » et « Éditer »  <Controls\List.mqh>

Champ avec une liste déroulante

Sélection dans une liste déroulante

« Éditer », « Bouton avec image » et « Liste »  <Controls\ComboBox.mqh>

Champ d'incrémentation/décrémentation

Énumération des valeurs

« Édition » et « Bouton avec image »  <Controls\SpinEdit.mqh>

Bouton radio

Switch « Bouton avec image » et « Sous-titre »  <Controls\RadioButton.mqh>
 Groupe de boutons radio  Édition des champs de type enum  « Rectangle » et « Bouton radio »  <Controls\RadioGroup.mqh>

Case à cocher

Option de sélection

« Bouton avec image » et « Sous-titre »  <Controls\CheckBox.mqh>

Groupe de cases à cocher

Édition d'un ensemble de drapeaux

 « Rectangle » et « case à cocher »  <Controls\CheckGroup.mqh>
 Dialogue  Formulaire de dialogue  « Rectangle », « Bouton avec image » et « Éditer »  <Controls\Dialog.mqh>



Création d'un panneau d'affichage

Définissons d'abord les termes. Le panneau d'affichage est un terme que nous utiliserons pour décrire un affichage personnalisé de fenêtre séparée qui n'a pas de tampon de dessin. Ce panneau affiche simplement les informations requises à l'aide des objets graphiques intégrés dans le terminal. Les informations peuvent être affichées :

  • numériquement,
  • comme texte,
  • comme couleur,
  • etc.

Nous examinerons en détail chaque étape requise et créerons un panneau graphique comme suit :



Afin de créer un panneau d'affichage, nous aurons besoin de deux fichiers :

  1. Le fichier Include contenant la description de la classe du panneau d'affichage.
  2. Le fichier de code source de l'indicateur.

Des modèles de ces fichiers peuvent être obtenus à l'aide de l'assistant Assistant MQL5. Dans le répertoire des indicateurs (MQL5\Indicators), créez un dossier séparé MyIndicators et un sous-dossier MyPanel. Le processus de création de dossiers ne sera pas traité ici car il est bien décrit dans l'Aide.


Description de la classe

Nous avons donc déjà créé le dossier de travail. Trouvons-le maintenant dans la fenêtre « Navigateur » et faites un clic droit dessus. Sélectionnez le « Nouveau fichier » dans le menu qui apparaît. Sélectionnez la « Nouvelle classe » parmi les options proposées par l'assistant MQL5 et cliquez sur « Suivant > ». Remplissez la boîte de dialogue de description de la classe comme indiqué ci-dessous :

Création d'une nouvelle classe dans l’assistant MQL

Cliquez sur « Terminer ». En conséquence, nous avons le code suivant :

//+------------------------------------------------------------------+
//|                                                  PanelDialog.mqh |
//|                        Copyright 2011, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class CPanelDialog : public CAppDialog
  {
private:

public:
                     CPanelDialog();
                    ~CPanelDialog();
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
CPanelDialog::CPanelDialog()
  {
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
CPanelDialog::~CPanelDialog()
  {
  }
//+------------------------------------------------------------------+


Ajoutez le fichier Include <Controls\Dialog.mqh> de la bibliothèque standard avec la description de la classe de base CAppDialog et les commentaires.

//+------------------------------------------------------------------+
//|                                                  PanelDialog.mqh |
//|                        Copyright 2011, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#include <Controls\Dialog.mqh>
//+------------------------------------------------------------------+
//| CPanelDialog class                                               |
//| Function: main application dialog                                |
//+------------------------------------------------------------------+
class CPanelDialog : public CAppDialog
  {
private:

public:
                     CPanelDialog(void);
                    ~CPanelDialog(void);
  };
//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
CPanelDialog::CPanelDialog(void)
  {
  }
//+------------------------------------------------------------------+
//| Destructor                                                       |
//+------------------------------------------------------------------+
CPanelDialog::~CPanelDialog(void)
  {
  }
//+------------------------------------------------------------------+

Nous avons maintenant la description de la classe qui va nous permettre d'utiliser une boîte de dialogue dans son indicateur. Notre boîte de dialogue est actuellement vide mais nous allons y ajouter des contrôles un peu plus tard. Pour le moment, passons à l'indicateur.


Le code source de l'indicateur

L'indicateur sera également créé à l'aide de l'assistant MQL5. Nos actions seront similaires à celles requises lors de la rédaction de la description de la classe. Il n'y a qu'une seule différence : nous sélectionnons « Indicateur personnalisé » parmi les options proposées par l'assistant MQL5. Afin de créer un indicateur, trois boîtes de dialogue doivent être remplies.

La première nécessite de préciser le nom de l'indicateur :

Création d'un nouvel indicateur dans l’assistant MQL


Dans la deuxième boîte de dialogue, cochez « OnChartEvent » (obligatoire) et « OnTimer » :

Définition des gestionnaires d'événements pour l'indicateur personnalisé dans l’assistant MQL



Cochez « Indicateur de fenêtre séparée » (obligatoire) dans la troisième boîte de dialogue :

Définition des propriétés de dessin d'indicateur dans l’assistant MQL


Et cliquez sur « Terminer ». Le code produit est le suivant :

//+------------------------------------------------------------------+
//|                                               PanelIndicator.mq5 |
//|                        Copyright 2011, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
              const int prev_calculated,
              const int begin,
              const double &price[])
  {
//---
   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
//---
   
  }
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                const long &lparam,
                const double &dparam,
                const string &sparam)
  {
//---
   
  }
//+------------------------------------------------------------------+


Notre modèle peut maintenant être complété en ajoutant :

  • descriptions manquantes des propriétés de l'indicateur ;
  • inclusion d’un fichier contenant la description de classe de notre boîte de dialogue ;
  • a global variable - l'objet de classe de notre dialogue ;
  • code pour créer la boîte de dialogue, démarrer l'application et créer le minuteur dans le corps de la fonction OnInit() ;
  • Fonction OnDeinit() contenant un code qui détruit la boîte de dialogue et tue le minuteur ;
  • fonction OnChartEvent(...) sur le code d'appel du gestionnaire d'événements ;
  • commentaires.

Nous avons l'indicateur prêt à l'emploi :

//+------------------------------------------------------------------+
//|                                               PanelIndicator.mq5 |
//|                        Copyright 2011, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
#property indicator_plots               0
#property indicator_buffers             0
#property indicator_minimum             0.0
#property indicator_maximum             0.0
//+------------------------------------------------------------------+
//| Include files                                                    |
//+------------------------------------------------------------------+
#include "PanelDialog.mqh"
//+------------------------------------------------------------------+
//| Global variables                                                 |
//+------------------------------------------------------------------+
CPanelDialog ExtDialog;
//+------------------------------------------------------------------+
//| Initialization                                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- creating the application dialog
   if(!ExtDialog.Create(0,"Panel Indicator",0,0,0,0,130))
     return(-1);
//--- starting the application
   if(!ExtDialog.Run())
     return(-2);
//--- creating the timer
   EventSetTimer(1);
//--- success
   return(0);
  }
//+------------------------------------------------------------------+
//| Deinitialization                                                 |
//+------------------------------------------------------------------+
int OnDeinit()
  {
//--- destroying the dialog
   ExtDialog.Destroy();
//--- killing the timer
   EventKillTimer();
  }
//+------------------------------------------------------------------+
//| Iteration                                                        |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
              const int prev_calculated,
              const int begin,
              const double &price[])
  {  
//--- returning the prev_calculated value for the next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Timer event handler                                              |
//+------------------------------------------------------------------+
void OnTimer()
  {
//---
  }
//+------------------------------------------------------------------+
//| Chart event handler                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                const long &lparam,
                const double &dparam,
                const string &sparam)
  {
//--- handling the event
   ExtDialog.ChartEvent(id,lparam,dparam,sparam);
  }
//+------------------------------------------------------------------+


L'indicateur dans le formulaire ci-dessus ne montre rien pour l'instant. Une fois compilé et déposé du navigateur sur le graphique, il sera affiché comme une boîte de dialogue vide dans une fenêtre séparée.

Bien que la boîte de dialogue soit vide, notre indicateur a déjà acquis certaines fonctionnalités :

  • la hauteur de la sous-fenêtre a été ajustée à la hauteur de la boîte de dialogue par l'indicateur lors de la création ;
  • la largeur de la boîte de dialogue est toujours égale à la largeur du graphique ;
  • l'indicateur peut minimiser et maximiser sa propre sous-fenêtre.

Laissez-le afficher

Pour que notre panneau commence à afficher des informations, nous devons décider des réponses à trois questions :

  1. Quel type d'informations voulons-nous afficher ?
  2. Quels éléments d'affichage et/ou contrôles supplémentaires doivent être placés sur notre boîte de dialogue ?
  3. Comment ces éléments/contrôles supplémentaires interagiront-ils ?

Un autre facteur important est que notre dialogue doit être visuellement attrayant et convivial. Cela n'affecte pas la fonctionnalité de la boîte de dialogue mais montre que nous nous soucions des utilisateurs du futur programme MQL5.

   Étape 1. Quel type d'informations voulons-nous afficher ?

Puisque l'article sert d'outil d'apprentissage, ne nous attardons pas sur l'utilisabilité de l'indicateur. La couleur sera affichée en fonction de trois paramètres. Nous ne compliquerons pas trop les paramètres - ce seront les niveaux « rouge », « vert » et « bleu ».

Les valeurs des paramètres seront configurées comme suit :

  • La valeur de niveau « rouge » sera configurée dans la plage de 0 à 255, changeant de manière aléatoire à chaque événement Calculate ;
  • La valeur de niveau « vert » sera configurée dans la plage de 0 à 255 en changeant de manière aléatoire à chaque événement Timer ;
  • La valeur du niveau « bleu » sera configurée dans la plage de 0 à 255 et sera modifiée manuellement au moyen d'une commande spéciale.

Soit dit en passant, les valeurs de ces niveaux seront également affichées dans notre indicateur.


   Étape 2. Quels commandes supplémentaires seront nécessaires ?

  1. La couleur sera affichée à l'aide de la commande par « Panneau ».
  2. Les niveaux « rouge » et « vert » seront affichés à l'aide du champ « Edition » en mode « Lecture seule ».
  3. Le niveau « bleu » sera géré par le champ « Spin Edit ». La même commande aidera à afficher la valeur du niveau.
  4. Les deux commandes « Edit » et « Spin Edit » seront enrichis de sous-titres explicatifs via la commande « Caption ».

Ajoutez les fichiers Include de la bibliothèque standard, ainsi que les contrôles et variables requis qui stockent les valeurs des paramètres à la description de classe ayant fourni des commentaires.

Nous aurons:

//+------------------------------------------------------------------+
//|                                                  PanelDialog.mqh |
//|                        Copyright 2011, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#include <Controls\Dialog.mqh>
#include <Controls\Panel.mqh>
#include <Controls\Edit.mqh>
#include <Controls\Label.mqh>
#include <Controls\SpinEdit.mqh>
//+------------------------------------------------------------------+
//| CPanelDialog class                                               |
//| Function: main application dialog                                |
//+------------------------------------------------------------------+
class CPanelDialog : public CAppDialog
  {
private:
   //--- additional controls
   CPanel            m_color;                         // object for displaying color
   CLabel            m_label_red;                     // "red" level caption object
   CEdit             m_field_red;                     // "red" value display object
   CLabel            m_label_green;                   // "green" level caption object
   CEdit             m_field_green;                   // "green" value display object
   CLabel            m_label_blue;                    // "blue" level caption object
   CSpinEdit         m_edit_blue;                     // "blue" value control object
   //--- parameter values
   int               m_red;                           // "red" value
   int               m_green;                         // "green" value
   int               m_blue;                          // "blue" value

public:
                     CPanelDialog(void);
                    ~CPanelDialog(void);
  };
//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
CPanelDialog::CPanelDialog(void)
  {
  }
//+------------------------------------------------------------------+
//| Destructor                                                       |
//+------------------------------------------------------------------+
CPanelDialog::~CPanelDialog(void)
  {
  }
//+------------------------------------------------------------------+


   Étape 3. Comment ces commandes de dialogue supplémentaires interagiront-elles ?
Le principe d'interaction entre les commandes de la boîte de dialogue sera très simple - « La boîte de dialogue affichera les changements de n'importe quel paramètre (niveaux « rouge », « vert » et « bleu ») ». La mise en œuvre des algorithmes d'interaction sera abordée plus tard car il est maintenant temps de commencer à créer le dialogue.


Quelques mots pour le plaisir des yeux

Avant de procéder à la création de la boîte de dialogue, jetons un oeil rapide dans l’aspect plaisir des yeux. Ou mieux, une disposition conviviale et un futur (possible) réarrangement des commandes de dialogue. Les constantes nommées (#define) servent au mieux cet objectif.

Les constantes nommées prédéfinies présentent certains avantages :

  • certaines valeurs numériques utilisées dans des cas spécifiques ne doivent pas être mémorisées. Les noms de constante sélectionnés avec précision y fourniront un accès rapide via la « Liste automatique des noms » ;
  • lorsque les valeurs constantes sont encore modifiées, de nombreuses inclusions de valeurs numériques n'ont pas besoin d'être recherchées et remplacées. Il suffit de modifier uniquement la description de la constante.

L'utilisation des constantes suivantes est suggérée :

//+------------------------------------------------------------------+
//| defines                                                          |
//+------------------------------------------------------------------+
//--- indents and spacing
#define INDENT_LEFT                         (11)      // left indent (including the border width)
#define INDENT_TOP                          (11)      // top indent (including the border width)
#define INDENT_RIGHT                        (11)      // right indent (including the border width)
#define INDENT_BOTTOM                       (11)      // bottom indent (including the border width)
#define CONTROLS_GAP_X                      (10)      // spacing along the X-axis
#define CONTROLS_GAP_Y                      (10)      // spacing along the Y-axis
//--- for labels
#define LABEL_WIDTH                         (50)      // size along the X-axis
//--- for edits
#define EDIT_WIDTH                          (50)      // size along the Y-axis
#define EDIT_HEIGHT                         (20)      // size along the Y-axis
//--- for base colors (RGB)
#define BASE_COLOR_MIN                      (0)       // minimum value of the color component
#define BASE_COLOR_MAX                      (255)     // maximum value of the color component


Remplissage du panneau d'affichage

Nous avons précédemment créé la classe panneau d'affichage ; maintenant, afin d'atteindre la fonctionnalité requise, nous devons procéder comme suit :

1. Redéfinir la méthode Create(...) de la classe parent. A l'origine, notre méthode apparaîtra comme suit :

//+------------------------------------------------------------------+
//| Creation                                                         |
//+------------------------------------------------------------------+
bool CPanelDialog::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
  {
//--- calling the method of the parent class
   if(!CAppDialog::Create(chart,name,subwin,x1,y1,x2,y2))  return(false);
//--- additional controls shall be created here

//--- success
   return(true);
  }


2. Créer des commandes supplémentaires.

Une légère parenthèse lyrique. Les codes pour créer toutes les commandes supplémentaires peuvent bien sûr être insérés directement dans le corps de la méthode Create(...), mais de cette façon nous risquons d'obtenir un gros « volume » illisible.

Nous allons donc diviser le processus de création en parties autonomes représentées par les méthodes suivantes :

  • bool CreateColor(void) - création de panneau de couleur,
  • bool CreateRed(void) - création de l'élément d'affichage « Rouge » avec sous-titre explicatif,
  • bool CreateGreen(void) - création de l'élément d'affichage « Vert » avec sous-titre explicatif,
  • bool CreateBlue(void) - création de commande « Bleu » avec sous-titre explicatif.

Ces méthodes sont appelées séquentiellement à partir de la méthode Create(...) :

//+------------------------------------------------------------------+
//| Creation                                                         |
//+------------------------------------------------------------------+
bool CPanelDialog::Create(const long chart,const string name,const int subwin,
                             const int x1,const int y1,const int x2,const int y2)
  {
//--- calling the parent class method
   if(!CAppDialog::Create(chart,name,subwin,x1,y1,x2,y2)) return(false);

//--- creating additional elements
   if(!CreateColor()) return(false);
   if(!CreateRed())   return(false);
   if(!CreateGreen()) return(false);
   if(!CreateBlue())  return(false);
//--- success
   return(true);
  }


Création de commandes

Nous ne passerons pas en revue la création de chaque commande supplémentaire, mais nous examinerons en détail la méthode bool CreateBlue(void).

C'est comme suit :

//+------------------------------------------------------------------+
//| Creating the "Blue" control with explanatory caption             |
//+------------------------------------------------------------------+
bool CPanelDialog::CreateBlue(void)
  {
//--- coordinates
   int x1=INDENT_LEFT;
   int y1=INDENT_TOP+2*(EDIT_HEIGHT+CONTROLS_GAP_Y);
   int x2=x1+EDIT_WIDTH;
   int y2=y1+EDIT_HEIGHT;
//--- creating the caption
   if(!m_label_blue.Create(m_chart_id,m_name+"LabelBlue",m_subwin,x1,y1+1,x2,y2)) return(false);
   if(!m_label_blue.Text("Blue")) return(false);
   if(!Add(m_label_blue)) return(false);
//--- adjusting coordinates
   x1+=LABEL_WIDTH+CONTROLS_GAP_X;
   x2=x1+EDIT_WIDTH;
//--- creating the control
   if(!m_edit_blue.Create(m_chart_id,m_name+"Blue",m_subwin,x1,y1,x2,y2)) return(false);
   if(!Add(m_edit_blue)) return(false);
   m_edit_blue.MinValue(BASE_COLOR_MIN);
   m_edit_blue.MaxValue(BASE_COLOR_MAX);
   m_edit_blue.Value(m_blue);
//--- success
   return(true);
  }

Il y a deux nuances :

  1. Le champ est créé avec des coordonnées relatives, c'est-à-dire que l'offset est fixé par rapport au coin supérieur gauche du conteneur (élément complexe) auquel le champ sera ajouté après sa création.
  2. Suite à la création, il est nécessaire d'ajouter le champ à un conteneur à l'aide de la méthode Add(...). Dans notre cas, la boîte de dialogue sert de conteneur.


Modification des paramètres

Ajouter la méthode void SetColor(void) pour changer la couleur du panneau de couleur ;

Afin de pouvoir modifier les paramètres (niveaux des couleurs de base) en externe, nous allons ajouter trois méthodes publiques :

  • void SetRed(const int value) - modifie le niveau « rouge » et affiche le changement dans l'indicateur,
  • void SetGreen(const int value) - modifie le niveau « vert » et affiche le changement dans l'indicateur,
  • void SetBlue(const int value) - modifie le niveau « bleu » et affiche le changement dans l'indicateur.

La phrase « affiche le changement dans l'indicateur » signifie que la nouvelle valeur du niveau de couleur de base est affichée sous forme numérique dans le champ correspondant et le panneau de couleur change de couleur.

Vous trouverez ci-dessous un code de l'une des méthodes pour servir d'exemple :

//+------------------------------------------------------------------+
//| Setting the "Red" value                                          |
//+------------------------------------------------------------------+
void CPanelDialog::SetRed(const int value)
  {
//--- checking
   if(value<0 || value>255) return;
//--- saving
   m_red=value;
//--- setting
   m_field_red.Text(IntegerToString(value));
//--- setting the panel color
   SetColor();
  }

Comme convenu ci-dessus :

  • La valeur du niveau « rouge » changera de manière aléatoire à chaque événement Calculate ;
  • La valeur du niveau "vert" changera de manière aléatoire à chaque événement Timer ;

Ajoutons le code pertinent dans l'indicateur d'origine :

//+------------------------------------------------------------------+
//|                                               PanelIndicator.mq5 |
//|                        Copyright 2011, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2011, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
#property indicator_plots               0
#property indicator_buffers             0
#property indicator_minimum             0.0
#property indicator_maximum             0.0
//+------------------------------------------------------------------+
//| Include files                                                    |
//+------------------------------------------------------------------+
#include "PanelDialog.mqh"
//+------------------------------------------------------------------+
//| Global variables                                                 |
//+------------------------------------------------------------------+
CPanelDialog ExtDialog;
//+------------------------------------------------------------------+
//| Initialization                                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- creating the application dialog
   if(!ExtDialog.Create(0,"Panel Indicator",0,0,0,0,130))
      return(-1);
//--- starting the application
   if(!ExtDialog.Run())
      return(-2);
//--- creating the timer
   EventSetTimer(1);
//--- success
   return(0);
  }
//+------------------------------------------------------------------+
//| Deinitialization                                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- destroying the dialog
   ExtDialog.Destroy();
//--- killing the timer
   EventKillTimer();
  }
//+------------------------------------------------------------------+
//| Iteration                                                        |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
  {
//--- changing the dialog property
   ExtDialog.SetRed(MathRand()%256);
//--- returning the prev_calculated value for the next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Timer event handler                                              |
//+------------------------------------------------------------------+
void OnTimer()
  {
//--- changing the dialog property
   ExtDialog.SetGreen(MathRand()%256);
  }
//+------------------------------------------------------------------+
//| Chart event handler                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//--- handling the event
   ExtDialog.ChartEvent(id,lparam,dparam,sparam);
  }
//+------------------------------------------------------------------+


Gestion événementielle

Toute l'interaction entre la boîte de dialogue et le Terminal ainsi que l'interaction entre les commandes de la boîte de dialogue est basée sur le mécanisme event. Nous n'allons pas passer en revue ses fonctions mais simplement l'utiliser.

Les événements peuvent classiquement être divisés en deux groupes :

  • Événements internes gérés en contournant la file d'attente des événements Terminal ;
  • Événements externes gérés via la file d'attente d'événements Terminal.

Nous traiterons les deux types d'événements.

Parmi les événements internes, seuls les événements de redimensionnement du dialogue nécessitent d'être traités. Pour cela, rechargez la méthode OnResize() de la classe parents. Notre méthode sera simple car il n'y a aucun changement dans la hauteur de la boîte de dialogue ; si la largeur du dialogue change, il suffit de modifier la largeur du panneau de couleur :

//+------------------------------------------------------------------+
//| Resize handler                                                   |
//+------------------------------------------------------------------+
bool CPanelDialog::OnResize(void)
  {
//--- calling the parent class method
   if(!CAppDialog::OnResize()) return(false);
//--- changing the color panel width
   m_color.Width(ClientAreaWidth()-(INDENT_RIGHT+LABEL_WIDTH+CONTROLS_GAP_X+EDIT_WIDTH+CONTROLS_GAP_X+INDENT_LEFT));
//--- success
   return(true);
  }

La liste des événements externes sera également limitée à un élément - l'événement de modification du niveau « bleu ». Les exigences pour le gestionnaire d'événements externe sont minimes : le gestionnaire doit être la méthode de classe sans paramètre de type void.

Décrivons le gestionnaire de cet événement :

//+------------------------------------------------------------------+
//| Handler of the event of changing the "blue" level                |
//+------------------------------------------------------------------+
void CPanelDialog::OnChangeBlue(void)
  {
//--- saving
   m_blue=m_edit_blue.Value();
//--- setting the panel color
   SetColor();
  }

Comme on peut le voir, il n'y a rien de difficile là-dedans.

Pour que notre boîte de dialogue gère les événements externes, la méthode de la classe parente doit être rechargée :

virtual bool  OnEvent(const int id,const long &lparam,
                       const double &dparam,const string &sparam);

Et maintenant un peu de mystère. Si vous avez déjà ouvert le fichier PanelDialog.mqh dans l'éditeur, vous verrez qu'il n'y a pas de corps de méthode OnEvent(...).

Ne soyez pas confus - le fait est que pour la description de la gestion des événements externes, un ensemble de macros a été créé (voir le fichier <Controls\Defines.mqh> dans la bibliothèque standard).

Notre gestionnaire d'événements est le suivant :

//+------------------------------------------------------------------+
//| Handling events                                                  |
//+------------------------------------------------------------------+
EVENT_MAP_BEGIN(CPanelDialog)
   ON_EVENT(ON_CHANGE,m_edit_blue,OnChangeBlue)
EVENT_MAP_END(CAppDialog)

Ce pseudo-code qui peut ne pas être clair à première vue, fait ce qui suit :

  • Lorsque l'événement ON_CHANGE est reçu du contrôle m_edit_blue, la méthode OnChangeBlue est appelée et le traitement de l'événement est terminé (retournant true) ;
  • À la réception de tout autre événement, le contrôle est transféré à la méthode de la classe parente.

Conclusion

Cet article a fourni l'examen du processus de création d'un panneau d'affichage à l'aide des classes de la Bibliothèque standard.

Il est peu probable que vous utilisiez l'indicateur tel qu'il a été créé, mais il n'est pas surchargé d'informations inutiles et nous avons réussi à couvrir presque toutes les particularités du processus lors de sa création.

Des exemples de livraison standard plus complexes sont disponibles dans les répertoires suivants de votre Terminal :

  • Experts\Examples\Controls\
  • Indicators\Examples\Panels\ChartPanel\
  • Indicators\Examples\Panels\SimplePanel\

Traduit du russe par MetaQuotes Ltd.
Article original : https://www.mql5.com/ru/articles/345

Fichiers joints |
paneldialog.mqh (13.04 KB)
panelindicator.mq5 (3.38 KB)
Les bases de la programmation orientée objet Les bases de la programmation orientée objet
Vous n'avez pas besoin de savoir ce que sont le polymorphisme, l'encapsulation, etc. pour utiliser la programmation orientée objet (POO)... vous pouvez simplement utiliser ces fonctionnalités. Cet article couvre les bases de la POO avec des exemples pratiques.
Accélération des calculs avec le réseau cloud MQL5 Accélération des calculs avec le réseau cloud MQL5
Combien de cœurs avez-vous sur votre ordinateur personnel ? Combien d'ordinateurs pouvez-vous utiliser pour optimiser une stratégie de trading ? Nous montrons ici comment utiliser le réseau cloud MQL5 pour accélérer les calculs en recevant la puissance de calcul à travers le monde d'un simple clic de souris. L'expression « Le temps, c'est de l'argent » devient de plus en plus d'actualité d'année en année, et nous ne pouvons pas nous permettre d'attendre des calculs importants pendant des dizaines d'heures, voire des jours.
Approche orientée objet pour créer des panneaux multi-délais et multi-devises Approche orientée objet pour créer des panneaux multi-délais et multi-devises
Cet article décrit comment la programmation orientée objet peut être utilisée pour créer des panneaux multi-délais et multi-devises pour MetaTrader 5. L'objectif principal est de créer un panneau universel, qui peut être utilisé pour afficher de nombreux types de données, tels que les prix, les changements de prix, les valeurs des indicateurs ou les conditions d'achat/vente personnalisées sans avoir besoin de modifier le code du panneau lui-même.
Contrôles graphiques personnalisés. Partie 3. Formulaires Contrôles graphiques personnalisés. Partie 3. Formulaires
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.