DoEasy. Steuerung (Teil 29): Das Hilfssteuerelement der ScrollBar
Inhalt
- Konzept
- Verbesserung der Bibliotheksklassen
- Basisklasse des ScrollBar-Hilfssteuerelements
- ScrollBarVertical- und ScrollBarHorisontal-Steuerelemente, die von dem Basis-Steuerelement abgeleitet sind
- Test
- Was kommt als Nächstes?
Konzept
Im vorherigen Artikel habe ich die Erstellung des Steuerelements TrackBar angekündigt - ein Element, das die Eingabe numerischer Werte durch Verschieben des Schiebereglers ermöglicht:
Da ein solches Objekt von dem ScrollBar-Steuerelement abgeleitet ist, werde ich in diesem Artikel mit der Erstellung dieses WinForms-Objekts beginnen.
Eine Bildlaufleiste wird verwendet, um den Inhalt des Formulars zu verschieben, wenn er über den Container hinausgeht. Die Bildlaufleisten befinden sich in der Regel am unteren und rechten Rand des Formulars. Die horizontale am unteren Rand blättert den Inhalt nach links und rechts, während die vertikale nach oben und unten blättert.
In diesem Artikel werde ich das Basisobjekt ScrollBar und zwei seiner Abkömmlinge entwickeln — ScrollBarVertical und ScrollBarHorisontal. Die Objekte werden statisch sein, d.h. sie werden den Inhalt des Formulars nicht verwalten. Darauf werde ich in späteren Artikeln eingehen. Jedes Scrollbar-Objekt besteht aus einem Hintergr und und darauf befindlichen Steuerelementen - zwei Schaltflächen (Auf-Ab für eine vertikale Scrollbar und Links-Rechts für eine horizontale). Jedes Objekt sollte einen Erfassungsbereich (ThumbArea) oder einen „Schieberegler“ haben, sodass es möglich ist, den Inhalt des Formulars zu verschieben, indem man es anfasst und mit der Maus bewegt. Die Schaltflächen mit Pfeilen dienen ebenfalls diesem Zweck. Alle diese Steuerelemente sind bereits mit der entsprechenden Mausinteraktionsfunktionalität ausgestattet. Daher werden wir heute einfach diese Objekte erstellen, und im nächsten Artikel werden wir die festgestellten Unzulänglichkeiten abschließen und mit der Entwicklung der Interaktion von Bildlaufleisten mit der Maus beginnen, um den Inhalt des Formulars zu steuern.
Bildlaufleisten sollten bei allen Objekten vorhanden sein, die es erlauben, andere Steuerelemente an sie anzuhängen, was bedeutet, dass sie Container-Objekte sein sollten. Zunächst wird die Bildlaufleiste ausgeblendet, wenn der Inhalt des Containers in sie hineinpasst. Wenn der Inhalt über den Container hinausgeht, sollte eine Bildlaufleiste erscheinen, die es dem Nutzer ermöglicht, den sichtbaren Bereich des Formulars durch Verschieben der darin enthaltenen Objekte zu kontrollieren. In diesem Artikel werde ich zwei Bildlaufleisten (vertikal und horizontal) erstellen und sie für das Hauptformular sichtbar machen, um ihr Aussehen zu bewerten und zu entscheiden, was als Nächstes mit ihnen geschehen soll.
Verbesserung der Bibliotheksklassen
Wenn der Mauszeiger über den ScrollBar-Steuerungsbereich (Schaltflächen und Scroll-Schieberegler) bewegt wird, sollten sich ihre Farben ändern. Die Farbe ändert sich beim Schweben und Erfassen - für jeden Zustand wird eine andere Farbe eingestellt.
Fügen wir sie der Liste der Makrosubstitutionen in \MQL5\Include\DoEasy\Defines.mqh hinzu:
#define CLR_DEF_CONTROL_PROGRESS_BAR_BACK_COLOR (C'0xF0,0xF0,0xF0') // ProgressBar control background color #define CLR_DEF_CONTROL_PROGRESS_BAR_BORDER_COLOR (C'0xBC,0xBC,0xBC') // ProgressBar control frame color #define CLR_DEF_CONTROL_PROGRESS_BAR_FORE_COLOR (C'0x00,0x78,0xD7') // ProgressBar control text color #define CLR_DEF_CONTROL_PROGRESS_BAR_BAR_COLOR (C'0x06,0xB0,0x25') // ProgressBar control progress line color #define CLR_DEF_CONTROL_SCROLL_BAR_TRACK_BACK_COLOR (C'0xF0,0xF0,0xF0') // ScrollBar control background color #define CLR_DEF_CONTROL_SCROLL_BAR_TRACK_BORDER_COLOR (C'0xFF,0xFF,0xFF') // ScrollBar control frame color #define CLR_DEF_CONTROL_SCROLL_BAR_TRACK_FORE_COLOR (C'0x60,0x60,0x60') // ScrollBar control text color #define CLR_DEF_CONTROL_SCROLL_BAR_THUMB_COLOR (C'0xCD,0xCD,0xCD') // ScrollBar control capture area color #define CLR_DEF_CONTROL_SCROLL_BAR_THUMB__MOUSE_DOWN (C'0x60,0x60,0x60') // Color of ScrollBar control capture area when clicking on the control #define CLR_DEF_CONTROL_SCROLL_BAR_THUMB_MOUSE_OVER (C'0xA6,0xA6,0xA6') // Color of ScrollBar control capture area when hovering over the control #define DEF_CONTROL_LIST_MARGIN_X (1) // Gap between columns in ListBox controls #define DEF_CONTROL_LIST_MARGIN_Y (0) // Gap between rows in ListBox controls
Hinzufügen von drei neuen Typen zur Liste der grafischen Elementtypen in derselben Datei:
//+---------------------------------------------+ //| The list of graphical element types | //+---------------------------------------------+ enum ENUM_GRAPH_ELEMENT_TYPE { GRAPH_ELEMENT_TYPE_STANDARD, // Standard graphical object GRAPH_ELEMENT_TYPE_STANDARD_EXTENDED, // Extended standard graphical object GRAPH_ELEMENT_TYPE_SHADOW_OBJ, // Shadow object GRAPH_ELEMENT_TYPE_ELEMENT, // Element GRAPH_ELEMENT_TYPE_FORM, // Form GRAPH_ELEMENT_TYPE_WINDOW, // Window //--- WinForms GRAPH_ELEMENT_TYPE_WF_UNDERLAY, // Panel object underlay GRAPH_ELEMENT_TYPE_WF_BASE, // Windows Forms Base //--- 'Container' object types are to be set below GRAPH_ELEMENT_TYPE_WF_CONTAINER, // Windows Forms container base object GRAPH_ELEMENT_TYPE_WF_PANEL, // Windows Forms Panel GRAPH_ELEMENT_TYPE_WF_GROUPBOX, // Windows Forms GroupBox GRAPH_ELEMENT_TYPE_WF_TAB_CONTROL, // Windows Forms TabControl GRAPH_ELEMENT_TYPE_WF_SPLIT_CONTAINER, // Windows Forms SplitContainer //--- 'Standard control' object types are to be set below GRAPH_ELEMENT_TYPE_WF_COMMON_BASE, // Windows Forms base standard control GRAPH_ELEMENT_TYPE_WF_LABEL, // Windows Forms Label GRAPH_ELEMENT_TYPE_WF_BUTTON, // Windows Forms Button GRAPH_ELEMENT_TYPE_WF_CHECKBOX, // Windows Forms CheckBox GRAPH_ELEMENT_TYPE_WF_RADIOBUTTON, // Windows Forms RadioButton GRAPH_ELEMENT_TYPE_WF_ELEMENTS_LIST_BOX, // Base list object of Windows Forms elements GRAPH_ELEMENT_TYPE_WF_LIST_BOX, // Windows Forms ListBox GRAPH_ELEMENT_TYPE_WF_CHECKED_LIST_BOX, // Windows Forms CheckedListBox GRAPH_ELEMENT_TYPE_WF_BUTTON_LIST_BOX, // Windows Forms ButtonListBox GRAPH_ELEMENT_TYPE_WF_TOOLTIP, // Windows Forms ToolTip GRAPH_ELEMENT_TYPE_WF_PROGRESS_BAR, // Windows Forms ProgressBar //--- Auxiliary elements of WinForms objects GRAPH_ELEMENT_TYPE_WF_LIST_BOX_ITEM, // Windows Forms ListBoxItem GRAPH_ELEMENT_TYPE_WF_TAB_HEADER, // Windows Forms TabHeader GRAPH_ELEMENT_TYPE_WF_TAB_FIELD, // Windows Forms TabField GRAPH_ELEMENT_TYPE_WF_SPLIT_CONTAINER_PANEL, // Windows Forms SplitContainerPanel GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON, // Windows Forms ArrowButton GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_UP, // Windows Forms UpArrowButton GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_DOWN, // Windows Forms DownArrowButton GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_LEFT, // Windows Forms LeftArrowButton GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_RIGHT, // Windows Forms RightArrowButton GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTONS_UD_BOX, // Windows Forms UpDownArrowButtonsBox GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTONS_LR_BOX, // Windows Forms LeftRightArrowButtonsBox GRAPH_ELEMENT_TYPE_WF_SPLITTER, // Windows Forms Splitter GRAPH_ELEMENT_TYPE_WF_HINT_BASE, // Windows Forms HintBase GRAPH_ELEMENT_TYPE_WF_HINT_MOVE_LEFT, // Windows Forms HintMoveLeft GRAPH_ELEMENT_TYPE_WF_HINT_MOVE_RIGHT, // Windows Forms HintMoveRight GRAPH_ELEMENT_TYPE_WF_HINT_MOVE_UP, // Windows Forms HintMoveUp GRAPH_ELEMENT_TYPE_WF_HINT_MOVE_DOWN, // Windows Forms HintMoveDown GRAPH_ELEMENT_TYPE_WF_BAR_PROGRESS_BAR, // Windows Forms BarProgressBar GRAPH_ELEMENT_TYPE_WF_GLARE_OBJ, // Glare object GRAPH_ELEMENT_TYPE_WF_SCROLL_BAR, // Windows Forms ScrollBar GRAPH_ELEMENT_TYPE_WF_SCROLL_BAR_HORISONTAL, // Windows Forms ScrollBarHorisontal GRAPH_ELEMENT_TYPE_WF_SCROLL_BAR_VERTICAL, // Windows Forms ScrollBarVertical }; //+------------------------------------------------------------------+
Hier habe ich ein grundlegendes Scrollbar-Element und zwei davon abgeleitete Steuerelemente hinzugefügt - horizontale und vertikale Scrollbars.
In \MQL5\Include\DoEasy\Data.mqh wurden neuen Nachrichtenindizes hinzugefügt:
MSG_GRAPH_ELEMENT_TYPE_WF_BAR_PROGRESS_BAR, // BarProgressBar control MSG_GRAPH_ELEMENT_TYPE_WF_PROGRESS_BAR, // ProgressBar control MSG_GRAPH_ELEMENT_TYPE_WF_SCROLL_BAR, // ScrollBar control MSG_GRAPH_ELEMENT_TYPE_WF_SCROLL_BAR_VERTICAL, // ScrollBarVertical control MSG_GRAPH_ELEMENT_TYPE_WF_SCROLL_BAR_HORISONTAL, // ScrollBarHorisontal control MSG_GRAPH_ELEMENT_TYPE_WF_GLARE_OBJ, // Glare object
und die Textnachrichten, die den neu hinzugefügten Indizes entsprechen:
{"Элемент управления BarProgressBar","Control element \"BarProgressBar\""}, {"Элемент управления ProgressBar","Control element \"ProgressBar\""}, {"Элемент управления ScrollBar","Control element \"ScrollBar\""}, {"Элемент управления ScrollBarVertical","Control element \"ScrollBarVertical\""}, {"Элемент управления ScrollBarHorisontal","Control element \"ScrollBarHorisontal\""}, {"Объект блика","Glare object"},
Jetzt können wir die Beschreibungen der hier neu erstellten Objekte anzeigen.
Um Beschreibungen der grafischen Objekte der Bibliothek anzuzeigen, verwenden wir die Methode TypeElementDescription() in der Klasse des Basisobjekts aller grafischen Objekte der Bibliothek in \MQL5\Include\DoEasy\Objects\Graph\GBaseObj.mqh.
Fügen wir die Ausgabe der Beschreibung der neuen Objekte hinzu:
//+------------------------------------------------------------------+ //| Return the description of the graphical element type | //+------------------------------------------------------------------+ string CGBaseObj::TypeElementDescription(const ENUM_GRAPH_ELEMENT_TYPE type) { return ( type==GRAPH_ELEMENT_TYPE_STANDARD ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_STANDARD) : type==GRAPH_ELEMENT_TYPE_STANDARD_EXTENDED ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_STANDARD_EXTENDED) : type==GRAPH_ELEMENT_TYPE_ELEMENT ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_ELEMENT) : type==GRAPH_ELEMENT_TYPE_SHADOW_OBJ ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_SHADOW_OBJ) : type==GRAPH_ELEMENT_TYPE_FORM ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_FORM) : type==GRAPH_ELEMENT_TYPE_WINDOW ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WINDOW) : //--- WinForms type==GRAPH_ELEMENT_TYPE_WF_UNDERLAY ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_UNDERLAY) : type==GRAPH_ELEMENT_TYPE_WF_BASE ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_BASE) : //--- Containers type==GRAPH_ELEMENT_TYPE_WF_CONTAINER ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_CONTAINER) : type==GRAPH_ELEMENT_TYPE_WF_GROUPBOX ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_GROUPBOX) : type==GRAPH_ELEMENT_TYPE_WF_PANEL ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_PANEL) : type==GRAPH_ELEMENT_TYPE_WF_TAB_CONTROL ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_TAB_CONTROL) : type==GRAPH_ELEMENT_TYPE_WF_SPLIT_CONTAINER ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_SPLIT_CONTAINER) : //--- Standard controls type==GRAPH_ELEMENT_TYPE_WF_COMMON_BASE ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_COMMON_BASE) : type==GRAPH_ELEMENT_TYPE_WF_LABEL ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_LABEL) : type==GRAPH_ELEMENT_TYPE_WF_CHECKBOX ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_CHECKBOX) : type==GRAPH_ELEMENT_TYPE_WF_RADIOBUTTON ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_RADIOBUTTON) : type==GRAPH_ELEMENT_TYPE_WF_BUTTON ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_BUTTON) : type==GRAPH_ELEMENT_TYPE_WF_ELEMENTS_LIST_BOX ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_ELEMENTS_LIST_BOX) : type==GRAPH_ELEMENT_TYPE_WF_LIST_BOX ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_LIST_BOX) : type==GRAPH_ELEMENT_TYPE_WF_LIST_BOX_ITEM ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_LIST_BOX_ITEM) : type==GRAPH_ELEMENT_TYPE_WF_CHECKED_LIST_BOX ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_CHECKED_LIST_BOX) : type==GRAPH_ELEMENT_TYPE_WF_BUTTON_LIST_BOX ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_BUTTON_LIST_BOX) : type==GRAPH_ELEMENT_TYPE_WF_TOOLTIP ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_TOOLTIP) : type==GRAPH_ELEMENT_TYPE_WF_PROGRESS_BAR ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_PROGRESS_BAR) : //--- Auxiliary control objects type==GRAPH_ELEMENT_TYPE_WF_TAB_HEADER ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_TAB_HEADER) : type==GRAPH_ELEMENT_TYPE_WF_TAB_FIELD ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_TAB_FIELD) : type==GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON) : type==GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_UP ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_UP) : type==GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_DOWN ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_DOWN) : type==GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_LEFT ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_LEFT) : type==GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_RIGHT ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_RIGHT) : type==GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTONS_UD_BOX ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTONS_UD_BOX) : type==GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTONS_LR_BOX ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTONS_LR_BOX) : type==GRAPH_ELEMENT_TYPE_WF_SPLIT_CONTAINER_PANEL ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_SPLIT_CONTAINER_PANEL) : type==GRAPH_ELEMENT_TYPE_WF_SPLITTER ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_SPLITTER) : type==GRAPH_ELEMENT_TYPE_WF_HINT_BASE ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_HINT_BASE) : type==GRAPH_ELEMENT_TYPE_WF_HINT_MOVE_LEFT ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_HINT_MOVE_LEFT) : type==GRAPH_ELEMENT_TYPE_WF_HINT_MOVE_RIGHT ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_HINT_MOVE_RIGHT) : type==GRAPH_ELEMENT_TYPE_WF_HINT_MOVE_UP ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_HINT_MOVE_UP) : type==GRAPH_ELEMENT_TYPE_WF_HINT_MOVE_DOWN ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_HINT_MOVE_DOWN) : type==GRAPH_ELEMENT_TYPE_WF_BAR_PROGRESS_BAR ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_BAR_PROGRESS_BAR) : type==GRAPH_ELEMENT_TYPE_WF_GLARE_OBJ ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_GLARE_OBJ) : type==GRAPH_ELEMENT_TYPE_WF_SCROLL_BAR ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_SCROLL_BAR) : type==GRAPH_ELEMENT_TYPE_WF_SCROLL_BAR_VERTICAL ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_SCROLL_BAR_VERTICAL) : type==GRAPH_ELEMENT_TYPE_WF_SCROLL_BAR_HORISONTAL ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_SCROLL_BAR_HORISONTAL) : "Unknown" ); } //+------------------------------------------------------------------+
Die Methode erhält den Objekttyp. Abhängig vom übergebenen Typ gibt die Methode einen Textstring zurück, indem sie das Objekt der Textnachrichtenklasse der CMessage-Bibliothek verwendet, die ich in den Artikeln der ersten Serie der Bibliotheksbeschreibung betrachtet habe.
Basisklasse des ScrollBar-Hilfssteuerelements
Das Basis-Scrollbar-Objekt wird von der Basisklasse aller WinForms-Bibliotheksobjekte geerbt. Es handelt sich dabei um eine Art abstraktes Scrollbar-Objekt, während die erforderlichen Parameter für ein bestimmtes Objekt bereits in seinen Nachkommen angegeben werden.
Im Ordner der Hilfsobjekte der Bibliothek \MQL5\Include\DoEasy\Objects\Graph\WForms\Helpers\ erstellen wir die neue Klasse CScrollBar in ScrollBar.mqh. Die Klasse sollte von der Klasse CWinFormBase abgeleitet sein, während die Dateien dieser und anderer Klassen in die Datei des erstellten Objekts aufgenommen werden sollten:
//+------------------------------------------------------------------+ //| ScrollBar.mqh | //| Copyright 2022, MetaQuotes Ltd. | //| https://mql5.com/en/users/artmedia70 | //+------------------------------------------------------------------+ #property copyright "Copyright 2022, MetaQuotes Ltd." #property link "https://mql5.com/en/users/artmedia70" #property version "1.00" #property strict // Necessary for mql4 //+---------------------------------------------+ //| Include files | //+---------------------------------------------+ #include "..\WinFormBase.mqh" #include "ArrowDownButton.mqh" #include "ArrowUpButton.mqh" #include "ArrowLeftButton.mqh" #include "ArrowRightButton.mqh" //+---------------------------------------------+ //| CScrollBar object class of WForms controls | //+---------------------------------------------+ class CScrollBar : public CWinFormBase {
Im privaten Teil der Klasse deklarieren wir die Methoden zur Erstellung von Pfeilschaltflächen, die Standardmethode zur Erstellung eines neuen Grafikobjekts, die Methode zur Berechnung der Größe des Erfassungsbereichs (Slider) und die Methode zur Initialisierung der Objektparameter:
//+------------------------------------------------------------------+ //| CScrollBar object class of WForms controls | //+------------------------------------------------------------------+ class CScrollBar : public CWinFormBase { private: //--- Create the ArrowButton objects virtual void CreateArrowButtons(const int width,const int height) { return; } //--- Create a new graphical object virtual CGCnvElement *CreateNewGObject(const ENUM_GRAPH_ELEMENT_TYPE type, const int element_num, const string descript, const int x, const int y, const int w, const int h, const color colour, const uchar opacity, const bool movable, const bool activity); //--- Calculate the capture area size virtual int CalculateThumbAreaSize(void); //--- Initialize the element properties void Initialize(void); protected:
Die Methode, die die Größe des Schiebereglers in verschiedenen untergeordneten Objekten berechnet, führt zu unterschiedlichen Größen des Erfassungsbereichs, da seine Position von der Ausrichtung der Bildlaufleiste abhängt - vertikal oder horizontal. Die Methode zur Erstellung von Schaltflächenobjekten erzeugt auch unterschiedliche Schaltflächen in verschiedenen geerbten Objekten: Für die vertikale Bildlaufleiste benötigen wir Schaltflächen mit Aufwärts- und Abwärtspfeilen und für die horizontale Bildlaufleiste Schaltflächen mit Links- und Rechtspfeilen. Alle diese Methoden sind virtuell, sodass sie in abgeleiteten Klassen überschrieben werden können.
Im geschützten Bereich der Klasse deklarieren wir die virtuelle Methode zur Erstellung eines Erfassungsbereichs (die Schaltflächen und der Schieberegler werden in der Methode erstellt) und den geschützten Konstruktor (Standard für grafische Elemente der Bibliothek). In den öffentlichen Abschnitt schreiben wir die Methoden, die die Flags für die Wartung der Objekteigenschaften zurückgeben, den parametrischen Konstruktor und den Event-Handler für den Timer des virtuellen Objekts:
protected: //--- Create the capture area object virtual void CreateThumbArea(void); //--- Protected constructor with object type, chart ID and subwindow CScrollBar(const ENUM_GRAPH_ELEMENT_TYPE type, CGCnvElement *main_obj,CGCnvElement *base_obj, const long chart_id, const int subwindow, const string descript, const int x, const int y, const int w, const int h); public: //--- Supported object properties (1) integer, (2) real and (3) string ones virtual bool SupportProperty(ENUM_CANV_ELEMENT_PROP_INTEGER property) { return true; } virtual bool SupportProperty(ENUM_CANV_ELEMENT_PROP_DOUBLE property) { return true; } virtual bool SupportProperty(ENUM_CANV_ELEMENT_PROP_STRING property) { return true; } //--- Constructor CScrollBar(CGCnvElement *main_obj,CGCnvElement *base_obj, const long chart_id, const int subwindow, const string descript, const int x, const int y, const int w, const int h); //--- Timer virtual void OnTimer(void); }; //+------------------------------------------------------------------+
Jedes Mal, wenn wir ein neues grafisches Element erstellen, berücksichtigen wir ähnliche Methoden - sie sind alle identisch und haben den gleichen Zweck für jedes grafische Objekt in der Bibliothek.
Betrachten wir nun die Implementierung der angegebenen Methoden.
Geschützter Konstruktor:
//+---------------------------------------------+ //| Protected constructor with an object type, | //| chart ID and subwindow | //+---------------------------------------------+ CScrollBar::CScrollBar(const ENUM_GRAPH_ELEMENT_TYPE type, CGCnvElement *main_obj,CGCnvElement *base_obj, const long chart_id, const int subwindow, const string descript, const int x, const int y, const int w, const int h) : CWinFormBase(type,main_obj,base_obj,chart_id,subwindow,descript,x,y,w,h) { //--- Set the specified graphical element type for the object and assign the library object type to the current object this.SetTypeElement(type); this.m_type=OBJECT_DE_TYPE_GWF_HELPER; this.Initialize(); } //+------------------------------------------------------------------+
Der Konstruktor erhält den Typ des erstellten Objekts und andere Standardparameter. In der Initialisierungszeichenfolge wird der Typ des erstellten Objekts an den Konstruktor der übergeordneten Klasse übergeben. Im Konstruktor legen wir den Typ eines grafischen Elements sowie den Typ eines grafischen Bibliotheksobjekts fest, und rufen die Parameterinitialisierungsmethode auf.
Der parametrische Konstruktor:
//+------------------------------------------------------------------+ //| Constructor indicating the main and base objects, | //| chart ID and subwindow | //+------------------------------------------------------------------+ CScrollBar::CScrollBar(CGCnvElement *main_obj,CGCnvElement *base_obj, const long chart_id, const int subwindow, const string descript, const int x, const int y, const int w, const int h) : CWinFormBase(GRAPH_ELEMENT_TYPE_WF_SCROLL_BAR,main_obj,base_obj,chart_id,subwindow,descript,x,y,w,h) { this.SetTypeElement(GRAPH_ELEMENT_TYPE_WF_SCROLL_BAR); this.m_type=OBJECT_DE_TYPE_GWF_HELPER; this.Initialize(); } //+------------------------------------------------------------------+
Hier ist alles identisch mit dem geschützten Konstruktor, aber der Objekttyp ist in der Initialisierungszeichenfolge als ScrollBar fest codiert.
Die Methode zur Initialisierung der Elementeigenschaften:
//+---------------------------------------------+ //| Initialize the element properties | //+---------------------------------------------+ void CScrollBar::Initialize(void) { this.SetBorderSizeAll(1); this.SetBorderStyle(FRAME_STYLE_SIMPLE); this.SetBackgroundColor(CLR_DEF_CONTROL_SCROLL_BAR_TRACK_BACK_COLOR,true); this.SetBorderColor(CLR_DEF_CONTROL_SCROLL_BAR_TRACK_BORDER_COLOR,true); this.SetForeColor(CLR_DEF_CONTROL_SCROLL_BAR_TRACK_FORE_COLOR,true); } //+------------------------------------------------------------------+
Hier stellen wir die Größe des Rahmens des Objekts auf ein Pixel auf jeder Seite ein, setzen den Rahmentyp auf „einfach“ und fügen die Hintergrund-, Rahmen- und Textfarben des Elements hinzu.
Die Methode, die das Objekt Capture Area erstellt:
//+---------------------------------------------+ //| Create the capture area object | //+---------------------------------------------+ void CScrollBar::CreateThumbArea(void) { this.CreateArrowButtons(DEF_ARROW_BUTTON_SIZE,DEF_ARROW_BUTTON_SIZE); } //+------------------------------------------------------------------+
Die virtuelle Methode CreateArrowButtons() wird in der Methode aufgerufen, um die Pfeilschaltflächen-Objekte und den Schieberegler zu erstellen, die in nachgeordneten Objekten neu definiert werden sollten.
Die Methode, mit der die Größe des Erfassungsbereichs berechnet wird:
//+---------------------------------------------+ //| Calculate the capture area size | //+---------------------------------------------+ int CScrollBar::CalculateThumbAreaSize(void) { return 0; } //+------------------------------------------------------------------+
Hier gibt die Methode Null zurück und sollte in abgeleiteten Klassen überschrieben werden, da für jedes der abgeleiteten Objekte die Größe und Position des Schiebereglers unterschiedlich sind.
Die Methode zum Erstellen eines neuen grafischen Objekts:
//+---------------------------------------------+ //| Create a new graphical object | //+---------------------------------------------+ CGCnvElement *CScrollBar::CreateNewGObject(const ENUM_GRAPH_ELEMENT_TYPE type, const int obj_num, const string descript, const int x, const int y, const int w, const int h, const color colour, const uchar opacity, const bool movable, const bool activity) { CGCnvElement *element=NULL; switch(type) { case GRAPH_ELEMENT_TYPE_WF_BUTTON : element=new CButton(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h); break; case GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_DOWN : element=new CArrowDownButton(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h); break; case GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_UP : element=new CArrowUpButton(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h); break; case GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_LEFT : element=new CArrowLeftButton(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h); break; case GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_RIGHT : element=new CArrowRightButton(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h); break; default: break; } if(element==NULL) ::Print(DFUN,CMessage::Text(MSG_LIB_SYS_FAILED_CREATE_ELM_OBJ),this.TypeElementDescription(type)); return element; } //+------------------------------------------------------------------+
Die Methode ist Standard für grafische Objekte der Bibliothek. Es ermöglicht uns, fünf Steuerelemente zu erstellen: Schaltflächen mit Auf-Ab-Pfeilen, Rechts-Links-Pfeilen und dem Schaltflächenobjekt, auf dem der Schieberegler basieren soll.
Ereignisbehandlung durch den Timer:
//+---------------------------------------------+ //| Timer | //+---------------------------------------------+ void CScrollBar::OnTimer(void) { } //+------------------------------------------------------------------+
Im Moment ist die Methode leer und tut nichts. Ich werde mich in späteren Artikeln damit befassen.
Dieses Objekt ist eine abstrakte Bildlaufleiste. Es tut nichts und wird verwendet, um zwei andere Objekte zu erstellen, die auf ihm basieren - vertikale und horizontale Bildlaufleisten.
ScrollBarVertical- und ScrollBarHorisontal-Steuerelemente, die von dem Basis-Steuerelement abgeleitet sind
Erstellen wir die Objekte, die von dem abstrakten Basisobjekt der Bildlaufleiste abgeleitet sind - vertikale und horizontale.
In \MQL5\Include\DoEasy\Objects\Graph\WForms\Helpers\ erstellen wir eine neue Datei ScrollBarVertical.mqh der Klasse CScrollBarVertical.
Die Klasse sollte vom Basis-Scrollbar-Objekt abgeleitet werden, während dessen Datei sowie einige andere notwendige Dateien in die erstellte Klassendatei aufgenommen werden sollten:
//+------------------------------------------------------------------+ //| ScrollBarVertical.mqh | //| Copyright 2022, MetaQuotes Ltd. | //| https://mql5.com/en/users/artmedia70 | //+------------------------------------------------------------------+ #property copyright "Copyright 2022, MetaQuotes Ltd." #property link "https://mql5.com/en/users/artmedia70" #property version "1.00" #property strict // Necessary for mql4 //+---------------------------------------------+ //| Include files | //+---------------------------------------------+ #include "..\Containers\Container.mqh" #include "..\Common Controls\Button.mqh" #include "ArrowDownButton.mqh" #include "ArrowUpButton.mqh" #include "ScrollBar.mqh" //+------------------------------------------------------------------+ //| CScrollBarVertical object class of WForms controls | //+------------------------------------------------------------------+ class CScrollBarVertical : public CScrollBar { }
Im privaten Abschnitt der Klasse deklarieren wir die virtuelle Methode zur Erstellung von Pfeilschaltflächen und die Methode zur Berechnung der Größe des Erfassungsbereichs.
Im geschützten Abschnitt deklarieren wir den Konstruktor der geschützten Klasse, während wir im öffentlichen Abschnitt die Methoden implementieren, die Flags für die Verwaltung der Objekteigenschaften, den parametrischen Konstruktor und den Timer-Event-Handler zurückgeben:
//+------------------------------------------------------------------+ //| CScrollBarVertical object class of WForms controls | //+------------------------------------------------------------------+ class CScrollBarVertical : public CScrollBar { private: //--- Create the ArrowButton objects virtual void CreateArrowButtons(const int width,const int height); //--- Calculate the capture area size virtual int CalculateThumbAreaSize(void); protected: //--- Protected constructor with object type, chart ID and subwindow CScrollBarVertical(const ENUM_GRAPH_ELEMENT_TYPE type, CGCnvElement *main_obj,CGCnvElement *base_obj, const long chart_id, const int subwindow, const string descript, const int x, const int y, const int w, const int h); public: //--- Supported object properties (1) integer, (2) real and (3) string ones virtual bool SupportProperty(ENUM_CANV_ELEMENT_PROP_INTEGER property) { return true; } virtual bool SupportProperty(ENUM_CANV_ELEMENT_PROP_DOUBLE property) { return true; } virtual bool SupportProperty(ENUM_CANV_ELEMENT_PROP_STRING property) { return true; } //--- Constructor CScrollBarVertical(CGCnvElement *main_obj,CGCnvElement *base_obj, const long chart_id, const int subwindow, const string descript, const int x, const int y, const int w, const int h); //--- Timer virtual void OnTimer(void); }; //+------------------------------------------------------------------+
Schauen wir uns die angegebenen Methoden genauer an.
Geschützter Konstruktor:
//+---------------------------------------------+ //| Protected constructor with an object type, | //| chart ID and subwindow | //+---------------------------------------------+ CScrollBarVertical::CScrollBarVertical(const ENUM_GRAPH_ELEMENT_TYPE type, CGCnvElement *main_obj,CGCnvElement *base_obj, const long chart_id, const int subwindow, const string descript, const int x, const int y, const int w, const int h) : CScrollBar(type,main_obj,base_obj,chart_id,subwindow,descript,x,y,w,h) { //--- Set the specified graphical element type for the object and assign the library object type to the current object this.SetTypeElement(type); this.CreateThumbArea(); } //+------------------------------------------------------------------+
Der Konstruktor empfängt den Typ eines erstellten Objekts und andere Parameter seiner Erstellung. Der Objekttyp wird im Initialisierungsstring an den Konstruktor der übergeordneten Klasse übergeben. Im Konstruktor legen wir den Typ des grafischen Objekts fest und rufen die Methode zur Erstellung des Erfassungsbereichs (Schaltflächen und Schieberegler) auf.
Der parametrische Konstruktor:
//+------------------------------------------------------------------+ //| Constructor indicating the main and base objects, | //| chart ID and subwindow | //+------------------------------------------------------------------+ CScrollBarVertical::CScrollBarVertical(CGCnvElement *main_obj,CGCnvElement *base_obj, const long chart_id, const int subwindow, const string descript, const int x, const int y, const int w, const int h) : CScrollBar(GRAPH_ELEMENT_TYPE_WF_SCROLL_BAR_VERTICAL,main_obj,base_obj,chart_id,subwindow,descript,x,y,w,h) { this.SetTypeElement(GRAPH_ELEMENT_TYPE_WF_SCROLL_BAR_VERTICAL); this.CreateThumbArea(); } //+------------------------------------------------------------------+
Hier ist alles identisch mit dem oben besprochenen geschützten Konstruktor, aber der Objekttyp ist fest als „Vertical scrollbar“ kodiert.
Die Methode, die die ArrowButton-Objekte erstellt:
//+---------------------------------------------+ //| Create the ArrowButton objects | //+---------------------------------------------+ void CScrollBarVertical::CreateArrowButtons(const int width,const int height) { this.CreateNewElement(GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_UP, -1,0, width,height,this.BackgroundColor(),255,true,false); this.CreateNewElement(GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_DOWN,-1,this.Height()-2*height,width,height,this.BackgroundColor(),255,true,false); this.CreateNewElement(GRAPH_ELEMENT_TYPE_WF_BUTTON,0,this.Height()/2-height,width,height,CLR_DEF_CONTROL_SCROLL_BAR_THUMB_COLOR,255,true,false); } //+------------------------------------------------------------------+
Hier erstellen wir ein Schaltflächenobjekt mit dem Pfeil nach oben, ein Schaltflächenobjekt mit dem Pfeil nach unten und ein Schaltflächenobjekt, das als Schieberegler fungieren wird.
In all diesen Objekten ist die Funktionalität der Interaktion mit dem Mauszeiger bereits angelegt. Daher werde ich im nächsten Artikel einfach eine Ereignisbehandlung für diese Objekte implementieren, um den Inhalt des Containers zu verwalten, an den die Bildlaufleiste angehängt ist.
Die Methode, mit der die Größe des Erfassungsbereichs berechnet wird:
//+---------------------------------------------+ //| Calculate the capture area size | //+---------------------------------------------+ int CScrollBarVertical::CalculateThumbAreaSize(void) { return 0; } //+------------------------------------------------------------------+
In dieser Version des Objekts gibt die Methode einfach null zurück. Das Schieberegler-Objekt wird mit einer festen Größe erstellt, und alle Änderungen an seiner Größe werden in den nachfolgenden Artikeln vorgenommen. Die Größe des Schiebereglers hängt von der Menge des Inhalts ab, der über den Container hinausgeht - je mehr Daten nicht in den sichtbaren Bereich des Formulars passen, desto kleiner ist der Schieberegler. Ich werde mich mit all diesen Berechnungen beschäftigen, wenn ich die Funktionalität für die Interaktion der Maus mit der Bildlaufleiste erstelle.
Ereignisbehandlung durch den Timer:
//+---------------------------------------------+ //| Timer | //+---------------------------------------------+ void CScrollBarVertical::OnTimer(void) { } //+------------------------------------------------------------------+
Wir werden uns in den folgenden Artikeln mit der Erstellung der Funktionen der Ereignisbehandlung befassen.
Das Steuerelement für die horizontale Bildlaufleiste ist mit der neu erstellten vertikalen Bildlaufleiste identisch. Betrachten wir die Klasse als Ganzes, ohne weitere Erklärungen, denn alles oben Gesagte gilt auch für die Klasse dieses Objekts.
Die Klasse sollte in ScrollBarHorisontal.mqh in \MQL5\Include\DoEasy\Objects\Graph\WForms\Helpers\ScrollBarHorisontal.mqh erstellt werden:
//+------------------------------------------------------------------+ //| ScrollBarVertical.mqh | //| Copyright 2022, MetaQuotes Ltd. | //| https://mql5.com/en/users/artmedia70 | //+------------------------------------------------------------------+ #property copyright "Copyright 2022, MetaQuotes Ltd." #property link "https://mql5.com/en/users/artmedia70" #property version "1.00" #property strict // Necessary for mql4 //+---------------------------------------------+ //| Include files | //+---------------------------------------------+ #include "..\Containers\Container.mqh" #include "..\Common Controls\Button.mqh" #include "ArrowLeftButton.mqh" #include "ArrowRightButton.mqh" //+------------------------------------------------------------------+ //| CScrollBarHorisontal object class of WForms controls | //+------------------------------------------------------------------+ class CScrollBarHorisontal : public CScrollBar { private: //--- Create the ArrowButton objects virtual void CreateArrowButtons(const int width,const int height); //--- Calculate the capture area size virtual int CalculateThumbAreaSize(void); protected: //--- Protected constructor with object type, chart ID and subwindow CScrollBarHorisontal(const ENUM_GRAPH_ELEMENT_TYPE type, CGCnvElement *main_obj,CGCnvElement *base_obj, const long chart_id, const int subwindow, const string descript, const int x, const int y, const int w, const int h); public: //--- Supported object properties (1) integer, (2) real and (3) string ones virtual bool SupportProperty(ENUM_CANV_ELEMENT_PROP_INTEGER property) { return true; } virtual bool SupportProperty(ENUM_CANV_ELEMENT_PROP_DOUBLE property) { return true; } virtual bool SupportProperty(ENUM_CANV_ELEMENT_PROP_STRING property) { return true; } //--- Constructor CScrollBarHorisontal(CGCnvElement *main_obj,CGCnvElement *base_obj, const long chart_id, const int subwindow, const string descript, const int x, const int y, const int w, const int h); //--- Timer virtual void OnTimer(void); }; //+---------------------------------------------+ //| Protected constructor with an object type, | //| chart ID and subwindow | //+---------------------------------------------+ CScrollBarHorisontal::CScrollBarHorisontal(const ENUM_GRAPH_ELEMENT_TYPE type, CGCnvElement *main_obj,CGCnvElement *base_obj, const long chart_id, const int subwindow, const string descript, const int x, const int y, const int w, const int h) : CScrollBar(type,main_obj,base_obj,chart_id,subwindow,descript,x,y,w,h) { //--- Set the specified graphical element type for the object and assign the library object type to the current object this.SetTypeElement(type); this.CreateThumbArea(); } //+------------------------------------------------------------------+ //| Constructor indicating the main and base objects, | //| chart ID and subwindow | //+------------------------------------------------------------------+ CScrollBarHorisontal::CScrollBarHorisontal(CGCnvElement *main_obj,CGCnvElement *base_obj, const long chart_id, const int subwindow, const string descript, const int x, const int y, const int w, const int h) : CScrollBar(GRAPH_ELEMENT_TYPE_WF_SCROLL_BAR_HORISONTAL,main_obj,base_obj,chart_id,subwindow,descript,x,y,w,h) { this.SetTypeElement(GRAPH_ELEMENT_TYPE_WF_SCROLL_BAR_HORISONTAL); this.CreateThumbArea(); } //+---------------------------------------------+ //| Create the ArrowButton objects | //+---------------------------------------------+ void CScrollBarHorisontal::CreateArrowButtons(const int width,const int height) { this.CreateNewElement(GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_LEFT, -1,-1, width,height,this.BackgroundColor(),255,true,false); this.CreateNewElement(GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_RIGHT,this.Width()-2*width,-1,width,height,this.BackgroundColor(),255,true,false); this.CreateNewElement(GRAPH_ELEMENT_TYPE_WF_BUTTON,this.Width()/2-width,0,width,height,CLR_DEF_CONTROL_SCROLL_BAR_THUMB_COLOR,255,true,false); } //+---------------------------------------------+ //| Calculate the capture area size | //+---------------------------------------------+ int CScrollBarHorisontal::CalculateThumbAreaSize(void) { return 0; } //+---------------------------------------------+ //| Timer | //+---------------------------------------------+ void CScrollBarHorisontal::OnTimer(void) { } //+------------------------------------------------------------------+
Die oben beschriebenen Scrollbar-Objektklassen werden standardmäßig in jedem Container-Objekt unabhängig von einem Nutzer angelegt und sofort nach dem Anlegen ausgeblendet. Objekte werden nur angezeigt, wenn der Inhalt des Containers seine Grenzen überschreitet, oder in Situationen, die von einem Entwickler festgelegt wurden. Ich werde sie während des Tests im Programm anzeigen.
Da Objekte standardmäßig in Containerobjekten vorhanden sein sollten, sollte ihre Erstellung in der Klasse des Containerobjekts in \MQL5\Include\DoEasy\Objects\Graph\WForms\Containers\Container.mqh organisiert werden.
Fügen wir die Dateien der neu erstellten Objekte in die Datei des Containerobjekts ein. Im privaten Abschnitt wird eine einfach geschriebene virtuelle Methode zur Erstellung von grafischen Objekten in die Methodendeklaration umgewandelt (ich werde ihre Implementierung weiter unten schreiben - vorher wurde sie in geerbten Klassen implementiert). Wir deklarieren auch die Methoden zur Erstellung von vertikalen und horizontalen Bildlaufleisten. Im geschützten Abschnitt deklarieren wir die Methode zur Erstellung beider Bildlaufleisten:
//+------------------------------------------------------------------+ //| Container.mqh | //| Copyright 2022, MetaQuotes Ltd. | //| https://mql5.com/en/users/artmedia70 | //+------------------------------------------------------------------+ #property copyright "Copyright 2022, MetaQuotes Ltd." #property link "https://mql5.com/en/users/artmedia70" #property version "1.00" #property strict // Necessary for mql4 //+---------------------------------------------+ //| Include files | //+---------------------------------------------+ #include "..\WinFormBase.mqh" #include "..\Common Controls\RadioButton.mqh" #include "..\Common Controls\Button.mqh" #include "..\Helpers\ScrollBarVertical.mqh" #include "..\Helpers\ScrollBarHorisontal.mqh" //+------------------------------------------------------------------+ //| Class of the base container object of WForms controls | //+------------------------------------------------------------------+ class CContainer : public CWinFormBase { private: //--- Create a new graphical object virtual CGCnvElement *CreateNewGObject(const ENUM_GRAPH_ELEMENT_TYPE type, const int element_num, const string descript, const int x, const int y, const int w, const int h, const color colour, const uchar opacity, const bool movable, const bool activity);// { return NULL; } //--- Calculate Dock objects' binding coordinates void CalculateCoords(CArrayObj *list); //--- Create the (1) vertical and (2) horizontal ScrollBar CWinFormBase *CreateScrollBarVertical(const int width); CWinFormBase *CreateScrollBarHorisontal(const int width); protected: //--- Adjust the element size to fit its content bool AutoSizeProcess(const bool redraw); //--- Set parameters for the attached object void SetObjParams(CWinFormBase *obj,const color colour); //--- Create vertical and horizontal ScrollBar objects void CreateScrollBars(const int width); public:
In beiden Klassenkonstruktoren rufen wir ganz am Ende der Objekterstellung die Methode zur Erstellung beider Bildlaufleisten auf:
//+---------------------------------------------+ //| Protected constructor with an object type, | //| chart ID and subwindow | //+---------------------------------------------+ CContainer::CContainer(const ENUM_GRAPH_ELEMENT_TYPE type, CGCnvElement *main_obj,CGCnvElement *base_obj, const long chart_id, const int subwindow, const string descript, const int x, const int y, const int w, const int h) : CWinFormBase(type,main_obj,base_obj,chart_id,subwindow,descript,x,y,w,h) { //--- Set the specified graphical element type for the object and assign the library object type to the current object this.SetTypeElement(type); this.m_type=OBJECT_DE_TYPE_GWF_CONTAINER; this.SetForeColor(CLR_DEF_FORE_COLOR,true); this.SetFontBoldType(FW_TYPE_NORMAL); this.SetMarginAll(3); this.SetPaddingAll(0); this.SetDockMode(CANV_ELEMENT_DOCK_MODE_NONE,false); this.SetBorderStyle(FRAME_STYLE_NONE); this.SetAutoScroll(false,false); this.SetAutoScrollMarginAll(0); this.SetAutoSize(false,false); this.SetAutoSizeMode(CANV_ELEMENT_AUTO_SIZE_MODE_GROW,false); this.Initialize(); this.SetCoordXInit(x); this.SetCoordYInit(y); this.SetWidthInit(w); this.SetHeightInit(h); this.CreateScrollBars(10); } //+------------------------------------------------------------------+ //| Constructor indicating the main and base objects, | //| chart ID and subwindow | //+------------------------------------------------------------------+ CContainer::CContainer(CGCnvElement *main_obj,CGCnvElement *base_obj, const long chart_id, const int subwindow, const string descript, const int x, const int y, const int w, const int h) : CWinFormBase(GRAPH_ELEMENT_TYPE_WF_CONTAINER,main_obj,base_obj,chart_id,subwindow,descript,x,y,w,h) { this.SetTypeElement(GRAPH_ELEMENT_TYPE_WF_CONTAINER); this.m_type=OBJECT_DE_TYPE_GWF_CONTAINER; this.SetForeColor(CLR_DEF_FORE_COLOR,true); this.SetFontBoldType(FW_TYPE_NORMAL); this.SetMarginAll(3); this.SetPaddingAll(0); this.SetDockMode(CANV_ELEMENT_DOCK_MODE_NONE,false); this.SetBorderStyle(FRAME_STYLE_NONE); this.SetAutoScroll(false,false); this.SetAutoScrollMarginAll(0); this.SetAutoSize(false,false); this.SetAutoSizeMode(CANV_ELEMENT_AUTO_SIZE_MODE_GROW,false); this.Initialize(); this.SetCoordXInit(x); this.SetCoordYInit(y); this.SetWidthInit(w); this.SetHeightInit(h); this.CreateScrollBars(10); } //+------------------------------------------------------------------+
Nachdem das Container-Objekt erstellt wurde, werden ihm zwei Bildlaufleisten angehängt. Sobald sie erstellt sind, werden die Balken ausgeblendet.
In der Methode, die Parameter für das angehängte Objekt festlegt, schreiben wir einen Codeblock, in dem die Eigenschaften der neu erstellten Bildlaufleistenobjekte festgelegt werden:
//+---------------------------------------------+ //| Set parameters for the attached object | //+---------------------------------------------+ void CContainer::SetObjParams(CWinFormBase *obj,const color colour) { //--- Set the text color of the object to be the same as that of the base container obj.SetForeColor(this.ForeColor(),true); //--- If the created object is not a container, set the same group for it as the one for its base object if(obj.TypeGraphElement()<GRAPH_ELEMENT_TYPE_WF_CONTAINER || obj.TypeGraphElement()>GRAPH_ELEMENT_TYPE_WF_SPLIT_CONTAINER) obj.SetGroup(this.Group()); //--- Depending on the object type switch(obj.TypeGraphElement()) { //--- For the Container, Panel and GroupBox WinForms objects case GRAPH_ELEMENT_TYPE_WF_CONTAINER : case GRAPH_ELEMENT_TYPE_WF_PANEL : case GRAPH_ELEMENT_TYPE_WF_GROUPBOX : obj.SetBorderColor(obj.BackgroundColor(),true); break; //--- For "Label", "CheckBox" and "RadioButton" WinForms objects case GRAPH_ELEMENT_TYPE_WF_LABEL : case GRAPH_ELEMENT_TYPE_WF_CHECKBOX : case GRAPH_ELEMENT_TYPE_WF_RADIOBUTTON : obj.SetForeColor(colour==clrNONE ? this.ForeColor() : colour,true); obj.SetBorderColor(obj.ForeColor(),true); obj.SetBackgroundColor(CLR_CANV_NULL,true); obj.SetOpacity(0,false); break; //--- For "Button", "TabHeader", TabField and "ListBoxItem" WinForms objects case GRAPH_ELEMENT_TYPE_WF_BUTTON : case GRAPH_ELEMENT_TYPE_WF_TAB_HEADER : case GRAPH_ELEMENT_TYPE_WF_TAB_FIELD : case GRAPH_ELEMENT_TYPE_WF_LIST_BOX_ITEM : obj.SetForeColor(this.ForeColor(),true); obj.SetBackgroundColor(colour==clrNONE ? CLR_DEF_CONTROL_STD_BACK_COLOR : colour,true); obj.SetBorderColor(obj.ForeColor(),true); obj.SetBorderStyle(FRAME_STYLE_SIMPLE); break; //--- For "ListBox", "CheckedListBox" and "ButtonListBox" WinForms object case GRAPH_ELEMENT_TYPE_WF_LIST_BOX : case GRAPH_ELEMENT_TYPE_WF_CHECKED_LIST_BOX : case GRAPH_ELEMENT_TYPE_WF_BUTTON_LIST_BOX : obj.SetBackgroundColor(colour==clrNONE ? CLR_DEF_CONTROL_STD_BACK_COLOR : colour,true); obj.SetBorderColor(CLR_DEF_BORDER_COLOR,true); obj.SetForeColor(CLR_DEF_FORE_COLOR,true); break; //--- For "TabControl" WinForms object case GRAPH_ELEMENT_TYPE_WF_TAB_CONTROL : obj.SetBackgroundColor(colour==clrNONE ? CLR_DEF_CONTROL_TAB_BACK_COLOR : colour,true); obj.SetBorderColor(CLR_DEF_CONTROL_TAB_BORDER_COLOR,true); obj.SetForeColor(CLR_DEF_FORE_COLOR,true); obj.SetOpacity(CLR_DEF_CONTROL_TAB_OPACITY); break; //--- For "SplitContainer" WinForms object case GRAPH_ELEMENT_TYPE_WF_SPLIT_CONTAINER : obj.SetBackgroundColor(colour==clrNONE ? CLR_CANV_NULL : colour,true); obj.SetBorderColor(CLR_CANV_NULL,true); obj.SetForeColor(CLR_DEF_FORE_COLOR,true); obj.SetOpacity(0); break; //--- For "SplitContainerPanel" WinForms object case GRAPH_ELEMENT_TYPE_WF_SPLIT_CONTAINER_PANEL: obj.SetBackgroundColor(colour==clrNONE ? CLR_DEF_CONTROL_SPLIT_CONTAINER_BACK_COLOR : colour,true); obj.SetBorderColor(CLR_DEF_CONTROL_SPLIT_CONTAINER_BORDER_COLOR,true); obj.SetForeColor(CLR_DEF_FORE_COLOR,true); break; //--- For "Splitter" WinForms object case GRAPH_ELEMENT_TYPE_WF_SPLITTER : obj.SetBackgroundColor(colour==clrNONE ? CLR_CANV_NULL : colour,true); obj.SetBorderColor(CLR_CANV_NULL,true); obj.SetForeColor(CLR_DEF_FORE_COLOR,true); obj.SetOpacity(0); obj.SetDisplayed(false); obj.Hide(); break; //--- For the "ArrowButton" WinForms object case GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON : case GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_UP : case GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_DOWN : case GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_LEFT : case GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_RIGHT : obj.SetBorderColor(CLR_DEF_CONTROL_TAB_HEAD_BORDER_COLOR,true); obj.SetBorderStyle(FRAME_STYLE_SIMPLE); break; //--- For "Hint" WinForms object case GRAPH_ELEMENT_TYPE_WF_HINT_BASE : obj.SetBackgroundColor(CLR_CANV_NULL,true); obj.SetBorderColor(CLR_CANV_NULL,true); obj.SetForeColor(CLR_CANV_NULL,true); obj.SetOpacity(0,false); obj.SetBorderStyle(FRAME_STYLE_NONE); break; //--- For "HintMoveLeft", "HintMoveRight", "HintMoveUp" and "HintMoveDown" WinForms object case GRAPH_ELEMENT_TYPE_WF_HINT_MOVE_LEFT : case GRAPH_ELEMENT_TYPE_WF_HINT_MOVE_RIGHT : case GRAPH_ELEMENT_TYPE_WF_HINT_MOVE_UP : case GRAPH_ELEMENT_TYPE_WF_HINT_MOVE_DOWN : obj.SetBackgroundColor(CLR_CANV_NULL,true); obj.SetBorderColor(CLR_CANV_NULL,true); obj.SetForeColor(CLR_DEF_CONTROL_HINT_FORE_COLOR,true); obj.SetOpacity(0,false); obj.SetBorderStyle(FRAME_STYLE_NONE); break; //--- For ToolTip WinForms object case GRAPH_ELEMENT_TYPE_WF_TOOLTIP : obj.SetBackgroundColor(CLR_DEF_CONTROL_HINT_BACK_COLOR,true); obj.SetBorderColor(CLR_DEF_CONTROL_HINT_BORDER_COLOR,true); obj.SetForeColor(CLR_DEF_CONTROL_HINT_FORE_COLOR,true); obj.SetBorderStyle(FRAME_STYLE_SIMPLE); obj.SetOpacity(0,false); obj.SetDisplayed(false); obj.Hide(); break; //--- For BarProgressBar WinForms object case GRAPH_ELEMENT_TYPE_WF_BAR_PROGRESS_BAR : obj.SetBackgroundColor(CLR_DEF_CONTROL_PROGRESS_BAR_BAR_COLOR,true); obj.SetBorderColor(CLR_DEF_CONTROL_PROGRESS_BAR_BAR_COLOR,true); obj.SetForeColor(CLR_DEF_CONTROL_PROGRESS_BAR_FORE_COLOR,true); obj.SetBorderStyle(FRAME_STYLE_NONE); break; //--- For ProgressBar WinForms object case GRAPH_ELEMENT_TYPE_WF_PROGRESS_BAR : obj.SetBackgroundColor(CLR_DEF_CONTROL_PROGRESS_BAR_BACK_COLOR,true); obj.SetBorderColor(CLR_DEF_CONTROL_PROGRESS_BAR_BORDER_COLOR,true); obj.SetForeColor(CLR_DEF_CONTROL_PROGRESS_BAR_FORE_COLOR,true); obj.SetBorderStyle(FRAME_STYLE_SIMPLE); break; //--- For ScrollBar WinForms object case GRAPH_ELEMENT_TYPE_WF_SCROLL_BAR : case GRAPH_ELEMENT_TYPE_WF_SCROLL_BAR_HORISONTAL: case GRAPH_ELEMENT_TYPE_WF_SCROLL_BAR_VERTICAL : obj.SetBackgroundColor(CLR_DEF_CONTROL_SCROLL_BAR_TRACK_BACK_COLOR,true); obj.SetBorderColor(CLR_DEF_CONTROL_SCROLL_BAR_TRACK_BORDER_COLOR,true); obj.SetForeColor(CLR_DEF_CONTROL_SCROLL_BAR_TRACK_FORE_COLOR,true); obj.SetBorderSizeAll(1); obj.SetBorderStyle(FRAME_STYLE_SIMPLE); break; //--- For GlareObj WinForms object case GRAPH_ELEMENT_TYPE_WF_GLARE_OBJ : obj.SetBackgroundColor(CLR_CANV_NULL,true); obj.SetBorderColor(CLR_CANV_NULL,true); obj.SetForeColor(CLR_CANV_NULL,true); obj.SetBorderStyle(FRAME_STYLE_NONE); break; default: break; } obj.Crop(); } //+------------------------------------------------------------------+
Die Methode wird immer aufgerufen, nachdem ein an den Container angehängtes Objekt erstellt wurde. Die Methode legt die Standardparameter für das neu erstellte Objekt fest. Sie können später durch andere ersetzt werden. Einmal erstellt, werden sie bei dieser Methode jedoch immer automatisch gesetzt.
Die Methode, die vertikale und horizontale ScrollBar-Objekte erzeugt:
//+------------------------------------------------------------------+ //| Create vertical and horizontal ScrollBar objects | //+------------------------------------------------------------------+ void CContainer::CreateScrollBars(const int width) { //--- Create the vertical scrollbar object CScrollBarVertical *sbv=this.CreateScrollBarVertical(DEF_ARROW_BUTTON_SIZE); //--- If the object has been created if(sbv!=NULL) { //--- set the object non-display flag and hide it sbv.SetDisplayed(false); sbv.Hide(); } //--- Create the horizontal scrollbar object CScrollBarHorisontal *sbh=this.CreateScrollBarHorisontal(DEF_ARROW_BUTTON_SIZE); //--- If the object has been created if(sbh!=NULL) { //--- set the object non-display flag and hide it sbh.SetDisplayed(false); sbh.Hide(); } } //+------------------------------------------------------------------+
Die Logik der Methode ist im Code kommentiert. Hier erstellen wir einfach zwei Bildlaufleisten und blenden sie aus, indem wir sie so einstellen, dass sie beim Aktualisieren, Anzeigen und Neuzeichnen des darunter liegenden Objekts, an das sie angehängt sind, keine Flags zeigen. Mit anderen Worten: Bildlaufleisten können nur dann angezeigt werden, wenn ihre Anzeige im Programm- oder Bibliothekscode ausdrücklich erlaubt wird.
Die Methode, die den vertikalen ScrollBar erstellt:
//+---------------------------------------------+ //| Create the vertical ScrollBar | //+---------------------------------------------+ CWinFormBase *CContainer::CreateScrollBarVertical(const int width) { //--- If failed to create the vertical scroll bar object, return NULL if(!this.CreateNewElement(GRAPH_ELEMENT_TYPE_WF_SCROLL_BAR_VERTICAL,this.RightEdge()-width,0,width,this.HeightWorkspace(),this.BackgroundColor(),255,true,false)) .return NULL; //--- Return the pointer to the vertical scrollbar object return this.GetElementByType(GRAPH_ELEMENT_TYPE_WF_SCROLL_BAR_VERTICAL,0); } //+------------------------------------------------------------------+
Erstellen eines Objekts und Rückgabe des Zeigers auf dieses Objekt aus der Liste der angehängten Objekte.
Die Methode, die den horizontalen ScrollBar erstellt:
//+---------------------------------------------+ //| Create the horizontal ScrollBar | //+---------------------------------------------+ CWinFormBase *CContainer::CreateScrollBarHorisontal(const int width) { //--- If failed to create the horizontal scroll bar object, return NULL if(!this.CreateNewElement(GRAPH_ELEMENT_TYPE_WF_SCROLL_BAR_HORISONTAL,0,this.BottomEdge()-width,this.WidthWorkspace(),width,this.BackgroundColor(),255,true,false)) .return NULL; //--- Return the pointer to the horizontal scrollbar object return this.GetElementByType(GRAPH_ELEMENT_TYPE_WF_SCROLL_BAR_HORISONTAL,0); } //+------------------------------------------------------------------+
Erstellen eines Objekts und Rückgabe des Zeigers auf dieses Objekt aus der Liste der angehängten Objekte.
Die Methode zum Erstellen eines neuen grafischen Objekts:
//+---------------------------------------------+ //| Create a new graphical object | //+---------------------------------------------+ CGCnvElement *CContainer::CreateNewGObject(const ENUM_GRAPH_ELEMENT_TYPE type, const int obj_num, const string descript, const int x, const int y, const int w, const int h, const color colour, const uchar opacity, const bool movable, const bool activity) { CGCnvElement *element=NULL; switch(type) { case GRAPH_ELEMENT_TYPE_WF_SCROLL_BAR : element=new CScrollBar(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h); break; case GRAPH_ELEMENT_TYPE_WF_SCROLL_BAR_VERTICAL : element=new CScrollBarVertical(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h); break; case GRAPH_ELEMENT_TYPE_WF_SCROLL_BAR_HORISONTAL: element=new CScrollBarHorisontal(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h);break; default : break; } if(element==NULL) ::Print(DFUN,CMessage::Text(MSG_LIB_SYS_FAILED_CREATE_ELM_OBJ),this.TypeElementDescription(type)); return element; } //+------------------------------------------------------------------+
Zuvor tat die Methode nichts und wurde in abgeleiteten Klassen überschrieben. Jetzt ist es möglich, Scrollbar-Objekte zu erstellen.
Da die Bildlaufleisten an den Containerobjekten an der unteren und rechten Seite befestigt sind, sollte die Größenänderung des Formulars auch die Bildlaufleistenobjekte verändern. Wir tun dies in \MQL5\Include\DoEasy\Objects\Graph\WForms\WinFormBase.mqh des WinForms-Basisobjekts.
In der Methode, die die neuen Abmessungen für das aktuelle Objekt festlegt, fügen wir den folgenden Codeblock hinzu:
//+---------------------------------------------+ //| Set the new size for the current object | //+---------------------------------------------+ bool CWinFormBase::Resize(const int w,const int h,const bool redraw) { //--- If the object width and height are equal to the passed ones, return 'true' if(this.Width()==w && this.Height()==h) return true; //--- Declare the variable with the property change result bool res=true; //--- Save the panel initial size int prev_w=this.Width(); int prev_h=this.Height(); //--- Set the property change result to the 'res' variable //--- (if the property value is not equal to the passed value) if(this.Width()!=w) res &=this.SetWidth(w); if(this.Height()!=h) res &=this.SetHeight(h); if(!res) return false; //--- Get the vertical scrollbar and CWinFormBase *scroll_v=this.GetElementByType(GRAPH_ELEMENT_TYPE_WF_SCROLL_BAR_VERTICAL,0); if(scroll_v!=NULL) { //--- change the vertical size to the size of the container workspace scroll_v.Resize(scroll_v.Width(),this.Height()-this.BorderSizeTop()-this.BorderSizeBottom(),false); //--- Get a button object with the down arrow from the vertical scrollbar object CWinFormBase *arr_d=scroll_v.GetElementByType(GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_DOWN,0); //--- If the button has been received if(arr_d!=NULL) { //--- Move it to the bottom edge of the vertical scrollbar if(arr_d.Move(arr_d.CoordX(),scroll_v.BottomEdge()-2*arr_d.Height())) { arr_d.SetCoordXRelative(arr_d.CoordX()-scroll_v.CoordX()); arr_d.SetCoordYRelative(arr_d.CoordY()-scroll_v.CoordY()); } } } //--- Get the horizontal scrollbar and CWinFormBase *scroll_h=this.GetElementByType(GRAPH_ELEMENT_TYPE_WF_SCROLL_BAR_HORISONTAL,0); if(scroll_h!=NULL) { //--- change the horizontal size to the size of the container workspace scroll_h.Resize(this.Width()-this.BorderSizeLeft()-this.BorderSizeRight(),scroll_h.Height(),false); //--- Get a button object with the right arrow from the horizontal scrollbar object CWinFormBase *arr_r=scroll_h.GetElementByType(GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_RIGHT,0); //--- If the button has been received if(arr_r!=NULL) { //--- Move it to the right edge of the horizontal scrollbar if(arr_r.Move(scroll_h.RightEdge()-2*arr_r.Width(),arr_r.CoordY())) { arr_r.SetCoordXRelative(arr_r.CoordX()-scroll_h.CoordX()); arr_r.SetCoordYRelative(arr_r.CoordY()-scroll_h.CoordY()); } } } //--- Calculate the value, by which the size should be changed int excess_w=this.Width()-prev_w; int excess_h=this.Height()-prev_h; //--- Get the "Shadow" object CShadowObj *shadow=this.GetShadowObj(); //--- If the object has a shadow and the "Shadow" object has been received, if(this.IsShadow() && shadow!=NULL) { //--- save shadow shifts by X and Y, int x=shadow.CoordXRelative(); int y=shadow.CoordYRelative(); //--- set the shadow new width and height res &=shadow.SetWidth(shadow.Width()+excess_w); res &=shadow.SetHeight(shadow.Height()+excess_h); //--- If the res variable contains 'false', //--- there was a resize error - return 'false' if(!res) return false; //--- If there is no need to redraw, remove the shadow if(!redraw) shadow.Erase(); //--- Save the previously set shadow shift values relative to the panel shadow.SetCoordXRelative(x); shadow.SetCoordYRelative(y); } //--- Redraw the entire element with new size if(redraw) this.Redraw(true); //--- All is successful - return 'true' return true; } //+------------------------------------------------------------------+
Wenn nun die Größe des Objekts geändert wird, ändern sich auch die Rollbalken entsprechend. Die Logik des hinzugefügten Codeblocks ist in den Kommentaren ausführlich beschrieben.
Wir binden alle Dateien aller erstellten grafischen Elemente in die Bibliothek in der Klassendatei des Panel-Objekts ein.
In \MQL5\Include\DoEasy\Objects\Graph\WForms\Containers\Panel.mqh binde wir die Dateien der neuen Steuerelemente ein:
//+---------------------------------------------+ //| Include files | //+---------------------------------------------+ #include "Container.mqh" #include "..\Helpers\TabField.mqh" #include "..\Helpers\ArrowUpButton.mqh" #include "..\Helpers\ArrowDownButton.mqh" #include "..\Helpers\ArrowLeftButton.mqh" #include "..\Helpers\ArrowRightButton.mqh" #include "..\Helpers\ArrowUpDownBox.mqh" #include "..\Helpers\ArrowLeftRightBox.mqh" #include "..\Helpers\HintMoveLeft.mqh" #include "..\Helpers\HintMoveRight.mqh" #include "..\Helpers\HintMoveUp.mqh" #include "..\Helpers\HintMoveDown.mqh" #include "..\Helpers\ScrollBarVertical.mqh" #include "..\Helpers\ScrollBarHorisontal.mqh" #include "GroupBox.mqh" #include "TabControl.mqh" #include "SplitContainer.mqh" #include "..\..\WForms\Common Controls\ListBox.mqh" #include "..\..\WForms\Common Controls\CheckedListBox.mqh" #include "..\..\WForms\Common Controls\ButtonListBox.mqh" #include "..\..\WForms\Common Controls\ToolTip.mqh" #include "..\..\WForms\Common Controls\ProgressBar.mqh" #include "..\..\WForms\GlareObj.mqh" //+---------------------------------------------+ //| Panel object class of WForms controls | //+---------------------------------------------+ class CPanel : public CContainer
In der Methode zur Erstellung eines neuen grafischen Objekts erstellen wir die Zeichenketten für die Erstellung neuer Bildlaufleistenobjekte hinzu:
//+---------------------------------------------+ //| Create a new graphical object | //+---------------------------------------------+ CGCnvElement *CPanel::CreateNewGObject(const ENUM_GRAPH_ELEMENT_TYPE type, const int obj_num, const string descript, const int x, const int y, const int w, const int h, const color colour, const uchar opacity, const bool movable, const bool activity) { CGCnvElement *element=NULL; switch(type) { case GRAPH_ELEMENT_TYPE_ELEMENT : element=new CGCnvElement(type,this.GetMain(),this.GetObject(),this.ID(),obj_num,this.ChartID(),this.SubWindow(),descript,x,y,w,h,colour,opacity,movable,activity); break; case GRAPH_ELEMENT_TYPE_FORM : element=new CForm(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h); break; case GRAPH_ELEMENT_TYPE_WF_CONTAINER : element=new CContainer(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h); break; case GRAPH_ELEMENT_TYPE_WF_GROUPBOX : element=new CGroupBox(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h); break; case GRAPH_ELEMENT_TYPE_WF_PANEL : element=new CPanel(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h); break; case GRAPH_ELEMENT_TYPE_WF_LABEL : element=new CLabel(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h); break; case GRAPH_ELEMENT_TYPE_WF_CHECKBOX : element=new CCheckBox(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h); break; case GRAPH_ELEMENT_TYPE_WF_RADIOBUTTON : element=new CRadioButton(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h); break; case GRAPH_ELEMENT_TYPE_WF_BUTTON : element=new CButton(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h); break; case GRAPH_ELEMENT_TYPE_WF_LIST_BOX : element=new CListBox(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h); break; case GRAPH_ELEMENT_TYPE_WF_LIST_BOX_ITEM : element=new CListBoxItem(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h); break; case GRAPH_ELEMENT_TYPE_WF_CHECKED_LIST_BOX : element=new CCheckedListBox(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h); break; case GRAPH_ELEMENT_TYPE_WF_BUTTON_LIST_BOX : element=new CButtonListBox(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h); break; case GRAPH_ELEMENT_TYPE_WF_TAB_HEADER : element=new CTabHeader(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h); break; case GRAPH_ELEMENT_TYPE_WF_TAB_FIELD : element=new CTabField(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h); break; case GRAPH_ELEMENT_TYPE_WF_TAB_CONTROL : element=new CTabControl(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h); break; case GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON : element=new CArrowButton(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h); break; case GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_UP : element=new CArrowUpButton(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h); break; case GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_DOWN : element=new CArrowDownButton(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h); break; case GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_LEFT : element=new CArrowLeftButton(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h); break; case GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_RIGHT : element=new CArrowRightButton(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h); break; case GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTONS_UD_BOX : element=new CArrowUpDownBox(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h); break; case GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTONS_LR_BOX : element=new CArrowLeftRightBox(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h); break; case GRAPH_ELEMENT_TYPE_WF_SPLIT_CONTAINER : element=new CSplitContainer(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h); break; case GRAPH_ELEMENT_TYPE_WF_SPLITTER : element=new CSplitter(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h); break; case GRAPH_ELEMENT_TYPE_WF_HINT_BASE : element=new CHintBase(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h); break; case GRAPH_ELEMENT_TYPE_WF_HINT_MOVE_LEFT : element=new CHintMoveLeft(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h); break; case GRAPH_ELEMENT_TYPE_WF_HINT_MOVE_RIGHT : element=new CHintMoveRight(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h); break; case GRAPH_ELEMENT_TYPE_WF_HINT_MOVE_UP : element=new CHintMoveUp(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h); break; case GRAPH_ELEMENT_TYPE_WF_HINT_MOVE_DOWN : element=new CHintMoveDown(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h); break; case GRAPH_ELEMENT_TYPE_WF_TOOLTIP : element=new CToolTip(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h); break; case GRAPH_ELEMENT_TYPE_WF_PROGRESS_BAR : element=new CProgressBar(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h); break; case GRAPH_ELEMENT_TYPE_WF_SCROLL_BAR : element=new CScrollBar(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h); break; case GRAPH_ELEMENT_TYPE_WF_SCROLL_BAR_VERTICAL : element=new CScrollBarVertical(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h); break; case GRAPH_ELEMENT_TYPE_WF_SCROLL_BAR_HORISONTAL: element=new CScrollBarHorisontal(this.GetMain(),this.GetObject(),this.ChartID(),this.SubWindow(),descript,x,y,w,h);break; default : break; } if(element==NULL) ::Print(DFUN,CMessage::Text(MSG_LIB_SYS_FAILED_CREATE_ELM_OBJ),this.TypeElementDescription(type)); return element; } //+------------------------------------------------------------------+
In diesem Objekt können wir nun Scrollbar-Objekte erstellen, die mit ihm verbunden sind.
Die gleichen Zeichenketten sollten zu den gleichen Methoden in anderen Klassen von Containerobjekten hinzugefügt werden.
Diese Änderungen sind bereits in den Bibliotheksdateien vorgenommen worden:
SplitContainerPanel.mqh, Containers\TabControl.mqh, TabField.mqh, SplitContainer.mqh.
Überprüfen wir die Ergebnisse.
Test
Um den Test durchzuführen, verwende ich den EA aus dem vorherigen Artikel und speichere ihn in \MQL5\Experts\TestDoEasy\Part129\ als TestDoEasy129.mq5.
Im OnInit(), d. h. im Codeblock für das Neuzeichnen aller erstellten Objekte, fügen wir die Zeiger auf die beiden Bildlaufleisten des Hauptpaneelobjekts hinzu und erzwingen deren Anzeige, um zu sehen, in welcher Form sie erstellt wurden:
//--- Display and redraw all created panels for(int i=0;i<FORMS_TOTAL;i++) { //--- Get the panel object pnl=engine.GetWFPanel("WinForms Panel"+(string)i); if(pnl!=NULL) { //--- display and redraw the panel pnl.Show(); pnl.Redraw(true); //--- Get the pointer to the vertical scrollbar object of the main panel CScrollBarVertical *sbv=pnl.GetElementByType(GRAPH_ELEMENT_TYPE_WF_SCROLL_BAR_VERTICAL,0); //--- Set the display flag for the object and show the scrollbar sbv.SetDisplayed(true); sbv.Show(); sbv.Redraw(true); //--- Get the pointer to the horizontal scrollbar object of the main panel CScrollBarHorisontal *sbh=pnl.GetElementByType(GRAPH_ELEMENT_TYPE_WF_SCROLL_BAR_HORISONTAL,0); //--- Set the display flag for the object and show the scrollbar sbh.SetDisplayed(true); sbh.Show(); sbh.Redraw(true); //--- Get the TabControl object from the panel CTabControl *tc=pnl.GetElementByType(GRAPH_ELEMENT_TYPE_WF_TAB_CONTROL,0); //--- Get the SplitContainer object from the first tab of the TabControl object CSplitContainer *sc=tc.GetTabElementByType(0,GRAPH_ELEMENT_TYPE_WF_SPLIT_CONTAINER,0); //--- Get the second panel from the SplitContainer object CSplitContainerPanel *scp=sc.GetPanel(1); //--- Get the ProgressBar object from the received panel CProgressBar *pb=scp.GetElementByType(GRAPH_ELEMENT_TYPE_WF_PROGRESS_BAR,0); //--- Wait for 1/10 of a second Sleep(100); //--- Get the width of the ProgressBar object int w=pb.Width(); //--- In the loop, increase the width of the ProgressBar by 180 pixels with a delay of 1/50 for(int n=0;n<180;n++) { Sleep(20); pb.Resize(w+n,pb.Height(),true); } //--- Set the values for PerformStep of the ProgressBar object pb.SetValuesForProcessing(0,350,1,0); //--- Reset ProgressBar to minimum pb.ResetProgressBar(); //--- If the style of the progress bar is "Continuous line", display the progress bar description if(pb.Style()==CANV_ELEMENT_PROGRESS_BAR_STYLE_CONTINUOUS) pb.ShowBarDescription(); //--- Wait for 1/5 second Sleep(200); //--- If the style of the progress bar is not "Continuous scrolling" if(pb.Style()!=CANV_ELEMENT_PROGRESS_BAR_STYLE_MARQUEE) { //--- In the loop from the minimum to the maximum value of ProgressBar for(int n=0;n<=pb.Maximum();n++) { //--- call the method for increasing the progress bar by a given step with a wait of 1/5 second pb.PerformStep(); //--- Set the number of completed steps in the description of the progress bar pb.SetBarDescriptionText("Progress Bar, pass: "+(InpProgressBarPercent ? pb.ValuePercentDescription() : pb.ValueDescription())); Sleep(20); } } //--- Wait for 1/2 second, set the description font type to Bold and write a completion message on the progress bar Sleep(500); pb.SetBarDescriptionFontFlags(FW_BOLD); pb.SetBarDescriptionText("Progress Bar: Done"); //--- Set the glare object type - rectangle, opacity 40, color - white pb.SetGlareStyle(CANV_ELEMENT_VISUAL_EFF_STYLE_RECTANGLE); pb.SetGlareOpacity(40); pb.SetGlareColor(clrWhite); } }
Kompilieren Sie den EA und starten Sie ihn auf einem Chart:
Wir sehen, dass die Bildlaufleisten an den richtigen Stellen erstellt werden und über normale Steuerelemente verfügen, die auf Mausinteraktionen reagieren. Steuerelemente auf Bildlaufleisten werden in den falschen Farben gezeichnet, wenn man mit dem Mauszeiger darüberfährt, weil ich noch keine Ereignishandler für diese Steuerelemente erstellt habe. Ich werde dies in späteren Artikeln korrigieren.
Was kommt als Nächstes?
Im nächsten Artikel werde ich die Entwicklung des ScrollBar-Objekts fortsetzen.
*Vorherige Artikel in dieser Reihe:
DoEasy. Steuerung (Teil 26): Fertigstellung des ToolTip WinForms-Objekts und Weiterführung der ProgressBar-Entwicklung
DoEasy. Steuerung (Teil 27): Arbeiten am WinForms Objekt der ProgressBar
DoEasy. Steuerung (Teil 28): Balkenstile im ProgressBar-Steuerelement
Übersetzt aus dem Russischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/ru/articles/11847
- 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.