Grafische Interfaces IX: Das Farbauswahl Control (Kapitel 1)
Inhalt
Einleitung
Bitte lesen Sie dazu auch den ersten Artikel Grafische Interfaces I: Vorbereiten der Bibliotheks-Struktur (Kapitel 1), damit Sie die Anwendung dieser Bibliothek besser verstehen können. Am Ende dieses Artikels finden Sie eine Liste aller Kapitel mit den dazugehörigen Links und Sie können die vollständige Version dieser Bibliothek herunterladen. Die Dateien müssen in den gleichen Verzeichnissen untergebracht werden, so, wie Sie auch in dem Archiv abgelegt sind.
Der IX Teil Dieser Serie beschreibt die folgenden Elemente (Controls) und Interfaces:
1. Erstes Kapitel:
- Farbauswahl-Control (CColorPicker Klasse).
- Farb-Button-Control (CColorButton Klasse).
2. Zweites Kapitel:
- Fortschrittsanzeige-Control (CProgressBar Klasse).
- Linien-Graph-Control (CLineGraph Klasse).
Es werden umfassende Beispiele für alle oben genannten Controls aufgezeigt, so, wie sie auch in den benutzerdefinierten Anwendungen verwendet werden können.
Das Farbauswahl-Control
Eine Farbpalette findet man in sehr vielen Anwendungen, wo es die Möglichkeit geben soll, einem Objekt eine Farbe zuweisen zu können. In den Metatrader Trading-Terminals kann eine Farbpalette dazu verwendet werden, um ganz einfach die Farben von Controls innerhalb einer MQL Anwendung verändern zu können. Wenn Sie zum Beispiel die Möglichkeit bieten wollen, die grafische Oberfläche farbig anzupassen, dann wäre es sehr unbequem, dieses ohne ein solches Tool durchführen zu müssen.
Eine Farbauswahl-Palette ist ein sehr komplexes Control, welches aus verschiedenen Komponenten besteht. Außer der tatsächlichen Palette besitzt dieses Control auch noch andere Objekte und weitere Gruppen von Controls. Die Komponenten dieses Controls werden nachfolgend aufgelistet:
- Hintergrund
- Die Farbpaletten, die ein spezielles Farbmodell anzeigt
- Marker für die festgelegte Farbe
- Marker für die ausgewählte Farbe
- Marker für die Farbe, wenn sich der Mauszeiger über einem Objekt befindet
- Eine Gruppe von Radiobuttons mit Edit-Boxen für die manuelle Konfiguration der Farbkomponenten.
- Eine Button um die Auswahl einer Farbe abzubrechen
- Ein Button um die angegebene Farbe des zweiten Markers zu fixieren.
Abbildung 1. Komponenten des Controls für die Farbauswahl.
Der oben dargestellte Screenshot zeigt eine Gruppe von Radiobuttons, die in drei Untergruppen mit je drei Radiobuttons aufgeteilt ist. Jede Untergruppe stellt ein Farbmodell dar, und jeder Radiobutton ist eine Komponente dieses Modells (Koordinate des Farbbereichs). Die folgende Liste zeigt die Abkürzungen aller Farb-Modelle, die in der Bibliothek verwendet werden.
1. HSL Farbmodell:
- H - Farbton. Werte von 0 bis 360.
- S - Sättigung. Werte von 0 bis 100.
- L - Helligkeit (Lightness). Werte von 0 bis 100.
2. RGB Farbmodell:
- R - Rot. Werte von 0 bis 255.
- G - Grün. Werte von 0 bis 255.
- B - Blau. Werte von 0 bis 255.
3. Lab Farbmodell:
- L - Helligkeit (luminance). Werte von 0 bis 100.
- a – Die erste chromatische Koordinate, die die Farbe zwischen Grün und Lila definiert. Werte von 128 bis 127.
- b – Die zweite chromatische Koordinate, die die Farbe zwischen Blau und Gelb definiert. Werte von 128 bis 127.
Wir schauen uns nun für die Erzeugung einer Farbpalette die CColorPicker Klasse an.
Die Entwicklung der CColorPicker Klasse
Wir erzeugen die ColorPicker.mqh Datei in dem gleichen Verzeichnis in welchem auch alle anderen Controls abgespeichert sind (<data folder>\MQLX\Include\EasyAndFastGUI\Controls). In dieser Datei erzeugen wir die CColorPicker Klasse mit den Standardmethoden und Variablen, wie ist das nachfolgende Listing zeigt:
//+---------------------------------------------------------------- //| ColorPicker.mqh | //| Copyright 2015, MetaQuotes Software Corp. | //| http://www.mql5.com | //+---------------------------------------------------------------- #include "Element.mqh" #include "Window.mqh" //+---------------------------------------------------------------- //| Klasse für die Erzeugung des Controls für die Farbauswahl | //+---------------------------------------------------------------- class CColorPicker : public CElement { private: //--- Pointer zu dem Formular, zu welchem das Control hinzugefügt wurde CWindow *m_wnd; //--- public: CColorPicker(void); ~CColorPicker(void); //--- public: //--- Abspeichern des Pointers der Form void WindowPointer(CWindow &object) { m_wnd=::GetPointer(object); } //--- public: //--- Der Eventhandler für Chart-Events virtual void OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam); //--- Timer virtual void OnEventTimer(void); //--- Verschieben eines Controls virtual void Moving(const int x,const int y); //--- (1) Anzeigen, (2) verstecken, (3) zurücksetzen, (4) löschen virtual void Show(void); virtual void Hide(void); virtual void Reset(void); virtual void Delete(void); //--- (1) Setzen, (2) Zurücksetzen der Prioritäten der linken Maustaste virtual void SetZorders(void); virtual void ResetZorders(void); //--- Zurücksetzen der Farbe virtual void ResetColors(void) {} };
Die folgenden Eigenschaften sollten für das festlegen eines grafischen Objektes verfügbar sein:
- Control-Bereichsfarbe
- Die Rahmenfarbe des Bereiches des Controls
- Die Rahmenfarbe der Farbpalette und Marker
Die Eigenschaften von den grafischen Objekten anderer Controls können verändert werden, sobald wir die Pointer erhalten haben.
class CColorPicker : public CElement { private: //--- Farbe des (1) Bereiches und (2) des Rahmens color m_area_color; color m_area_border_color; //--- Farbe des Rahmens der Palette color m_palette_border_color; //--- public: //--- Setzen der Farbe (1) des Bereiches und (2) des Rahmens, (3) des Rahmens der Palette void AreaBackColor(const color clr) { m_area_color=clr; } void AreaBorderColor(const color clr) { m_area_border_color=clr; } void PaletteBorderColor(const color clr) { m_palette_border_color=clr; } };
Da wir in diesem Control auch andere Controls als Komponenten der Farbpalette benutzen, müssen wir die Dateien mit den entsprechenden Klassen dieser Controls der ColorPicker.mqh Datei hinzufügen. Für die Erzeugung der Farbpalette, benötigen wir 17 private Methoden und eine public Methode.
//+---------------------------------------------------------------- //| ColorPicker.mqh | //| Copyright 2015, MetaQuotes Software Corp. | //| http://www.mql5.com | //+---------------------------------------------------------------- #include "Element.mqh" #include "Window.mqh" #include "SpinEdit.mqh" #include "SimpleButton.mqh" #include "RadioButtons.mqh" //+---------------------------------------------------------------- //| Klasse für die Erzeugung der Farbpalette | //+---------------------------------------------------------------- class CColorPicker : public CElement { private: //--- Objekte für die Erzeugung des Controls CRectLabel m_area; CRectCanvas m_canvas; CRectLabel m_current; CRectLabel m_picked; CRectLabel m_hover; //--- CRadioButtons m_radio_buttons; CSpinEdit m_hsl_h_edit; CSpinEdit m_hsl_s_edit; CSpinEdit m_hsl_l_edit; //--- CSpinEdit m_rgb_r_edit; CSpinEdit m_rgb_g_edit; CSpinEdit m_rgb_b_edit; //--- CSpinEdit m_lab_l_edit; CSpinEdit m_lab_a_edit; CSpinEdit m_lab_b_edit; //--- CSimpleButton m_button_ok; CSimpleButton m_button_cancel; //--- public: //--- Methoden für die Erzeugung des Controls bool CreateColorPicker(const long chart_id,const int subwin,const int x,const int y); //--- private: bool CreateArea(void); bool CreatePalette(void); bool CreateCurrentSample(void); bool CreatePickedSample(void); bool CreateHoverSample(void); bool CreateRadioButtons(void); bool CreateHslHEdit(void); bool CreateHslSEdit(void); bool CreateHslLEdit(void); bool CreateRgbREdit(void); bool CreateRgbGEdit(void); bool CreateRgbBEdit(void); bool CreateLabLEdit(void); bool CreateLabAEdit(void); bool CreateLabBEdit(void); bool CreateButtonOK(const string text); bool CreateButtonCancel(const string text); };
Wenn Sie einen der Radio-Buttons neben der Farbpalette ändern, dann werden zweidimensionale Schnitte von Farbflächen, in Übereinstimmung mit den angegebenen Werten, einer ausgewählten Komponente angezeigt. Mit anderen Worten, für das Zeichnen eines Schnitts müssen wir zunächst eine Berechnung in Bezug auf den aktuellen Wert der Komponente durchführen. Hierfür schreiben wir drei separate Methoden für jedes Farbmodell. Der Index des ausgewählten Radiobuttons wird allen diesen Methoden übergeben(selected index).
Für den Farbwechsel verwenden wir Methoden der Klasse CColors die in der Basisklasse der Controls deklariert ist.(CElement). Es gibt aber in der CColors Klasse keine passende Methode um eine Konvertierung von dem RGB Format zu dem Lab-Format durchzuführen. Daher müssen wir an der Stelle, wo eine Konvertierung von RGB->Lab benötigt wird, eine doppelte Korrektur über das Master-FarbmodellXYZ hinzufügen: RGB->XYZ->Lab. Für die Berechnung und das Abspeichern der Werte der Komponenten aller Farbmodelle innerhalb der CColorPicker Klasse, benötigen wir die Deklaration von weiteren Variablen.
class CColorPicker : public CElement { private: //--- Werte der Komponenten in den unterschiedlichen Farbmodellen: // HSL double m_hsl_h; double m_hsl_s; double m_hsl_l; //--- RGB double m_rgb_r; double m_rgb_g; double m_rgb_b; //--- Lab double m_lab_l; double m_lab_a; double m_lab_b; //--- XYZ double m_xyz_x; double m_xyz_y; double m_xyz_z; //--- private: //--- Zeichnen der Palette basierend auf dem HSL Farbmodell (0: H, 1: S, 2: L) void DrawHSL(const int index); //--- Zeichnen der Palette basierend auf dem RGB-Farbmodell (3: R, 4: G, 5: B) void DrawRGB(const int index); //--- Zeichnen der Palette basierend auf dem LAB Farbmodell (6: L, 7: a, 8: b) void DrawLab(const int index); };
Wir zeigen hier beispielhaft nur den Programmcode von einer dieser Methoden CColorPicker::DrawHSL(), da der einzige Unterschied in der vorläufigen Berechnung vor der Änderung zu finden ist. Der Programmcode der anderen Methoden kann über die an diesen Artikel angehängten Dateien heruntergeladen werden.
Die Berechnungen und das Zeichnen werden für jeden Pixel durchgeführt. Bitte beachten Sie, dass die Berechnungen relativ zu der Größe der Farbpalette durchgeführt werden. Zum Beispiel können sie unter Verwendung dieses Programmcodes auch ein ähnliches Control mit einer Farbpalette, die eine andere Form hat, erzeugen. (Sie muss nicht unbedingt ein Quadrat sein).
Abbildung 2. Ein Beispiel einer Farbpalette mit der Größe von 500x255 Pixeln.
//+---------------------------------------------------------------- //| Zeichnen der HSL-Palette | //+---------------------------------------------------------------- void CColorPicker::DrawHSL(const int index) { switch(index) { //--- Hue (H) - Der Farbton mit Werten von 0 bis 360 case 0 : { //--- Berechnung der H-Komponente m_hsl_h=m_hsl_h_edit.GetValue()/360.0; //--- for(int ly=0; ly<m_canvas.YSize(); ly++) { //--- Berechnung der L-Komponente m_hsl_l=ly/(double)m_canvas.YSize(); //--- for(int lx=0; lx<m_canvas.XSize(); lx++) { //--- Berechnung der S-Komponente m_hsl_s=lx/(double)m_canvas.XSize(); //--- Konvertierung von HSL zu RGB m_clr.HSLtoRGB(m_hsl_h,m_hsl_s,m_hsl_l,m_rgb_r,m_rgb_g,m_rgb_b); //--- Verbinden der Kanäle uint rgb_color=XRGB(m_rgb_r,m_rgb_g,m_rgb_b); m_canvas.PixelSet(lx,m_canvas.YSize()-ly,rgb_color); } } break; } //--- Sättigung(S) - Sättigung mit den Werten von 0 bis 100 case 1 : { //--- Berechnung der S-Komponente m_hsl_s=m_hsl_s_edit.GetValue()/100.0; //--- for(int ly=0; ly<m_canvas.YSize(); ly++) { //--- Berechnung der L-Komponente m_hsl_l=ly/(double)m_canvas.YSize(); //--- for(int lx=0; lx<m_canvas.XSize(); lx++) { //--- Berechnung der H-Komponente m_hsl_h=lx/(double)m_canvas.XSize(); //--- Konvertierung von HSL zu RGB m_clr.HSLtoRGB(m_hsl_h,m_hsl_s,m_hsl_l,m_rgb_r,m_rgb_g,m_rgb_b); //--- Verbinden der Kanäle uint rgb_color=XRGB(m_rgb_r,m_rgb_g,m_rgb_b); m_canvas.PixelSet(lx,m_canvas.YSize()-ly,rgb_color); } } break; } //--- Helligkeit (Lightness) (L) - Helligkeit mit den Werten von 0 bis 100 case 2 : { //--- Berechnung der L-Komponente m_hsl_l=m_hsl_l_edit.GetValue()/100.0; //--- for(int ly=0; ly<m_canvas.YSize(); ly++) { //--- Berechnung der S-Komponente m_hsl_s=ly/(double)m_canvas.YSize(); //--- for(int lx=0; lx<m_canvas.XSize(); lx++) { //--- Berechnung der H-Komponente m_hsl_h=lx/(double)m_canvas.XSize(); //--- Konvertierung von HSL zu RGB m_clr.HSLtoRGB(m_hsl_h,m_hsl_s,m_hsl_l,m_rgb_r,m_rgb_g,m_rgb_b); //--- Verbinden der Kanäle uint rgb_color=XRGB(m_rgb_r,m_rgb_g,m_rgb_b); m_canvas.PixelSet(lx,m_canvas.YSize()-ly,rgb_color); } } break; } } }
Um einen Rahmen um das Canvas der Farbpalette zeichnen zu können, schreiben wir die CColorPicker::DrawPaletteBorder() Methode:
class CColorPicker : public CElement { private: //--- Zeichnen des Rahmens der Platte void DrawPaletteBorder(void); }; //+---------------------------------------------------------------- //| Zeichnen des Rahmens der Palette | //+---------------------------------------------------------------- void CColorPicker::DrawPaletteBorder(void) { //--- Größe der Palette int x_size=m_canvas.XSize()-1; int y_size=m_canvas.YSize()-1; //--- Zeichnen des Rahmens m_canvas.Line(0,0,x_size,0,m_palette_border_color); m_canvas.Line(0,y_size,x_size,y_size,m_palette_border_color); m_canvas.Line(0,0,0,y_size,m_palette_border_color); m_canvas.Line(x_size,0,x_size,y_size,m_palette_border_color); }
Alle oben aufgeführten Methoden werden in der Hauptmethode für das Zeichnen, der CColorPicker::DrawPalette() Methode aufgerufen.
class CColorPicker : public CElement { private: //--- Zeichnen der Palette void DrawPalette(const int index); }; //+---------------------------------------------------------------- //| Zeichnen der Palette | //+---------------------------------------------------------------- void CColorPicker::DrawPalette(const int index) { switch(index) { //--- HSL (0: H, 1: S, 2: L) case 0 : case 1 : case 2 : { DrawHSL(index); break; } //--- RGB (3: R, 4: G, 5: B) case 3 : case 4 : case 5 : { DrawRGB(index); break; } //--- LAB (6: L, 7: a, 8: b) case 6 : case 7 : case 8 : { DrawLab(index); break; } } //--- Zeichnen des Rahmens der Palette DrawPaletteBorder(); //--- Aktualisieren der Palette m_canvas.Update(); }
Wenn eine Farbe aus der Palette ausgewählt wird oder eine zu konfigurierende Komponente in dem Control dargestellt wird, werden die Werte aller Edit-Boxen automatisch neu berechnet. Wir benötigen Methoden, die die Komponenten aller Farbmodelle eines Controls berechnen können unter Berücksichtigung des Controls, dessen Schnitt grade auf der Palette dargestellt wird.
Zunächst brauchen wir Methoden für die Korrektur der RGB Komponenten und HSL Modelle, die in vielen anderen Methoden dieser Klasse benötigt werden:
class CColorPicker : public CElement { private: //--- Korrektur der RGB Komponenten void AdjustmentComponentRGB(void); //--- Korrektur der HSL Komponenten void AdjustmentComponentHSL(void); }; //+---------------------------------------------------------------- //| Korrektur der RGB Komponenten | //+---------------------------------------------------------------- void CColorPicker::AdjustmentComponentRGB(void) { m_rgb_r=::fmin(::fmax(m_rgb_r,0),255); m_rgb_g=::fmin(::fmax(m_rgb_g,0),255); m_rgb_b=::fmin(::fmax(m_rgb_b,0),255); } //+---------------------------------------------------------------- //| Korrektur der HSL Komponenten | //+---------------------------------------------------------------- void CColorPicker::AdjustmentComponentHSL(void) { m_hsl_h*=360; m_hsl_s*=100; m_hsl_l*=100; }
Nach der Berechnung aller Komponenten, müssen wir neue Werte in die Edit-Boxen schreiben. In einigen Fällen müssen wir (1) die Werte aller Komponenten, und manchmal die Werte (2) für alle außer der aktuell selektierten Komponente setzen. Für diese Situationen werden wir die CColorPicker::SetControls() Methode schreiben, die in zwei Modi arbeiten kann.
class CColorPicker : public CElement { private: //--- Setzen der aktuellen Parameter in den Edit-Boxen void SetControls(const int index,const bool fix_selected); }; //+---------------------------------------------------------------- //| Setzen der aktuellen Parameter in den Edit-Boxen | //+---------------------------------------------------------------- void CColorPicker::SetControls(const int index,const bool fix_selected) { //--- Falls ein Wert in einer Editbox des ausgewählten Radio-Buttons fixiert werden muss if(fix_selected) { //--- HSL components if(index!=0) m_hsl_h_edit.ChangeValue(m_hsl_h); if(index!=1) m_hsl_s_edit.ChangeValue(m_hsl_s); if(index!=2) m_hsl_l_edit.ChangeValue(m_hsl_l); //--- RGB Komponenten if(index!=3) m_rgb_r_edit.ChangeValue(m_rgb_r); if(index!=4) m_rgb_g_edit.ChangeValue(m_rgb_g); if(index!=5) m_rgb_b_edit.ChangeValue(m_rgb_b); //--- Lab Komponenten if(index!=6) m_lab_l_edit.ChangeValue(m_lab_l); if(index!=7) m_lab_a_edit.ChangeValue(m_lab_a); if(index!=8) m_lab_b_edit.ChangeValue(m_lab_b); return; } //--- Falls es notwendig ist, alle Werte aller Edith Boxen von allen Farbmodellen zu korrigieren m_hsl_h_edit.ChangeValue(m_hsl_h); m_hsl_s_edit.ChangeValue(m_hsl_s); m_hsl_l_edit.ChangeValue(m_hsl_l); //--- m_rgb_r_edit.ChangeValue(m_rgb_r); m_rgb_g_edit.ChangeValue(m_rgb_g); m_rgb_b_edit.ChangeValue(m_rgb_b); //--- m_lab_l_edit.ChangeValue(m_lab_l); m_lab_a_edit.ChangeValue(m_lab_a); m_lab_b_edit.ChangeValue(m_lab_b); }
Für die Berechnung aller Komponenten aller Farbmodelle des Controls, dessen Schnitt gerade auf der Palette dargestellt wird, schreiben wir drei unterschiedliche Methoden: CColorPicker::SetHSL(), CColorPicker::SetRGB() und CColorPicker::SetLab(). Da sich diese Methoden sehr ähnlich sind, werden wir hier nur die — CColorPicker::SetRGB() Methode besprechen. Am Anfang der Methode, fragen wir die Werte der Edit-Boxen des RGB Modells ab. Die Werte werden dann nach HSLund Lab konvertiert. Am Ende rufen wir die CColorPicker::SetControls() Methode in dem Modus für das Setzen der Werte für alle Farbmodelle mit dem false Control.
class CColorPicker : public CElement { private: //--- Setzen der Parameter der Farbmodelle relativ zu (1) HSL, (2) RGB, (3) Lab void SetHSL(void); void SetRGB(void); void SetLab(void); }; //+---------------------------------------------------------------- //| Setzen der Parameter der Farbmodelle relativ zu RGB | //+---------------------------------------------------------------- void CColorPicker::SetRGB(void) { //--- Abfrage der aktuellen Werte der RGB Komponenten m_rgb_r=m_rgb_r_edit.GetValue(); m_rgb_g=m_rgb_g_edit.GetValue(); m_rgb_b=m_rgb_b_edit.GetValue(); //--- Konvertierung der RGB Komponenten zu HSL Komponenten m_clr.RGBtoHSL(m_rgb_r,m_rgb_g,m_rgb_b,m_hsl_h,m_hsl_s,m_hsl_l); //--- Korrektur der HSL Komponenten AdjustmentComponentHSL(); //--- Konvertierung der RGB Komponenten zu LAB Komponenten m_clr.RGBtoXYZ(m_rgb_r,m_rgb_g,m_rgb_b,m_xyz_x,m_xyz_y,m_xyz_z); m_clr.XYZtoCIELab(m_xyz_x,m_xyz_y,m_xyz_z,m_lab_l,m_lab_a,m_lab_b); //--- Setzen der aktuellen Parameter in den Edit-Boxen SetControls(0,false); }
Zum Schluss benötigen wir noch eine Hauptmethode, in welcher alle oben genannten Methoden für die Berechnung, das Zeichnen und das Setzen der Werte der Komponenten durchgeführt wird. Wir nennen sie CColorPicker::SetComponents(). Sie arbeitet auch in zwei Modi. Falls das fix_selected Argument gleich true ist, dann werden die Komponenten relativ zu der ausgewählten Farbe berechnet, und die Werte in der Editbox werden relativ zu dem ausgewählten Radiobutton der Komponente gesetzt. Wenn das fix_selected Argument gleich false ist, dann wird die Berechnung relativ zu dem ausgewählten Farbmodell durchgeführt. Nach den ganzen Berechnungen, wird die Farbpalette neu gezeichnet.
class CColorPicker : public CElement { private: //--- Berechnen und setzen der Farbkomponenten void SetComponents(const int index,const bool fix_selected); }; //+---------------------------------------------------------------- //| Berechnen und setzen der Farbkomponenten | //+---------------------------------------------------------------- void CColorPicker::SetComponents(const int index=0,const bool fix_selected=true) { //--- Falls es gewünscht ist, die Farben relativ zu dem ausgewählten Radiobutton einer Komponente zu korrigieren if(fix_selected) { //--- Zerlegen der gewählten Farbe in RGB Komponenten m_rgb_r=m_clr.GetR(m_picked_color); m_rgb_g=m_clr.GetG(m_picked_color); m_rgb_b=m_clr.GetB(m_picked_color); //--- Konvertierung der RGB Komponenten zu HSL Komponenten m_clr.RGBtoHSL(m_rgb_r,m_rgb_g,m_rgb_b,m_hsl_h,m_hsl_s,m_hsl_l); //--- Korrektur der HSL Komponenten AdjustmentComponentHSL(); //--- Konvertierung der RGB Komponenten zu LAB Komponenten m_clr.RGBtoXYZ(m_rgb_r,m_rgb_g,m_rgb_b,m_xyz_x,m_xyz_y,m_xyz_z); m_clr.XYZtoCIELab(m_xyz_x,m_xyz_y,m_xyz_z,m_lab_l,m_lab_a,m_lab_b); //--- Setzen der Farben in den Edit-Boxen SetControls(m_radio_buttons.SelectedButtonIndex(),true); return; } //--- Festlegen der Parameter des Farbmodells switch(index) { case 0 : case 1 : case 2 : SetHSL(); break; case 3 : case 4 : case 5 : SetRGB(); break; case 6 : case 7 : case 8 : SetLab(); break; } //--- Zeichnen der Palette relativ zu dem ausgewählten Radiobutton DrawPalette(m_radio_buttons.SelectedButtonIndex()); }
Um einem Marker Objekt die aktuell ausgewählte Farbe der Farbpalette zuweisen zu können, schreiben wir die, CColorPicker::CurrentColor() Methode. Im weiteren Verlauf des Artikels werden wir zeigen wo sie verwendet wird.
class CColorPicker : public CElement { public: //--- Setzen einer vom Anwender ausgewählten Farbe aus der Palette void CurrentColor(const color clr); }; //+---------------------------------------------------------------- //| Setzen der aktuellen Farbe | //+---------------------------------------------------------------- void CColorPicker::CurrentColor(const color clr) { m_hover_color=clr; m_hover.Color(clr); m_hover.BackColor(clr); m_hover.Tooltip(::ColorToString(clr)); //--- m_picked_color=clr; m_picked.Color(clr); m_picked.BackColor(clr); m_picked.Tooltip(::ColorToString(clr)); //--- m_current_color=clr; m_current.BackColor(clr); m_current.Tooltip(::ColorToString(clr)); }
Alle Methoden für die Berechnungen sind nun fertig. Wir werden jetzt mit den Methoden für die Verarbeitung von Events fortfahren.
Methoden für die Verarbeitung der Events des Controls
Die folgenden Methoden werden für die Verarbeitung von Events und das Verwalten der Farbpalette benötigt:
- Die CColorPicker::OnHoverColor() Methode — Abfrage der Farbe (über der Palette) am Mauszeiger. Das Programm verlässt diese Methode, falls sich der Mauszeiger außerhalb des Bereiches der Palette befindet. Wenn sich der Mauszeiger über der Palette befindet, dann definieren wir die Koordinaten und fragen die Farbe an der Position des Mauszeigers ab. Anschließend wird die ausgewählte Farbe dem selektierten Marker zugewiesen und mit der ColorToString() Methode, bekommen die grafischen Objekte des Markers und der Farbpalette einen Tooltip – einen String mit der Farbe in dem RGB-Format.
//+---------------------------------------------------------------- //| Abfrage der Farbe am Mauszeiger | //+---------------------------------------------------------------- bool CColorPicker::OnHoverColor(const int x,const int y) { //--- Abbrechen, falls ich den Mauszeiger nicht über der Palette befindet if(!m_canvas.MouseFocus()) return(false); //--- Definition der Farbe der Palette am Mauszeiger int lx =x-m_canvas.X(); int ly =y-m_canvas.Y(); m_hover_color=(color)::ColorToARGB(m_canvas.PixelGet(lx,ly),0); //--- Setzen der Farbe und des Tooltips am ausgewählten Marker m_hover.Color(m_hover_color); m_hover.BackColor(m_hover_color); m_hover.Tooltip(::ColorToString(m_hover_color)); //--- Setzen des Tooltips für die Palette m_canvas.Tooltip(::ColorToString(m_hover_color)); return(true); }
- Die CColorPicker::OnClickPalette() Methode — Verarbeitet einen Klick auf die Farbpalette. Zu Beginn der Methode wird der Objektname überprüft. Falls ein Klick auf der Palette stattgefunden hat, dann wird die Farbe am Mauszeiger und ein Tooltip für den ausgewählten Marker gespeichert und gesetzt. Am Ende wird die CColorPicker::SetComponents() Methode für die Berechnung und Einstellung der Komponenten der Farbmodelle, relativ zu dem ausgewählten Radiobutton der Komponente, aufgerufen.
//+---------------------------------------------------------------- //| Verarbeiten eines Klicks auf die Farbpalette | //+---------------------------------------------------------------- bool CColorPicker::OnClickPalette(const string clicked_object) { //--- Abbrechen, falls der Objektname nicht übereinstimmt if(clicked_object!=m_canvas.Name()) return(false); //--- Setzen der Farbe und des Tooltips am ausgewählten Marker m_picked_color=m_hover_color; m_picked.Color(m_picked_color); m_picked.BackColor(m_picked_color); m_picked.Tooltip(::ColorToString(m_picked_color)); //--- Berechnen und setzen der Farbkomponenten relativ zu dem ausgewählten Radiobutton SetComponents(); return(true); }
- Die CColorPicker::OnClickRadioButton() Methode behandelt einen Klick auf einen Radiobutton. Zunächst müssen zwei Überprüfungen vorgenommen werden: (1) Der Bezeichner des Elementes und (2) der dargestellte Text des Radiobuttons. Wenn diese Überprüfungen erfolgreich waren, dann wird die Farbpalette neu gezeichnet (relativ zu der selektierten Komponente des Farbmodells, zu welchem sie gehört)
//+---------------------------------------------------------------- //| Verarbeiten eines Klicks auf den Radiobutton | //+---------------------------------------------------------------- bool CColorPicker::OnClickRadioButton(const long id,const int button_index,const string button_text) { //--- Abbrechen, falls die Bezeichner nicht übereinstimmen if(id!=CElement::Id()) return(false); //--- Abbrechen, falls der Text des Radiobuttons nicht überein stimmt if(button_text!=m_radio_buttons.SelectedButtonText()) return(false); //--- Aktualisierung der Palette unter Berücksichtigung der letzten Veränderungen DrawPalette(button_index); return(true); }
- Die CColorPicker::OnEndEdit() Methode behandelt die Eingabe eines neuen Wertes in die Editbox. Hier ist eine einfache Überprüfung des Bezeichners ausreichend und anschließend werden die Komponenten aller Farbmodelle berechnet(Relativ zu der einen, die den selektierten Radio-Button besitzt.)
//+---------------------------------------------------------------- //| Verarbeitung der Eingabe eines neuen Wertes in eine EditBox | //+---------------------------------------------------------------- bool CColorPicker::OnEndEdit(const long id,const int button_index) { //--- Abbrechen, falls die Bezeichner nicht übereinstimmen if(id!=CElement::Id()) return(false); //--- Berechnen und setzen aller Farbkomponenten für alle Farbmodelle SetComponents(button_index,false); return(true); }
- Die CColorPicker::OnClickButtonOK() Methode behandelt einen Klick auf den 'OK' Button. Dieses ist nicht die endgültige Version dieser Methode. Sie wird später in dem Artikel noch geändert. Das einzige, was wir zur Zeit nur wissen müssen ist, dass in dem Moment wo auf den Button geklickt wird, die ausgewählte Farbe als aktuelle Farbe abgespeichert wird.
//+---------------------------------------------------------------- //| Verarbeitung eines Klicks auf den OK-Button | //+---------------------------------------------------------------- bool CColorPicker::OnClickButtonOK(const string clicked_object) { //--- Abbrechen, falls der Objektname nicht übereinstimmt if(clicked_object!=m_button_ok.Text()) return(false); //--- Abspeichern der selektierten Farbe m_current_color=m_picked_color; m_current.BackColor(m_current_color); m_current.Tooltip(::ColorToString(m_current_color)); return(true); }
- Die CColorPicker::OnClickButtonCancel() Methode verarbeitet einen Klick auf den 'Cancel' Button. Es gibt hier nur eine Überprüfung des Objektnamens. Anschließend, falls das Formular, zu welchem das Control hinzugefügt worden ist vom Typ 'Dialogfenster' ist, wird es geschlossen.
//+---------------------------------------------------------------- //| Verarbeitung eines Klicks auf den 'Cancel' Button | //+---------------------------------------------------------------- bool CColorPicker::OnClickButtonCancel(const string clicked_object) { //--- Abbrechen, falls der Objektname nicht übereinstimmt if(clicked_object!=m_button_cancel.Text()) return(false); //--- Schließe das Fenster, falls es sich um ein Dialogfenster handelt if(m_wnd.WindowType()==W_DIALOG) m_wnd.CloseDialogBox(); //--- return(true); }
In dem Eventhandler der CColorPicker::OnEvent() Farbpalette gibt es sechs Blöcke. Jede der oben aufgeführten Methoden wird bei dem Eintreffen des zugehörigen Bezeichners aufgerufen. Der gesamte Programmcode des Eventhandlers wird in dem nachfolgenden Listing gezeigt:
//+---------------------------------------------------------------- //| Eventhandler der Chart-Events | //+---------------------------------------------------------------- void CColorPicker::OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam) { //--- Verarbeiten der Events von Mausbewegungen if(id==CHARTEVENT_MOUSE_MOVE) { //--- Abbrechen, falls das Control versteckt ist if(!CElement::IsVisible()) return; //--- Koordinaten und der Status der linken Maustaste int x=(int)lparam; int y=(int)dparam; m_mouse_state=(bool)int(sparam); CElement::MouseFocus(x>X() && x<X2() && y>Y() && y<Y2()); m_canvas.MouseFocus(x>m_canvas.X() && x<m_canvas.X2()-1 && y>m_canvas.Y() && y<m_canvas.Y2()-1); //--- Abfrage der Farbe am Mauszeiger if(OnHoverColor(x,y)) return; //--- return; } //--- Verarbeitung eines Klicks mit der linken Maustaste auf ein Objekt if(id==CHARTEVENT_OBJECT_CLICK) { //--- Falls auf die Farbpalette geklickt wurde if(OnClickPalette(sparam)) return; //--- return; } //--- Verarbeiten einer Eingabe eines Wertes in eine EditBox if(id==CHARTEVENT_CUSTOM+ON_END_EDIT) { //--- Überprüfung des neuen Wertes if(OnEndEdit(lparam,(int)dparam)) return; //--- return; } //--- Verarbeiten eines Klicks auf ein Control if(id==CHARTEVENT_CUSTOM+ON_CLICK_LABEL) { //--- Falls auf ein Radiobutton geklickt wurde if(OnClickRadioButton(lparam,(int)dparam,sparam)) return; //--- return; } //--- Verarbeiten eines Klicks auf die Schalter von EditBoxen if(id==CHARTEVENT_CUSTOM+ON_CLICK_INC || id==CHARTEVENT_CUSTOM+ON_CLICK_DEC) { //--- Überprüfung des neuen Wertes if(OnEndEdit(lparam,(int)dparam)) return; //--- return; } //--- Verarbeiten eines Klicks auf den Control-Button if(id==CHARTEVENT_CUSTOM+ON_CLICK_BUTTON) { //--- Abbrechen, falls die Bezeichner nicht übereinstimmen if(lparam!=CElement::Id()) return; //--- Falls auf "OK" geklickt wurde if(OnClickButtonOK(sparam)) return; //--- Falls auf "CANCEL" geklickt wurde if(OnClickButtonCancel(sparam)) return; //--- return; } }
Viele Controls der Bibliothek besitzen die FastSwitching() Methode. Diese wird normalerweise für das schnelle verändern von Werten in EditBoxen, Scrollbars oder Listen von Tabellen verwendet. Hier wird sie dazu verwendet, um die Farbpalette neu zu zeichnen, falls ein schnelles Verändern des Zählers einer EditBox aktiviert wurde. Den Programmcode der CColorPicker::FastSwitching() Methode finden Sie in den Dateien, die diesem Artikel beigefügt sind.
Farbiger Button
Die Klasse für die Erzeugung der Farbpalette ist fertig, aber ein Element für die vollständige Nutzung fehlt noch. Wir benötigen noch einen Button, der dazu verwendet wird, das Fenster mit der Farbpalette aufzurufen. Der Button sollte die Möglichkeit besitzen, das aktuelle Farbschema sichtbar zu machen. Wir werden jetzt für einen solchen Button eine Klasse schreiben. Die nachfolgende Liste zeigt die Komponenten dieses Buttons
- Bereich des Controls
- Textlabel mit einer Beschreibung
- Der Indikator für die ausgewählte Farbe
- Der Bereich des Buttons
- Die Beschreibung der ausgewählten Farbe im RGB Format
Abbildung 3. Die Komponenten des Buttons für den Aufruf der Farbpalette.
Wir sind bereits in den vorangegangenen Artikeln auf ähnliche Controls eingegangen. Daher werden wir hier keine weitere Beschreibung dieser Klasse aufführen. Stattdessen werden wir mit der Interaktion zwischen dem Button und der Farbpalette weitermachen. Sehen Sie sich dazu die ColorButton.mqh Datei mit der CColorButton Klasse an, um mehr darüber zu lernen.
Wir müssen nun die Farbpalette mit dem Button verbinden, damit sie aufgerufen werden kann. Wir machen dieses mithilfe des Button-Pointers, welcher in der CColorPicker Klasse abgespeichert ist. Dafür verbinden wir die ColorButton.mqh Date mit der ColorPicker.mqh Datei und deklarieren eine CColorButton Klasse, in welcher der Pointer zu dem Button abgespeichert wird.
//+---------------------------------------------------------------- //| ColorPicker.mqh | //| Copyright 2015, MetaQuotes Software Corp. | //| http://www.mql5.com | //+---------------------------------------------------------------- #include "Element.mqh" #include "Window.mqh" #include "SpinEdit.mqh" #include "SimpleButton.mqh" #include "RadioButtons.mqh" #include "ColorButton.mqh" //+---------------------------------------------------------------- //| Klasse für die Erzeugung des Controls für die Farbauswahl | //+---------------------------------------------------------------- class CColorPicker : public CElement { private: //--- Der Pointer zu dem Button, der das Control für die Farbauswahl aufruft CColorButton *m_color_button; };
Dazu benötigen wir noch eine öffentliche Methode. Um die Interaktion zwischen dem Button und der Farbpalette einfacher gestalten zu können, werden allen Markern der Palette die aktuelle Farbe des Buttons zugewiesen, währen der Pointer abgespeichert wird. Anschließend wird ein Fenster mit der Farbpalette geöffnet. Sehen Sie sich dazu das nachfolgende Programmbeispiel an.
class CColorPicker : public CElement { public: //--- Abspeichern des Pointers von dem Button, der die Farbpalette aufgerufen hat void ColorButtonPointer(CColorButton &object); }; //+---------------------------------------------------------------- //| Abspeichern des Pointers von dem Button, der die Farbpalette aufgerufen hat | //| Öffnen des Fensters, zu welchem die Palette gehört | //+---------------------------------------------------------------- void CColorPicker::ColorButtonPointer(CColorButton &object) { //--- Pointer des Buttons abspeichern m_color_button=::GetPointer(object); //--- Allen Marken der Palette die Farbe des Buttons zuweisen CurrentColor(object.CurrentColor()); //--- Öffnen des Fensters, zu welchem die Palette gehört m_wnd.Show(); }
Hierzu benötigen wir noch Methoden, um die Farbe des Buttons abzufragen und zu setzen. Die festgelegte Farbe erscheint auf dem Marker des Buttons und als zusätzliche Informationen enthält der Text des Buttons einen String der die Farbe in dem RGB Format darstellt.
class CColorButton : public CElement { public: //--- Abfrage und setzen der aktuellen Farbe der Parameter color CurrentColor(void) const { return(m_current_color); } void CurrentColor(const color clr); }; //+---------------------------------------------------------------- //| Verändern der aktuellen Farbe des Parameters | //+---------------------------------------------------------------- void CColorButton::CurrentColor(const color clr) { m_current_color=clr; m_button_icon.BackColor(clr); m_button_label.Description(::ColorToString(clr)); }
Und jetzt noch eine kleine Erweiterung in der CColorPicker::OnClickButtonOK() Methode. Wenn ein Pointer zu dem Button gesetzt wurde, dann:
- Dann wird die von der Palette ausgewählte Farbe auf dem Button gezeigt;
- Das Fenster, zu welchem die Farbpalette gehört, kann nun geschlossen werden
- Eine Nachricht wird generiert, dass eine neue Farbe aus der Palette gewählt wurde. Hierfür benötigen wir in der Defines.mqh Datei einen neuen Event-Bezeichner ON_CHANGE_COLOR. Diese Nachricht beinhaltet zudem (1) Control-Bezeichner (2) Element-Index und(3) Den Text des Buttons der die Palette aufgerufen hat. Auf diese Weise sind wir in der Lage zu verstehen, welcher Button mit dem Event gemeint ist und das wird uns später helfen, das Event korrekt zu verarbeiten.
- Der Pointer zu dem Button wird zurückgesetzt.
Wenn es keinen Pointer zu einem Button gibt, dann wird für den Entwickler eine Nachricht mit einem Tooltip und im Log gezeigt.
//+---------------------------------------------------------------- //| Verarbeitung eines Klicks auf den OK-Button | //+---------------------------------------------------------------- bool CColorPicker::OnClickButtonOK(const string clicked_object) { //--- Abbrechen, falls der Objektname nicht übereinstimmt if(clicked_object!=m_button_ok.Text()) return(false); //--- Abspeichern der selektierten Farbe m_current_color=m_picked_color; m_current.BackColor(m_current_color); m_current.Tooltip(::ColorToString(m_current_color)); //--- Wenn es einen Pointer zu einem Button gibt if(::CheckPointer(m_color_button)!=POINTER_INVALID) { //--- Lege die ausgewählte Farbe für den Button fest m_color_button.CurrentColor(m_current_color); //--- Schließe das Fenster m_wnd.CloseDialogBox(); //--- Eine Nachricht darüber senden ::EventChartCustom(m_chart_id,ON_CHANGE_COLOR,CElement::Id(),CElement::Index(),m_color_button.LabelText()); //--- Setze die Pointer zurück m_color_button=NULL; } else { //--- Falls es sich um ein Dialogfenster handelt und es keinen Pointer gibt, // ...dann zeige eine Nachricht, dass es keinen Pointer zu dem Button gibt, der das Control aufgerufen hat if(m_wnd.WindowType()==W_DIALOG) ::Print(__FUNCTION__," > Non-valid pointer of calling control (CColorButton)."); } //--- return(true); }
Nun ist alles für einen Test der Farbpalette bereit
Test der Controls
Sie können irgendeinen Expert Advisor auf den vorangegangenen Artikeln dafür verwenden. Machen Sie von diesem eine Kopie und behalten sie nur das Hauptmenü und den Status-String In dem Hauptfenster (W_MAIN) des grafischen Interfaces erzeugen wir fünf Buttons für den Aufruf des Dialogfensters (W_DIALOG) mit der Farbpalette. Mit anderen Worten, es reicht aus, nur eine Farbpalette für die gesamte MQL Anwendung zu erzeugen. Jedes Mal wenn ein Button für den Aufruf eines Dialogfensters mit einer Farbpalette geklickt wird, wird das selbe Fenster geöffnet. Aber der Pointer des Buttons muss während des Aufrufs der CColorPicker Klasse übergeben werden. Dieses Implementation zeigen wir später in der benutzerdefinierten Klasse der Anwendung.
In der benutzerdefinierten Klasse mit dem Namen CProgram benötigen wir die Deklaration von Klassen für die Erzeugung von zusätzlichen Fenstern(CWindow), fünf Buttons für den Aufruf der Farbpaletten CColorButton und CColorPicker, und zudem Methoden für deren Erzeugung mit Abständen von dem aüßersten Punkt des Formulars.
class CProgram : public CWndEvents { private: //--- Form 2 - Fenster mit der Farbpalette für die Farbauswahl CWindow m_window2; //--- Buttons für den Aufruf des Fensters mit der Farbpalette CColorButton m_color_button1; CColorButton m_color_button2; CColorButton m_color_button3; CColorButton m_color_button4; CColorButton m_color_button5; //--- Farbpalette CColorPicker m_color_picker; //--- private: //--- Form 2 bool CreateWindow2(const string text); //--- Buttons für den Aufruf der Palette #define COLORBUTTON1_GAP_X (7) #define COLORBUTTON1_GAP_Y (50) bool CreateColorButton1(const string text); #define COLORBUTTON2_GAP_X (7) #define COLORBUTTON2_GAP_Y (75) bool CreateColorButton2(const string text); #define COLORBUTTON3_GAP_X (7) #define COLORBUTTON3_GAP_Y (100) bool CreateColorButton3(const string text); #define COLORBUTTON4_GAP_X (7) #define COLORBUTTON4_GAP_Y (125) bool CreateColorButton4(const string text); #define COLORBUTTON5_GAP_X (7) #define COLORBUTTON5_GAP_Y (150) bool CreateColorButton5(const string text); //--- Farbpalette #define COLORPICKER_GAP_X (1) #define COLORPICKER_GAP_Y (20) bool CreateColorPicker(void); };
Die Methoden für die Erzeugung der Buttons für den Aufruf der Farbpalette sind fast alle identisch, und daher werden wir hier nur das Beispiel für einen Button zeigen. Ein Unterschied liegt lediglich bei dem Festlegen der anfänglichen Farbe, die in dem Indikator des Buttons dargestellt wird und in dem Text der Beschreibung.
//+---------------------------------------------------------------- //| Erzeugung des Buttons für den Aufruf der Farbpalette 1 | //+---------------------------------------------------------------- bool CProgram::CreateColorButton1(const string text) { //--- Abspeichern des Pointers des Fensters m_color_button1.WindowPointer(m_window1); //--- Koordinaten int x=m_window1.X()+COLORBUTTON1_GAP_X; int y=m_window1.Y()+COLORBUTTON1_GAP_Y; //--- Festlegen der Eigenschaften vor der Erzeugung m_color_button1.XSize(195); m_color_button1.YSize(18); m_color_button1.ButtonXSize(100); m_color_button1.ButtonYSize(18); m_color_button1.AreaColor(clrWhiteSmoke); m_color_button1.LabelColor(clrBlack); m_color_button1.BackColor(C'220,220,220'); m_color_button1.BorderColor(clrSilver); m_color_button1.CurrentColor(clrRed); //--- Erzeugen des Elementes if(!m_color_button1.CreateColorButton(m_chart_id,m_subwin,text,x,y)) return(false); //--- Den Pointer zum Control in der Basis hinzufügen CWndContainer::AddToElementsArray(0,m_color_button1); return(true); }
Der Programmcode für die Erzeugung des Formulars des Dialogfensters für die Farbpalette unterscheidet sich von dem Hauptfenster nur durch die Festlegung des Fenstertyps (W_DIALOG). Zusätzlich legen wir noch ein, eindeutiges Bild für dieses Fenster fest, dass seinen Verwendungszweck verdeutlicht. Alle hier verwendeten Bilder finden Sie am Ende des Artikels.
//+---------------------------------------------------------------- //| Erzeugen des Formulars 2 für die Farbpalette | //+---------------------------------------------------------------- #resource "\\Images\\EasyAndFastGUI\\Icons\\bmp16\\color_picker.bmp" //--- bool CProgram::CreateWindow2(const string caption_text) { //--- Abspeichern des Pointers des Fensters CWndContainer::AddWindow(m_window2); //--- Koordinaten int x=(m_window2.X()>0) ? m_window2.X() : 30; int y=(m_window2.Y()>0) ? m_window2.Y() : 30; //--- Eigenschaften m_window2.Movable(true); m_window2.XSize(350); m_window2.YSize(286); m_window2.WindowType(W_DIALOG); m_window2.WindowBgColor(clrWhiteSmoke); m_window2.WindowBorderColor(clrLightSteelBlue); m_window2.CaptionBgColor(clrLightSteelBlue); m_window2.CaptionBgColorHover(clrLightSteelBlue); m_window2.IconFile("Images\\EasyAndFastGUI\\Icons\\bmp16\\color_picker.bmp"); //--- Erzeugen der Form if(!m_window2.CreateWindow(m_chart_id,m_subwin,caption_text,x,y)) return(false); //--- return(true); }
Das nachfolgende Listing beinhaltet den Programmcode der CProgram::CreateColorPicker() Methode für die Erzeugung der Farbpalette. Es ist wichtig, den Pointer des Dialogfensters abzuspeichern, zu welchem ein Control hinzugefügt wird. Wenn ein Pointer eines Controls zu der Basis der Controls hinzugefügt wird, muss der Index des Fensters, zu welchem das Element hinzugefügt werden muss, gesendet werden. In unserem Fall ist das der Index des Dialogfensters [1].
//+---------------------------------------------------------------- //| Erzeugen der Farbpalette für die Farbwahl | //+---------------------------------------------------------------- bool CProgram::CreateColorPicker(void) { //--- Abspeichern des Pointers des Fensters m_color_picker.WindowPointer(m_window2); //--- Koordinaten int x=m_window2.X()+COLORPICKER_GAP_X; int y=m_window2.Y()+COLORPICKER_GAP_Y; //--- Erzeugung des Controls if(!m_color_picker.CreateColorPicker(m_chart_id,m_subwin,x,y)) return(false); //--- Den Pointer zum Control in der Basis hinzufügen CWndContainer::AddToElementsArray(1,m_color_picker); return(true); }
Wir müssen sicherstellen, dass wenn auf den Button geklickt wird, sein Pointer auch der Farbpalette übergeben wird. Dieses könnten wir in dem Eventhandler der benutzerdefinierten Klasse CProgram::OnEvent() erledigen. Wenn auf einen Button geklickt wird, dann wird eine Nachricht mit dem ON_CLICK_BUTTON Eventbezeichner generiert. Die Nachricht beinhaltet zudem den Text der Beschreibung des Buttons der dazu verwendet wird festzustellen, welches Objekt vom Typ CColorButton der Farbpalette gesendet werden muss. Direkt nach dem Senden des Objektes des Buttons, wird ein Fenster mit der Farbpalette geöffnet und alle Marker erhalten die Farbe des Objektes, welches gerade gesendet worden ist. Dieses wird mit den nachfolgenden Programmlisting demonstriert:
//+---------------------------------------------------------------- //| Event handler | //+---------------------------------------------------------------- void CProgram::OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam) { //--- Button click event if(id==CHARTEVENT_CUSTOM+ON_CLICK_BUTTON) { //--- Falls Button 1 geklickt wurde if(sparam==m_color_button1.LabelText()) { m_color_picker.ColorButtonPointer(m_color_button1); return; } //--- Falls Button 2 geklickt wurde if(sparam==m_color_button2.LabelText()) { m_color_picker.ColorButtonPointer(m_color_button2); return; } //--- Falls Button 3 geklickt wurde if(sparam==m_color_button3.LabelText()) { m_color_picker.ColorButtonPointer(m_color_button3); return; } //--- Falls Button 4 geklickt wurde if(sparam==m_color_button4.LabelText()) { m_color_picker.ColorButtonPointer(m_color_button4); return; } //--- Falls Button 5 geklickt wurde if(sparam==m_color_button5.LabelText()) { m_color_picker.ColorButtonPointer(m_color_button5); return; } } }
Nachdem die Farbauswahl durch einen Klick auf den "ОК" Button der Farbpalette bestätigt wurde, wird eine Nachricht mit dem ON_CHANGE_COLOR Bezeichner verarbeitet:
void CProgram::OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam) { //--- Event über die Veränderung einer Farbe unter Verwendung der Farbpalette if(id==CHARTEVENT_CUSTOM+ON_CHANGE_COLOR) { //---Wenn die Bezeichnung der Controls übereinstimmen if(lparam==m_color_picker.Id()) { //--- Falls die Antwort von Button 1 ist if(sparam==m_color_button1.LabelText()) { //--- Ändere die Farbe des Objektes die zu dem Button1 gehört... return; } //--- Falls die Antwort von Button 2 ist if(sparam==m_color_button2.LabelText()) { //--- Ändere die Farbe des Objektes die zu dem Button 2 gehört... return; } //--- Falls die Antwort von Button 3 ist if(sparam==m_color_button3.LabelText()) { //--- Ändere die Farbe des Objektes die zu dem Button 3 gehört... return; } //--- Falls die Antwort von Button 4 ist if(sparam==m_color_button4.LabelText()) { //--- Ändere die Farbe des Objektes die zu dem Button 4 gehört... return; } //--- Falls die Antwort von Button 5 ist if(sparam==m_color_button5.LabelText()) { //--- Ändere die Farbe des Objektes die zu dem Button 5 gehört... return; } } return; } }
Kompilieren Sie dieses Programm und laden Sie es auf einen Chart. Das Ergebnis zeigt der nachfolgende Screenshot:
Abbildung 4. Test der Buttons für den Aufruf der Farbpalette
Durch einen Klick auf einer der fünf Buttons, die in dem Hauptfenster gezeigt werden, öffnet sich das Fenster mit der Farbauswahl:
Abbildung 5. Test des Farbauswahl-Elementes
Nun funktioniert alles wie geplant.
Schlussfolgerung
In diesem Artikel haben wir ein komplexes Control, welches aus verschiedenen Komponenten besteht, präsentiert. (Erstes Kapitel des 9. Teils dieser Serie der Artikel). Als zusätzliches Control haben wir einen speziellen Button für den Aufruf der Farbpalette generiert. Nun haben die Anwender der hier entwickelten Bibliothek die Möglichkeit, die Farben von Objekten über die Verwendung eines grafischen Interfaces innerhalb einer MQL Anwendung zu verändern.
Die folgenden Artikel beinhalten Beschreibungen für Klassen von weiteren Controls, wie zum Beispiel die Fortschrittsanzeige und den Linienchart.
Unterhalb dieses Artikels finden Sie das gesamte Material, welches sie herunterladen können, um ist auf Ihrem PC zu testen. Wenn Sie fragen zur Verwendung dieses Materials haben, dann können Sie zunächst auf die detaillierte Beschreibung in dem Artikel zu dieser Bibliothek zurückgreifen oder Sie stellen Ihre Frage(n) in den Kommentaren zu diesem Artikel.
Liste der Artikel (Kapitel) des neunten Teils:
- Grafische Interfaces IX: Das Farbauswahl Control (Kapitel 1)
- Grafische Interfaces IX: Die Fortschrittsanzeige und das Linienchart-Control(Kapitel 2)
Übersetzt aus dem Russischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/ru/articles/2579
- Freie Handelsapplikationen
- Über 8.000 Signale zum Kopieren
- Wirtschaftsnachrichten für die Lage an den Finanzmärkte
Sie stimmen der Website-Richtlinie und den Nutzungsbedingungen zu.