Erstellen einer interaktiven grafischen Nutzeroberfläche in MQL5 (Teil 1): Erstellen des Panels
Einführung
Willkommen zum ersten Teil unseres umfassenden Leitfadens zur Erstellung von nutzerdefinierten grafischen Nutzeroberflächen (GUI) in MetaQuotes Language 5 (MQL5)! Als Händler und Entwickler wissen wir, wie wichtig effiziente und nutzerfreundliche Schnittstellen für unsere Handelsinstrumente sind. In dieser Serie werden wir in die Welt von MQL5 eintauchen und erkunden, wie Sie leistungsstarke GUI-Panels erstellen können, die Ihr Handelserlebnis verbessern.
In diesem ersten Teil werden die Grundlagen behandelt: Einrichten des Projekts, Entwerfen des Layouts des Bedienfelds und Hinzufügen wichtiger Steuerelemente. Im nächsten Teil werden wir das Panel live, interaktiv und responsiv gestalten. Egal, ob Sie ein erfahrener MQL5-Programmierer sind oder gerade erst anfangen, dieser Artikel enthält eine Schritt-für-Schritt-Anleitung, mit der Sie ein funktionales und optisch ansprechendes GUI-Panel erstellen können. Wir werden die oben genannten Ziele mit Hilfe der folgenden Themen erreichen:
- Elemente Illustration
- GUI-Panel-Montage in MQL5
- Schlussfolgerung
Auf dieser Reise werden wir ausgiebig MetaQuotes Language 5 (MQL5) als Basisumgebung für die integrierte Entwicklungsumgebung (IDE) verwenden und die Dateien auf dem MetaTrader 5 (MT5) Trading Terminal ausführen. Daher ist es von größter Bedeutung, dass die oben genannten Versionen vorhanden sind. Fangen wir an.
Illustration der Elemente
Wir werden ein GUI-Panel erstellen, das die gebräuchlichsten Dienstprogramme enthält, die jeder Händler benötigen könnte, und daher wollen wir in dieser Serie alles umreißen und abdecken. Die Anzahl der Elemente, die behandelt werden müssen, ist daher sehr umfangreich, aber wir werden sie zum besseren Verständnis zusammenfassen. Wir werden 4 Elemente für unsere GUI-Entwicklung verwenden, und damit werden wir sie erstellen. Das Panel wird die Erstellung von Handelsschaltflächen, scharfen Rechtecken, Live-Updates, die Verwendung von Emojis, verschiedenen Schriftarten, Etiketten, beweglichen Panelteilen und Hover-Effekten ermöglichen. Um das Ganze zu veranschaulichen, haben wir ein Beispiel angeführt.
GUI-Panel-Montage in MQL5
Um das Panel zu erstellen, werden wir es auf einen Expertenberater stützen. Um einen Expert Advisor (EA) zu erstellen, klicken Sie auf Ihrem MetaTrader 5-Terminal auf die Registerkarte Tools und aktivieren Sie MetaQuotes Language Editor oder drücken Sie einfach F4 auf Ihrer Tastatur. Alternativ können Sie auch auf das IDE-Symbol (Integrated Development Environment) in der Symbolleiste klicken. Dadurch wird die MetaQuotes-Spracheditor-Umgebung geöffnet, die das Schreiben von Handelsrobotern, technischen Indikatoren, Skripten und Funktionsbibliotheken ermöglicht.
Sobald der MetaEditor geöffnet ist, navigieren Sie in der Symbolleiste zur Registerkarte „Datei“ und wählen Sie „Neue Datei“, oder drücken Sie einfach die Tastenkombination STRG + N, um ein neues Dokument zu erstellen. Alternativ können Sie auch auf das Symbol New auf der Registerkarte Werkzeuge klicken. Daraufhin erscheint ein Popup-Fenster des MQL-Assistenten.
Markieren Sie in dem sich öffnenden Assistenten die Option Expert Advisor (Vorlage) und klicken Sie auf Weiter.
Geben Sie in den allgemeinen Eigenschaften des Expertenberaters unter dem Abschnitt Name den Dateinamen Ihres Experten an. Beachten Sie, dass Sie den Backslash vor dem Namen des EA verwenden, um einen Ordner anzugeben oder zu erstellen, wenn er nicht existiert. Hier haben wir zum Beispiel standardmäßig „Experts\“. Das bedeutet, dass unser EA im Ordner Experts erstellt wird und wir ihn dort finden können. Die anderen Abschnitte sind ziemlich einfach, aber Sie können dem Link am Ende des Assistenten folgen, um zu erfahren, wie der Prozess genau abläuft.
Nachdem Sie den gewünschten Namen des Expert Advisors eingegeben haben, klicken Sie auf Weiter, dann auf Weiter und schließlich auf Fertig stellen. Nachdem wir all das getan haben, sind wir nun bereit, unser GUI-Panel zu codieren und zu programmieren.
Zunächst müssen wir Funktionen für die 4 Elemente erstellen, die wir benötigen, d. h. für die rechteckige Beschriftung, die Schaltfläche, das Bearbeitungsfeld und die Textbeschriftungen. Dies ist von großem Nutzen, da es uns ermöglicht, dieselbe Funktion bei der Erstellung ähnlicher Merkmale wiederzuverwenden, anstatt den gesamten Prozess bei der Erstellung ähnlicher Objekte wiederholen zu müssen. Außerdem sparen wir dadurch eine Menge Zeit und Platz, da der Prozess schnell und unkompliziert ist und die Codeschnipsel kurz.
Um die rechteckige Beschriftung zu erstellen, werden wir eine Funktion erstellen, die 10 Argumente oder Parameter benötigt.
//+------------------------------------------------------------------+ //| Function to create rectangle label | //+------------------------------------------------------------------+ bool createRecLabel(string objName, int xD, int yD, int xS, int yS, color clrBg, int widthBorder, color clrBorder = clrNONE, ENUM_BORDER_TYPE borderType = BORDER_FLAT, ENUM_LINE_STYLE borderStyle = STYLE_SOLID) { ... }
Die Funktionssignatur veranschaulicht alles. Es handelt sich um eine boolesche Funktion mit dem Namen „createRecLabel“, was bedeutet, dass sie bei Erfolg bzw. Misserfolg zwei boolesche Flags, true bzw. false, zurückgibt. Zum besseren Verständnis der Parameter werden diese im Folgenden einzeln erläutert.
- objName: Dieser Parameter steht für den eindeutigen Label-Namen des Rechteckobjekts. Er dient als Bezeichner für das zu erstellende grafische Element.
- xD und yD: Diese Parameter bestimmen die X- und Y-Abstände von der Ecke, in der die Rechteckbeschriftung positioniert werden soll. Betrachten Sie sie als die Koordinaten, die die obere linke Ecke des Rechtecks relativ zum Chart definieren.
- xS und yS: Diese Parameter geben die Breite und Höhe des Rechtecks an. Der Wert xS bestimmt, wie breit das Rechteck horizontal ist, während yS die vertikale Höhe bestimmt.
- clrBg: Der Parameter clrBg gibt die Hintergrundfarbe der Rechteckbeschriftung an. Wählen Sie eine Farbe, die einen guten Kontrast zum Hintergrund des Charts bildet oder die andere Elemente ergänzt.
- widthBorder: Dieser Parameter bestimmt die Breite des Rahmens um das Rechteck. Wenn Sie einen Rand wünschen, geben Sie einen positiven Wert ein; andernfalls verwenden Sie Null, um keinen Rand zu erhalten.
- clrBorder: Optionaler Parameter für die Farbe des Rahmens. Wenn Sie einen Rahmen wünschen, geben Sie eine Farbe an (z. B. clrNONE für keine Rahmenfarbe).
- borderType: Gibt die Art des Rahmens für das Rechteck an. Zur Auswahl stehen flache, erhabene oder andere Formen. Für einen einfachen flachen Rahmen verwenden Sie BORDER_FLAT.
- borderStyle: Wenn Sie einen flachen Rahmen wählen, bestimmt dieser Parameter den Linienstil (z. B. durchgezogen, gestrichelt). Verwenden Sie STYLE_SOLID für eine durchgehende Linie.
In der Funktionssignatur sollten Sie bemerkt haben, dass einige der Argumente bereits auf einen Wert initialisiert sind. Der Initialisierungswert stellt den Standardwert dar, der diesem Parameter zugewiesen wird, falls er während des Funktionsaufrufs ignoriert wird. Unsere Standard-Rahmenfarbe ist beispielsweise „none“, d. h., wenn der Farbwert während des Funktionsaufrufs nicht angegeben wird, wird für den Rand unseres Rechtecks keine Farbe verwendet.
Innerhalb des Funktionskörpers, der von geschweiften Klammern ({}) eingerahmt wird, definieren wir unsere Prozeduren zur Erstellung von Objekten.
// Create a rectangle label object if (!ObjectCreate(0, objName, OBJ_RECTANGLE_LABEL, 0, 0, 0)) { Print(__FUNCTION__, ": failed to create rec label! Error code = ", _LastError); return (false); // Return false if object creation fails }
Wir beginnen mit einer if-Anweisung, um zu prüfen, ob das Objekt nicht erstellt wurde. Wir verwenden die Funktion ObjectCreate, die einen boolescher Wert zurückgibt und 6 Argumenten hat. Diese Funktion erstellt ein Objekt mit dem angegebenen Namen, Typ und den Anfangskoordinaten im angegebenen Teilfenster des Charts. Zunächst geben wir das Chartfenster an, 0 bedeutet, dass das Objekt im Hauptfenster erstellt werden soll. Dann geben wir den Objektnamen an. Dies ist der Name, der einem bestimmten Objekt eindeutig zugewiesen wird. Das zu erstellende Objekt ist vom Typ „OBJ_RECTANGLE_LABEL“, d.h. es handelt sich um ein Objekt zur Erstellung und Gestaltung der nutzerdefinierten grafischen Oberfläche. Anschließend wird das Fenster angegeben, 0 für das aktuelle Chartfenster. Schließlich geben wir die Zeit- und Preiswerte als Null (0) an, da wir sie nicht mit dem Chart, sondern mit den Koordinaten des Chartfensters verbinden werden. Die Zuordnung wird mit Hilfe von Pixeln festgelegt.
Wenn die Erstellung des Objekts fehlschlägt, also die Funktion „ObjectCreate“ false zurückgibt, hat es keinen Sinn, weiterzumachen, wir kehren mit einem Fehler zurück. In diesem Fall informieren wir über den Fehler, indem wir ihn neben dem Fehlercode in das Journal drucken und false zurückgeben. Es könnte ein vorheriger Fehler vorliegen, und um den neuesten Fehler zu erhalten, müssen wir den vorherigen Fehler löschen. Dies geschieht durch den Aufruf der Funktion „ResetLastError“, einer intgrierten MQL5-Funktion, unmittelbar vor der Logik der Objekterstellung.
ResetLastError(); // Reset any previous error codes
Der Zweck der Funktion besteht darin, den Wert der vordefinierten Variablen „_LastError“, in der der Fehlercode der letzten fehlerhaften Operation gespeichert ist, auf Null zu setzen. Durch den Aufruf dieser Funktion wird sichergestellt, dass alle vorherigen Fehlercodes gelöscht werden, bevor mit den nächsten Operationen fortgefahren wird. Dieser Schritt ist wichtig, weil er es uns ermöglicht, neue Fehler unabhängig von früheren Fehlerzuständen zu behandeln.
Wenn wir bis zu diesem Punkt nicht zurückkehren, bedeutet dies, dass wir das Objekt erstellt haben, und wir können mit der Aktualisierung der Eigenschaften des Objekts fortfahren. Eine eingebaute Funktion „ObjectSet...“ setzt den Wert der entsprechenden Objekteigenschaft. Die Objekteigenschaft muss vom Typ datetime, integer, color, boolean oder character sein.
// Set properties for the rectangle label ObjectSetInteger(0, objName, OBJPROP_XDISTANCE, xD); // X distance from the corner ObjectSetInteger(0, objName, OBJPROP_YDISTANCE, yD); // Y distance from the corner ObjectSetInteger(0, objName, OBJPROP_XSIZE, xS); // Width of the rectangle ObjectSetInteger(0, objName, OBJPROP_YSIZE, yS); // Height of the rectangle ObjectSetInteger(0, objName, OBJPROP_CORNER, CORNER_LEFT_UPPER); // Positioning corner ObjectSetInteger(0, objName, OBJPROP_BGCOLOR, clrBg); // Rectangle background color ObjectSetInteger(0, objName, OBJPROP_BORDER_TYPE, borderType); // Border type ObjectSetInteger(0, objName, OBJPROP_STYLE, borderStyle); // Border style (only if borderType is flat) ObjectSetInteger(0, objName, OBJPROP_WIDTH, widthBorder); // Border width (only if borderType is flat) ObjectSetInteger(0, objName, OBJPROP_COLOR, clrBorder); // Border color (only if borderType is flat) ObjectSetInteger(0, objName, OBJPROP_BACK, false); // Not a background object ObjectSetInteger(0, objName, OBJPROP_STATE, false); // Not selectable ObjectSetInteger(0, objName, OBJPROP_SELECTABLE, false); // Not selectable ObjectSetInteger(0, objName, OBJPROP_SELECTED, false); // Not selected
Wir wollen uns auf die erste Eigenschaftslogik konzentrieren.
ObjectSetInteger(0, objName, OBJPROP_XDISTANCE, xD); // X distance from the corner
Hier verwenden wir die eingebaute Funktion „ObjectSetInteger“ und übergeben die entsprechenden Parameter. Die Parameter sind wie unten beschrieben.
- Chart id: Dies ist die ID des Charts. „0“ bezieht sich auf das aktuelle Chart (Chart-ID). Wir passen die Eigenschaften eines Objekts in diesem Chart an.
- Name: Dies ist der Name des Objekts: „objName“ steht für den eindeutigen Namen, der dem Rechteckbeschriftungsobjekt zugewiesen wurde.
- Property id: Dies ist die ID der Objekteigenschaft und ihr Wert kann einer der Werte der Aufzählung „ENUM_OBJECT_PROPERTY_INTEGER“ sein. „OBJPROP_XDISTANCE“ gibt an, dass wir die Eigenschaft X-Distanz ändern.
- Property Wert: Dies ist der Eigenschaftswert. Der Wert, der „xD“ zugewiesen wird, bestimmt, wie weit rechts (oder links, falls negativ) die obere linke Ecke unserer Rechteckbeschriftung horizontal vom linken Rand des Charts positioniert wird.
Auch die anderen Eigenschaften werden nach demselben Schema festgelegt. „OBJPROP_YDISTANCE“ konfiguriert die Y-Abstandseigenschaft der Rechteckbeschriftung. Der Wert „yD“ legt fest, wie weit die linke obere Ecke der Rechteckbeschriftung vertikal vom oberen Rand des Charts entfernt sein soll. Mit anderen Worten, sie steuert die vertikale Platzierung der Beschriftung innerhalb des Chartbereichs. Damit wird der Y-Abstand von der Ecke festgelegt. Mit „OBJPROP_XSIZE“ und „OBJPROP_YSIZE“ wird die Breite bzw. Höhe des Rechtecks festgelegt.
Um unser Objekt zu positionieren, verwenden wir die Eigenschaft „OBJPROP_CORNER“, um die Ecke zu bestimmen, in der sich unser Objekt im Chartfenster befinden soll.
ObjectSetInteger(0, objName, OBJPROP_CORNER, CORNER_LEFT_UPPER); // Positioning corner
Es kann nur 4 Eigenschaftsarten geben:
- CORNER_LEFT_UPPER: Der Mittelpunkt der Koordinaten befindet sich in der oberen linken Ecke des Charts.
- CORNER_LEFT_LOWER: Der Mittelpunkt der Koordinaten befindet sich in der unteren linken Ecke des Charts.
- CORNER_RIGHT_LOWER: Der Mittelpunkt der Koordinaten befindet sich in der unteren rechten Ecke des Charts.
- CORNER_RIGHT_UPPER: Der Mittelpunkt der Koordinaten befindet sich in der oberen rechten Ecke des Charts.
In einer fotografischen Darstellung haben wir das hier.
Der Rest der Eigenschaften ist einfach zu handhaben. Zum besseren Verständnis haben wir sie mit Kommentaren versehen. Dann wird das Chart einfach neu gezeichnet, damit die Änderungen automatisch wirksam werden, ohne dass auf eine Änderung der Kursnotierungen oder der Chartereignisse gewartet werden muss.
ChartRedraw(0); // Redraw the chart
Schließlich geben wir true zurück, was bedeutet, dass die Erstellung und Aktualisierung der Objekteigenschaften erfolgreich war.
return (true); // Return true if object creation and property settings are successful
Der vollständige Funktionscode, der für die Erstellung eines Rechteckobjekts im Chartfenster verantwortlich ist, lautet wie folgt.
bool createRecLabel(string objName, int xD, int yD, int xS, int yS, color clrBg, int widthBorder, color clrBorder = clrNONE, ENUM_BORDER_TYPE borderType = BORDER_FLAT, ENUM_LINE_STYLE borderStyle = STYLE_SOLID) { ResetLastError(); // Reset any previous error codes // Create a rectangle label object if (!ObjectCreate(0, objName, OBJ_RECTANGLE_LABEL, 0, 0, 0)) { Print(__FUNCTION__, ": failed to create rec label! Error code = ", _LastError); return (false); // Return false if object creation fails } // Set properties for the rectangle label ObjectSetInteger(0, objName, OBJPROP_XDISTANCE, xD); // X distance from the corner ObjectSetInteger(0, objName, OBJPROP_YDISTANCE, yD); // Y distance from the corner ObjectSetInteger(0, objName, OBJPROP_XSIZE, xS); // Width of the rectangle ObjectSetInteger(0, objName, OBJPROP_YSIZE, yS); // Height of the rectangle ObjectSetInteger(0, objName, OBJPROP_CORNER, CORNER_LEFT_UPPER); // Positioning corner ObjectSetInteger(0, objName, OBJPROP_BGCOLOR, clrBg); // Rectangle background color ObjectSetInteger(0, objName, OBJPROP_BORDER_TYPE, borderType); // Border type ObjectSetInteger(0, objName, OBJPROP_STYLE, borderStyle); // Border style (only if borderType is flat) ObjectSetInteger(0, objName, OBJPROP_WIDTH, widthBorder); // Border width (only if borderType is flat) ObjectSetInteger(0, objName, OBJPROP_COLOR, clrBorder); // Border color (only if borderType is flat) ObjectSetInteger(0, objName, OBJPROP_BACK, false); // Not a background object ObjectSetInteger(0, objName, OBJPROP_STATE, false); // Not selectable ObjectSetInteger(0, objName, OBJPROP_SELECTABLE, false); // Not selectable ObjectSetInteger(0, objName, OBJPROP_SELECTED, false); // Not selected ChartRedraw(0); // Redraw the chart return (true); // Return true if object creation and property settings are successful }
Um ein Schaltflächenobjekt zu erstellen, wird derselbe Funktionsansatz verwendet. Der Code zum Erstellen einer nutzerdefinierten Schaltflächenfunktion lautet wie folgt.
//+------------------------------------------------------------------+ //| Function to create button | //+------------------------------------------------------------------+ bool createButton(string objName, int xD, int yD, int xS, int yS, string txt = "", color clrTxt = clrBlack, int fontSize = 12, color clrBg = clrNONE, color clrBorder = clrNONE, string font = "Arial Rounded MT Bold") { // Reset any previous errors ResetLastError(); // Attempt to create the button object if (!ObjectCreate(0, objName, OBJ_BUTTON, 0, 0, 0)) { // Print an error message if creation fails Print(__FUNCTION__, ": failed to create the button! Error code = ", _LastError); return (false); } // Set properties for the button ObjectSetInteger(0, objName, OBJPROP_XDISTANCE, xD); // X distance from the corner ObjectSetInteger(0, objName, OBJPROP_YDISTANCE, yD); // Y distance from the corner ObjectSetInteger(0, objName, OBJPROP_XSIZE, xS); // Width of the button ObjectSetInteger(0, objName, OBJPROP_YSIZE, yS); // Height of the button ObjectSetInteger(0, objName, OBJPROP_CORNER, CORNER_LEFT_UPPER); // Positioning corner ObjectSetString(0, objName, OBJPROP_TEXT, txt); // Text displayed on the button ObjectSetInteger(0, objName, OBJPROP_COLOR, clrTxt); // Text color ObjectSetInteger(0, objName, OBJPROP_FONTSIZE, fontSize); // Font size ObjectSetString(0, objName, OBJPROP_FONT, font); // Font name ObjectSetInteger(0, objName, OBJPROP_BGCOLOR, clrBg); // Background color ObjectSetInteger(0, objName, OBJPROP_BORDER_COLOR, clrBorder); // Border color ObjectSetInteger(0, objName, OBJPROP_BACK, false); // Transparent background ObjectSetInteger(0, objName, OBJPROP_STATE, false); // Button state (not pressed) ObjectSetInteger(0, objName, OBJPROP_SELECTABLE, false); // Not selectable ObjectSetInteger(0, objName, OBJPROP_SELECTED, false); // Not selected // Redraw the chart to display the button ChartRedraw(0); return (true); // Button creation successful }
Die Unterschiede im Code bestehen darin, dass ein Rechteck-Objekt keinen Text enthalten kann, eine Schaltfläche jedoch einen beschreibenden Text über die Funktionalität der Schaltfläche enthält, falls dies erforderlich ist. Daher berücksichtigen wir bei den Eingabeparametern Texteigenschaften, in unserem Fall den Textwert, die Farbe, die Schriftgröße und den Schriftnamen. Der Rahmentyp für unsere Schaltfläche ist statisch, sodass wir seine Eigenschaften loswerden und nur die Rahmenfarbe behalten.
Der Objekttyp, den wir erstellen, ist „OBJ_BUTTON“, was bedeutet, dass wir ein grafisches Schaltflächenobjekt erstellen. Die Ankerpunkte werden in Pixel angegeben. Die Rahmeneigenschaft, die wir beibehalten, ist die Rahmenfarbe und der Rest wird durch die Texteingabeeigenschaften ersetzt.
Zur Erstellung der Schaltfläche für das Bearbeitungsfeld wird die gleiche Logik verwendet.
//+------------------------------------------------------------------+ //| Function to create edit field | //+------------------------------------------------------------------+ bool createEdit(string objName, int xD, int yD, int xS, int yS, string txt = "", color clrTxt = clrBlack, int fontSize = 12, color clrBg = clrNONE, color clrBorder = clrNONE, string font = "Arial Rounded MT Bold") { // Reset any previous errors ResetLastError(); // Attempt to create the edit object if (!ObjectCreate(0, objName, OBJ_EDIT, 0, 0, 0)) { // Print an error message if creation fails Print(__FUNCTION__, ": failed to create the edit! Error code = ", _LastError); return (false); } // Set properties for the edit field ObjectSetInteger(0, objName, OBJPROP_XDISTANCE, xD); // X distance from the corner ObjectSetInteger(0, objName, OBJPROP_YDISTANCE, yD); // Y distance from the corner ObjectSetInteger(0, objName, OBJPROP_XSIZE, xS); // Width of the edit field ObjectSetInteger(0, objName, OBJPROP_YSIZE, yS); // Height of the edit field ObjectSetInteger(0, objName, OBJPROP_CORNER, CORNER_LEFT_UPPER); // Positioning corner ObjectSetString(0, objName, OBJPROP_TEXT, txt); // Default text in the edit field ObjectSetInteger(0, objName, OBJPROP_COLOR, clrTxt); // Text color ObjectSetInteger(0, objName, OBJPROP_FONTSIZE, fontSize); // Font size ObjectSetString(0, objName, OBJPROP_FONT, font); // Font name ObjectSetInteger(0, objName, OBJPROP_BGCOLOR, clrBg); // Background color ObjectSetInteger(0, objName, OBJPROP_BORDER_COLOR, clrBorder); // Border color ObjectSetInteger(0, objName, OBJPROP_ALIGN, ALIGN_LEFT); // Text alignment (left-aligned) ObjectSetInteger(0, objName, OBJPROP_READONLY, false); // Edit field is not read-only ObjectSetInteger(0, objName, OBJPROP_BACK, false); // Transparent background ObjectSetInteger(0, objName, OBJPROP_STATE, false); // Edit field state (not active) ObjectSetInteger(0, objName, OBJPROP_SELECTABLE, false); // Not selectable ObjectSetInteger(0, objName, OBJPROP_SELECTED, false); // Not selected // Redraw the chart to display the edit field ChartRedraw(0); return (true); // Edit field creation successful }
Der Hauptunterschied im Code im Vergleich zur Erstellung einer Schaltflächenfunktion ist erstens der Objekttyp. Wir verwenden „OBJ_EDIT“, um zu signalisieren, dass wir eine editierbare Schaltfläche erstellen wollen. Dann fügen wir zu den Feldeigenschaften die Eigenschaft der horizontalen Textausrichtung hinzu, die entweder rechts, links oder mittig sein kann. In unserem Fall entscheiden wir uns für eine horizontale Ausrichtung des Textes nach links.
ObjectSetInteger(0, objName, OBJPROP_ALIGN, ALIGN_LEFT); // Text alignment (left-aligned)
Der letzte Unterschied ist die Eigenschaft, die die Möglichkeit bietet, den Text im Objekt zu bearbeiten. Um die Bearbeitung zu ermöglichen, setzen wir die Eigenschaft „OBJPROP_READONLY“ auf den Wert false.
ObjectSetInteger(0, objName, OBJPROP_READONLY, false); // Edit field is not read-only
Der Rest der Argumente bleibt bestehen.
Schließlich brauchen wir noch die Funktion des letzten Elements, das die Textbeschriftung ist. Die Kennzeichnung des Textes macht ein Hintergrundobjekt überflüssig und ist daher wesentlich einfacher zu implementieren als die übrigen Funktionen. Wir brauchen nur den Text und konzentrieren uns daher auf die Texteigenschaften. Sein Code lautet wie folgt.
//+------------------------------------------------------------------+ //| Function to create text label | //+------------------------------------------------------------------+ bool createLabel(string objName, int xD, int yD, string txt, color clrTxt = clrBlack, int fontSize = 12, string font = "Arial Rounded MT Bold") { // Reset any previous errors ResetLastError(); // Attempt to create the label object if (!ObjectCreate(0, objName, OBJ_LABEL, 0, 0, 0)) { // Print an error message if creation fails Print(__FUNCTION__, ": failed to create the label! Error code = ", _LastError); return (false); } // Set properties for the label ObjectSetInteger(0, objName, OBJPROP_XDISTANCE, xD); // X distance from the corner ObjectSetInteger(0, objName, OBJPROP_YDISTANCE, yD); // Y distance from the corner ObjectSetInteger(0, objName, OBJPROP_CORNER, CORNER_LEFT_UPPER); // Positioning corner ObjectSetString(0, objName, OBJPROP_TEXT, txt); // Text displayed on the label ObjectSetInteger(0, objName, OBJPROP_COLOR, clrTxt); // Text color ObjectSetInteger(0, objName, OBJPROP_FONTSIZE, fontSize); // Font size ObjectSetString(0, objName, OBJPROP_FONT, font); // Font name ObjectSetInteger(0, objName, OBJPROP_BACK, false); // Transparent background ObjectSetInteger(0, objName, OBJPROP_STATE, false); // Label state (not active) ObjectSetInteger(0, objName, OBJPROP_SELECTABLE, false); // Not selectable ObjectSetInteger(0, objName, OBJPROP_SELECTED, false); // Not selected // Redraw the chart to display the label ChartRedraw(0); return (true); // Label creation successful }
Die wichtigsten Unterschiede in dieser Codestruktur gegenüber der Funktion der Schaltfläche sind die Objektgröße und die Rahmeneigenschaften. In der Funktionssignatur werden sowohl die Objektgrößen als auch die Randeigenschaften entfernt. Wir definieren unseren Objekttyp als „OBJ_LABEL“, um zu signalisieren, dass wir es gemäß seinen angegebenen Koordinaten in das Chartfenster zeichnen. Schließlich werden wir die Parameter Größe und Rahmen entfernen, und das ist alles. So einfach ist das.
Da wir nun die Funktionen haben, die wir für die Erstellung einer grafischen Nutzeroberfläche benötigen, wollen wir sie für die Erstellung des Panels verwenden. Wir brauchen Namen für die Objekte und um die Interaktion der Objektnamen einfach zu verwalten, ist es viel einfacher, Makros zu definieren.
#define MAIN_REC "MAIN_REC"
Wir verwenden das #define-Schlüsselwort, um ein Makro mit dem Namen „MAIN_REC“ und dem Wert "MAIN_REC" zu definieren, um unseren Basisnamen für das Hauptrechteck einfach zu speichern, anstatt den Namen bei jeder Erstellung der Ebene erneut eingeben zu müssen, was uns viel Zeit spart und die Gefahr einer falschen Namensgebung verringert. Grundsätzlich werden Makros also zur Textersetzung während der Kompilierung verwendet.
Unser Code wird sich hauptsächlich auf den Initialisierungsabschnitt des Experten stützen, da wir das Panel in der Initialisierungsinstanz erstellen wollen. OnInit wird also den größten Teil der Codestruktur enthalten.
//+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit(){ ... return(INIT_SUCCEEDED); }
Die Funktion OnInit ist eine Ereignisbehandlung, die bei der Initialisierungsinstanz des Experten aufgerufen wird, um gegebenenfalls notwendige Initialisierungen vorzunehmen.
Anschließend rufen wir die Funktion auf, um eine rechteckige Kennzeichnung zu erstellen, indem wir ihren Namen eingeben und ihre Parameter angeben.
createRecLabel(MAIN_REC,10,30,250,400,clrWhite,1,clrBlack);
Hier lautet der Name des Rechtecks „MAIN_REC“, wie in der Makrodefinition angegeben. Unser Abstand entlang der x-Achse, der Zeit- und Datumsskala, von der linken oberen Ecke des Chartfensters beträgt 10 Pixel, und der Abstand entlang der y-Achse, der Preisskala, beträgt 30 Pixel. Die Breite beträgt 250 Pixel und die Höhe 400 Pixel. Wir wählen eine weiße Hintergrundfarbe, eine Rahmenbreite von 1 und eine schwarze Rahmenfarbe. Um die Pixel annähernd zu erfassen, können Sie das Chart auf 0 verkleinern, und die Anzahl der Balken zwischen zwei Fadenkreuzkoordinaten ist gleich der Anzahl der Pixel auf der horizontalen Skala. Ein Beispiel, das ist gemeint:
Die anderen Parameter wurden weggelassen, was bedeutet, dass die Standardwerte automatisch angewendet werden, d. h. der Rahmentyp ist flach und der Linienstil ist eine durchgehende, durchgezogene Linie. Nach der Zusammenstellung ergibt sich das folgende Bild.
Selbst wenn wir alle Parameter mit den Standardwerten wie unten angeben würden, wären die Ergebnisse immer die gleichen.
createRecLabel(MAIN_REC,10,30,250,400,clrWhite,1,clrBlack,BORDER_FLAT,STYLE_SOLID);
Um einen Unterrahmen zu erstellen, deklarieren wir wieder explizit ein Makro für denselben.
#define MAIN_SUB_REC "MAIN_SUB_REC"
Dann rufen wir die gleiche Funktion auf, um den Unterrahmen zu erstellen. Wir wollen, dass unser Rahmen innerhalb des Rahmens des Basisrahmens des Panels liegt und müssen daher eine etwas andere Farbe verwenden. Um dies zu erreichen, haben wir eine hellblaue Farbe und einen Rand von 5 Pixeln verwendet.
createRecLabel(MAIN_SUB_REC,15,35,240,390,clrLightBlue,1,clrNONE);
Da wir einen Rand von 5 Pixeln wollen, schieben wir von links um 5 Pixel und von oben um 5 Pixel. Der Abstand auf der x-Achse beträgt also die ursprünglichen 10 Pixel plus eine Marge von 5, was 15 Pixel ergibt. Das Gleiche gilt für die Skala der y-Achse. Das bedeutet, dass auch die Größe um 5 Pixel reduziert werden muss, aber Moment mal, wir brauchen auch einen Rand von 5 Pixeln rechts vom Panel. Daher ist eine Verkleinerung um 5 Pixel auf jeder Seite für zwei Seiten erforderlich. Die Gesamtzahl der benötigten Pixel ist also 5 multipliziert mit 2, was 10 Pixel ergibt. Eine Verringerung der Größe des Unterrechtecks um 10 Pixel ergibt 250 - 10 = 240 Pixel als Breite und 400 - 10 = 390 Pixel als Höhe des Unterrechtecks. Hier sind die Ergebnisse, die wir erhalten.
Die hellblaue Farbe ist nicht so ansprechend für die Augen, also wählen wir eine dunklere Farbe. Um mehr Kontrolle über die verwendete Farbe zu erhalten, stellen wir die Hintergrundfarbe in Literalen dar. Dies geschieht im Format "C'000,000,000'", wobei die dreifachen Nullen eine beliebige Zahl zwischen 0 und 255 sein können. Das verwendete Format ist RGB (Rot, Grün, Blau). Die drei Werte stehen für die Rot-, Grün- bzw. Blaukomponente auf einer Skala von 0 bis 255. Die Zahl 245.245.245 entspricht also einem fast weißen Farbton.
createRecLabel(MAIN_SUB_REC,15,35,240,390,C'245,245,245',1,clrNONE);
Wir setzen die Rahmenfarbe auf „keine“, um eine ansprechendere Farbmischung zu erzielen. Es wird immer empfohlen, das Programm zu kompilieren und das Ergebnis jedes Mal zu überprüfen, wenn Sie ein neues GUI-Element hinzufügen. Nachfolgend sind die Ergebnisse aufgeführt.
Um vertikale und horizontale Begrenzungslinien zu erstellen, definieren wir zwei weitere Makros.
#define MAIN_LINE_UP "MAIN_LINE_UP" #define MAIN_LINE_DN "MAIN_LINE_DN"
Es wird die gleiche Struktur verwendet, aber dieses Mal wird ein erhöhter Rand verwendet. Dadurch wird die Verwendung der Rahmenfarbe ignoriert und es entsteht eine Illusion der Begrenzung.
createRecLabel(MAIN_LINE_UP,15,35,240,1,C'245,245,245',1,clrNONE,BORDER_RAISED); createRecLabel(MAIN_LINE_DN,15,35-1,1,390+1,C'245,245,245',1,clrNONE,BORDER_RAISED);
Das ist das Ergebnis.
Bis zu diesem Punkt ist die Einrichtung unserer Rahmen, Ränder und Grenzen für unser GUI-Panel abgeschlossen. Anschließend fügen wir die anderen Hilfsmittel des Panels hinzu, wie z. B. Schaltflächen, Titel, Bearbeitungsfelder und Beschriftungen sowie deren Eigenschaften und Effekte.
Lassen Sie uns zunächst dem Panel einen Titel geben.
#define LABEL_NAME "LABEL_NAME" ... createLabel(LABEL_NAME,25,35,"DashBoard v1.0",clrBlue,14,"Cooper Black");
Zunächst definieren wir ein Makro für den Titelnamen und rufen die Funktion auf, die für die Erstellung der Etiketten zuständig ist, indem wir ihren Namen eingeben. Die Abstände zur x-Achse und zur y-Achse geben wir mit 25 bzw. 35 Pixeln an. Die Texteingabe, die wir wählen, ist „DashBoard v1.0“, was den Paneltyp und die Version als erstes angibt. Gleichzeitig geben wir als Textfarbe blau mit einer Schriftgröße von 14 und als Schriftart „Cooper Black“ an. Bei der Angabe der Schriftart wird nicht zwischen Groß- und Kleinschreibung unterschieden. Groß- oder Kleinschreibung oder eine Mischung aus beidem hat keine Auswirkungen. Es könnte auch „Cooper Black“ oder „COOPER BLACK“ lauten. Wichtig ist nur, dass Sie den richtigen Schriftnamen angeben. Öffnen Sie die Kompilierung, erhalten wir die folgenden Ergebnisse.
Sie haben bemerkt, dass sich die Schriftart ändern kann. Wir wollen der Musik Zucker geben und sehen, wie sie sich entwickelt. Einige Schriftarten enthalten Icons und Emojis. Jetzt akzeptiert und integriert MQL5 einige von ihnen. Beispiele für Schriftarten sind „Webdings“, „Wingdings“, „Wingdings 2“ und „Wingdings 3“. Es gibt noch viele weitere, aber wir haben uns für die oben genannten entschieden. Das bedeutet, dass wir das Panel mit diesen Symbolen und Emoji-Schriftarten aufpeppen können. Diese sind im Folgenden aufgeführt.
Wir fügen drei Symbole vor dem Namen des Panels hinzu: ein Herz, ein Werkzeug und ein Krankenwagen-Symbol. Natürlich können Sie diese nach Ihren Wünschen auswählen. Das erfordert wiederum die Definition von drei Makros, die unsere Symbolnamen aufnehmen und später bei der Erstellung der Symbole verwenden. Hier ist die Logik.
#define ICON_HEART "ICON_HEART" #define ICON_TOOL "ICON_TOOL" #define ICON_CAR "ICON_CAR" ... createLabel(ICON_HEART,190,35,"Y",clrRed,15,"Webdings");
Es wird die gleiche Funktion verwendet, mit den Achsenabständen, der Farbe und der Schriftgröße. Sie können jedoch feststellen, dass der Name der Schriftart nun in „Webdings“ geändert wurde und der Textwert in Großbuchstaben „Y“ lautet. Das bedeutet nicht, dass wir „Y“ als Ausgabe anzeigen werden. Wir zeigen das entsprechende Symbol an, das dem jeweiligen Zeichen entspricht. Was die Schriftart anbelangt, so ist das Symbol unter dem Zeichen wie unten, das Herzsymbol.
Der Wert des Textes hängt von der Groß- und Kleinschreibung ab, denn wie Sie sehen können, unterscheidet sich das Symbol unter dem Kleinbuchstaben „y“ von dem des Großbuchstaben „Y“. Nach der Zusammenstellung ergibt sich folgendes Bild.
Die beiden anderen Symbole können nun auf die gleiche Weise wie das vorherige Symbol hinzugefügt werden.
createLabel(ICON_TOOL,210,35,"@",clrBlue,15,"Webdings"); createLabel(ICON_CAR,230,35,"h",clrBlack,15,"Webdings");
Dieselbe Implementierung wird dann verwendet, um dem Chart die anderen Hilfsobjekte hinzuzufügen. Die Logik ist wie folgt.
#define LINE1 "LINE1" #define BTN_CLOSE "BTN_CLOSE" #define BTN_MARKET "BTN_MARKET" #define BTN_PROFIT "BTN_PROFIT" #define BTN_LOSS "BTN_LOSS" #define BTN_PENDING "BTN_PENDING" #define LINE2 "LINE2" ... createRecLabel(LINE1,15+10,60,240-10,1,C'245,245,245',1,clrNONE,BORDER_RAISED); createLabel(BTN_CLOSE,25,65,"Close",clrBlack,13,"Impact"); createLabel(BTN_MARKET,70,65,"Market",clrDarkRed,13,"Impact"); createLabel(BTN_PROFIT,125,65,"Profit",clrGreen,13,"Impact"); createLabel(BTN_LOSS,170,65,"Loss",clrRed,13,"Impact"); createLabel(BTN_PENDING,205,65,"Pend'n",clrDarkGray,13,"Impact"); createRecLabel(LINE2,15+10,87,240-10,1,C'245,245,245',1,clrNONE,BORDER_RAISED);
Wir definieren die Namen der Objektmakros und rufen die entsprechenden nutzerdefinierten Funktionen auf, um die Objekte zu erstellen. Es wird eine Instanz von zwei vertikalen Begrenzungslinien erstellt, die die Schaltflächen des Beschriftungsprogramms einschließen. Die Bezeichnungen lauten Close, Market, Profit, Loss und Pending, angepasst an „Pend'n“, um den Wortlaut innerhalb der Rahmengrenzen unterzubringen. Diese dienen dazu, alle Markt- und Pending-Aufträge zu schließen, nur die Markt-Aufträge zu schließen, nur die Positionen mit Gewinn zu schließen, nur die Positionen mit Verlust zu schließen bzw. Pending-Aufträge zu löschen. Beim Kompilieren erhalten wir dieses Ergebnis.
Bis zu diesem Punkt haben wir den Kopfbereich unseres Panels erfolgreich erstellt. Wir fahren nun fort, die Schaltflächen-Dienstprogramme zu erstellen. Konzentrieren wir uns zunächst auf die Schaltfläche für das Handelsvolumen. Unsere Schaltfläche wird eine Beschriftung und ein Dropdown-Feld haben.
#define BTN_LOTS "BTN_LOTS" #define LABEL_LOTS "LABEL_LOTS" #define ICON_DROP_DN1 "ICON_DROP_DN1"
Die Definition der Makros ist abgeschlossen. Anschließend erstellen wir eine Schaltfläche, indem wir die Schaltfläche-Funktion aufrufen.
createButton(BTN_LOTS,25,95,130,25,"",clrBlack,12,C'210,210,210',C'150,150,150');
Auch hier geben wir die x- und y-Abstände der Schaltflächen mit einer Größe von 130 Pixeln in der Breite bzw. 25 Pixeln in der Höhe an. Für den Text konnten wir einen Wert angeben, haben uns aber dagegen entschieden, da wir die Kontrolle über die Positionierung des Textes haben wollten. Schließlich werden buchstäbliche Farbdarstellungen verwendet, um sowohl den Hintergrund als auch den Rand der Schaltfläche festzulegen. Da wir uns entschieden haben, die Standardbeschriftung der Schaltflächen wegzulassen, haben wir eine neue Textbeschriftung erstellt, die mit Hilfe der folgenden Funktion in der Nähe der Schaltflächen erscheinen soll.
createLabel(LABEL_LOTS,25+10,95+5,"LotSize",clrBlack,9);
Die Funktion ist Ihnen nun vertraut und Sie kennen die Parameter, die übergeben werden. Für das Dropdown-Symbol wird eine Schriftart verwendet, die das Symbol darstellt.
createLabel(ICON_DROP_DN1,130,95+5,CharToString(240),C'070,070,070',20,"Wingdings 3");
Sie können feststellen, dass wir beim Text-Argument ein Zeichen in eine Zeichenkette umwandeln, was eine andere Möglichkeit ist, den entsprechenden Zeichencode anstelle der Zeichenkette zu liefern. Dies ist hilfreich, wenn Sie den Symbolcode bereits kennen. Zur Erstellung der Schaltfläche für das Bearbeitungsfeld wird das gleiche Verfahren angewandt.
#define EDIT_LOTS "EDIT_LOTS" #define BTN_P1 "BTN_P1" #define BTN_M1 "BTN_M1" ... createEdit(EDIT_LOTS,165,95,60,25,"0.01",clrBlack,14,clrWhite,C'100,100,100',"Callibri"); createButton(BTN_P1,225,95,20,12,"5",clrBlack,12,clrLightGray,C'100,100,100',"Webdings"); createButton(BTN_M1,225,95+12,20,12,"6",clrBlack,12,clrLightGray,C'100,100,100',"Webdings");
Wir definieren die Makronamen wie üblich und rufen Funktionen auf. Für die Erstellung der Schaltfläche „Bearbeiten“ wird die Größe von 60 und 25 Pixel als Breite bzw. Höhe verwendet. Der Standardtext ist auf 0,01 mit einer schwarzen Textfarbe, einer Schriftgröße von 14 und einer Schriftart „Callibri“ eingestellt. Der Schaltflächenhintergrund ist auf Weiß mit einem fast dunklen Farbton als Rahmenfarbe eingestellt. Für die Erhöhung und Verringerung des Handelsvolumens verwenden wir die Schriftart „Webdings“ und die Textwerte „5“ bzw. „6“. Hier ist der Meilenstein, den wir bei der Zusammenstellung erreicht haben.
Dies ist ein guter Fortschritt. Um die anderen Stop-Loss- und Take-Profit-Schaltflächen zu erstellen, gilt dieselbe Logik wie im folgenden Code.
#define BTN_SL "BTN_SL" #define LABEL_SL "LABEL_SL" #define ICON_DROP_DN2 "ICON_DROP_DN2" #define EDIT_SL "EDIT_SL" #define BTN_P2 "BTN_P2" #define BTN_M2 "BTN_M2" #define BTN_TP "BTN_TP" #define LABEL_TP "LABEL_TP" #define ICON_DROP_DN3 "ICON_DROP_DN3" #define EDIT_TP "EDIT_TP" #define BTN_P3 "BTN_P3" #define BTN_M3 "BTN_M3" ... createButton(BTN_SL,25,95+30,130,25,"",clrBlack,12,C'210,210,210',C'150,150,150'); createLabel(LABEL_SL,35,95+30,"SL Pips",clrBlack,14); createLabel(ICON_DROP_DN2,130,100+30,CharToString(240),C'070,070,070',20,"Wingdings 3"); createEdit(EDIT_SL,165,95+30,60,25,"100.0",clrBlack,13,clrWhite,C'100,100,100',"Callibri"); createButton(BTN_P2,225,95+30,20,12,"5",clrBlack,12,clrLightGray,C'100,100,100',"Webdings"); createButton(BTN_M2,225,107+30,20,12,"6",clrBlack,12,clrLightGray,C'100,100,100',"Webdings"); createButton(BTN_TP,25,95+30+30,130,25,"",clrBlack,12,C'210,210,210',C'150,150,150'); createLabel(LABEL_TP,35,95+30+30,"TP Pips",clrBlack,14); createLabel(ICON_DROP_DN3,130,100+30+30,CharToString(240),C'070,070,070',20,"Wingdings 3"); createEdit(EDIT_TP,165,95+30+30,60,25,"100.0",clrBlack,13,clrWhite,C'100,100,100',"Callibri"); createButton(BTN_P3,225,95+30+30,20,12,"5",clrBlack,12,clrLightGray,C'100,100,100',"Webdings"); createButton(BTN_M3,225,107+30+30,20,12,"6",clrBlack,12,clrLightGray,C'100,100,100',"Webdings");
Utility-Makros werden definiert und die entsprechenden Funktionen zu ihrer Erstellung aufgerufen. Dieser Code unterscheidet sich in seiner Logik nicht von dem ursprünglichen Code, den wir zur Erstellung der Schaltflächen für das Handelsvolumen verwendet haben. Wenn Sie kompilieren, sollten Sie dieses Ergebnis erhalten.
#define BTN_BUY "BTN_BUY" #define LABEL_BUY "LABEL_BUY" #define LABEL_BUY_PRICE "LABEL_BUY_PRICE" #define BTN_OVERLAY "BTN_OVERLAY" #define BTN_SPREAD "BTN_SPREAD" #define BTN_SELL "BTN_SELL" #define LABEL_SELL "LABEL_SELL" #define LABEL_SELL_PRICE "LABEL_SELL_PRICE" #define BTN_CONTACT "BTN_CONTACT" ... createRecLabel(BTN_SELL,25,335,105,60,clrRed,1,clrNONE); createLabel(LABEL_SELL,35,335,"Sell",clrWhite,15,"ARIAL black"); createLabel(LABEL_SELL_PRICE,35,335+30,DoubleToString(Bid(),_Digits),clrWhite,13,"ARIAL black"); createRecLabel(BTN_BUY,140,335,105,60,clrGreen,1,clrNONE); createLabel(LABEL_BUY,150+35,335,"Buy",clrWhite,15,"ARIAL black"); createLabel(LABEL_BUY_PRICE,150,335+30,DoubleToString(Ask(),_Digits),clrWhite,13,"ARIAL black"); createRecLabel(BTN_OVERLAY,90,335,90,25,C'245,245,245',0,clrNONE); createButton(BTN_SPREAD,95,335,80,20,(string)Spread(),clrBlack,13,clrWhite,clrBlack); createButton(BTN_CONTACT,25,335+62,230-10,25,"https://t.me/Forex_Algo_Trader",clrBlack,10,clrNONE,clrBlack);
Um die Schaltflächen zum Kaufen, Verkaufen, Überlagern, eine Schaltfläche für Zusatzinformationen und eine Schaltfläche für den Spread zu erstellen, wird der obige Code implementiert. Das Einzige, was sich zusätzlich ändert, ist der Text für die Verkaufs- und Ankaufspreise sowie der Spread-Wert. Zusätzliche nutzerdefinierte Funktionen, Bid, Ask und Spread, werden aufgerufen, um die Werte zu füllen. Die Bid- und Ask-Funktionen geben einen Wert vom Datentyp „double“ zurück. Um den Double-Wert in eine Zeichenkette umzuwandeln, wird die eingebaute Funktion „DoubleToString“ aufgerufen. Für die Spanne wird der Integer-Wert direkt in die Zeichenkette eingegeben. Die nutzerdefinierten Funktionen sind wie folgt.
double Ask(){return(NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits));} double Bid(){return(NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits));} int Spread(){return((int)SymbolInfoInteger(_Symbol,SYMBOL_SPREAD));}
Die Funktionen geben die jeweiligen Datentypen der Symbolinformationen zurück. Nach der Kompilierung erhalten wir das folgende Ergebnis.
Nun erstellen wir einige zusätzliche Schaltflächen, die wir zur Veranschaulichung verwenden, wie eine scharfkantige Schaltfläche erstellt werden kann, und ein Duplikat davon, das wir zur Automatisierung des Hover-Effekts verwenden werden.
#define BTN_SHARP "BTN_SHARP" #define LABEL_SHARP "LABEL_SHARP" #define BTN_HOVER "BTN_HOVER" #define LABEL_HOVER "LABEL_HOVER" ... createRecLabel(BTN_SHARP,25,190,220,35,C'220,220,220',2,C'100,100,100'); createLabel(LABEL_SHARP,25+20,190+5,"Sharp Edged Button",clrBlack,12,"ARIAL black"); //createRecLabel(BTN_HOVER,25,230,220,35,C'220,220,220',3,C'050,050,255'); createRecLabel(BTN_HOVER,25,230,220,35,C'220,220,220',3,C'100,100,100'); createLabel(LABEL_HOVER,25+50,230+5,"Hover Effect",clrBlack,12,"ARIAL black");
Nachstehend finden Sie den Meilenstein.
Es gibt etwas zusätzlichen Platz, der für andere Dienstprogramme verwendet werden kann, aber wir wollen ihn mit einigen Emoji- und Symbolzeichen füllen.
#define LABEL_EXTRA1 "LABEL_EXTRA1" #define LABEL_EXTRA2 "LABEL_EXTRA2" #define LABEL_EXTRA3 "LABEL_EXTRA3" #define LABEL_EXTRA4 "LABEL_EXTRA4" ... createLabel(LABEL_EXTRA1,25,290,"_",clrBlack,25,"WEBDINGS"); createLabel(LABEL_EXTRA2,25+40,290,"J",clrBlack,25,"WINGDINGS"); createLabel(LABEL_EXTRA3,25+40+40,290,"{",clrBlack,25,"WINGDINGS 2"); createLabel(LABEL_EXTRA4,25+40+40+40,290,"G",clrBlack,25,"WINGDINGS 3");
Sobald die Schaltfläche für das Handelsvolumen angeklickt wird, möchten wir einige Instanzen für die Erstellung einer Dropdown-Liste haben, aus der wir verschiedene Optionen auswählen können. Wir brauchen 3 Optionen sowie ein Symbol, um die Liste an eine andere Stelle als den ursprünglichen Erstellungspunkt zu ziehen. Es gilt die gleiche Logik.
#define BTN_DROP_DN "BTN_DROP_DN" #define LABEL_OPT1 "LABEL_OPT1" #define LABEL_OPT2 "LABEL_OPT2" #define LABEL_OPT3 "LABEL_OPT3" #define ICON_DRAG "ICON_DRAG" ... void createDropDown(){ createRecLabel(BTN_DROP_DN,25,95+25,130,70,clrWhite,2,clrBlack); createLabel(LABEL_OPT1,25+10,95+25,"LotSize",clrBlack,12,"stencil"); createLabel(LABEL_OPT2,25+10,95+25+20,"Risk Percent %",clrBlack,12,"calibri Italic"); createLabel(LABEL_OPT3,25+10,95+25+20+20,"Money Balance",clrBlack,12,"Arial bold"); createLabel(ICON_DRAG,25+10+95,95+25,"d",clrRoyalBlue,15,"webdings"); }
Hier erstellen wir die Schaltflächen und Beschriftungen in einer nutzerdefinierten Funktion, sodass wir die Funktion aufrufen, sobald das Handelsvolumen angeklickt wird. Um jedoch die Positionen der Hilfsmittel anzuzeigen, rufen wir die Funktion auf, werden aber später die aufgerufene Funktion auskommentieren.
createDropDown();
Der letzte Meilenstein ist wie folgt.
Schließlich müssen wir die erstellten Objekte zerstören und löschen, sobald der Expert Advisor aus dem Chart entfernt wurde. Um dies zu erreichen, wird eine weitere Funktion zum Löschen der erstellten Objekte erstellt.
void destroyPanel(){ ObjectDelete(0,MAIN_REC); ObjectDelete(0,MAIN_SUB_REC); ObjectDelete(0,MAIN_LINE_UP); //... other objects ChartRedraw(0); }
Eine ungültige nutzerdefinierte Funktion bedeutet, dass sie nichts zurückgibt. Die eingebaute Funktion „ObjectDelete“ wird verwendet, um die entsprechenden Objekte wie übergeben zu löschen. Sie benötigt zwei Argumente, die Chart-ID, 0 für das aktuelle Chart, und den Namen des zu löschenden Objekts. Diese Funktion wird während der Deinitialisierungsfunktion des Experten aufgerufen.
//+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason){ //--- destroyPanel(); }
Im Folgenden finden Sie den vollständigen Quellcode, der für die Erstellung des GUI-Panels verantwortlich ist, wie in MQL5 für MetaTrader 5 (MT5). dargestellt.
//+------------------------------------------------------------------+ //| DASHBOARD PART 1.mq5 | //| Copyright 2024, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2024, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" //--- DEFINE MACRO PROPERTIES #define MAIN_REC "MAIN_REC" #define MAIN_SUB_REC "MAIN_SUB_REC" #define MAIN_LINE_UP "MAIN_LINE_UP" #define MAIN_LINE_DN "MAIN_LINE_DN" #define LABEL_NAME "LABEL_NAME" #define ICON_HEART "ICON_HEART" #define ICON_TOOL "ICON_TOOL" #define ICON_CAR "ICON_CAR" #define LINE1 "LINE1" #define BTN_CLOSE "BTN_CLOSE" #define BTN_MARKET "BTN_MARKET" #define BTN_PROFIT "BTN_PROFIT" #define BTN_LOSS "BTN_LOSS" #define BTN_PENDING "BTN_PENDING" #define LINE2 "LINE2" #define BTN_LOTS "BTN_LOTS" #define LABEL_LOTS "LABEL_LOTS" #define ICON_DROP_DN1 "ICON_DROP_DN1" #define EDIT_LOTS "EDIT_LOTS" #define BTN_P1 "BTN_P1" #define BTN_M1 "BTN_M1" #define BTN_SL "BTN_SL" #define LABEL_SL "LABEL_SL" #define ICON_DROP_DN2 "ICON_DROP_DN2" #define EDIT_SL "EDIT_SL" #define BTN_P2 "BTN_P2" #define BTN_M2 "BTN_M2" #define BTN_TP "BTN_TP" #define LABEL_TP "LABEL_TP" #define ICON_DROP_DN3 "ICON_DROP_DN3" #define EDIT_TP "EDIT_TP" #define BTN_P3 "BTN_P3" #define BTN_M3 "BTN_M3" #define BTN_BUY "BTN_BUY" #define LABEL_BUY "LABEL_BUY" #define LABEL_BUY_PRICE "LABEL_BUY_PRICE" #define BTN_OVERLAY "BTN_OVERLAY" #define BTN_SPREAD "BTN_SPREAD" #define BTN_SELL "BTN_SELL" #define LABEL_SELL "LABEL_SELL" #define LABEL_SELL_PRICE "LABEL_SELL_PRICE" #define BTN_CONTACT "BTN_CONTACT" #define BTN_SHARP "BTN_SHARP" #define LABEL_SHARP "LABEL_SHARP" #define BTN_HOVER "BTN_HOVER" #define LABEL_HOVER "LABEL_HOVER" #define LABEL_EXTRA1 "LABEL_EXTRA1" #define LABEL_EXTRA2 "LABEL_EXTRA2" #define LABEL_EXTRA3 "LABEL_EXTRA3" #define LABEL_EXTRA4 "LABEL_EXTRA4" #define BTN_DROP_DN "BTN_DROP_DN" #define LABEL_OPT1 "LABEL_OPT1" #define LABEL_OPT2 "LABEL_OPT2" #define LABEL_OPT3 "LABEL_OPT3" #define ICON_DRAG "ICON_DRAG" //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit(){ createRecLabel(MAIN_REC,10,30,250,400,clrWhite,1,clrBlack); createRecLabel(MAIN_SUB_REC,15,35,240,390,C'245,245,245',1,clrNONE); createRecLabel(MAIN_LINE_UP,15,35,240,1,C'245,245,245',1,clrNONE,BORDER_RAISED); createRecLabel(MAIN_LINE_DN,15,35-1,1,390+1,C'245,245,245',1,clrNONE,BORDER_RAISED); createLabel(LABEL_NAME,25,35,"DashBoard v1.0",clrBlue,14,"Cooper Black"); createLabel(ICON_HEART,190,35,"Y",clrRed,15,"Webdings"); createLabel(ICON_TOOL,210,35,"@",clrBlue,15,"Webdings"); createLabel(ICON_CAR,230,35,"h",clrBlack,15,"Webdings"); createRecLabel(LINE1,15+10,60,240-10,1,C'245,245,245',1,clrNONE,BORDER_RAISED); createLabel(BTN_CLOSE,25,65,"Close",clrBlack,13,"Impact"); createLabel(BTN_MARKET,70,65,"Market",clrDarkRed,13,"Impact"); createLabel(BTN_PROFIT,125,65,"Profit",clrGreen,13,"Impact"); createLabel(BTN_LOSS,170,65,"Loss",clrRed,13,"Impact"); createLabel(BTN_PENDING,205,65,"Pend'n",clrDarkGray,13,"Impact"); createRecLabel(LINE2,15+10,87,240-10,1,C'245,245,245',1,clrNONE,BORDER_RAISED); createButton(BTN_LOTS,25,95,130,25,"",clrBlack,12,C'210,210,210',C'150,150,150'); createLabel(LABEL_LOTS,25+10,95+5,"LotSize",clrBlack,9); //createLabel(ICON_DROP_DN1,150,75,CharToString(100),clrBlack,12,"Wingdings"); createLabel(ICON_DROP_DN1,130,95+5,CharToString(240),C'070,070,070',20,"Wingdings 3"); createEdit(EDIT_LOTS,165,95,60,25,"0.01",clrBlack,14,clrWhite,C'100,100,100',"Callibri"); createButton(BTN_P1,225,95,20,12,"5",clrBlack,12,clrLightGray,C'100,100,100',"Webdings"); createButton(BTN_M1,225,95+12,20,12,"6",clrBlack,12,clrLightGray,C'100,100,100',"Webdings"); createButton(BTN_SL,25,95+30,130,25,"",clrBlack,12,C'210,210,210',C'150,150,150'); createLabel(LABEL_SL,35,95+30,"SL Pips",clrBlack,14); createLabel(ICON_DROP_DN2,130,100+30,CharToString(240),C'070,070,070',20,"Wingdings 3"); createEdit(EDIT_SL,165,95+30,60,25,"100.0",clrBlack,13,clrWhite,C'100,100,100',"Callibri"); createButton(BTN_P2,225,95+30,20,12,"5",clrBlack,12,clrLightGray,C'100,100,100',"Webdings"); createButton(BTN_M2,225,107+30,20,12,"6",clrBlack,12,clrLightGray,C'100,100,100',"Webdings"); createButton(BTN_TP,25,95+30+30,130,25,"",clrBlack,12,C'210,210,210',C'150,150,150'); createLabel(LABEL_TP,35,95+30+30,"TP Pips",clrBlack,14); createLabel(ICON_DROP_DN3,130,100+30+30,CharToString(240),C'070,070,070',20,"Wingdings 3"); createEdit(EDIT_TP,165,95+30+30,60,25,"100.0",clrBlack,13,clrWhite,C'100,100,100',"Callibri"); createButton(BTN_P3,225,95+30+30,20,12,"5",clrBlack,12,clrLightGray,C'100,100,100',"Webdings"); createButton(BTN_M3,225,107+30+30,20,12,"6",clrBlack,12,clrLightGray,C'100,100,100',"Webdings"); createRecLabel(BTN_SELL,25,335,105,60,clrRed,1,clrNONE); createLabel(LABEL_SELL,35,335,"Sell",clrWhite,15,"ARIAL black"); createLabel(LABEL_SELL_PRICE,35,335+30,DoubleToString(Bid(),_Digits),clrWhite,13,"ARIAL black"); createRecLabel(BTN_BUY,140,335,105,60,clrGreen,1,clrNONE); createLabel(LABEL_BUY,150+35,335,"Buy",clrWhite,15,"ARIAL black"); createLabel(LABEL_BUY_PRICE,150,335+30,DoubleToString(Ask(),_Digits),clrWhite,13,"ARIAL black"); createRecLabel(BTN_OVERLAY,90,335,90,25,C'245,245,245',0,clrNONE); createButton(BTN_SPREAD,95,335,80,20,(string)Spread(),clrBlack,13,clrWhite,clrBlack); createButton(BTN_CONTACT,25,335+62,230-10,25,"https://t.me/Forex_Algo_Trader",clrBlack,10,clrNONE,clrBlack); createRecLabel(BTN_SHARP,25,190,220,35,C'220,220,220',2,C'100,100,100'); createLabel(LABEL_SHARP,25+20,190+5,"Sharp Edged Button",clrBlack,12,"ARIAL black"); //createRecLabel(BTN_HOVER,25,230,220,35,C'220,220,220',3,C'050,050,255'); createRecLabel(BTN_HOVER,25,230,220,35,C'220,220,220',3,C'100,100,100'); createLabel(LABEL_HOVER,25+50,230+5,"Hover Effect",clrBlack,12,"ARIAL black"); createLabel(LABEL_EXTRA1,25,290,"_",clrBlack,25,"WEBDINGS"); createLabel(LABEL_EXTRA2,25+40,290,"J",clrBlack,25,"WINGDINGS"); createLabel(LABEL_EXTRA3,25+40+40,290,"{",clrBlack,25,"WINGDINGS 2"); createLabel(LABEL_EXTRA4,25+40+40+40,290,"G",clrBlack,25,"WINGDINGS 3"); // createDropDown(); return(INIT_SUCCEEDED); } double Ask(){return(NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits));} double Bid(){return(NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits));} int Spread(){return((int)SymbolInfoInteger(_Symbol,SYMBOL_SPREAD));} //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason){ //--- destroyPanel(); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick(){ } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Function to create rectangle label | //+------------------------------------------------------------------+ bool createRecLabel(string objName, int xD, int yD, int xS, int yS, color clrBg, int widthBorder, color clrBorder = clrNONE, ENUM_BORDER_TYPE borderType = BORDER_FLAT, ENUM_LINE_STYLE borderStyle = STYLE_SOLID) { ResetLastError(); // Reset any previous error codes // Create a rectangle label object if (!ObjectCreate(0, objName, OBJ_RECTANGLE_LABEL, 0, 0, 0)) { Print(__FUNCTION__, ": failed to create rec label! Error code = ", _LastError); return (false); // Return false if object creation fails } // Set properties for the rectangle label ObjectSetInteger(0, objName, OBJPROP_XDISTANCE, xD); // X distance from the corner ObjectSetInteger(0, objName, OBJPROP_YDISTANCE, yD); // Y distance from the corner ObjectSetInteger(0, objName, OBJPROP_XSIZE, xS); // Width of the rectangle ObjectSetInteger(0, objName, OBJPROP_YSIZE, yS); // Height of the rectangle ObjectSetInteger(0, objName, OBJPROP_CORNER, CORNER_LEFT_UPPER); // Positioning corner ObjectSetInteger(0, objName, OBJPROP_BGCOLOR, clrBg); // Rectangle background color ObjectSetInteger(0, objName, OBJPROP_BORDER_TYPE, borderType); // Border type ObjectSetInteger(0, objName, OBJPROP_STYLE, borderStyle); // Border style (only if borderType is flat) ObjectSetInteger(0, objName, OBJPROP_WIDTH, widthBorder); // Border width (only if borderType is flat) ObjectSetInteger(0, objName, OBJPROP_COLOR, clrBorder); // Border color (only if borderType is flat) ObjectSetInteger(0, objName, OBJPROP_BACK, false); // Not a background object ObjectSetInteger(0, objName, OBJPROP_STATE, false); // Not selectable ObjectSetInteger(0, objName, OBJPROP_SELECTABLE, false); // Not selectable ObjectSetInteger(0, objName, OBJPROP_SELECTED, false); // Not selected ChartRedraw(0); // Redraw the chart return (true); // Return true if object creation and property settings are successful } //+------------------------------------------------------------------+ //| Function to create button | //+------------------------------------------------------------------+ bool createButton(string objName, int xD, int yD, int xS, int yS, string txt = "", color clrTxt = clrBlack, int fontSize = 12, color clrBg = clrNONE, color clrBorder = clrNONE, string font = "Arial Rounded MT Bold") { // Reset any previous errors ResetLastError(); // Attempt to create the button object if (!ObjectCreate(0, objName, OBJ_BUTTON, 0, 0, 0)) { // Print an error message if creation fails Print(__FUNCTION__, ": failed to create the button! Error code = ", _LastError); return (false); } // Set properties for the button ObjectSetInteger(0, objName, OBJPROP_XDISTANCE, xD); // X distance from the corner ObjectSetInteger(0, objName, OBJPROP_YDISTANCE, yD); // Y distance from the corner ObjectSetInteger(0, objName, OBJPROP_XSIZE, xS); // Width of the button ObjectSetInteger(0, objName, OBJPROP_YSIZE, yS); // Height of the button ObjectSetInteger(0, objName, OBJPROP_CORNER, CORNER_LEFT_UPPER); // Positioning corner ObjectSetString(0, objName, OBJPROP_TEXT, txt); // Text displayed on the button ObjectSetInteger(0, objName, OBJPROP_COLOR, clrTxt); // Text color ObjectSetInteger(0, objName, OBJPROP_FONTSIZE, fontSize); // Font size ObjectSetString(0, objName, OBJPROP_FONT, font); // Font name ObjectSetInteger(0, objName, OBJPROP_BGCOLOR, clrBg); // Background color ObjectSetInteger(0, objName, OBJPROP_BORDER_COLOR, clrBorder); // Border color ObjectSetInteger(0, objName, OBJPROP_BACK, false); // Transparent background ObjectSetInteger(0, objName, OBJPROP_STATE, false); // Button state (not pressed) ObjectSetInteger(0, objName, OBJPROP_SELECTABLE, false); // Not selectable ObjectSetInteger(0, objName, OBJPROP_SELECTED, false); // Not selected // Redraw the chart to display the button ChartRedraw(0); return (true); // Button creation successful } //+------------------------------------------------------------------+ //| Function to create edit field | //+------------------------------------------------------------------+ bool createEdit(string objName, int xD, int yD, int xS, int yS, string txt = "", color clrTxt = clrBlack, int fontSize = 12, color clrBg = clrNONE, color clrBorder = clrNONE, string font = "Arial Rounded MT Bold") { // Reset any previous errors ResetLastError(); // Attempt to create the edit object if (!ObjectCreate(0, objName, OBJ_EDIT, 0, 0, 0)) { // Print an error message if creation fails Print(__FUNCTION__, ": failed to create the edit! Error code = ", _LastError); return (false); } // Set properties for the edit field ObjectSetInteger(0, objName, OBJPROP_XDISTANCE, xD); // X distance from the corner ObjectSetInteger(0, objName, OBJPROP_YDISTANCE, yD); // Y distance from the corner ObjectSetInteger(0, objName, OBJPROP_XSIZE, xS); // Width of the edit field ObjectSetInteger(0, objName, OBJPROP_YSIZE, yS); // Height of the edit field ObjectSetInteger(0, objName, OBJPROP_CORNER, CORNER_LEFT_UPPER); // Positioning corner ObjectSetString(0, objName, OBJPROP_TEXT, txt); // Default text in the edit field ObjectSetInteger(0, objName, OBJPROP_COLOR, clrTxt); // Text color ObjectSetInteger(0, objName, OBJPROP_FONTSIZE, fontSize); // Font size ObjectSetString(0, objName, OBJPROP_FONT, font); // Font name ObjectSetInteger(0, objName, OBJPROP_BGCOLOR, clrBg); // Background color ObjectSetInteger(0, objName, OBJPROP_BORDER_COLOR, clrBorder); // Border color ObjectSetInteger(0, objName, OBJPROP_ALIGN, ALIGN_LEFT); // Text alignment (left-aligned) ObjectSetInteger(0, objName, OBJPROP_READONLY, false); // Edit field is not read-only ObjectSetInteger(0, objName, OBJPROP_BACK, false); // Transparent background ObjectSetInteger(0, objName, OBJPROP_STATE, false); // Edit field state (not active) ObjectSetInteger(0, objName, OBJPROP_SELECTABLE, false); // Not selectable ObjectSetInteger(0, objName, OBJPROP_SELECTED, false); // Not selected // Redraw the chart to display the edit field ChartRedraw(0); return (true); // Edit field creation successful } //+------------------------------------------------------------------+ //| Function to create text label | //+------------------------------------------------------------------+ bool createLabel(string objName, int xD, int yD, string txt, color clrTxt = clrBlack, int fontSize = 12, string font = "Arial Rounded MT Bold") { // Reset any previous errors ResetLastError(); // Attempt to create the label object if (!ObjectCreate(0, objName, OBJ_LABEL, 0, 0, 0)) { // Print an error message if creation fails Print(__FUNCTION__, ": failed to create the label! Error code = ", _LastError); return (false); } // Set properties for the label ObjectSetInteger(0, objName, OBJPROP_XDISTANCE, xD); // X distance from the corner ObjectSetInteger(0, objName, OBJPROP_YDISTANCE, yD); // Y distance from the corner ObjectSetInteger(0, objName, OBJPROP_CORNER, CORNER_LEFT_UPPER); // Positioning corner ObjectSetString(0, objName, OBJPROP_TEXT, txt); // Text displayed on the label ObjectSetInteger(0, objName, OBJPROP_COLOR, clrTxt); // Text color ObjectSetInteger(0, objName, OBJPROP_FONTSIZE, fontSize); // Font size ObjectSetString(0, objName, OBJPROP_FONT, font); // Font name ObjectSetInteger(0, objName, OBJPROP_BACK, false); // Transparent background ObjectSetInteger(0, objName, OBJPROP_STATE, false); // Label state (not active) ObjectSetInteger(0, objName, OBJPROP_SELECTABLE, false); // Not selectable ObjectSetInteger(0, objName, OBJPROP_SELECTED, false); // Not selected // Redraw the chart to display the label ChartRedraw(0); return (true); // Label creation successful } //+------------------------------------------------------------------+ //| Function to create the drop down utilities | //+------------------------------------------------------------------+ void createDropDown(){ createRecLabel(BTN_DROP_DN,25,95+25,130,70,clrWhite,2,clrBlack); createLabel(LABEL_OPT1,25+10,95+25,"LotSize",clrBlack,12,"stencil"); createLabel(LABEL_OPT2,25+10,95+25+20,"Risk Percent %",clrBlack,12,"calibri Italic"); createLabel(LABEL_OPT3,25+10,95+25+20+20,"Money Balance",clrBlack,12,"Arial bold"); createLabel(ICON_DRAG,25+10+95,95+25,"d",clrRoyalBlue,15,"webdings"); } //+------------------------------------------------------------------+ //| Function to destroy the entire GUI Panel | //+------------------------------------------------------------------+ void destroyPanel(){ ObjectDelete(0,MAIN_REC); ObjectDelete(0,MAIN_SUB_REC); ObjectDelete(0,MAIN_LINE_UP); ObjectDelete(0,MAIN_LINE_DN); ObjectDelete(0,BTN_LOTS); ObjectDelete(0,LABEL_NAME); ObjectDelete(0,LABEL_LOTS); ObjectDelete(0,ICON_HEART); ObjectDelete(0,ICON_TOOL); ObjectDelete(0,ICON_CAR); ObjectDelete(0,ICON_DROP_DN1); ObjectDelete(0,LINE1); ObjectDelete(0,BTN_CLOSE); ObjectDelete(0,BTN_MARKET); ObjectDelete(0,BTN_PROFIT); ObjectDelete(0,BTN_LOSS); ObjectDelete(0,BTN_PENDING); ObjectDelete(0,LINE2); ObjectDelete(0,EDIT_LOTS); ObjectDelete(0,BTN_P1); ObjectDelete(0,BTN_M1); ObjectDelete(0,BTN_SL); ObjectDelete(0,LABEL_SL); ObjectDelete(0,ICON_DROP_DN2); ObjectDelete(0,EDIT_SL); ObjectDelete(0,BTN_P2); ObjectDelete(0,BTN_M2); ObjectDelete(0,BTN_TP); ObjectDelete(0,LABEL_TP); ObjectDelete(0,ICON_DROP_DN3); ObjectDelete(0,EDIT_TP); ObjectDelete(0,BTN_P3); ObjectDelete(0,BTN_M3); ObjectDelete(0,BTN_BUY); ObjectDelete(0,LABEL_BUY); ObjectDelete(0,LABEL_BUY_PRICE); ObjectDelete(0,BTN_OVERLAY); ObjectDelete(0,BTN_SPREAD); ObjectDelete(0,BTN_SELL); ObjectDelete(0,LABEL_SELL); ObjectDelete(0,LABEL_SELL_PRICE); ObjectDelete(0,BTN_CONTACT); ObjectDelete(0,BTN_SHARP); ObjectDelete(0,LABEL_SHARP); ObjectDelete(0,BTN_HOVER); ObjectDelete(0,LABEL_HOVER); ObjectDelete(0,LABEL_EXTRA1); ObjectDelete(0,LABEL_EXTRA2); ObjectDelete(0,LABEL_EXTRA3); ObjectDelete(0,LABEL_EXTRA4); ObjectDelete(0,BTN_DROP_DN); ObjectDelete(0,LABEL_OPT1); ObjectDelete(0,LABEL_OPT2); ObjectDelete(0,LABEL_OPT3); ObjectDelete(0,ICON_DRAG); ChartRedraw(0); }
Schlussfolgerung
Abschließend können Sie feststellen, dass die Erstellung von GUI-Panels nicht so komplex ist, wie man denkt. Der Prozess umfasst eine Reihe von Schritten, die von der Definition der Abmessungen des Panels, d. h. der Festlegung der Position, der Größe und des Aussehens des Panels, das absolute oder auf das Chart bezogene Koordinaten verwenden kann, über die Erstellung verschiedener grafischer Objekte wie Schaltflächen, Beschriftungen, Bearbeitungsfelder und Rechteckbeschriftungen unter Angabe ihrer Eigenschaften (Farbe, Text, Schriftart usw.) bis hin zur Implementierung in Ereignisbehandlungsroutinen für die Erstellung der Panels und Nutzerinteraktionen reichen.
Dieser erste Teil hat die erfolgreiche Erstellung des Panels erfolgreich dargestellt. Der zweite Teil wird das Panel zum Leben erwecken, indem er es reaktionsfähig macht. Zum Beispiel werden wir die Schaltflächen so gestalten, dass sie bei Klicks reagieren, die Preisangaben bei jedem Tick aktualisieren, die Dropdown-Liste verschiebbar machen, Hover-Effekte zu den Schaltflächen hinzufügen und vieles mehr. Wir hoffen, dass Ihnen dieser Artikel bei der Erstellung von GUI-Panels nützlich war und dass Sie das hier vermittelte Wissen nutzen können, um noch komplexere und ausgefallenere GUI-Panels zu erstellen.
Übersetzt aus dem Englischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/en/articles/15205
- 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.