
Grafische Interfaces VI: Die Slider und Dual-Slider Controls (Kapitel 2)
Inhalt
Einleitung
Der erste Artikel Grafisches Interface I: Vorbereiten der Bibliotheksstruktur (Kapitel 1) Beschreibt im Detail wofür diese Bibliothek gedacht ist. Am Ende von jedem Kapitel, finden Sie eine vollständige Liste mit Links zu diesem Artikel. Zudem finden Sie dort eine Möglichkeit das Projekt, entsprechend dem aktuellen Entwicklungsstand, herunterzuladen. Die Dateien müssen in den gleichen Verzeichnissen untergebracht werden, so, wie Sie auch in dem Archiv abgelegt sind.
In dem vorherigen Artikel haben wir unsere Bibliothek um die vier sehr häufig verwendeten Controls: Checkbox, Edit, Edit mit Checkbox und Check-Combobox erweitert. Das zweite Kapitel des sechsten Teils widmet sich den Slider (Schieberegler) und Dual-Slider Controls.
Das Slider Control
Ein Slider ist eine Art Edit-Control, welches eine Bandbreite, die durch ein Minimum und ein Maximum festgelegt wird, besitzt. Anders als bei den Edit Control, welches wir in dem vorherigen Artikel genau besprochen haben, besitzt ein Slider keine Buttons, um Werte zu verändern. Dafür gibt es hier eine Linie, die zu diesem Zwecke verschoben werden kann. Ein solches Interface-Element ist dann sinnvoll, wenn man nur ungefähre Werte innerhalb einer bestimmten Spanne eingeben will und ein exakter wird nicht unbedingt notwendig ist. Aber es gibt immer noch die Möglichkeit einen genauen Wert manuell einzugeben.
Dieses Element wird aus sechs grafischen Objekten zusammengebaut. Diese sind:
- Hintergrund
- Caption (text label)
- Eingabefeld
- Slider-Linie
- Slider-Läufer
- Slider Indikator
Abbildung 1. Komponenten des Slider-Controls
Lassen Sie uns diese Klasse im Detail studieren.
Entwickeln einer Klasse für die Erzeugung eines Slider Controls
Erzeugen Sie die Slider.mqh Dateien beziehen Sie diese in der WndContainer.mqh Datei mit ein:
//+------------------------------------------------------------------+ //| WndContainer.mqh | //| Copyright 2015, MetaQuotes Software Corp. | //| http://www.mql5.com | //+------------------------------------------------------------------+ #include "Slider.mqh"
Erzeugen sie in der Slider.mqh Datei die CSlider Klasse mit den Standards Methoden, die in allen Controls dieser Bibliothek enthalten sein müssen. Zudem beziehen sie noch die Dateien Element.mqh und Window.mqh, und die SeparateLine.mqh Datei mit der CSeparateLine Klasse für das Erzeugen einer Trennlinie mit ein. Die CSeparateLine Klasse haben wir bereits in dem Artikel Graphische Interfaces II: Die Trennlinie und Kontextmenü Elemente (Kapitel 2) besprochen Weshalb wir hier nicht weiter darauf eingehen. Das einzige, worauf ich noch eben hinweisen möchte, ist, dass wenn eine Höhe von größer als 2 Pixeln angegeben wird, es einen Leerraum zwischen den beiden gezeichneten Linien gibt. Optisch sieht es aus wie ein Schatten, was für eine Slider-Linie auch geeignet ist (slit or slot) in welchem sich der Slider-Runner bewegt..
//+------------------------------------------------------------------+ //| Slider.mqh | //| Copyright 2015, MetaQuotes Software Corp. | //| http://www.mql5.com | //+------------------------------------------------------------------+ #include "Element.mqh" #include "Window.mqh" #include "SeparateLine.mqh" //+------------------------------------------------------------------+ //| Klasse für das Erzeugen eines Sliders | //+------------------------------------------------------------------+ class CSlider : public CElement { private: //--- Ein Pointer zu der Form zu welchem das Element hinzugefügt worden ist CWindow *m_wnd; public: CSlider(void); ~CSlider(void); //--- public: //--- Speichert den Pointer void WindowPointer(CWindow &object) { m_wnd=::GetPointer(object); } //--- public: //--- Chart Eventhandler virtual void OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam); //--- Timer virtual void OnEventTimer(void); //--- Bewegen des Elementes 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) Set, (2) reset priorities of the left mouse button press virtual void SetZorders(void); virtual void ResetZorders(void); //--- Zurücksetzen der Farbe virtual void ResetColors(void); };
Der Anwender der Bibliothek sollte die Möglichkeit haben, sämtliche Eigenschaften aller Objekte, die in diesem Control verwendet werden, einstellen zu können. Diese Eigenschaften werden nachfolgend aufgelistet.
- Farbe des Hintergrundes des Elementes
- Text für die Beschreibung des Sliders
- Die Farben für das Textlabel für die unterschiedlichen Zustände
- Der aktuelle Wert in dem Eingabefeld
- Die Größe des Eingabefeldes
- Die Farben des Eingabefeldes in den unterschiedlichen Zuständen
- Die Farbe des Textes in dem Eingabefeld in den unterschiedlichen Zuständen
- Die Farbe des Rahmens von dem Eingabefeld in den unterschiedlichen Zuständen
- Größe des Schlitzes längs der y-Achse (Höhe)
- Farbe der Linien für den Schlitz
- Farbe des Slider Indikators in den unterschiedlichen Zuständen
- Die Größe des Slider Läufers
- Die Farbe des Läufers des Sliders
- Prioritäten für einen Klick mit der linken Maustaste
Nachfolgend finden Sie den Programmcode der Klasse mit den Variablen und Methoden für die Elementeigenschaften, die wir oben aufgezählt haben:
class CSlider : public CElement { private: //--- Farbe des Element-Hintergrundes color m_area_color; //--- Text für eine Beschreibung des Sliders string m_label_text; //--- Die Farben für das Textlabel für die unterschiedlichen Zustände color m_label_color; color m_label_color_hover; color m_label_color_locked; color m_label_color_array[]; //--- Die Größe des Eingabefeldes int m_edit_x_size; int m_edit_y_size; //--- Die Farbe des Eingabefeldes in den unterschiedlichen Zuständen color m_edit_color; color m_edit_color_locked; //--- Die Farbe des Textes des Eingabefeldes in den unterschiedlichen Zuständen color m_edit_text_color; color m_edit_text_color_locked; //--- Die Farbe des Rahmens des Eingabefeldes in den unterschiedlichen Zuständen color m_edit_border_color; color m_edit_border_color_hover; color m_edit_border_color_locked; color m_edit_border_color_array[]; //--- Die Größe des Schlitzes int m_slot_y_size; //--- Die Farbe des Schlitzes color m_slot_line_dark_color; color m_slot_line_light_color; //--- Die Farbe des Indikators in unterschiedlichen Zuständen color m_slot_indicator_color; color m_slot_indicator_color_locked; //--- Die Größe des Läufers int m_thumb_x_size; int m_thumb_y_size; //--- Die Farbe des Läufers des Sliders color m_thumb_color; color m_thumb_color_hover; color m_thumb_color_locked; color m_thumb_color_pressed; //--- Priorität für die linke Maustaste int m_zorder; int m_area_zorder; int m_edit_zorder; //--- public: //--- (1) Hintergrundfarbe, (2) Die Farbe des Text-Labels void AreaColor(const color clr) { m_area_color=clr; } void LabelColor(const color clr) { m_label_color=clr; } void LabelColorHover(const color clr) { m_label_color_hover=clr; } void LabelColorLocked(const color clr) { m_label_color_locked=clr; } //--- Größe des (1) Eingabefeldes und (2) des Schlitzes void EditXSize(const int x_size) { m_edit_x_size=x_size; } void EditYSize(const int y_size) { m_edit_y_size=y_size; } void SlotYSize(const int y_size) { m_slot_y_size=y_size; } //--- Die Farbe des Eingabefeldes in den unterschiedlichen Zuständen void EditColor(const color clr) { m_edit_color=clr; } void EditColorLocked(const color clr) { m_edit_color_locked=clr; } //--- Die Farbe des Textes des Eingabefeldes in den unterschiedlichen Zuständen void EditTextColor(const color clr) { m_edit_text_color=clr; } void EditTextColorLocked(const color clr) { m_edit_text_color_locked=clr; } //--- Die Farbe des Rahmens des Eingabefeldes in den unterschiedlichen Zuständen void EditBorderColor(const color clr) { m_edit_border_color=clr; } void EditBorderColorHover(const color clr) { m_edit_border_color_hover=clr; } void EditBorderColorLocked(const color clr) { m_edit_border_color_locked=clr; } //--- (1) Dunkle und (2) Helle Farbe der Trennlinie (Schlitz) void SlotLineDarkColor(const color clr) { m_slot_line_dark_color=clr; } void SlotLineLightColor(const color clr) { m_slot_line_light_color=clr; } //--- Die Farbe des leider Indikators in den unterschiedlichen Zuständen void SlotIndicatorColor(const color clr) { m_slot_indicator_color=clr; } void SlotIndicatorColorLocked(const color clr) { m_slot_indicator_color_locked=clr; } //--- Die Größe des Läufers void ThumbXSize(const int x_size) { m_thumb_x_size=x_size; } void ThumbYSize(const int y_size) { m_thumb_y_size=y_size; } //--- Die Farbe des Läufers des Sliders void ThumbColor(const color clr) { m_thumb_color=clr; } void ThumbColorHover(const color clr) { m_thumb_color_hover=clr; } void ThumbColorLocked(const color clr) { m_thumb_color_locked=clr; } void ThumbColorPressed(const color clr) { m_thumb_color_pressed=clr; } };
Die Eigenschaften auf der vorherigen Liste beziehen sich hauptsächlich auf die Farbe und die Größe der Elemente. Die Eigenschaften, die sich auf die Spanne und das Eingabefeld beziehen, bilden eine separate Gruppe. Diese Eigenschaften sind:
- Minimaler Wert
- Maximaler wert
- Schritt für die Veränderungen des Wertes in dem Eingabefeld
- Der Modus für die Text-Ausrichtung
- Die Anzahl der Nachkommastellen
class CSlider : public CElement { private: //--- (1) Minimum und (2) Maximum Wert, (3) Schrittweite für die Veränderung des Wertes double m_min_value; double m_max_value; double m_step_value; //--- Anzahl der Nachkommastellen int m_digits; //--- Modus der Textausrichtung ENUM_ALIGN_MODE m_align_mode; //--- public: //--- Minimum-Wert double MinValue(void) const { return(m_min_value); } void MinValue(const double value) { m_min_value=value; } //--- Maximum-Wert double MaxValue(void) const { return(m_max_value); } void MaxValue(const double value) { m_max_value=value; } //--- Schrittweite für die Veränderung des Wertes double StepValue(void) const { return(m_step_value); } void StepValue(const double value) { m_step_value=(value<=0)? 1 : value; } //--- (1) Anzahl der Nachkommastellen, (2) Modus der Textausrichtung void SetDigits(const int digits) { m_digits=::fabs(digits); } void AlignMode(ENUM_ALIGN_MODE mode) { m_align_mode=mode; } };
Um den aktuellen Wert abzufragen, sowie ihn einzustellen und einen neuen Wert in das Eingabefeld einzugeben, verwenden wir die Methoden CSlider::GetValue(), CSlider::SetValue() und CSlider::ChangeValue():
class CSlider : public CElement { private: //--- Aktueller Wert in dem Eingabefeld double m_edit_value; //--- public: //--- Abfragen und Setzen des Wertes in dem Eingabefeld double GetValue(void) const { return(m_edit_value); } bool SetValue(const double value); //--- Verändern des Wertes in dem Eingabefeld void ChangeValue(const double value); }; //+------------------------------------------------------------------+ //| Setzen des aktuellen Wertes | //+------------------------------------------------------------------+ bool CSlider::SetValue(const double value) { //--- Für die Einstellungen double corrected_value=0.0; //--- Einstellung unter Berücksichtigung der Schrittweite corrected_value=::MathRound(value/m_step_value)*m_step_value; //--- Überprüfung auf Minimum/Maximum if(corrected_value<=m_min_value) corrected_value=m_min_value; if(corrected_value>=m_max_value) corrected_value=m_max_value; //--- Falls sich der Wert geändert hat if(m_edit_value!=corrected_value) { m_edit_value=corrected_value; return(true); } //--- Wert ist unverändert return(false); } //+------------------------------------------------------------------+ //| Verändern des Wertes in dem Eingabefeld | //+------------------------------------------------------------------+ void CSlider::ChangeValue(const double value) { //--- Überprüfen, Einstellen und Abspeichern des neuen Wertes SetValue(value); //--- Setzen des neuen Wertes in dem Eingabefeld m_edit.Description(::DoubleToString(GetValue(),m_digits)); }
Wenn sich der Kleider bewegt, dann muss der Wert in dem Eingabefeld in Abhängigkeit zu der X Koordinate berechnet werden. Wenn der Wert manuell eingegeben wird, dann muss die X Koordinate des Slider Läufers in Relation zu dem neuen Wert berechnet werden. Mit anderen Worten, bei der Entwicklung muss die Möglichkeit einer inversen Transformation berücksichtigt werden.
Für die korrekte Berechnung, benötigen wir noch weitere Variablen in der Klasse, die für die Berechnung verwendet wird. Diese Variablen müssen nur einmalig berechnet werden, wenn das Element erzeugt wird. Nachfolgend nun die Beschreibung dieser Variablen:
- Die Anzahl der Pixel in dem Arbeitsbereich (m_pixels_total).
- Die anzahl der Schritte (Spanne) in dem Arbeitsbereich (m_value_steps_total).
- Schrittweite in Relation zu der Breite des Arbeitsbereichs (m_position_step).
Lassen Sie uns eine Methode für die Berechnung dieser Werte entwickeln. Wir nennen sie CSlider::CalculateCoefficients() nennen:
class CSlider : public CElement { private: //--- Anzahl der Pixel im Arbeitsbereich int m_pixels_total; //--- Anzahl der Schritte im Arbeitsbereich int m_value_steps_total; //--- Schrittweite der transformierten Breite des Arbeitsbereichs double m_position_step; //--- private: //--- Berechnung der Werte (Schritte und Koeffizienten) bool CalculateCoefficients(void); }; //+------------------------------------------------------------------+ //| Berechnung der Werte (Schritte und Koeffizienten) | //+------------------------------------------------------------------+ bool CSlider::CalculateCoefficients(void) { //--- Abbrechen, falls die Breite des Elementes kleiner als die Breite des Slider-Läufers ist if(CElement::XSize()<m_thumb_x_size) return(false); //--- Anzahl der Pixel im Arbeitsbereich m_pixels_total=CElement::XSize()-m_thumb_x_size; //--- Die Anzahl der schritte in der Werte-Spanne des Arbeitsbereichs m_value_steps_total=int((m_max_value-m_min_value)/m_step_value); //--- Schritt in Relation zu der Breite des Arbeitsbereichs m_position_step=m_step_value*(double(m_value_steps_total)/double(m_pixels_total)); return(true); }
Jetzt können die oben aufgelisteten Werte der Variablen für die Berechnung der X Koordinate des Slider Läufers in Relation zu dem Wert in dem Eingabefeld und auch umgekehrt berechnet werden. Lassen Sie uns dafür zwei separate Methoden schreiben CSlider::CalculateThumbX() und CSlider::CalculateThumbPos().
Zu Beginn der CSlider::CalculateThumbX() Methode, berechnen wir die Werte der externe lokalen variable (neg_range) für Einstellungen, falls der Wert des Minimums negativ ist. Anschließen berechnen wir die X Koordinate für den Slider-Läufer. Anschließen, falls die Linie des Sliders überschritten wird, wird der Wert angepasst. Am Ende der Methode wird ein neuer Wert für die X Koordinate für den Slider Läufer und die Abstände von der Ecke des Formulars, zu welchen dieses Element hinzugefügt wurde, berechnet.
Ganz am Anfang der CSlider::CalculateThumbPos() Methode, erhalten wir die Position des Slider Läufers aus der Werte-Spanne. Anschließend wird eine Einstellung vorgenommen, falls der Wert des Minimums negativ ist und der Wert der m_current_pos_x Variable korrekt ist. Danach, wird eine Korrektur des Wertes vorgenommen, falls der Arbeitsbereich überschritten wurde.
class CSlider : public CElement { private: //--- Die aktuelle Position des Slider-Läufers: (1) Wert, (2) Die x-Koordinate double m_current_pos; double m_current_pos_x; //--- private: //--- Die Berechnung der x-Koordinate des Slider-Läufers void CalculateThumbX(void); //--- Verändert die aktuelle Position des Slider-Läufers in Relation zu dem aktuellen Wert void CalculateThumbPos(void); }; //+------------------------------------------------------------------+ //| Berechnung der x-Koordinate des Slider-Läufers | //+------------------------------------------------------------------+ void CSlider::CalculateThumbX(void) { //--- Anpassung unter der Berücksichtigung, dass der Minimum-Wert auch negativ sein kann double neg_range=(m_min_value<0)? ::fabs(m_min_value/m_position_step) : 0; //--- Berechnung der X Koordinate für den Slider-Läufer m_current_pos_x=m_area.X()+(m_edit_value/m_position_step)+neg_range; //--- Falls der Arbeitsbereich nach links überschritten wurde if(m_current_pos_x<m_area.X()) m_current_pos_x=m_area.X(); //--- Falls der Arbeitsbereich nach rechts überschritten wurde if(m_current_pos_x+m_thumb.XSize()>m_area.X2()) m_current_pos_x=m_area.X2()-m_thumb.XSize(); //--- Abspeichern und Setzen der neuen X Koordinaten m_thumb.X(int(m_current_pos_x)); m_thumb.X_Distance(int(m_current_pos_x)); m_thumb.XGap(m_thumb.X()-m_wnd.X()); } //+------------------------------------------------------------------+ //| Berechnung der Position des Slider Läufers in der Werte-Spanne | //+------------------------------------------------------------------+ void CSlider::CalculateThumbPos(void) { //--- Die Positionsnummer des Slider-Läufers abfragen m_current_pos=(m_thumb.X()-m_area.X())*m_position_step; //--- Anpassung unter der Berücksichtigung, dass der Minimum-Wert auch negativ sein kann if(m_min_value<0 && m_current_pos_x!=WRONG_VALUE) m_current_pos+=int(m_min_value); //--- Überprüfen auf Verlassen des Arbeitsbereichs nach links oder rechts if(m_thumb.X2()>=m_area.X2()) m_current_pos=int(m_max_value); if(m_thumb.X()<=m_area.X()) m_current_pos=int(m_min_value); }
Während der Slider Läufer bewegt wird, muss die Breite des Slider-Indikators berechnet und aktualisiert werden. Die rechte Seite des Slider-Indikators muss an die Slider-Läufer gebunden werden. Lassen Sie uns dafür die CSlider::UpdateIndicator() Methode schreiben:
class CSlider : public CElement { private: //--- Aktualisierung des Slider-Indikators void UpdateIndicator(void); }; //+------------------------------------------------------------------+ //| Aktualisierung des Slider-Indikators | //+------------------------------------------------------------------+ void CSlider::UpdateIndicator(void) { //--- Berechnung der Größe int x_size=m_thumb.X()-m_indicator.X(); //--- Anpassung im Falle eines ungültigen Wertes if(x_size<=0) x_size=1; //--- Setzen der neuen Größe m_indicator.X_Size(x_size); }
Um das Slider-Control erzeugen zu können, benötigen wir sechs private und eine public Methode.
class CSlider : public CElement { public: //--- Methoden für die Erzeugung des Controls bool CreateSlider(const long chart_id,const int subwin,const string text,const int x,const int y); //--- private: bool CreateArea(void); bool CreateLabel(void); bool CreateEdit(void); bool CreateSlot(void); bool CreateIndicator(void); bool CreateThumb(void); };
Wir werden hier nur den Programmcode der CSlider::CreateThumb() Methode besprechen, weil alle anderen Methoden für die Berechnung bereits besprochen wurden. Die anderen Methoden beinhalten nichts, was wir nicht schon in den vorherigen Artikeln besprochen haben.
//+------------------------------------------------------------------+ //| Erzeugt den Slider-Läufer | //+------------------------------------------------------------------+ bool CSlider::CreateThumb(void) { //--- Den Objektnamen bilden string name=CElement::ProgramName()+"_slider_thumb_"+(string)CElement::Id(); //--- Koordinaten int x=CElement::X(); int y=m_slot.Y()-((m_thumb_y_size-m_slot_y_size)/2); //--- Setzen des Objektes if(!m_thumb.Create(m_chart_id,name,m_subwin,x,y,m_thumb_x_size,m_thumb_y_size)) return(false); //--- Setzen der Eigenschaften m_thumb.Color(m_thumb_color); m_thumb.BackColor(m_thumb_color); m_thumb.BorderType(BORDER_FLAT); m_thumb.Corner(m_corner); m_thumb.Selectable(false); m_thumb.Z_Order(m_zorder); m_thumb.Tooltip("\n"); //--- Abspeichern der Größe (In dem Objekt) m_thumb.XSize(m_thumb.X_Size()); m_thumb.YSize(m_thumb.Y_Size()); //--- Abspeichern der Koordinaten m_thumb.X(x); m_thumb.Y(y); //--- Ränder von den Kanten m_thumb.XGap(x-m_wnd.X()); m_thumb.YGap(y-m_wnd.Y()); //--- Berechnung der Werte der Hilfs-Variablen CalculateCoefficients(); //--- Berechnung der x-Koordinate des Slider-Läufers in Relation zu dem aktuellen Wert in dem Eingabefeld CalculateThumbX(); //--- Berechnung der Slider-Läufer-Position in der Werte Spanne CalculateThumbPos(); //--- Aktualisierung des Slider-Indikators UpdateIndicator(); //--- Abspeichern des Objekt-Pointers CElement::AddToArray(m_thumb); return(true); }
Die Methoden für das Bewegen des Slider-Läufers, sind identisch mit den gleichnamigen Methoden in den CScroll und CScrollH Klassen, welche in dem Artikel Grafische Interfaces V: Die horizontale und vertikale Scrollbar (Kapitel 1) besprochen wurden. Aus diesem Grunde gehen wir hier auf den Code nicht weiter ein. Wir deklarieren ihn nur in dem Körper der CSlider Klasse.
class CSlider : public CElement { private: //--- Status der Maustaste (Gedrückt/nicht gedrückt) ENUM_THUMB_MOUSE_STATE m_clamping_area_mouse; //--- Für die Identifikation des Modus des leider Läufers bool m_slider_thumb_state; //--- Variablen in Zusammenhang mit der Bewegung des Slider-Läufers int m_slider_size_fixing; int m_slider_point_fixing; //--- private: //--- Prozess der Bewegung des Slider-Läufers void OnDragThumb(const int x); //--- Aktualisierung der Position des Slider-Läufers void UpdateThumb(const int new_x_point); //--- Überprüfte den Status der Maustaste void CheckMouseButtonState(void); //--- Zurücksetzen der Variablen, die mit der Bewegung des Slider-Läufers in Zusammenhang stehen void ZeroThumbVariables(void); };
Um Eingaben in das Eingabefeld verarbeiten zu können, erzeugen wir die CSlider::OnEndEdit() Methode, die in der CSlider::OnEvent() Eventhandler Methode aufgerufen wird.
Am Anfang der CSlider::OnEndEdit() wird eine Überprüfung des Namens vorgenommen, um festzustellen, ob es sich um eine Eingabe in das richtige Eingabefeld handelt. Anschließend fragen wir den aktuellen Wert des Eingabefeldes ab. Anschließend führen wir eine Überprüfung über ungültige Werte durch, nehmen Anpassungen vor, berechnen die X Koordinaten des 2. Läufers und eine Position in der Werte Spanne. Anschließend wird der Slider-Indikator aktualisiert. Am Ende dieser Methode muss eine Nachricht mit (1) dem benutzerdefinierten Event-Bezeichner ON_END_EDIT, (2) dem Bezeichner des Elementes, (3) dem Index des Elementes (4) und der Beschreibung des Text-Label gesendet werden.
class CSlider : public CElement { private: //--- Verarbeiten der manuellen Eingabe eines neuen Wertes bool OnEndEdit(const string object_name); }; //+------------------------------------------------------------------+ //| HVerarbeiten der manuellen Eingabe eines neuen Wertes | //+------------------------------------------------------------------+ bool CSlider::OnEndEdit(const string object_name) { //--- Abbrechen, falls die Objektnamen nicht übereinstimmen if(object_name!=m_edit.Name()) return(false); //--- Abfrage des eingegebenen Wertes double entered_value=::StringToDouble(m_edit.Description()); //--- Überprüfen, Einstellen und Abspeichern des neuen Wertes ChangeValue(entered_value); //--- Berechnen der x-Koordinate des Slider-Läufers CalculateThumbX(); //--- Berechnen der Position in der Werte-Spanne CalculateThumbPos(); //--- Aktualisierung des Slider-Indikators UpdateIndicator(); //--- Eine Nachricht darüber senden ::EventChartCustom(m_chart_id,ON_END_EDIT,CElement::Id(),CElement::Index(),m_label.Description()); return(true); }
Hier muss ebenfalls die Nachricht gesendet werden, falls die Bewegung des Slider Läufers stoppt. Die CSlider::ZeroThumbVariables() Methode bietet sich hier am besten an. Sie wird in der CSlider::CheckMouseButtonState() Methode aufgerufen, in dem Bereich für die Protokollierung der linken Maustaste. Der Aufruf der CSlider::ZeroThumbVariables() Methode, beinhaltet schon den Fall, dass die linke Maustaste losgelassen wurde. Falls die Maustaste über dem Bereich des Slider-Läufers gedrückt wurde, bedeutet das, dass die Veränderung der Position des Slider-Läufers abgeschlossen ist und eine Nachricht über die Veränderung des Wertes in dem Eingabefeld gesendet werden muss.
//+---------------------------------------------------------------------------+ //| Zurücksetzen der Variablen in Zusammenhang mit der Bewegung der Scrollbar | //+---------------------------------------------------------------------------+ void CSlider::ZeroThumbVariables(void) { //--- Wenn wir uns hier befinden, bedeutet das, dass die linke Maustaste losgelassen wurde. // Falls die linke Maustaste über dem Slider-Läufer gedrückt wurde... if(m_clamping_area_mouse==THUMB_PRESSED_INSIDE) { //--- ... Senden einer Nachricht über die Veränderung des Wertes in dem Eingabefeld (nach abgeschlossener Bewegung des Slider-Läufers) ::EventChartCustom(m_chart_id,ON_END_EDIT,CElement::Id(),CElement::Index(),m_label.Description()); } //--- m_slider_size_fixing =0; m_clamping_area_mouse =THUMB_NOT_PRESSED; //--- Falls der Element-Bezeichner dem aktivierenden Bezeichner entspricht, // Entsperren des Formulars und zurücksetzen des Bezeichners des aktivierenden Elementes if(CElement::Id()==m_wnd.IdActivatedElement()) { m_wnd.IsLocked(false); m_wnd.IdActivatedElement(WRONG_VALUE); } }
Der vollständige Programmcode des CSlider::OnEvent() Eventhandlers sieht in unserem Falle wie folgt aus:
//+------------------------------------------------------------------+ //| Chart Eventhandler | //+------------------------------------------------------------------+ void CSlider::OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam) { //--- Verarbeiten des Mauszeiger Bewegungs Events if(id==CHARTEVENT_MOUSE_MOVE) { //--- Abbrechen, falls das Element 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); //--- Überprüfung des Fokus über dem Element CElement::MouseFocus(x>X() && x<X2() && y>Y() && y<Y2()); m_thumb.MouseFocus(x>m_thumb.X() && x<m_thumb.X2() && y>m_thumb.Y() && y<m_thumb.Y2()); //--- Abbrechen, falls das Element gesperrt ist if(!m_slider_state) return; //--- Überprüfen und Abspeichern des Status der linken Maustaste CheckMouseButtonState(); //--- Verändern der Farbe des Slider-Läufers ChangeThumbColor(); //--- Falls das Management der Slider-Linie übergeben wurde, Identifizierung der Position if(m_clamping_area_mouse==THUMB_PRESSED_INSIDE) { //--- Bewegendes Slider-Läufers OnDragThumb(x); //--- Berechnung der Slider-Läufer-Position in der Werte Spanne CalculateThumbPos(); //--- Setzen eines neuen Wertes in dem Eingabefeld ChangeValue(m_current_pos); //--- Aktualisierung des Slider-Indikators UpdateIndicator(); return; } } //--- Verarbeiten des Events über die Veränderung des Wertes in dem Eingabefeld if(id==CHARTEVENT_OBJECT_ENDEDIT) { //--- Verarbeiten der Eingabe des Wertes if(OnEndEdit(sparam)) return; } }
Wir haben nun die Methoden für die Erzeugung und der Verwaltung des Slider-Elementes implementiert. Lassen Sie uns dieses nun in einer MQL Anwendung, die wir schon aus den vorherigen Artikeln kennen, testen.
Test des Slider Control
In dem vorherigen Artikel haben wir innerhalb unserer Testanwendung vier Checkboxen erzeugt, die die Verfügbarkeit andere Elemente gesteuert haben. Wir fügen jetzt noch das Slider-Element und eine fünfte Checkbox für die Verwaltung der Verfügbarkeit dem grafischen Interface hinzu. Deklarieren Sie dafür in der CProgram Klasse die Instanzen der CCheckBox und CSlider Klassen, sowie Methoden für die Ränder von der Ecke des Formulars zu welchem dieses Control hinzugefügt wird.
//+------------------------------------------------------------------+ //| Kasse für das erzeugende Anwendung | //+------------------------------------------------------------------+ class CProgram : public CWndEvents { private: //--- Checkboxen CCheckBox m_checkbox5; //--- Sliders CSlider m_slider1; //--- private: //--- Checkboxen #define CHECKBOX5_GAP_X (7) #define CHECKBOX5_GAP_Y (200) bool CreateCheckBox5(const string text); //--- Sliders #define SLIDER1_GAP_X (32) #define SLIDER1_GAP_Y (225) bool CreateSlider1(const string text); };
Die Methoden für die Erzeugung der Checkboxen haben wir schon in den vorangegangenen Artikel besprochen. Aus diesem Grunde gehen wir nun direkt zu der Methode für die Erzeugung des CProgram::CreateSlider1()-Elementes über. Unter der Verwendung der CSlider::MinValue() und CSlider::MaxValue() Methoden, setzen wir eine Werte-Spanne von -1 bis 1. Die Schrittgrösse legen wir auf die 8. Nachkommastelle fest (0.00000001). Die Verfügbarkeit hängt von dem Status der fünften Checkbox ab..
//+------------------------------------------------------------------+ //| Erzeugt slider 1 | //+------------------------------------------------------------------+ bool CProgram::CreateSlider1(const string text) { //--- Abspeichern des Fenster-Pointers m_slider1.WindowPointer(m_window1); //--- Koordinaten int x=m_window1.X()+SLIDER1_GAP_X; int y=m_window1.Y()+SLIDER1_GAP_Y; //--- Wert double v=(m_slider1.GetValue()==WRONG_VALUE) ? 0.84615385 : m_slider1.GetValue(); //--- Festlegen der Eigenschaften vor der Erzeugung m_slider1.XSize(264); m_slider1.YSize(40); m_slider1.EditXSize(87); m_slider1.MaxValue(1); m_slider1.StepValue(0.00000001); m_slider1.MinValue(-1); m_slider1.SetDigits(8); m_slider1.SetValue(v); m_slider1.AreaColor(clrWhiteSmoke); m_slider1.LabelColor(clrBlack); m_slider1.LabelColorLocked(clrSilver); m_slider1.EditColorLocked(clrWhiteSmoke); m_slider1.EditBorderColor(clrSilver); m_slider1.EditBorderColorLocked(clrSilver); m_slider1.EditTextColorLocked(clrSilver); m_slider1.SlotLineDarkColor(clrSilver); m_slider1.SlotLineLightColor(clrWhite); m_slider1.SlotYSize(4); m_slider1.ThumbColorLocked(clrLightGray); m_slider1.ThumbColorPressed(clrSilver); m_slider1.SlotIndicatorColor(C'85,170,255'); m_slider1.SlotIndicatorColorLocked(clrLightGray); //--- Erzeugung des Controls if(!m_slider1.CreateSlider(m_chart_id,m_subwin,text,x,y)) return(false); //--- Die Verfügbarkeit hängt von dem Status der fünften Checkbox ab m_slider1.SliderState(m_checkbox5.CheckButtonState()); //--- Hinzufügen des Objektes zu dem gemeinsamen Array von Objektgruppen CWndContainer::AddToElementsArray(0,m_slider1); return(true); }
Die neuen Methoden für das Erzeugen des Elementes müssen in der Hauptmethode für das Erzeugen des grafischen Interfaces aufgerufen werden. Nachfolgend ist der Code einer verkürzten Version dieser Methode:
//+------------------------------------------------------------------+ //| Erzeugung des Trading-Panels | //+------------------------------------------------------------------+ bool CProgram::CreateTradePanel(void) { //--- Erzeugen des Formulars 1 für die Controls //---Erzeugung der Controls: // Hauptmenü //--- Kontextmenüs //--- Erzeugen der Statusbar //--- Checkboxen if(!CreateCheckBox5("Checkbox 5")) return(false); //--- Sliders if(!CreateSlider1("Slider 1:")) return(false); //--- Neuzeichnen des Charts m_chart.Redraw(); return(true); }
Wir protokollieren die Veränderung des Status der fünften Checkbox für das Steuern der Verfügbarkeit des Sliders in dem CProgram::OnEvent() Eventhandler der Anwendung. Das Event mit dem Bezeichner ON_END_EDIT Gibt uns einen Hinweis darauf, dass sich der Wert in dem Eingabefeld geändert hat.
//+------------------------------------------------------------------+ //| Event handler | //+------------------------------------------------------------------+ void CProgram::OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam) { //--- Das Event für ein Klick auf das Textlabel if(id==CHARTEVENT_CUSTOM+ON_CLICK_LABEL) { ::Print(__FUNCTION__," > id: ",id,"; lparam: ",lparam,"; dparam: ",dparam,"; sparam: ",sparam); //--- Falls auf die fünfte Checkbox geklickt wurde if(lparam==m_checkbox5.Id()) { //--- Setzen des Status des ersten Sliders m_slider1.SliderState(m_checkbox5.CheckButtonState()); } } //--- Das Ende der Eingabe eines Wertes in dem Eingabefeld (Event) if(id==CHARTEVENT_CUSTOM+ON_END_EDIT) { ::Print(__FUNCTION__," > id: ",id,"; lparam: ",lparam,"; dparam: ",dparam,"; sparam: ",sparam); } }
Nun kann das Programm kompiliert und auf den Chart geladen werden. Versuchen Sie mit den Controls des grafischen Interfaces dieser Anwendung zu arbeiten. Wenn wir alles richtig gemacht haben, dann sollte das Ergebnis wie in dem nachfolgenden Screenshot gezeigt aussehen:
Abbildung 2. Test des Slider-Controls.
Das Dual-Slider-Control
Der Unterschied zwischen einem Dual-Slider und einem einfachen Slider ist, dass der Dual Slider die Auswahl einer Werte-Spanne ermöglicht. Aus diesem Grunde gibt es auf der Slider-Linie zwei Slider-Läufer. Der linke Slider-Läufer kann von der linken Seite bis zu dem rechten Slider-Läufer bewegt werden. Der rechte Slider-Läufer kann von der rechten Seite bis zu dem linken Slider-Läufer bewegt werden. Ein Dual-Slider hat auch zwei Eingabefelder, welche die Werte der Positionen der Slider-Läufer repräsentieren. In diesen Eingabefeldern können Werte manuell eingegeben werden. Dieses führt natürlich zu einer veränderten Position der Slider-Läufer.
Dieses Control wird aus acht einfachen grafischen Objekten zusammengestellt. :Diese sind:
- Hintergrund
- Beschriftung (text label).
- Linkes Eingabefeld.
- Rechtes Eingabefeld
- Slider Linie.
- Linker Slider-Läufer.
- Rechter Slider-Läufer
- Slider-Indikator.
Abbildung 3. Die Komponenten eines Dual-Slider-Controls
Lassen Sie uns die Klasse für einen Dual-Slider anschauen und die Unterschiede zu dem einfachen Slider aufzeigen.
Entwickeln einer Klasse für die Erzeugung des Dual-Slider-Control
Beziehen Sie die DualSlider.mqh Datei mit in der CDualSlider Klasse in der WndContainer.mqh Datei mit ein:
//+------------------------------------------------------------------+ //| WndContainer.mqh | //| Copyright 2015, MetaQuotes Software Corp. | //| http://www.mql5.com | //+------------------------------------------------------------------+ #include "DualSlider.mqh"
In Bezug auf die Eigenschaften des Controls, ist die CDualSlider Klasse mit der CSlider Klasse identisch. Der einzige Unterschied besteht darin, dass das linke und rechte Eingabefeld und die Slider-Läufer separate Variablen und Methoden benötigen. Die Unterschiede zwischen diesen Methoden sind aber unwesentlich und aus diesem Grunde werden wir hier nicht weiter darauf eingehen. Sie finden den Programmcode in den angehängten Dateien.
class CDualSlider : public CElement { private: //--- Die aktuellen Werte in den Eingabefeldern (Links und rechts) double m_left_edit_value; double m_right_edit_value; //--- Die aktuellen Positionen der Slider-Läufer(Links und rechts) double m_left_current_pos; double m_left_current_pos_x; double m_right_current_pos; double m_right_current_pos_x; //--- Status der Maustaste (Gedrückt/nicht gedrückt) Für die Slider Läufer (Links und rechts) ENUM_THUMB_MOUSE_STATE m_clamping_mouse_left_thumb; ENUM_THUMB_MOUSE_STATE m_clamping_mouse_right_thumb; //--- public: //--- Rückgabe und setzen der Werte in den Eingabefeldern (Links und rechts) double GetLeftValue(void) const { return(m_left_edit_value); } double GetRightValue(void) const { return(m_right_edit_value); } bool SetLeftValue(double value); bool SetRightValue(double value); //--- Verändern der Werte in den Eingabefeldern (Links und rechts) void ChangeLeftValue(const double value); void ChangeRightValue(const double value); //--- private: //--- Vorgang für das Bewegen der Slider-Läufer (Links und rechts) void OnDragLeftThumb(const int x); void OnDragRightThumb(const int x); //---Aktualisieren der Position der Slider-Läufer (Links und rechts) void UpdateLeftThumb(const int new_x_point); void UpdateRightThumb(const int new_x_point); //--- Überprüft den Status der linken Maustaste über einen Slider-Läufer void CheckMouseOnLeftThumb(void); void CheckMouseOnRightThumb(void); //--- Berechnung der X Koordinaten der Slider (Links und rechts) void CalculateLeftThumbX(void); void CalculateRightThumbX(void); //--- Verändert die Position des linken Slider-Läufers in Relation zu dem Wert (Links und rechts) void CalculateLeftThumbPos(void); void CalculateRightThumbPos(void); };
Hier zeigen wir nur den Programmcode der Methoden, wo zwei Eingabefelder und die Slider-Läufer behandelt werden. Nachfolgend ist die Struktur der CDualSlider::OnEndEdit() Methode dargestellt:
class CDualSlider : public CElement { private: //--- Verarbeiten der manuellen Eingabe eines neuen Wertes bool OnEndEdit(const string object_name); }; //+------------------------------------------------------------------+ //| Abschließen der Eingabe eines Wertes | //+------------------------------------------------------------------+ bool CDualSlider::OnEndEdit(const string object_name) { //--- Falls der Wert in dem linken Eingabefeld eingegeben wurde if(object_name==m_left_edit.Name()) { //--- Abfrage des eingegebenen Wertes double entered_value=::StringToDouble(m_left_edit.Description()); //--- Überprüfen, Einstellen und Abspeichern des neuen Wertes ChangeLeftValue(entered_value); //--- Berechnen der x-Koordinate des Slider-Läufers CalculateLeftThumbX(); //--- Aktualisierung der Position des Slider-Läufers UpdateLeftThumb(m_left_thumb.X()); //--- Berechnen der Position in der Werte-Spanne CalculateLeftThumbPos(); //--- Überprüfen, Einstellen und Abspeichern des neuen Wertes ChangeLeftValue(m_left_current_pos); //--- Aktualisierung des Slider-Indikators UpdateIndicator(); //--- Eine Nachricht darüber senden ::EventChartCustom(m_chart_id,ON_END_EDIT,CElement::Id(),CElement::Index(),m_label.Description()); return(true); } //--- Falls der Wert in dem rechten Eingabefeld eingegeben wurde if(object_name==m_right_edit.Name()) { //--- Abfrage des eingegebenen Wertes double entered_value=::StringToDouble(m_right_edit.Description()); //--- Überprüfen, Einstellen und Abspeichern des neuen Wertes ChangeRightValue(entered_value); //--- Berechnen der x-Koordinate des Slider-Läufers CalculateRightThumbX(); //--- Aktualisierung der Position des Slider-Läufers UpdateRightThumb(m_right_thumb.X()); //--- Berechnen der Position in der Werte-Spanne CalculateRightThumbPos(); //--- Überprüfen, Einstellen und Abspeichern des neuen Wertes ChangeRightValue(m_right_current_pos); //--- Aktualisierung des Slider-Indikators UpdateIndicator(); //--- Eine Nachricht darüber senden ::EventChartCustom(m_chart_id,ON_END_EDIT,CElement::Id(),CElement::Index(),m_label.Description()); return(true); } //--- return(false); }
Das gleiche wird bei der Bewegung des linken und rechten Läufers angewendet. Der CDualSlider::OnEvent() Eventhandler besitzt für jeden von ihnen einen eigenen Codeblock:
//+-----------------------------------------------------------------+ //| Chart Eventhandler | //+-----------------------------------------------------------------+ void CDualSlider::OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam) { //--- Verarbeiten des Mauszeiger Bewegungs Events if(id==CHARTEVENT_MOUSE_MOVE) { //--- Abbrechen, falls das Element 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); //--- Überprüfung des Fokus über dem Element CElement::MouseFocus(x>X() && x<X2() && y>Y() && y<Y2()); m_left_thumb.MouseFocus(x>m_left_thumb.X() && x<m_left_thumb.X2() && y>m_left_thumb.Y() && y<m_left_thumb.Y2()); m_right_thumb.MouseFocus(x>m_right_thumb.X() && x<m_right_thumb.X2() && y>m_right_thumb.Y() && y<m_right_thumb.Y2()); //--- Abbrechen, falls das Element gesperrt ist if(!m_slider_state) return; //--- Überprüfen und Abspeichern des Status der linken Maustaste CheckMouseOnLeftThumb(); CheckMouseOnRightThumb(); //--- Verändern der Farbe des Slider-Läufers ChangeThumbColor(); //--- Falls die Verwaltung an die Slider-Linie übergeben wurde (Linker Slider-Läufer) if(m_clamping_mouse_left_thumb==THUMB_PRESSED_INSIDE) { //--- Bewegendes Slider-Läufers OnDragLeftThumb(x); //--- Berechnung der Slider-Läufer-Position in der Werte Spanne CalculateLeftThumbPos(); //--- Setzen eines neuen Wertes in dem Eingabefeld ChangeLeftValue(m_left_current_pos); //--- Aktualisierung des Slider-Indikators UpdateIndicator(); return; } //--- Falls die Verwaltung dem rechten Slider-Läufer übergeben wurde if(m_clamping_mouse_right_thumb==THUMB_PRESSED_INSIDE) { //--- Bewegendes Slider-Läufers OnDragRightThumb(x); //--- Berechnung der Slider-Läufer-Position in der Werte Spanne CalculateRightThumbPos(); //--- Setzen eines neuen Wertes in dem Eingabefeld ChangeRightValue(m_right_current_pos); //--- Aktualisierung des Slider-Indikators UpdateIndicator(); return; } } }
Sie können die Dateien die diesem Artikel beigefügt sind herunterladen und den Programmcode derCDualSlider Klasse im Detail studieren.
Test des Dual-Slider-Controls
Fügen Sie das Dual-Slider-Control dem grafischen Interface unserer Test-Anwendung hinzu. Deklarieren Sie eine Instanz der CDualSlider Und eine Methode mit den Rändern von der Ecke des Formulars in der CProgram benutzerdefinierten Klasse der Anwendung:
//+-----------------------------------------------------------------+ //| Kasse für das erzeugende Anwendung | //+-----------------------------------------------------------------+ class CProgram : public CWndEvents { private: //--- Sliders CDualSlider m_dual_slider1; //--- private: //--- Sliders #define DUALSLIDER1_GAP_X (32) #define DUALSLIDER1_GAP_Y (275) bool CreateDualSlider1(const string text); };
Der nachfolgende Programmcode zeigt den Code der CProgram::CreateDualSlider1() Methode. Legen Sie die Wertebereich von -2000 bis 1000 fest. Die Verfügbarkeit dieses Controls hängt ebenfalls von dem aktuellen Status der fünften Checkbox ab.
//+-----------------------------------------------------------------+ //| Erzeugt den Dual-Slider 1 | //+-----------------------------------------------------------------+ bool CProgram::CreateDualSlider1(const string text) { //--- Abspeichern des Fenster-Pointers m_dual_slider1.WindowPointer(m_window1); //--- Koordinaten int x=m_window1.X()+DUALSLIDER1_GAP_X; int y=m_window1.Y()+DUALSLIDER1_GAP_Y; //--- Werte double v1=(m_dual_slider1.GetLeftValue()==WRONG_VALUE) ? 0 : m_dual_slider1.GetLeftValue(); double v2=(m_dual_slider1.GetRightValue()==WRONG_VALUE) ? 500 : m_dual_slider1.GetRightValue(); //--- Festlegen der Eigenschaften vor der Erzeugung m_dual_slider1.XSize(264); m_dual_slider1.YSize(40); m_dual_slider1.EditXSize(87); m_dual_slider1.MaxValue(1000); m_dual_slider1.StepValue(1); m_dual_slider1.MinValue(-2000); m_dual_slider1.SetDigits(0); m_dual_slider1.SetLeftValue(v1); m_dual_slider1.SetRightValue(v2); m_dual_slider1.AreaColor(clrWhiteSmoke); m_dual_slider1.LabelColor(clrBlack); m_dual_slider1.LabelColorLocked(clrSilver); m_dual_slider1.EditColorLocked(clrWhiteSmoke); m_dual_slider1.EditBorderColor(clrSilver); m_dual_slider1.EditBorderColorLocked(clrSilver); m_dual_slider1.EditTextColorLocked(clrSilver); m_dual_slider1.SlotLineDarkColor(clrSilver); m_dual_slider1.SlotLineLightColor(clrWhite); m_dual_slider1.SlotYSize(4); m_dual_slider1.ThumbColorLocked(clrLightGray); m_dual_slider1.ThumbColorPressed(clrSilver); m_dual_slider1.SlotIndicatorColor(C'85,170,255'); m_dual_slider1.SlotIndicatorColorLocked(clrLightGray); //--- Erzeugung des Controls if(!m_dual_slider1.CreateSlider(m_chart_id,m_subwin,text,x,y)) return(false); //--- Die Verfügbarkeit hängt von dem Status der fünften Checkbox ab m_dual_slider1.SliderState(m_checkbox5.CheckButtonState()); //--- Hinzufügen des Objektes zu dem gemeinsamen Array von Objektgruppen CWndContainer::AddToElementsArray(0,m_dual_slider1); return(true); }
Vergessen Sie nicht den Aufruf der Methode für das Erzeugen des neuen Controls in der Hauptmethode für das Erzeugen des grafischen Interfaces hinzuzufügen.
//+------------------------------------------------------------------+ //| Erzeugung des Trading-Panels | //+------------------------------------------------------------------+ bool CProgram::CreateTradePanel(void) { //--- Erzeugen des Formulars 1 für die Controls //---Erzeugung der Controls: // Hauptmenü //--- Kontextmenüs //--- Erzeugen der Statusbar //--- Checkboxen //--- Sliders if(!CreateDualSlider1("Dual Slider 1:")) return(false); //--- Neuzeichnen des Charts m_chart.Redraw(); return(true); }
Jetzt steuert der Status der fünften Checkbox zwei Controls- Den einfachen Schieberegler und den doppelten Schieberegler.
//+------------------------------------------------------------------+ //| Event handler | //+------------------------------------------------------------------+ void CProgram::OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam) { //--- Das Event für ein Klick auf das Textlabel if(id==CHARTEVENT_CUSTOM+ON_CLICK_LABEL) { ::Print(__FUNCTION__," > id: ",id,"; lparam: ",lparam,"; dparam: ",dparam,"; sparam: ",sparam); //--- Falls auf die fünfte Checkbox geklickt wurde if(lparam==m_checkbox5.Id()) { //--- Setzen des Status für die Schieberegler m_slider1.SliderState(m_checkbox5.CheckButtonState()); m_dual_slider1.SliderState(m_checkbox5.CheckButtonState()); } } //--- Das Ende der Eingabe eines Wertes in dem Eingabefeld (Event) if(id==CHARTEVENT_CUSTOM+ON_END_EDIT) { ::Print(__FUNCTION__," > id: ",id,"; lparam: ",lparam,"; dparam: ",dparam,"; sparam: ",sparam); } }
Kompilieren Sie dieses Programm und laden Sie es auf einen Chart. Der nachfolgende Screenshot zeigt das Resultat:
Abbildung 4. Der doppelte Schieberegler.
Schlussfolgerung
In dem sechsten Teil dieser Serie haben wir sechs Controls betrachtet:
- Checkbox.
- Das Edit-Control
- Edit mit Checkbox
- Check Combobox
- Schlieberegler (Slider).
- Doppelter Schieberegler (Dual slider).
Zur Zeit sieht das schematische Diagramm unserer Bibliothek für das Erzeugen von grafischen Interfaces wie folgt aus:
Abbildung 5. Die Struktur unserer Bibliothek zum aktuellen Stand der Entwicklung
In den nächsten Teil unserer Serie werden wir unsere Bibliothek mit Tabellen und Tabs erweitern.
Sie können das gesamte Material des sechsten Teils herunterladen und 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 sechten Teils:
- Graphische Interfaces VI: Das Checkbox Control, Das Edit Control und deren gemischte Typen (Kapitel 1)
- Grafische Interfaces VI: Die Slider und Dual-Slider Controls (Kapitel 2)
Übersetzt aus dem Russischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/ru/articles/2468





- 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.