MQL5で取引管理者パネルを作成する(第3回):ビジュアルスタイリングによるGUIの強化(I)
内容
はじめに
前回の記事で示した目標を振り返ると、どれだけの成果を上げたか自信を持って言えるでしょうか。個人的には、現在の進展を超えて更なる成長を促進するためのアイデアが浮かびます。たとえば、管理パネルにダークテーマとライトテーマの切り替え機能を実装した場合、どれほど便利になるか想像してみてください。また、スタイリッシュなボタンの追加や、さまざまなフォントの提供、さらには主要言語間での言語切り替え機能を加えることで、ユーザーエクスペリエンスをさらに向上させることができます。これにより、パネルはより多くのユーザーにとって使いやすくなります。
私たちの目標は、取引管理者に対し、取引プラットフォーム内で統合された包括的なコミュニケーションソリューションを提供することです。私たちが目指すコンセプトは、1970年代以降のグラフィカルユーザーインターフェイス(GUI)における影響力のある研究と開発から多くのインスピレーションを受けています。著名な貢献者には、Alan Kay、Xerox PARC、Apple (macOS)、Microsoft (Windows)、CSS (Cascading Style Sheets)、GoogleのMaterial Designなどが挙げられます。これらの先人たちの洞察を活用することで、ユーザーのニーズを満たし、全体的なエクスペリエンスを向上させる管理パネルを作成できると信じています。。
これまでに開発した基本的な管理パネル
これまでに達成した成果を要約すると、次のようになります。
- メッセージングインターフェイスとTelegram統合を備えた管理パネルを作成した
- 最小化、最大化、閉じる、クイックメッセージのボタンなどの重要なボタンをインターフェイスに追加した
この記事の最後には、MQL5で完全にカスタマイズされ、視覚的にスタイリングされた取引管理パネルが完成します。インターフェイスの外観と機能性を向上させるさまざまなスタイル設定テクニックを実装し、トレーダーにとってプロフェッショナルで使いやすい環境を作り上げる方法を学びます。
この記事の主な目的は次のとおりです。- MQL5を使用した基本的なスタイリング手法を適用する
- フォント、色、レイアウトをカスタマイズする
- 視覚的な要素によってユーザーインタラクションを強化する
- ライトテーマモードとダークテーマモード間のカスタマイズ機能を組み込む
- アニメーションやトランジションなどの動的な機能を追加する
MQL5 GUIスタイル機能の適用
MQL5は、取引アプリケーションのGUIをスタイリングするためのさまざまな機能とオプションを提供します。これにより、ユーザーのニーズや目指すデザインに合わせて、色、フォント、レイアウトをカスタマイズできます。
MQL5でGUIをスタイリングするためには、いくつかの重要な機能とテクニックを活用します。 ここでは、ボタン、ラベル、パネルなどのグラフィックオブジェクトのプロパティを変更する方法について説明します。これらの機能を使用することで、背景色や境界線のスタイル、フォントサイズ、その他の視覚的要素をカスタマイズし、統一感のある外観と雰囲気を作り上げることができます。
- 色とフォントのカスタマイズ
- テーマ管理ロジック
- 新しいボタンレイアウトの調整
色とフォントのカスタマイズ
フォント配列とインデックス
まず、管理パネルのフォント選択を管理するために、availableFonts配列とcurrentFontIndexを定義します。availableFonts配列には、「Arial」、「Courier New」、「Verdana」、「Times New Roman」などのフォント名が含まれており、ユーザーはパネルの外観をカスタマイズするためのさまざまな選択肢を利用できます。currentFontIndexは、この配列のインデックスを使用して、選択されたフォントを追跡します。この設定により、ユーザーがフォントを変更するたびに簡単にフォントを切り替え、UIコンポーネントに即座に適用できるため、ユーザーエクスペリエンスが動的で一貫したものになります。
// Array of available fonts string availableFonts[] = {"Arial", "Courier New", "Verdana", "Times New Roman"}; // Index of the current font in use int currentFontIndex = 0;
フォント変更ボタンの作成
「Font<>」というラベルの付いたボタンを作成し、管理パネル内に戦略的に配置します。これは単なるボタンではなく、フォントを変更するための重要な機能を持ちます。パネルのレイアウトにうまく適合することを確認し、作成に関する問題を処理します。このボタンを追加することで、ユーザーはさまざまなフォントを直感的に切り替えることができ、パネルの使いやすさと美的柔軟性が向上します。ボタンの作成中に問題が発生した場合は、エラーメッセージを出力して問題の追跡を容易にします。// Create a button for changing the font CButton changeFontButton; changeFontButton.Create(panel, "ChangeFontButton", 0, 10, 10, 100, 30); changeFontButton.Text("Font<>"); // Verify button creation and handle errors if(!changeFontButton.IsCreated()) { Print("Error creating Font<> button."); }フォント変更ボタンのクリックの処理
OnChangeFontButtonClick関数の実装目標は、フォント変更プロセスをスムーズに管理することです。この関数では、currentFontIndexを更新して、availableFonts配列の次のフォントを選択し、必要に応じて先頭に戻ります。インデックスの更新後、入力ボックス、クリアボタン、送信ボタンなどの関連するUIコンポーネントに新しいフォントを適用し、パネル全体で一貫した外観を維持します。変更を確定するために、ChartRedrawを使用して画面表示を更新し、フォント変更が成功したことをユーザーに知らせる確認メッセージを表示します。// Function to handle the font change button click void OnChangeFontButtonClick() { // Update the font index, wrapping around if necessary currentFontIndex = (currentFontIndex + 1) % ArraySize(availableFonts); string newFont = availableFonts[currentFontIndex]; // Apply the new font to UI components inputBox.Font(newFont); clearButton.Font(newFont); sendButton.Font(newFont); // Refresh the display to apply the changes ChartRedraw(); // Print confirmation of the font change Print("Font changed to ", newFont); }ボタンクリックを処理するためのOnChartEvent
OnChartEvent関数では、フォント変更ボタンを含むさまざまなチャートオブジェクトに対するユーザー操作を処理します。この関数は、ボタンのクリックイベントをリッスンし、sparam文字列を調べてどのボタンがクリックされたかを確認します。「ChangeFontButton」がクリックされると、フォントの変更を管理するためにOnChangeFontButtonClick関数が呼び出されます。このイベント駆動型のアプローチにより、UIの応答性とインタラクティブ性が維持され、ユーザーのアクションによって適切な応答がトリガーされ、魅力的なインターフェイスが維持されます。// Function to handle chart events void OnChartEvent(const int id, const int sub_id, const int type, const int x, const int y, const int state) { // Handle button clicks if(type == CHARTEVENT_OBJECT_CLICK) { string buttonName = ObjectGetString(0, "ChangeFontButton", OBJPROP_TEXT); if(buttonName == "Font<>") { OnChangeFontButtonClick(); } } }
フォント切り替えが機能している
テーマ管理ロジック
テーマ切り替えロジック
まず、ライトテーマとダークテーマという 2 つの異なるテーマを使用してテーマ管理システムを設定します。切り替えを管理するには、現在アクティブなテーマを追跡するブール変数isDarkModeを使用します。切り替えは簡単です。ユーザーがテーマボタンをクリックすると、isDarkModeの値が反転し、管理パネル全体の外観と操作性が変わります。各テーマの色を個別に定義することで、プロセスが合理化され、必要に応じて新しいスタイルを簡単に維持および適用できるようになります。bool isDarkMode = false; // Tracks the current theme mode (light or dark) color lightBackgroundColor = clrWhite; // Background color for light mode color darkBackgroundColor = clrBlack; // Background color for dark mode color lightTextColor = clrBlack; // Text color for light mode color darkTextColor = clrWhite; // Text color for dark mode
テーマ切り替えボタンの作成
次に、「Theme<>」というラベルの付いたボタンを作成します。このボタンは管理パネル内に配置され、ユーザーがライトモードとダークモードを簡単に切り替えられるようにします。作成中に何か問題が発生した場合、メッセージを出力してエラーが処理されるようにしています。これにより、トラブルシューティングが容易になり、インターフェイスが直感的で応答性に優れたものになります。//Creating the theme switch button if(!CreateButton("ToggleThemeButton", "Theme<>", 50, 220, 100, 30)) { Print("Error: Failed to create theme toggle button"); // Error handling if button creation fails }
テーマ切り替えボタンをクリックの処理
次に、OnToggleModeButtonClick関数を実装して、実際のテーマの変更を処理します。この関数は、isDarkMode変数を反転し、ライトテーマとダークテーマを切り替えます。どのテーマがアクティブであるかがわかったら、パネル、ボタン、テキストなどのすべてUI要素に、対応する背景色とテキスト色を適用します。テーマの変更は、素早い更新によりリアルタイムで行われるため、インターフェイスがスムーズで応答性が高くなります。モードが変更されたことをユーザーに知らせるために、確認メッセージも出力します。//Theme switching handler void OnToggleModeButtonClick() { isDarkMode = !isDarkMode; // Toggle the theme mode if(isDarkMode) { ApplyTheme(darkBackgroundColor, darkTextColor); // Apply dark mode colors } else { ApplyTheme(lightBackgroundColor, lightTextColor); // Apply light mode colors } Print("Theme has been switched"); // Inform the user that the theme has changed }
テーマ切り替えボタンのクリックを処理するためOnChartEvent
OnChartEvent関数では、ユーザーが「テーマの切り替え」ボタンをクリックしたことを検出し、OnToggleModeButtonClick関数をトリガーします。このイベント駆動型のアプローチにより、パネルがユーザーのアクションに即座に応答することが保証されます。ボタンのクリック イベントをリッスンすることで、管理パネルがインタラクティブで魅力的な状態を維持し、ユーザーが必要に応じてライトテーマとダークテーマを簡単に切り替えられるようにします。//The OneChartEvent for the theme void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { if(id == CHARTEVENT_OBJECT_CLICK) // Check if the event is a button click { if(sparam == "ToggleThemeButton") // Check if the clicked button is the theme toggle button { OnToggleModeButtonClick(); // Call the function to handle the theme change } } }
オブジェクトを再作成せずにテーマを適用する
私たちの重要な設計上の決定1つは、パネルのオブジェクトを再作成せずにテーマを更新することです。UI コンポーネントを解体して新しいコンポーネントを構築する代わりに、既存の要素に新しい配色を適用するだけです。これにより、システムの効率が維持され、遅延が削減され、スムーズなユーザー エクスペリエンスが維持されます。また、新しい色を動的に適用する際に、パネルが応答性を維持することも保証されます。//Applying theme void ApplyTheme(color backgroundColor, color textColor) { // Update background and text colors of existing objects ObjectSetInteger(0, "AdminPanelBackground", OBJPROP_COLOR, backgroundColor); // Change background color ObjectSetInteger(0, "ClearButton", OBJPROP_COLOR, textColor); // Change text color of clear button ObjectSetInteger(0, "SendButton", OBJPROP_COLOR, textColor); // Change text color of send button ObjectSetInteger(0, "InputBox", OBJPROP_COLOR, textColor); // Change text color of input box ChartRedraw(); // Redraw the chart to reflect the changes }
新しいボタンレイアウトの調整
フォント変更ボタン
フォント変更ボタンは、管理パネルの左上隅を (95, 95)、右下隅を (230, 115)に配置しました。これにより、送信ボタンとクリアボタンの左側に配置されます。その寸法は、「フォント<>」ラベルとユーザーフレンドリーな操作に十分な幅があります。このボタンを使用すると、パネル内のすべてのテキスト要素に対してさまざまなフォント オプションを切り替えることができます。if (!changeFontButton.Create(chart_id, "ChangeFontButton", 0, 95, 95, 230, 115))
テーマ切り替えボタン
テーマ切り替えボタンについては、左上の座標 (5, 95)、右下の座標 (90, 115)に配置しました。これにより、ボタンがパネルの左端、フォント変更ボタンの少し上に配置され、明確な区別が実現します。コンパクトなサイズと他のボタンに近いため、ユーザーはインターフェイスを煩雑にすることなく、ダークテーマとライトテーマを簡単に切り替えることができます。if (!toggleThemeButton.Create(chart_id, "ToggleThemeButton", 0, 5, 95, 90, 115))
すべての新機能が完璧に統合された完全なプログラムをご紹介します。//+------------------------------------------------------------------+ //| Admin Panel.mq5 | //| Copyright 2024, Clemence Benjamin | //| https://www.mql5.com/ja/users/billionaire2024/seller | //+------------------------------------------------------------------+ #property copyright "Copyright 2024, Clemence Benjamin" #property link "https://www.mql5.com/ja/users/billionaire2024/seller" #property description "A responsive Admin Panel. Send messages to your telegram clients without leaving MT5" #property version "1.11" #include <Trade\Trade.mqh> #include <Controls\Dialog.mqh> #include <Controls\Button.mqh> #include <Controls\Edit.mqh> #include <Controls\Label.mqh> // Input parameters input string QuickMessage1 = "Updates"; input string QuickMessage2 = "Close all"; input string QuickMessage3 = "In deep profits"; input string QuickMessage4 = "Hold position"; input string QuickMessage5 = "Swing Entry"; input string QuickMessage6 = "Scalp Entry"; input string QuickMessage7 = "Book profit"; input string QuickMessage8 = "Invalid Signal"; input string InputChatId = "Enter Chat ID from Telegram bot API"; input string InputBotToken = "Enter BOT TOKEN from your Telegram bot"; // Global variables CDialog adminPanel; CButton sendButton, clearButton, changeFontButton, toggleThemeButton; CButton quickMessageButtons[8], minimizeButton, maximizeButton, closeButton; CEdit inputBox; CLabel charCounter; #define BG_RECT_NAME "BackgroundRect" bool minimized = false; bool darkTheme = false; int MAX_MESSAGE_LENGTH = 4096; string availableFonts[] = { "Arial", "Courier New", "Verdana", "Times New Roman" }; int currentFontIndex = 0; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { // Initialize the Dialog if (!adminPanel.Create(ChartID(), "Admin Panel", 0, 30, 30, 500, 500)) { Print("Failed to create dialog"); return INIT_FAILED; } // Create controls if (!CreateControls()) { Print("Control creation failed"); return INIT_FAILED; } adminPanel.Show(); // Initialize with the default theme CreateOrUpdateBackground(ChartID(), darkTheme ? clrBlack : clrWhite); Print("Initialization complete"); return INIT_SUCCEEDED; } //+------------------------------------------------------------------+ //| Create necessary UI controls | //+------------------------------------------------------------------+ bool CreateControls() { long chart_id = ChartID(); // Create the input box if (!inputBox.Create(chart_id, "InputBox", 0, 5, 25, 460, 95)) { Print("Failed to create input box"); return false; } adminPanel.Add(inputBox); // Character counter if (!charCounter.Create(chart_id, "CharCounter", 0, 380, 5, 460, 25)) { Print("Failed to create character counter"); return false; } charCounter.Text("0/" + IntegerToString(MAX_MESSAGE_LENGTH)); adminPanel.Add(charCounter); // Clear button if (!clearButton.Create(chart_id, "ClearButton", 0, 235, 95, 345, 125)) { Print("Failed to create clear button"); return false; } clearButton.Text("Clear"); adminPanel.Add(clearButton); // Send button if (!sendButton.Create(chart_id, "SendButton", 0, 350, 95, 460, 125)) { Print("Failed to create send button"); return false; } sendButton.Text("Send"); adminPanel.Add(sendButton); // Change font button if (!changeFontButton.Create(chart_id, "ChangeFontButton", 0, 95, 95, 230, 115)) { Print("Failed to create change font button"); return false; } changeFontButton.Text("Font<>"); adminPanel.Add(changeFontButton); // Toggle theme button if (!toggleThemeButton.Create(chart_id, "ToggleThemeButton", 0, 5, 95, 90, 115)) { Print("Failed to create toggle theme button"); return false; } toggleThemeButton.Text("Theme<>"); adminPanel.Add(toggleThemeButton); // Minimize button if (!minimizeButton.Create(chart_id, "MinimizeButton", 0, 375, -22, 405, 0)) { Print("Failed to create minimize button"); return false; } minimizeButton.Text("_"); adminPanel.Add(minimizeButton); // Maximize button if (!maximizeButton.Create(chart_id, "MaximizeButton", 0, 405, -22, 435, 0)) { Print("Failed to create maximize button"); return false; } maximizeButton.Text("[ ]"); adminPanel.Add(maximizeButton); // Close button if (!closeButton.Create(chart_id, "CloseButton", 0, 435, -22, 465, 0)) { Print("Failed to create close button"); return false; } closeButton.Text("X"); adminPanel.Add(closeButton); // Quick messages return CreateQuickMessageButtons(); } //+------------------------------------------------------------------+ //| Create quick message buttons | //+------------------------------------------------------------------+ bool CreateQuickMessageButtons() { string quickMessages[8] = { QuickMessage1, QuickMessage2, QuickMessage3, QuickMessage4, QuickMessage5, QuickMessage6, QuickMessage7, QuickMessage8 }; int startX = 5, startY = 160, width = 222, height = 65, spacing = 5; for (int i = 0; i < 8; i++) { if (!quickMessageButtons[i].Create(ChartID(), "QuickMessageButton" + IntegerToString(i + 1), 0, startX + (i % 2) * (width + spacing), startY + (i / 2) * (height + spacing), startX + (i % 2) * (width + spacing) + width, startY + (i / 2) * (height + spacing) + height)) { Print("Failed to create quick message button ", i + 1); return false; } quickMessageButtons[i].Text(quickMessages[i]); adminPanel.Add(quickMessageButtons[i]); } return true; } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { adminPanel.Destroy(); ObjectDelete(ChartID(), BG_RECT_NAME); Print("Deinitialization complete"); } //+------------------------------------------------------------------+ //| Handle chart events | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { switch (id) { case CHARTEVENT_OBJECT_CLICK: if (sparam == "SendButton") OnSendButtonClick(); else if (sparam == "ClearButton") OnClearButtonClick(); else if (sparam == "ChangeFontButton") OnChangeFontButtonClick(); else if (sparam == "ToggleThemeButton") OnToggleThemeButtonClick(); else if (sparam == "MinimizeButton") OnMinimizeButtonClick(); else if (sparam == "MaximizeButton") OnMaximizeButtonClick(); else if (sparam == "CloseButton") OnCloseButtonClick(); else if (StringFind(sparam, "QuickMessageButton") != -1) { int index = StringToInteger(StringSubstr(sparam, 18)); OnQuickMessageButtonClick(index - 1); } break; case CHARTEVENT_OBJECT_ENDEDIT: if (sparam == "InputBox") OnInputChange(); break; } } //+------------------------------------------------------------------+ //| Handle custom message send button click | //+------------------------------------------------------------------+ void OnSendButtonClick() { string message = inputBox.Text(); if (message != "") { if (SendMessageToTelegram(message)) Print("Custom message sent: ", message); else Print("Failed to send custom message."); } else { Print("No message entered."); } } //+------------------------------------------------------------------+ //| Handle clear button click | //+------------------------------------------------------------------+ void OnClearButtonClick() { inputBox.Text(""); // Clear the text in the input box OnInputChange(); // Update the character counter Print("Input box cleared."); } //+------------------------------------------------------------------+ //| Handle quick message button click | //+------------------------------------------------------------------+ void OnQuickMessageButtonClick(int index) { string quickMessages[8] = { QuickMessage1, QuickMessage2, QuickMessage3, QuickMessage4, QuickMessage5, QuickMessage6, QuickMessage7, QuickMessage8 }; string message = quickMessages[index]; if (SendMessageToTelegram(message)) Print("Quick message sent: ", message); else Print("Failed to send quick message."); } //+------------------------------------------------------------------+ //| Update character counter | //+------------------------------------------------------------------+ void OnInputChange() { int currentLength = StringLen(inputBox.Text()); charCounter.Text(IntegerToString(currentLength) + "/" + IntegerToString(MAX_MESSAGE_LENGTH)); ChartRedraw(); } //+------------------------------------------------------------------+ //| Handle toggle theme button click | //+------------------------------------------------------------------+ void OnToggleThemeButtonClick() { darkTheme = !darkTheme; color bgColor = darkTheme ? clrBlack : clrWhite; color textColor = darkTheme ? clrWhite : clrBlack; // Set text color appropriate to the theme inputBox.Color(textColor); clearButton.Color(textColor); sendButton.Color(textColor); toggleThemeButton.Color(textColor); changeFontButton.Color(textColor); for(int i = 0; i < ArraySize(quickMessageButtons); i++) { quickMessageButtons[i].Color(textColor); } charCounter.Color(textColor); CreateOrUpdateBackground(ChartID(), bgColor); ChartRedraw(); } //+------------------------------------------------------------------+ //| Create and update background rectangle | //+------------------------------------------------------------------+ void CreateOrUpdateBackground(long chart_id, color bgColor) { if (!ObjectFind(chart_id, BG_RECT_NAME)) { if (!ObjectCreate(chart_id, BG_RECT_NAME, OBJ_RECTANGLE, 0, 0, 0)) Print("Failed to create background rectangle"); } ObjectSetInteger(chart_id, BG_RECT_NAME, OBJPROP_COLOR, bgColor); ObjectSetInteger(chart_id, BG_RECT_NAME, OBJPROP_BACK, true); ObjectSetInteger(chart_id, BG_RECT_NAME, OBJPROP_SELECTABLE, false); ObjectSetInteger(chart_id, BG_RECT_NAME, OBJPROP_SELECTED, false); ObjectSetInteger(chart_id, BG_RECT_NAME, OBJPROP_HIDDEN, false); ObjectSetInteger(chart_id, BG_RECT_NAME, OBJPROP_CORNER, CORNER_LEFT_UPPER); ObjectSetInteger(chart_id, BG_RECT_NAME, OBJPROP_XOFFSET, 25); ObjectSetInteger(chart_id, BG_RECT_NAME, OBJPROP_YOFFSET, 25); } //+------------------------------------------------------------------+ //| Handle change font button click | //+------------------------------------------------------------------+ void OnChangeFontButtonClick() { currentFontIndex = (currentFontIndex + 1) % ArraySize(availableFonts); inputBox.Font(availableFonts[currentFontIndex]); clearButton.Font(availableFonts[currentFontIndex]); sendButton.Font(availableFonts[currentFontIndex]); toggleThemeButton.Font(availableFonts[currentFontIndex]); changeFontButton.Font(availableFonts[currentFontIndex]); for(int i = 0; i < ArraySize(quickMessageButtons); i++) { quickMessageButtons[i].Font(availableFonts[currentFontIndex]); } Print("Font changed to: ", availableFonts[currentFontIndex]); ChartRedraw(); } //+------------------------------------------------------------------+ //| Handle minimize button click | //+------------------------------------------------------------------+ void OnMinimizeButtonClick() { minimized = true; adminPanel.Hide(); minimizeButton.Hide(); maximizeButton.Show(); closeButton.Show(); Print("Panel minimized."); } //+------------------------------------------------------------------+ //| Handle maximize button click | //+------------------------------------------------------------------+ void OnMaximizeButtonClick() { if (minimized) { adminPanel.Show(); minimizeButton.Show(); maximizeButton.Hide(); closeButton.Hide(); Print("Panel maximized."); } } //+------------------------------------------------------------------+ //| Handle close button click | //+------------------------------------------------------------------+ void OnCloseButtonClick() { ExpertRemove(); // Completely remove the EA Print("Admin Panel closed."); } //+------------------------------------------------------------------+ //| Send the message to Telegram | //+------------------------------------------------------------------+ bool SendMessageToTelegram(string message) { string url = "https://api.telegram.org/bot" + InputBotToken + "/sendMessage"; string jsonMessage = "{\"chat_id\":\"" + InputChatId + "\", \"text\":\"" + message + "\"}"; char post_data[]; ArrayResize(post_data, StringToCharArray(jsonMessage, post_data, 0, WHOLE_ARRAY) - 1); int timeout = 5000; char result[]; string responseHeaders; int res = WebRequest("POST", url, "Content-Type: application/json\r\n", timeout, post_data, result, responseHeaders); if (res == 200) // HTTP 200 OK { Print("Message sent successfully: ", message); return true; } else { Print("Failed to send message. HTTP code: ", res, " Error code: ", GetLastError()); Print("Response: ", CharArrayToString(result)); return false; } }
XAUUSDでテストされた新機能
これらの基本的なスタイリング手法を導入することで、GUIにさらに優れたインタラクティブ性と視覚的な魅力をもたらす、より高度なカスタマイズ オプションを検討できるようになりました。上の画像から、テーマが前景テキストにのみ機能していることがわかりますが、パネルの背景にも影響を与える必要があります。次のセグメントでは、この問題を解決する方法について説明します。
GUIの高度な強化
テーマ管理用のダイアログクラスの拡張
テーマ管理用ダイアログを拡張するには、管理パネルでテーマを管理する方法と同様に、既存のダイアログクラスをカスタマイズして動的なテーマの変更をサポートします。これには、背景色とテキスト色のプロパティ、およびさまざまなテーマ(ライトテーマまたはダークテーマ)を適用するためのメソッドを含めるようにCDialogクラスを変更またはサブクラス化することが含まれます。コンストラクタをオーバーライドするか、ApplyThemeなどのメソッドを追加することで、このクラスを使用して作成されたダイアログボックスが、ダイアログオブジェクトを再作成せずにテーマの変更に応答することを保証できます。
Dialogクラスの色のカスタマイズ
重要な理由
テーマ管理のためにDialogクラスを拡張することで、管理パネルだけでなく、すべてのUI要素にわたって、よりシームレスで統一されたユーザーエクスペリエンスが実現します。このアプローチにより、ダイアログボックスを含むアプリケーションのすべての部分が選択したテーマに適応し、視覚的な一貫性と使いやすさが向上します。特に取引アプリケーションなど、ユーザーが長時間インターフェースを操作するケースでは、この機能が重要となり、カスタマイズ可能なテーマによって目の疲れを軽減し、全体的なユーザー満足度の向上にもつながります。
管理パネル:Dialogクラスを変更した後の背景テーマ
その他のオプション
Dialogクラスを拡張するのは直接的で柔軟なアプローチですが、もう 1 つのオプションは、より高いレベルでテーマ管理を適用することです。たとえば、個々のコンポーネントを変更することなく、ダイアログを含むすべてUI要素のプロパティを自動的に更新するグローバル テーマ管理システムを作成できます。さらに、外部ライブラリを活用したり、カスタム ダイアログフレームワークを設計したりすることで、特定のスタイル設定のニーズが生じた場合にUI要素をより細かく制御できるようになります。
CEditクラス
Google検索によると、Telegramメッセージは、最大長が4096文字でUTF-8でエンコードされている必要があります。このプロジェクトで値を実装しようとした際、文字数が最大63文字に制限されていましたが、これは次の記事で説明するCEdit クラスの制約範囲内に収まるはずです。
結論
結管理パネルプログラムにおけるフォントとテーマの管理の実装は、有望な結果を示しました。ダイアログクラスの静的背景にはまだ制約があるものの、テキストの前景はテーマ変更にうまく適応し、ユーザーエクスペリエンスが向上しました。また、動的フォント管理も効果的に機能し、ユーザーはさまざまなフォントを簡単に切り替えることが可能になりました。今後は、ダイアログクラスを拡張し、動的な背景の更新を含むテーマ変更に完全対応させることが次の目標です。この改善により、現在の制約を克服し、より統一感のある視覚的に魅力的なインターフェイスを提供できるようになります。これらの課題については、今後の記事で詳しく取り上げる予定ですので、どうぞご期待ください!
これらのスタイリング手法をご自身の取引パネルで試し、MQL5のさらなるカスタマイズオプションも探ってみてください。皆さんの体験やご意見をお聞かせいただければ幸いです。また、高度なGUIデザインの課題に取り組む際には、以下のコメント欄で共有してください。このプロジェクトのソースファイルも添付してありますので、ぜひご確認ください。
MetaQuotes Ltdにより英語から翻訳されました。
元の記事: https://www.mql5.com/en/articles/15419
- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索