
Crea i Tuoi Pannelli Grafici in MQL5
Introduzione
C'è un nuovo set di classi disponibile nella Libreria Standard. Queste classi sono progettate per lo sviluppo indipendente di finestre di dialogo di controllo e pannelli di visualizzazione nei programmi MQL5.
Il nuovo set di classi consente a tutti di creare componenti di interfaccia personalizzati utilizzando il modello basato su eventi come modello di base. Tutto si basa sugli oggetti e gli eventi del grafico integrati del Terminale.
- Pannello di visualizzazione in una sottofinestra del grafico separata;
- Pannello di controllo per un Expert Advisor;
- Pannello di controllo del display personalizzato.
In questo articolo, verrà illustrato quanto sia facile creare pannelli di visualizzazione propri in una sottofinestra del grafico separata utilizzando le classi Libreria Standard.
Cosa Ha da Offrire la Libreria Standard?
La Libreria Standard fornisce allo sviluppatore i seguenti controlli pronti per l'uso:
1. Controlli semplici:
Controllo Applicazione Implementazione basata sull'oggetto integrato File della Libreria Standard Pulsante con testo
Garantire l'interazione tra il mouse e il programma MQL
"Button" <Controls\Button.mqh> Pulsante con immagine
Garantire l'interazione tra il mouse e il programma MQL
"Etichetta grafica" <Controls\BmpButton.mqh> Modifica
Inserimento o visualizzazione di informazioni di testo (in modalità "Sola Lettura")
"Edit" <Controls\Edit.mqh> Didascalia
Visualizzazione di informazioni di testo ausiliarie
"Text label" <Controls\Label.mqh> Pannello
Controllo ausiliario (raggruppamento visivo dei controlli)
Etichetta Rettangolare <Controls\Panel.mqh> Immagine
Controllo decorativo
"Etichetta grafica" <Controls\Picture.mqh>
2. Controlli complessi:
Controllo Applicazione Implementazione basata sui controlli File della Libreria Standard Lista
Visualizzazione di un elenco
"Rettangolo", "Pulsante con immagine" e "Modifica" <Controls\List.mqh> Campo con un elenco a tendina
Selezione da un elenco a tendina
"Modifica", "Pulsante con immagine" ed "Elenco" <Controls\ComboBox.mqh> Campo Incremento/decremento
Enumerazione dei valori
"Modifica" e "Pulsante con immagine" <Controls\SpinEdit.mqh> Radio button
Switch "Pulsante con immagine" e "Didascalia" <Controls\RadioButton.mqh> Gruppo radio button Modifica dei campi di tipo enum "Rettangolo" e "Radio button" <Controls\RadioGroup.mqh> Checkbox
Opzione di selezione
"Pulsante con immagine" e "Didascalia" <Controls\CheckBox.mqh> Gruppo checkbox
Modifica di un set di flag
"Rettangolo" e "Checkbox" <Controls\CheckGroup.mqh> Dialogo Modulo finestra di dialogo "Rettangolo", "Pulsante con immagine" e "Modifica" <Controls\Dialog.mqh>
Creazione di un Pannello di Visualizzazione
Definiamo prima i termini. Il pannello di Visualizzazione è un termine che useremo per descrivere una visualizzazione personalizzata della finestra separata che non ha buffer di disegno. Tale pannello mostra semplicemente le informazioni richieste utilizzando gli oggetti grafico integrati nel Terminale. Le informazioni possono essere visualizzate:
- numericamente,
- come testo,
- come colore,
- ecc.
Daremo uno sguardo dettagliato ad ogni passaggio richiesto e creeremo un pannello grafico come segue:
Per creare un pannello di visualizzazione, avremo bisogno di due file:
- Il file di include contenente la descrizione della classe del pannello di visualizzazione.
- File di codice sorgente dell'indicatore.
I modelli di questi file possono essere ottenuti utilizzandoMQL5 Wizard. Nella directory degli indicatori (MQL5\Indicators), creare una cartella separata MyIndicators e una sottocartella MyPanel. Il processo di creazione delle cartelle non verrà trattato qui come è ben descritto nella Guida.
Descrizione della Classe
Quindi, abbiamo già creato la cartella di lavoro. Cerchiamo ora di trovarlo nella finestra "Navigator" e fare click con il pulsante destro del mouse su di esso. Seleziona "Nuovo file" nel menu che compare. Seleziona la "Nuova classe" tra le opzioni fornite dalla MQL5 Wizard e fai click su "Avanti >". Completa la finestra di dialogo della descrizione della classe come mostrato di seguito:
Fai click su "Fine". Di conseguenza, abbiamo il seguente codice:
//+------------------------------------------------------------------+ //| 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() { } //+------------------------------------------------------------------+
Aggiungere il file include <Controls\Dialog.mqh> dalla Libreria Standard con la descrizione della classe CAppDialog di base e i commenti.
//+------------------------------------------------------------------+ //| 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) { } //+------------------------------------------------------------------+
Ora, abbiamo la descrizione della classe che ci permetterà di utilizzare una finestra di dialogo nel suo indicatore. La nostra finestra di dialogo è attualmente vuota, ma aggiungeremo controlli un po’ più tardi. Al momento, passiamo all'indicatore.
Il Codice Sorgente dell'Indicatore
L'indicatore verrà creato anche utilizzando MQL5 Wizard. Le nostre azioni saranno simili a quelle richieste quando si scrive la descrizione della classe. C'è solo una differenza: selezioniamo "Indicatore personalizzato" tra le opzioni fornite da MQL5 Wizard. Per creare un indicatore, è necessario completare tre finestre di dialogo.
Il primo richiede di specificare il nome dell'indicatore:
Nella seconda finestra di dialogo, spuntare "OnChartEvent" (obbligatorio) e "OnTimer":
Spuntare "Separate Window Indicator" (obbligatorio) nella terza finestra di dialogo:
E fai click su "Fine". Il codice prodotto è il seguente:
//+------------------------------------------------------------------+ //| 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) { //--- } //+------------------------------------------------------------------+
Il nostro modello può ora essere completato aggiungendo:
- le descrizioni mancanti delle proprietà dell'indicatore;
- includere il file contenente la descrizione della classe della nostra finestra di dialogo;
- una variabile globale - l'oggetto classe della nostra finestra di dialogo;
- il codice per la creazione della finestra di dialogo, l'avvio dell'applicazione e la creazione del timer nel corpo della funzione OnInit();
- OnDeinit() contenente un codice che distrugge la finestra di dialogo e spegne il timer;
- la funzione OnChartEvent(...) al codice chiamante del gestore eventi;
- commenti.
Abbiamo l'indicatore pronto per l'uso:
//+------------------------------------------------------------------+ //| 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'indicatore nel modulo di cui sopra non mostra ancora nulla. Una volta compilato e rilasciato dal Navigatore sul grafico, verrà visualizzato come una finestra di dialogo vuota in una finestra separata.
Nonostante la finestra di dialogo sia vuota, il nostro indicatore ha già acquisito alcune funzionalità:
- l'altezza della sottofinestra è stata regolata all'altezza della finestra di dialogo dall'indicatore durante la creazione;
- la larghezza della finestra di dialogo è sempre uguale alla larghezza del grafico;
- l'indicatore può ridurre al minimo e ottimizzare la propria sottofinestra.
Lascia che si visualizzi
Affinché il nostro pannello inizi a visualizzare qualsiasi informazione, dovremmo decidere le risposte a tre domande:
- Che tipo di informazioni vogliamo visualizzare?
- Quali elementi di visualizzazione e/o controlli aggiuntivi devono essere inseriti nella nostra finestra di dialogo?
- Come interagiranno questi elementi/controlli aggiuntivi?
Un altro fattore importante è che la nostra finestra di dialogo deve essere visivamente accattivante e facile da usare. Non influisce sulla funzionalità della finestra di dialogo, ma mostra che ci preoccupiamo degli utenti del futuro programma MQL5.
Fase 1. Che tipo di informazioni vogliamo visualizzare?
Poiché l'articolo funge da strumento di apprendimento, non soffermiamoci sull'usabilità dell'indicatore. Il colore verrà visualizzato in funzione di tre parametri. Non complicheremo eccessivamente i parametri: questi saranno livelli "rosso", "verde" e "blu".
I valori dei parametri verranno impostati come segue:
- Il valore del livello "rosso" verrà impostato nell'intervallo da 0 a 255 cambiando in modo casuale ad ogni evento Calculate;
- Il valore del livello "verde" verrà impostato nell'intervallo da 0 a 255 cambiando in modo casuale ad ogni evento Timer;
- Il valore del livello "blu" verrà impostato nell'intervallo da 0 a 255 e verrà modificato manualmente mediante uno speciale controllo.
A tal proposito, i valori di questi livelli verranno visualizzati anche nel nostro indicatore.
Step 2. Quali controlli aggiuntivi saranno necessari?
Fase 3. Come interagiranno questi controlli di dialogo aggiuntivi?
- Il colore verrà visualizzato utilizzando il controllo "Pannello".
- I livelli "rosso" e "verde" verranno visualizzati utilizzando il controllo "Modifica" in modalità "Sola lettura".
- Il livello "blu" sarà gestito dal controllo "Spin Edit". Lo stesso controllo aiuterà a visualizzare il valore del livello.
- Entrambi i controlli "Edit" e "Spin Edit" verranno migliorati con didascalie esplicative tramite il controllo "Didascalia".
Aggiungere i file di include dalla Libreria Standard, nonché i controlli e le variabili necessari che memorizzano i valori dei parametri nella descrizione della classe dopo aver fornito i commenti.
Avremo:
//+------------------------------------------------------------------+ //| 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) { } //+------------------------------------------------------------------+
Il principio di interazione tra i controlli della finestra di dialogo sarà molto semplice: "La finestra di dialogo visualizzerà le modifiche in qualsiasi parametro (livelli "rosso", "verde" e "blu")". L'implementazione degli algoritmi di interazione verrà affrontata in seguito poiché ora è giunto il momento di iniziare a creare la finestra di dialogo.
Qualche parola sul richiamo visivo
Prima di procedere alla creazione della finestra di dialogo, cerchiamo di avere una rapida panoramica del richiamo visivo. O per meglio dire, un’organizzazione user-friendly e (possibile) futura riorganizzazione dei controlli delle finestre di dialogo. Le costanti denominate (#define) servono meglio a questo scopo.
Ci sono alcuni vantaggi offerti dalle costanti denominate predefinite:
- alcuni valori numerici utilizzati in casi specifici non devono essere ricordati. I nomi costanti accuratamente selezionati forniranno un rapido accesso ad essi tramite l’"Auto List Names";
- quando i valori costanti vengono ulteriormente modificati, non è necessario cercare e sostituire numerose inclusioni di valori numerici. È sufficiente modificare solo la descrizione della costante.
Si suggerisce l'uso delle seguenti costanti:
//+------------------------------------------------------------------+ //| 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
Riempimento del Pannello di Visualizzazione
In precedenza abbiamo creato la classe del pannello di visualizzazione;ora, per ottenere la funzionalità richiesta, dobbiamo fare quanto segue:
1. Ridefinire il metodo Create(...) della classe padre. Inizialmente, il nostro metodo apparirà come segue:
//+------------------------------------------------------------------+ //| 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. Creare controlli aggiuntivi.
Una leggera digressione poetica. I codici per la creazione di tutti i controlli aggiuntivi possono ovviamente essere inseriti direttamente nel corpo del metodo Create(...), ma in questo modo rischiamo di ottenere un grande "volume" illeggibile.
Divideremo quindi il processo di creazione in parti autonome rappresentate da metodi:
- bool CreateColor(void) - creazione di pannelli di colore,
- bool CreateRed(void) - creazione dell'elemento di visualizzazione "Red" con didascalia esplicativa,
- bool CreateGreen(void) - creazione dell'elemento di visualizzazione "Green" con didascalia esplicativa,
- bool CreateBlue(void) - creazione del controllo "Blue" con didascalia esplicativa.
Questi metodi vengono chiamati in sequenza dal metodo 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); }
Creazione di Controlli
Non esamineremo la creazione di ogni controllo aggiuntivo, ma daremo un'occhiata dettagliata al metodo bool CreateBlue(void).
È il seguente:
//+------------------------------------------------------------------+ //| 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); }
Ci sono due sfumature:
- Il controllo viene creato con le relative coordinate, ovvero l'offset viene impostato rispetto all'angolo in alto a sinistra del contenitore (elemento complesso) a cui verrà aggiunto il controllo dopo la creazione.
- Dopo la creazione, è necessario aggiungere il controllo a un contenitore utilizzando il metodo Add(...). Nel nostro caso, la finestra di dialogo funge da contenitore.
Modifica dei Parametri
Aggiungete il metodo void SetColor(void) per modificare il colore del pannello dei colori;
Per poter modificare i parametri (livelli dei colori di base) esternamente, aggiungeremo tre metodi pubblici:
- void SetRed(const int value) - cambia il livello "rosso" e visualizza il cambiamento nell'indicatore,
- void SetGreen(const int value) - cambia il livello "verde" e visualizza il cambiamento nell'indicatore,
- void SetBlue(const int value) - cambia il livello "blu" e visualizza la variazione nell'indicatore.
La frase "visualizza il cambiamento nell'indicatore" significa che il nuovo valore del livello di colore di base viene visualizzato nella forma numerica nel controllo corrispondente e il pannello dei colori cambia colore.
Di seguito, viene riportato un codice di uno dei metodi che fungono da esempio:
//+------------------------------------------------------------------+ //| 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(); }
Come concordato in precedenza:
- Il valore del livello "rosso" cambierà in modo casuale ad ogni evento Calculate;
- Il valore del livello "verde" cambierà in modo casuale ad ogni evento Timer;
Aggiungiamo il codice corrispondente nell'indicatore originale:
//+------------------------------------------------------------------+ //| 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); } //+------------------------------------------------------------------+
Gestione degli Eventi
L'intera interazione tra la finestra di dialogo e il Terminale, nonché l'interazione tra i controlli della finestra di dialogo si basa sul meccanismo event. Non esamineremo le sue funzioni, ma semplicemente lo useremo.
Gli eventi possono essere convenzionalmente suddivisi in due gruppi:
- Eventi interni gestiti ignorando la coda degli eventi del Terminale;
- Eventi esterni gestiti tramite la coda di eventi del Terminale.
Gestiremo entrambi i tipi di eventi.
Tra gli eventi interni, devono essere gestiti solo gli eventi di ridimensionamento della finestra di dialogo. A tale scopo, ricarica il metodo OnResize() della classe padre. Il nostro metodo sarà semplice in quanto non vi è alcun cambiamento nell'altezza della finestra di dialogo; se la larghezza della finestra di dialogo cambia, dobbiamo solo modificare la larghezza del pannello di colore:
//+------------------------------------------------------------------+ //| 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); }
Anche l'elenco degli eventi esterni sarà limitato a un elemento: l'evento di modifica del livello "blu". I requisiti per il gestore eventi esterno sono minimi: il gestore deve essere il metodo di classe senza parametri di tipo void.
Descriviamo il gestore di questo evento:
//+------------------------------------------------------------------+ //| 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(); }
Come si può vedere, non c'è nulla di difficile in esso.
Affinché la nostra finestra di dialogo gestisca eventi esterni, il metodo della classe padre deve essere ricaricato:
virtual bool OnEvent(const int id,const long &lparam, const double &dparam,const string &sparam);
E ora un po' di mistero. Se il file PanelDialog.mqh è già stato aperto nell'editor, si vedrà che non è presente alcun corpo del metodo OnEvent(...).
Non confonderti - il fatto è che, per la descrizione della gestione degli eventi esterni, è stato creato un set di macro (vedere <Controls\Defines.mqh> file nella Libreria Standard).
Il gestore eventi è il seguente:
//+------------------------------------------------------------------+ //| Handling events | //+------------------------------------------------------------------+ EVENT_MAP_BEGIN(CPanelDialog) ON_EVENT(ON_CHANGE,m_edit_blue,OnChangeBlue) EVENT_MAP_END(CAppDialog)
Questo pseudocodice, che potrebbe non essere chiaro a prima vista, fa quanto segue:
- Quando l'evento ON_CHANGE viene ricevuto dal controllo m_edit_blue, viene chiamato il metodo OnChangeBlue e la gestione dell'evento viene completata (restituendo true);
- Nel ricevere qualsiasi altro evento, il controllo viene trasferito al metodo della classe padre.
Conclusione
In questo articolo, è stata fornita la revisione del processo di creazione di un pannello di visualizzazione utilizzando le classi Libreria Standard.
È improbabile che utilizzi l'indicatore così come è stato creato, tuttavia non è sovraccarico di informazioni inutili e siamo riusciti a coprire quasi tutte le peculiarità del processo durante la sua creazione.
Esempi di consegna standard più complessi sono disponibili nelle seguenti directory del Terminale:
- Esperti\Esempi\Controlli\
- Indicatori\Esempi\Pannelli\ChartPanel\
- Indicators\Examples\Panels\SimplePanel\
Tradotto dal russo da MetaQuotes Ltd.
Articolo originale: https://www.mql5.com/ru/articles/345





- App di trading gratuite
- Oltre 8.000 segnali per il copy trading
- Notizie economiche per esplorare i mercati finanziari
Accetti la politica del sito e le condizioni d’uso