DoEasy-コントロール(第10部):WinFormsオブジェクト - インターフェイスのアニメーション化
内容
概念
以前に作成されたすべてのWinFormsオブジェクトは、実際には、画面全体にドラッグできる静的な画像です。次に、オブジェクトとユーザーおよびオブジェクトとの対話機能を実装して、グラフィカルインターフェイスをアニメーション化します。
既に作成したWinFormsオブジェクトは、グラフィカルインターフェイスを構築するための独立したユニットであると同時に、より複雑なオブジェクトのコンポーネントでもあります。より複雑なオブジェクトを正しく動作させるためにも、新しい機能が必要になります。現在の記事では、これらすべての実装を開始します。さらに、マウスと相互作用するオブジェクトのビジュアルコンポーネントを作成します。以降の記事では、これらのオブジェクトのイベント機能を実装し、新しいライブラリWinFormsオブジェクトの作成を続けます。
マウスと対話でき、可用性フラグを持つアクティブな各GUIオブジェクトは、対話できることをユーザーに通知する必要があります。例として単純なボタンを見てみましょう。マウスのカーソルを合わせると、ボタンの色がわずかに変わり、アクティブで操作の準備ができていることがユーザーに通知されます。押すと、再び色が変わりますが、まだトリガーはされません。インタラクションオブジェクト内でマウスボタンを離すと、トリガーされます。オブジェクト上でマウスボタンを長押しながらカーソルをオブジェクトから離してからマウスボタンを離すと、オブジェクトはトリガーされません。マウスボタンを押す前の状態に戻ります。Windowsオペレーティングシステムのすべてのオブジェクトがこのように動作します。ここでは、WinFormsオブジェクトに対して同じ動作を実装します。
ビジュアルコンポーネントを作成したら、WinFormsオブジェクトのイベント機能の作成を開始します。これにより、単純なオブジェクトからより複雑なオブジェクトを作成できるようになります。複雑なオブジェクトを構成する単純なオブジェクトのイベントは、オブジェクト自体によって分析および処理されます。それに応じて外観が変化し、その結果、オブジェクトはこのオブジェクトで発生したイベントを制御プログラムチャートに送信します。
オブジェクトは同じ状態に対してより多くの色(基本色、マウスカーソルが合わされたときの色、オブジェクトのボタンが押されたときの色)を持つ必要があるため、これらを持つ可能性のある異なるオブジェクトプロパティにこれらの新しい色を追加しましょう。オブジェクトプロパティに新しい色が存在する場合は、後でこれらのオブジェクトのビジュアルエディタを簡単に作成できます。すべてのプロパティはパネルに表示して処理できます。オブジェクトのプロパティで新しい追加の色が設定されていない場合、それらを表示するには、オブジェクトごとに手動で設定する必要がありますが、この解決策は最も洗練されたものではありません。
ライブラリクラスの改善
\MQL5\Include\DoEasy\Defines.mqhで、さまざまなWinFormsオブジェクトの状態のデフォルトカラーの新しいマクロ置換を追加します。
//--- Canvas parameters #define PAUSE_FOR_CANV_UPDATE (16) // Canvas update frequency #define CLR_CANV_NULL (0x00FFFFFF) // Zero for the canvas with the alpha channel #define CLR_DEF_FORE_COLOR (C'0x2D,0x43,0x48') // Default color for texts of objects on canvas #define CLR_DEF_FORE_COLOR_MOUSE_DOWN (C'0x0E,0x11,0x98') // Default color for texts of objects on canvas when clicking the mouse on the control #define CLR_DEF_FORE_COLOR_MOUSE_OVER (C'0x14,0x67,0xF1') // Default color for texts of objects on canvas when hovering the mouse over the control #define CLR_DEF_FORE_COLOR_OPACITY (255) // Default color non-transparency for canvas object texts #define CLR_DEF_BORDER_COLOR (C'0x2D,0x43,0x48') // Default color for object frames on canvas #define CLR_DEF_BORDER_MOUSE_DOWN (C'0x61,0x88,0xC9') // Default color for object frames on canvas when clicking the mouse on the control #define CLR_DEF_BORDER_MOUSE_OVER (C'0x93,0xAD,0xC8') // Default color for object frames on canvas when hovering the mouse over the control #define CLR_DEF_BORDER_COLOR_OPACITY (255) // Default color non-transparency for canvas object frames #define CLR_DEF_BORDER_COLOR_DARKNESS (-2.0) // Default color opacity for canvas object frames (when using the background color) #define CLR_DEF_FRAME_GBOX_COLOR (C'0xDC,0xDC,0xDC') // Default color for GroupBox object frames on canvas #define CLR_DEF_OPACITY (200) // Default color non-transparency for canvas objects #define CLR_DEF_SHADOW_COLOR (C'0x6B,0x6B,0x6B') // Default color for canvas object shadows #define CLR_DEF_SHADOW_OPACITY (127) // Default color opacity for canvas objects #define DEF_SHADOW_BLUR (4) // Default blur for canvas object shadows #define CLR_DEF_CHECK_BACK_COLOR (C'0xFF,0xFF,0xFF') // Color of control checkbox background #define CLR_DEF_CHECK_BACK_OPACITY (255) // Opacity of the control checkbox background color #define CLR_DEF_CHECK_BACK_MOUSE_DOWN (C'0xC0,0xDC,0xF3') // Color of control checkbox background when clicking on the control #define CLR_DEF_CHECK_BACK_MOUSE_OVER (C'0xD8,0xE6,0xF2') // Color of control checkbox background when hovering the mouse over the control #define CLR_DEF_CHECK_BORDER_COLOR (C'0x2D,0x43,0x48') // Color of control checkbox frame #define CLR_DEF_CHECK_BORDER_OPACITY (255) // Opacity of the control checkbox frame color #define CLR_DEF_CHECK_BORDER_MOUSE_DOWN (C'0x00,0x54,0x99') // Color of control checkbox frame when clicking on the control #define CLR_DEF_CHECK_BORDER_MOUSE_OVER (C'0x00,0x78,0xD7') // Color of control checkbox frame when hovering the mouse over the control #define CLR_DEF_CHECK_FLAG_COLOR (C'0x04,0x7B,0x0D') // Color of control checkbox #define CLR_DEF_CHECK_FLAG_OPACITY (255) // Opacity of the control checkbox color #define CLR_DEF_CHECK_FLAG_MOUSE_DOWN (C'0x00,0x54,0x99') // Color of control checkbox when clicking on the control #define CLR_DEF_CHECK_FLAG_MOUSE_OVER (C'0x00,0x78,0xD7') // Color of control checkbox when hovering the mouse over the control #define CLR_DEF_CONTROL_STD_BACK_COLOR (C'0xF0,0xF0,0xF0') // Standard controls background color #define CLR_DEF_CONTROL_STD_MOUSE_DOWN (C'0xC0,0xDC,0xF3') // Color of standard control background when clicking on the control #define CLR_DEF_CONTROL_STD_MOUSE_OVER (C'0xD8,0xE6,0xF2') // Color of standard controls background when hovering the mouse over the control #define CLR_DEF_CONTROL_STD_OPACITY (255) // Opacity of standard controls background color #define CLR_DEF_CONTROL_STD_BACK_COLOR_ON (C'0xC9,0xDE,0xD0') // Background color of standard controls which are on #define CLR_DEF_CONTROL_STD_BACK_DOWN_ON (C'0xA6,0xC8,0xB0') // Color of standard control background when clicking on the control when it is on #define CLR_DEF_CONTROL_STD_BACK_OVER_ON (C'0xB8,0xD3,0xC0') // Color of standard control background when hovering the mouse over the control when it is on #define DEF_FONT ("Calibri") // Default font #define DEF_FONT_SIZE (8) // Default font size #define DEF_CHECK_SIZE (12) // Verification flag default size #define OUTER_AREA_SIZE (16) // Size of one side of the outer area around the form workspace #define DEF_FRAME_WIDTH_SIZE (3) // Default form/panel/window frame width //--- Graphical object parameters
チェックボックスにForeColorは必要ありません。BorderColor(チェックボックスの枠の色)に置き換えましょう。マウスを操作すると、背景色とともに変化します。チェックボックスの色は、ここではForeColorとして使用されます。
フォームに関連するさらに別のマウスの状態をライブラリで追跡する必要があります。これは、カーソルがアクティブ領域にあり、クリック後にマウスボタンが離されたときです。フォームに関連する可能なマウス状態のリストに新しい状態を追加します。
//+------------------------------------------------------------------+ //| The list of possible mouse states relative to the form | //+------------------------------------------------------------------+ enum ENUM_MOUSE_FORM_STATE { MOUSE_FORM_STATE_NONE = 0, // Undefined state //--- Outside the form MOUSE_FORM_STATE_OUTSIDE_FORM_NOT_PRESSED, // The cursor is outside the form, the mouse buttons are not clicked MOUSE_FORM_STATE_OUTSIDE_FORM_PRESSED, // The cursor is outside the form, the mouse button (any) is clicked MOUSE_FORM_STATE_OUTSIDE_FORM_WHEEL, // The cursor is outside the form, the mouse wheel is being scrolled //--- Within the form MOUSE_FORM_STATE_INSIDE_FORM_NOT_PRESSED, // The cursor is inside the form, no mouse buttons are clicked MOUSE_FORM_STATE_INSIDE_FORM_PRESSED, // The cursor is inside the form, the mouse button (any) is clicked MOUSE_FORM_STATE_INSIDE_FORM_WHEEL, // The cursor is inside the form, the mouse wheel is being scrolled //--- Within the window header area MOUSE_FORM_STATE_INSIDE_ACTIVE_AREA_NOT_PRESSED, // The cursor is inside the active area, the mouse buttons are not clicked MOUSE_FORM_STATE_INSIDE_ACTIVE_AREA_PRESSED, // The cursor is inside the active area, any mouse button is clicked MOUSE_FORM_STATE_INSIDE_ACTIVE_AREA_WHEEL, // The cursor is inside the active area, the mouse wheel is being scrolled MOUSE_FORM_STATE_INSIDE_ACTIVE_AREA_RELEASED, // The cursor is inside the active area, left mouse button is released //--- Within the window scrolling area MOUSE_FORM_STATE_INSIDE_SCROLL_AREA_NOT_PRESSED, // The cursor is within the window scrolling area, the mouse buttons are not clicked MOUSE_FORM_STATE_INSIDE_SCROLL_AREA_PRESSED, // The cursor is within the window scrolling area, the mouse button (any) is clicked MOUSE_FORM_STATE_INSIDE_SCROLL_AREA_WHEEL, // The cursor is within the window scrolling area, the mouse wheel is being scrolled }; //+------------------------------------------------------------------+
この状態を追跡することで、マウスボタンを離した瞬間を判断できます。この瞬間が、グラフィカルオブジェクトの状態を変更するための鍵となります。
マウスの操作に反応するには、どのマウスイベントが発生したかを知る必要があります。その後、このイベントの処理に基づいて、ライブラリユーザーがプログラムでこのイベントを処理できるように、プログラムに送信します。
マウスイベントのリストを使用して新しい列挙を作成します。
//+------------------------------------------------------------------+ //| List of possible mouse events | //+------------------------------------------------------------------+ enum ENUM_MOUSE_EVENT { MOUSE_EVENT_NO_EVENT = CHART_OBJ_EVENTS_NEXT_CODE, // No event //--- MOUSE_EVENT_OUTSIDE_FORM_NOT_PRESSED, // The cursor is outside the form, the mouse buttons are not clicked MOUSE_EVENT_OUTSIDE_FORM_PRESSED, // The cursor is outside the form, the mouse button (any) is clicked MOUSE_EVENT_OUTSIDE_FORM_WHEEL, // The cursor is outside the form, the mouse wheel is being scrolled //--- Within the form MOUSE_EVENT_INSIDE_FORM_NOT_PRESSED, // The cursor is inside the form, no mouse buttons are clicked MOUSE_EVENT_INSIDE_FORM_PRESSED, // The cursor is inside the form, the mouse button (any) is clicked MOUSE_EVENT_INSIDE_FORM_WHEEL, // The cursor is inside the form, the mouse wheel is being scrolled //--- Within the window header area MOUSE_EVENT_INSIDE_ACTIVE_AREA_NOT_PRESSED, // The cursor is inside the active area, the mouse buttons are not clicked MOUSE_EVENT_INSIDE_ACTIVE_AREA_PRESSED, // The cursor is inside the active area, any mouse button is clicked MOUSE_EVENT_INSIDE_ACTIVE_AREA_WHEEL, // The cursor is inside the active area, the mouse wheel is being scrolled MOUSE_EVENT_INSIDE_ACTIVE_AREA_RELEASED, // The cursor is inside the active area, left mouse button is released //--- Within the window scrolling area MOUSE_EVENT_INSIDE_SCROLL_AREA_NOT_PRESSED, // The cursor is within the window scrolling area, the mouse buttons are not clicked MOUSE_EVENT_INSIDE_SCROLL_AREA_PRESSED, // The cursor is within the window scrolling area, the mouse button (any) is clicked MOUSE_EVENT_INSIDE_SCROLL_AREA_WHEEL, // The cursor is within the window scrolling area, the mouse wheel is being scrolled }; #define ENUM_MOUSE_EVENT_NEXT_CODE (MOUSE_EVENT_INSIDE_SCROLL_AREA_WHEEL+1) // The code of the next event after the last chart event code //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Data for handling graphical elements | //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| List of possible graphical object events | //+------------------------------------------------------------------+ enum ENUM_GRAPH_OBJ_EVENT { GRAPH_OBJ_EVENT_NO_EVENT = ENUM_MOUSE_EVENT_NEXT_CODE,// No event GRAPH_OBJ_EVENT_CREATE, // "Creating a new graphical object" event GRAPH_OBJ_EVENT_CHANGE, // "Changing graphical object properties" event GRAPH_OBJ_EVENT_RENAME, // "Renaming graphical object" event GRAPH_OBJ_EVENT_DELETE, // "Removing graphical object" event GRAPH_OBJ_EVENT_DEL_CHART, // "Removing a graphical object together with the chart window" event }; #define GRAPH_OBJ_EVENTS_NEXT_CODE (GRAPH_OBJ_EVENT_DEL_CHART+1) // The code of the next event after the last graphical object event code //+------------------------------------------------------------------+
チャートイベントのリストとチャートオブジェクトイベントのリストの間に新しいイベント列挙を「ねじ込んだ」ので、グラフィカルオブジェクトの最初のイベントの初期値は最後のマウスイベント+1として計算されます。
グラフィック要素の整数プロパティのリストに新しいプロパティを追加します。
//+------------------------------------------------------------------+ //| Integer properties of the graphical element on the canvas | //+------------------------------------------------------------------+ enum ENUM_CANV_ELEMENT_PROP_INTEGER { CANV_ELEMENT_PROP_ID = 0, // Element ID CANV_ELEMENT_PROP_TYPE, // Graphical element type //---... //---... CANV_ELEMENT_PROP_FORE_COLOR, // Default text color for all control objects CANV_ELEMENT_PROP_FORE_COLOR_OPACITY, // Default text color opacity for all control objects CANV_ELEMENT_PROP_FORE_COLOR_MOUSE_DOWN, // Default control text color when clicking on the control CANV_ELEMENT_PROP_FORE_COLOR_MOUSE_OVER, // Default control text color when hovering the mouse over the control CANV_ELEMENT_PROP_FORE_COLOR_TOGGLE, // Text color of the control which is on CANV_ELEMENT_PROP_FORE_COLOR_TOGGLE_MOUSE_DOWN, // Default control text color when clicking on the control which is on CANV_ELEMENT_PROP_FORE_COLOR_TOGGLE_MOUSE_OVER, // Default control text color when hovering the mouse over the control which is on CANV_ELEMENT_PROP_BACKGROUND_COLOR, // Control background color CANV_ELEMENT_PROP_BACKGROUND_COLOR_OPACITY, // Opacity of control background color CANV_ELEMENT_PROP_BACKGROUND_COLOR_MOUSE_DOWN, // Control background color when clicking on the control CANV_ELEMENT_PROP_BACKGROUND_COLOR_MOUSE_OVER, // Control background color when hovering the mouse over the control CANV_ELEMENT_PROP_BACKGROUND_COLOR_TOGGLE, // Background color of the control which is on CANV_ELEMENT_PROP_BACKGROUND_COLOR_TOGGLE_MOUSE_DOWN,// Control background color when clicking on the control which is on CANV_ELEMENT_PROP_BACKGROUND_COLOR_TOGGLE_MOUSE_OVER,// Control background color hovering the mouse over control which is on CANV_ELEMENT_PROP_BOLD_TYPE, // Font width type CANV_ELEMENT_PROP_BORDER_STYLE, // Control frame style //---... //---... CANV_ELEMENT_PROP_CHECK_STATE, // Status of a control having a checkbox CANV_ELEMENT_PROP_AUTOCHECK, // Auto change flag status when it is selected CANV_ELEMENT_PROP_BUTTON_TOGGLE, // Toggle flag of the control featuring a button CANV_ELEMENT_PROP_BUTTON_STATE, // Status of the Toggle control featuring a button CANV_ELEMENT_PROP_CHECK_BACKGROUND_COLOR, // Color of control checkbox background CANV_ELEMENT_PROP_CHECK_BACKGROUND_COLOR_OPACITY, // Opacity of the control checkbox background color //---... //---... CANV_ELEMENT_PROP_CHECK_FLAG_COLOR_MOUSE_DOWN, // Color of control checkbox when clicking on the control CANV_ELEMENT_PROP_CHECK_FLAG_COLOR_MOUSE_OVER, // Color of control checkbox when hovering the mouse over the control }; #define CANV_ELEMENT_PROP_INTEGER_TOTAL (81) // Total number of integer properties #define CANV_ELEMENT_PROP_INTEGER_SKIP (0) // Number of integer properties not used in sorting //+------------------------------------------------------------------+
実数プロパティの総数を71から81に増やします.。
キャンバス上のグラフィック要素を並べ替える可能性のある基準の列挙に新しいプロパティを追加します。
//+------------------------------------------------------------------+ //| Possible sorting criteria of graphical elements on the canvas | //+------------------------------------------------------------------+ #define FIRST_CANV_ELEMENT_DBL_PROP (CANV_ELEMENT_PROP_INTEGER_TOTAL-CANV_ELEMENT_PROP_INTEGER_SKIP) #define FIRST_CANV_ELEMENT_STR_PROP (CANV_ELEMENT_PROP_INTEGER_TOTAL-CANV_ELEMENT_PROP_INTEGER_SKIP+CANV_ELEMENT_PROP_DOUBLE_TOTAL-CANV_ELEMENT_PROP_DOUBLE_SKIP) enum ENUM_SORT_CANV_ELEMENT_MODE { //--- Sort by integer properties SORT_BY_CANV_ELEMENT_ID = 0, // Sort by element ID SORT_BY_CANV_ELEMENT_TYPE, // Sort by graphical element type //---... //---... SORT_BY_CANV_ELEMENT_FORE_COLOR, // Sort by default text color for all control objects SORT_BY_CANV_ELEMENT_FORE_COLOR_OPACITY, // Sort by default text color opacity for all control objects SORT_BY_CANV_ELEMENT_FORE_COLOR_MOUSE_DOWN, // Sort by control text color when clicking on the control SORT_BY_CANV_ELEMENT_FORE_COLOR_MOUSE_OVER, // Sort by control text color when hovering the mouse over the control SORT_BY_CANV_ELEMENT_FORE_COLOR_TOGGLE, // Sort by control text color when the control is on SORT_BY_CANV_ELEMENT_FORE_COLOR_TOGGLE_MOUSE_DOWN, // Sort by the default control text color when clicking on the control while it is on SORT_BY_CANV_ELEMENT_FORE_COLOR_TOGGLE_MOUSE_OVER, // Sort by the default control text color when hovering the mouse over the control while it is on SORT_BY_CANV_ELEMENT_BACKGROUND_COLOR, // Sort by control background text color SORT_BY_CANV_ELEMENT_BACKGROUND_COLOR_OPACITY, // Sort by control background color opacity SORT_BY_CANV_ELEMENT_BACKGROUND_COLOR_MOUSE_DOWN, // Sort by control background text color when clicking on the control SORT_BY_CANV_ELEMENT_BACKGROUND_COLOR_MOUSE_OVER, // Sort by control background text color when hovering the mouse over the control SORT_BY_CANV_ELEMENT_BACKGROUND_COLOR_TOGGLE, // Sort by control background color when the control is on SORT_BY_CANV_ELEMENT_BACKGROUND_COLOR_TOGGLE_MOUSE_DOWN,// Sort by control background color when clicking on the control while it is on SORT_BY_CANV_ELEMENT_BACKGROUND_COLOR_TOGGLE_MOUSE_OVER,// Sort by control background color when hovering the mouse over the control while it is on SORT_BY_CANV_ELEMENT_BOLD_TYPE, // Sort by font width type SORT_BY_CANV_ELEMENT_BORDER_STYLE, // Sort by control frame style //---... //---... SORT_BY_CANV_ELEMENT_CHECK_STATE, // Sort by status of a control having a checkbox SORT_BY_CANV_ELEMENT_AUTOCHECK, // Sort by auto change flag status when it is selected SORT_BY_CANV_ELEMENT_BUTTON_TOGGLE, // Sort by the Toggle flag of the control featuring a button SORT_BY_CANV_ELEMENT_BUTTON_STATE, // Sort by the status of the Toggle control featuring a button SORT_BY_CANV_ELEMENT_CHECK_BACKGROUND_COLOR, // Sort by color of control checkbox background SORT_BY_CANV_ELEMENT_CHECK_BACKGROUND_COLOR_OPACITY, // Sort by opacity of control checkbox background color //---... //---... SORT_BY_CANV_ELEMENT_CHECK_FLAG_COLOR_MOUSE_DOWN, // Sort by color of control checkbox when clicking on the control SORT_BY_CANV_ELEMENT_CHECK_FLAG_COLOR_MOUSE_OVER, // Sort by color of control checkbox when hovering the mouse over the control //--- Sort by real properties //--- Sort by string properties SORT_BY_CANV_ELEMENT_NAME_OBJ = FIRST_CANV_ELEMENT_STR_PROP,// Sort by an element object name SORT_BY_CANV_ELEMENT_NAME_RES, // Sort by the graphical resource name SORT_BY_CANV_ELEMENT_TEXT, // Sort by graphical element text }; //+------------------------------------------------------------------+
これで、新しいプロパティでオブジェクトを並べ替えて選択できるようになりました。
\MQL5\Include\DoEasy\Data.mqhに、ライブラリの新しいメッセージインデックスを追加します。
MSG_CANV_ELEMENT_PROP_FORE_COLOR, // Default text color for all control objects MSG_CANV_ELEMENT_PROP_FORE_COLOR_OPACITY, // Default text color opacity for all control objects MSG_CANV_ELEMENT_PROP_FORE_COLOR_MOUSE_DOWN, // Default control text color when clicking on the control MSG_CANV_ELEMENT_PROP_FORE_COLOR_MOUSE_OVER, // Default control text color when hovering the mouse over the control MSG_CANV_ELEMENT_PROP_FORE_COLOR_TOGGLE, // Text color of the control which is on MSG_CANV_ELEMENT_PROP_FORE_COLOR_TOGGLE_MOUSE_DOWN,// Default control text color when clicking on the control which is on MSG_CANV_ELEMENT_PROP_FORE_COLOR_TOGGLE_MOUSE_OVER,// Default control text color when hovering the mouse over the control which is on MSG_CANV_ELEMENT_PROP_BACKGROUND_COLOR, // Control background color MSG_CANV_ELEMENT_PROP_BACKGROUND_COLOR_OPACITY, // Opacity of control background color MSG_CANV_ELEMENT_PROP_BACKGROUND_COLOR_MOUSE_DOWN, // Control background color when clicking on the control MSG_CANV_ELEMENT_PROP_BACKGROUND_COLOR_MOUSE_OVER, // Control background color when hovering the mouse over the control MSG_CANV_ELEMENT_PROP_BACKGROUND_COLOR_TOGGLE, // Background color of the control which is on MSG_CANV_ELEMENT_PROP_BACKGROUND_COLOR_TOGGLE_MOUSE_DOWN,// Control background color when clicking on the control which is on MSG_CANV_ELEMENT_PROP_BACKGROUND_COLOR_TOGGLE_MOUSE_OVER,// Control background color when hovering the mouse over control which is on MSG_CANV_ELEMENT_PROP_BOLD_TYPE, // Font width type MSG_CANV_ELEMENT_PROP_BORDER_STYLE, // Control frame style
...
MSG_CANV_ELEMENT_PROP_CHECK_STATE, // Status of a control having a checkbox MSG_CANV_ELEMENT_PROP_AUTOCHECK, // Auto change flag status when it is selected MSG_CANV_ELEMENT_PROP_BUTTON_TOGGLE, // Toggle flag of the control featuring a button MSG_CANV_ELEMENT_PROP_BUTTON_STATE, // Status of the Toggle control featuring a button MSG_CANV_ELEMENT_PROP_CHECK_BACKGROUND_COLOR, // Color of control checkbox background MSG_CANV_ELEMENT_PROP_CHECK_BACKGROUND_COLOR_OPACITY,// Opacity of the control checkbox background color MSG_CANV_ELEMENT_PROP_CHECK_BACKGROUND_COLOR_MOUSE_DOWN,// Color of control checkbox background when clicking on the control MSG_CANV_ELEMENT_PROP_CHECK_BACKGROUND_COLOR_MOUSE_OVER,// Color of control checkbox background when hovering the mouse over the control MSG_CANV_ELEMENT_PROP_CHECK_FORE_COLOR, // Color of control checkbox frame MSG_CANV_ELEMENT_PROP_CHECK_FORE_COLOR_OPACITY, // Opacity of the control checkbox frame color MSG_CANV_ELEMENT_PROP_CHECK_FORE_COLOR_MOUSE_DOWN, // Color of control checkbox frame when clicking on the control MSG_CANV_ELEMENT_PROP_CHECK_FORE_COLOR_MOUSE_OVER, // Color of control checkbox frame when hovering the mouse over the control MSG_CANV_ELEMENT_PROP_CHECK_FLAG_COLOR, // Color of control checkbox MSG_CANV_ELEMENT_PROP_CHECK_FLAG_COLOR_OPACITY, // Opacity of the control checkbox color MSG_CANV_ELEMENT_PROP_CHECK_FLAG_COLOR_MOUSE_DOWN, // Color of control checkbox when clicking on the control MSG_CANV_ELEMENT_PROP_CHECK_FLAG_COLOR_MOUSE_OVER, // Color of control checkbox when hovering the mouse over the control //--- Real properties of graphical elements //--- String properties of graphical elements MSG_CANV_ELEMENT_PROP_NAME_OBJ, // Graphical element object name MSG_CANV_ELEMENT_PROP_NAME_RES, // Graphical resource name MSG_CANV_ELEMENT_PROP_TEXT, // Graphical element text
新しく追加したインデックスに対応するメッセージテキストも追加します。
{"Цвет текста по умолчанию для всех объектов элемента управления","Default text color for all objects in the control"}, {"Непрозрачность цвета текста по умолчанию для всех объектов элемента управления","Default text color opacity for all objects in the control"}, {"Цвет текста элемента по умолчанию при нажатии мышки на элемент управления","The default text color of an element when the mouse is pressed on the control"}, {"Цвет текста элемента по умолчанию при наведении мышки на элемент управления","The default text color of an element when hovering over the control"}, {"Цвет текста элемента управления в состоянии \"включено\"","The text color of a control in the enabled state"}, {"Цвет текста элемента управления по умолчанию в состоянии \"включено\" при нажатии мышки на элемент управления","The default text color of the control in the \"On\" state when the mouse is pressed on the control"}, {"Цвет текста элемента управления по умолчанию в состоянии \"включено\" при наведении мышки на элемент управления","The default text color of a control in the \"On\" state when hovering the mouse over the control"}, {"Цвет фона элемента управления","Background color of the control"}, {"Непрозрачность цвета фона элемента управления","Opacity of the control's background color"}, {"Цвет фона элемента управления при нажатии мышки на элемент управления","Background color of the control when the mouse is clicked on the control"}, {"Цвет фона элемента управления при наведении мышки на элемент управления","Background color of the control when hovering the mouse over the control"}, {"Цвет фона элемента управления в состоянии \"включено\"","Background color of the control in the enabled state"}, {"Цвет фона элемента управления в состоянии \"включено\" при нажатии мышки на элемент управления","The background color of the control in the \"On\" state when the mouse is pressed on the control"}, {"Цвет фона элемента управления в состоянии \"включено\" при наведении мышки на элемент управления","The background color of a control in the \"On\" state when the mouse is over the control"}, {"Тип толщины шрифта","Font weight type"}, {"Стиль рамки элемента управления","Control's border style"},
...
{"Состояние элемента управления, имеющего флажок проверки","The state of a control that has a checkbox"}, {"Автоматическое изменение состояния флажка при его выборе","Automatically change the state of the checkbox when it is selected"}, {"Флаг \"Переключатель\" элемента управления, имеющего кнопку","\"Button-toggle\" flag of a control"}, {"Состояние элемента управления \"Переключатель\", имеющего кнопку","The \"Toggle-button\" control state"}, {"Цвет фона флажка проверки элемента управления","The background color of the control's validation checkbox"}, {"Непрозрачность цвета фона флажка проверки элемента управления","Opacity of the backgroung color of the checkbox control"}, {"Цвет фона флажка проверки элемента управления при нажатии мышки на элемент управления","The background color of the control's checkbox when the control is pressed with the mouse"}, {"Цвет фона флажка проверки элемента управления при наведении мышки на элемент управления","The background color of the control's validation checkbox when hovering the mouse over the control"}, {"Цвет рамки флажка проверки элемента управления","Border color of the checkbox control"}, {"Непрозрачность цвета рамки флажка проверки элемента управления","Border color opacity of the checkbox control"}, {"Цвет рамки флажка проверки элемента управления при нажатии мышки на элемент управления","Border color of the checkbox control when the mouse is pressed on the control"}, {"Цвет рамки флажка проверки элемента управления при наведении мышки на элемент управления","Border color of the checkbox control when hovering the mouse over the control"}, {"Цвет флажка проверки элемента управления","Control Checkbox Color"}, {"Непрозрачность цвета флажка проверки элемента управления","Opacity of control's checkbox color"}, {"Цвет флажка проверки элемента управления при нажатии мышки на элемент управления","Control Checkbox Colorl when the mouse is pressed on the control"}, {"Цвет флажка проверки элемента управления при наведении мышки на элемент управления","Control Checkbox Colorl when hovering the mouse over the control"}, //--- String properties of graphical elements {"Имя объекта-графического элемента","The name of the graphic element object"}, {"Имя графического ресурса","Image resource name"}, {"Текст графического элемента","Text of the graphic element"},
オブジェクトにカーソルを合わせるまたはクリックすると、背景色を変更する必要があります。ただし、元の色を復元するには、最初のオブジェクトの作成時にそれを記憶し、以前に保存した色から必要な色を取得する必要があります。
グラフィカルオブジェクトの背景色はグラデーションにすることができるため(つまり色の配列を使用するため)、初期色を格納するための変数だけでなく、配列全体が必要です。オブジェクトの作成時に、グラデーションカラーの配列とまったく同じ方法で入力されます。色を復元するときは、保存された配列から色を取得します。
\MQL5\Include\DoEasy\Objects\Graph\GCnvElement.mqhのprotectedセクションで、初期背景色の配列を宣言し、色配列に入力するメソッドをprivateセクションから移動します。このメソッドは継承されたクラスで必要になるからです。
//+------------------------------------------------------------------+ //| Class of the graphical element object | //+------------------------------------------------------------------+ class CGCnvElement : public CGBaseObj { protected: CGCnvElement *m_element_main; // Pointer to the initial parent element within all the groups of bound objects CGCnvElement *m_element_base; // Pointer to the parent element within related objects of the current group CCanvas m_canvas; // CCanvas class object CPause m_pause; // Pause class object bool m_shadow; // Shadow presence color m_chart_color_bg; // Chart background color uint m_duplicate_res[]; // Array for storing resource data copy color m_array_colors_bg[]; // Array of element background colors color m_array_colors_bg_dwn[]; // Array of control background colors when clicking on the control color m_array_colors_bg_ovr[]; // Array of control background colors when hovering the mouse over the control bool m_gradient_v; // Vertical gradient filling flag bool m_gradient_c; // Cyclic gradient filling flag int m_init_relative_x; // Initial relative X coordinate int m_init_relative_y; // Initial relative Y coordinate color m_array_colors_bg_init[]; // Array of element background colors (initial color) //--- Create (1) the object structure and (2) the object from the structure virtual bool ObjectToStruct(void); virtual void StructToObject(void); //--- Copy the color array to the specified background color array void CopyArraysColors(color &array_dst[],const color &array_src[],const string source); private:
クラスのprivateセクションでオブジェクトデータ構造体に新しいオブジェクト整数プロパティを追加します。
private: int m_shift_coord_x; // Offset of the X coordinate relative to the base object int m_shift_coord_y; // Offset of the Y coordinate relative to the base object struct SData { //--- Object integer properties int id; // Element ID int type; // Graphical element type //---... //---... color check_flag_color_mouse_down; // Color of control checkbox when clicking on the control color check_flag_color_mouse_over; // Color of control checkbox when clicking on the control color fore_color_mouse_down; // Default control text color when clicking on the control color fore_color_mouse_over; // Default control text color when hovering the mouse over the control color fore_color_toggle; // Text color of the control which is on color fore_color_toggle_mouse_down; // Default control text color when clicking on the control which is on color fore_color_toggle_mouse_over; // Default control text color when hovering the mouse over the control which is on color background_color_toggle; // Background color of the control which is on color background_color_toggle_mouse_down; // Control background color when clicking on the control which is on color background_color_toggle_mouse_over; // Control background color when hovering the mouse over the control which is on bool button_toggle; // Toggle flag of the control featuring a button bool button_state; // Status of the Toggle control featuring a button //--- Object real properties //--- Object string properties uchar name_obj[64]; // Graphical element object name uchar name_res[64]; // Graphical resource name uchar text[256]; // Graphical element text }; SData m_struct_obj; // Object structure uchar m_uchar_array[]; // uchar array of the object structure
これは、将来、オブジェクトをメディアに正しく保存し、そこから読み取るために必要です。
元の背景色を記憶するために、グラデーションカラーの配列を保存する別のメソッドを追加しましょう。
//--- Save the colors to the background color array void SaveColorsBG(color &colors[]) { this.CopyArraysColors(this.m_array_colors_bg,colors,DFUN); } void SaveColorsBGMouseDown(color &colors[]) { this.CopyArraysColors(this.m_array_colors_bg_dwn,colors,DFUN); } void SaveColorsBGMouseOver(color &colors[]) { this.CopyArraysColors(this.m_array_colors_bg_ovr,colors,DFUN); } void SaveColorsBGInit(color &colors[]) { this.CopyArraysColors(this.m_array_colors_bg_init,colors,DFUN); } public:
メソッドは、背景色を設定するメソッドで呼び出されます。これを実現するために、フラグを導入し、オブジェクトの背景色を設定した後に初期背景色を保存する必要があることをその仮変数に指定します。したがって、オブジェクトの背景色を設定してその初期色を配列に記憶するか、単に新しい背景色を設定して、以前に配列に設定された背景グラデーション色のセット全体から復元するかを選択できます。.マウスを操作したときに色が変わるすべてのオブジェクトに対してこれをおこないます。
//--- Set the main background color void SetBackgroundColor(const color colour,const bool set_init_color) { this.SetProperty(CANV_ELEMENT_PROP_BACKGROUND_COLOR,colour); color arr[1]; arr[0]=colour; this.SaveColorsBG(arr); if(set_init_color) this.SetBackgroundColorInit(this.BackgroundColor()); } void SetBackgroundColors(color &colors[],const bool set_init_colors) { this.SaveColorsBG(colors); this.SetProperty(CANV_ELEMENT_PROP_BACKGROUND_COLOR,this.m_array_colors_bg[0]); if(set_init_colors) this.SetBackgroundColorsInit(colors); }
初期の背景色を設定するための同様のメソッドを追加しましょう。
void SetBackgroundColorsMouseOver(color &colors[]) { this.SaveColorsBGMouseOver(colors); this.SetProperty(CANV_ELEMENT_PROP_BACKGROUND_COLOR_MOUSE_OVER,this.m_array_colors_bg_ovr[0]); } //--- Set the initial main background color void SetBackgroundColorInit(const color colour) { color arr[1]; arr[0]=colour; this.SaveColorsBGInit(arr); } void SetBackgroundColorsInit(color &colors[]) { this.SaveColorsBGInit(colors); } //--- Set (1) object movability, (2) activity, (3) interaction,
これらのメソッドを呼び出すことによって保存される初期色を保存する必要があることを示すフラグを除いて、メインの背景色を設定するメソッドとすべて同じです。
初期の背景色を返すメソッドを書きます。
//--- Return the background color when hovering the mouse over the control color BackgroundColorMouseOver(void) const { return (color)this.GetProperty(CANV_ELEMENT_PROP_BACKGROUND_COLOR_MOUSE_OVER); } color BackgroundColorMouseOver(const uint index) const { uint total=this.m_array_colors_bg_ovr.Size(); if(total==0) return this.BackgroundColorMouseOver(); return(index>total-1 ? this.m_array_colors_bg_ovr[total-1] : this.m_array_colors_bg_ovr[index]); } //--- Return the initial color of the main background color BackgroundColorInit(void) const { return (color)this.m_array_colors_bg_init[0]; } color BackgroundColorInit(const uint index)const { uint total=this.m_array_colors_bg_init.Size(); if(total==0) return this.BackgroundColor(); return(index>total-1 ? this.m_array_colors_bg_init[total-1] : this.m_array_colors_bg_init[index]); } //--- Return (1) the opacity, coordinate (2) of the right and (3) bottom element edge
メソッドは、唯一の背景色、またはメソッドに渡されたインデックスに対応するグラデーションカラーのセットからの色のいずれかを返します。
両方のクラスコンストラクタで、新しいプロパティを初期化して初期背景色を保存するためのフラグを渡します。
//+------------------------------------------------------------------+ //| Parametric constructor | //+------------------------------------------------------------------+ CGCnvElement::CGCnvElement(const ENUM_GRAPH_ELEMENT_TYPE element_type, const int element_id, const int element_num, const long chart_id, const int wnd_num, const string name, const int x, const int y, const int w, const int h, const color colour, const uchar opacity, const bool movable=true, const bool activity=true, const bool redraw=false) : m_shadow(false) { this.m_type=OBJECT_DE_TYPE_GELEMENT; this.m_element_main=NULL; this.m_element_base=NULL; this.m_chart_color_bg=(color)::ChartGetInteger((chart_id==NULL ? ::ChartID() : chart_id),CHART_COLOR_BACKGROUND); this.m_name=(::StringFind(name,this.m_name_prefix)<0 ? this.m_name_prefix : "")+name; this.m_chart_id=(chart_id==NULL || chart_id==0 ? ::ChartID() : chart_id); this.m_subwindow=wnd_num; this.m_type_element=element_type; this.SetFont(DEF_FONT,DEF_FONT_SIZE); this.m_text_anchor=0; this.m_text_x=0; this.m_text_y=0; this.SetBackgroundColor(colour,true); this.SetOpacity(opacity); this.m_shift_coord_x=0; this.m_shift_coord_y=0; if(::ArrayResize(this.m_array_colors_bg,1)==1) this.m_array_colors_bg[0]=this.BackgroundColor(); if(::ArrayResize(this.m_array_colors_bg_dwn,1)==1) this.m_array_colors_bg_dwn[0]=this.BackgroundColor(); if(::ArrayResize(this.m_array_colors_bg_ovr,1)==1) this.m_array_colors_bg_ovr[0]=this.BackgroundColor(); if(this.Create(chart_id,wnd_num,this.m_name,x,y,w,h,redraw)) { this.SetProperty(CANV_ELEMENT_PROP_NAME_RES,this.m_canvas.ResourceName()); // Graphical resource name this.SetProperty(CANV_ELEMENT_PROP_CHART_ID,CGBaseObj::ChartID()); // Chart ID this.SetProperty(CANV_ELEMENT_PROP_WND_NUM,CGBaseObj::SubWindow()); // Chart subwindow index this.SetProperty(CANV_ELEMENT_PROP_NAME_OBJ,CGBaseObj::Name()); // Element object name this.SetProperty(CANV_ELEMENT_PROP_TYPE,element_type); // Graphical element type this.SetProperty(CANV_ELEMENT_PROP_ID,element_id); // Element ID this.SetProperty(CANV_ELEMENT_PROP_NUM,element_num); // Element index in the list this.SetProperty(CANV_ELEMENT_PROP_COORD_X,x); // Element's X coordinate on the chart this.SetProperty(CANV_ELEMENT_PROP_COORD_Y,y); // Element's Y coordinate on the chart this.SetProperty(CANV_ELEMENT_PROP_WIDTH,w); // Element width this.SetProperty(CANV_ELEMENT_PROP_HEIGHT,h); // Element height this.SetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_LEFT,0); // Active area offset from the left edge of the element this.SetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_TOP,0); // Active area offset from the upper edge of the element this.SetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_RIGHT,0); // Active area offset from the right edge of the element this.SetProperty(CANV_ELEMENT_PROP_ACT_SHIFT_BOTTOM,0); // Active area offset from the bottom edge of the element this.SetProperty(CANV_ELEMENT_PROP_MOVABLE,movable); // Element moveability flag this.SetProperty(CANV_ELEMENT_PROP_ACTIVE,activity); // Element activity flag this.SetProperty(CANV_ELEMENT_PROP_INTERACTION,false); // Flag of interaction with the outside environment this.SetProperty(CANV_ELEMENT_PROP_ENABLED,true); // Element availability flag this.SetProperty(CANV_ELEMENT_PROP_RIGHT,this.RightEdge()); // Element right border this.SetProperty(CANV_ELEMENT_PROP_BOTTOM,this.BottomEdge()); // Element bottom border this.SetProperty(CANV_ELEMENT_PROP_COORD_ACT_X,this.ActiveAreaLeft()); // X coordinate of the element active area this.SetProperty(CANV_ELEMENT_PROP_COORD_ACT_Y,this.ActiveAreaTop()); // Y coordinate of the element active area this.SetProperty(CANV_ELEMENT_PROP_ACT_RIGHT,this.ActiveAreaRight()); // Right border of the element active area this.SetProperty(CANV_ELEMENT_PROP_ACT_BOTTOM,this.ActiveAreaBottom()); // Bottom border of the element active area //--- this.SetProperty(CANV_ELEMENT_PROP_BELONG,ENUM_GRAPH_OBJ_BELONG::GRAPH_OBJ_BELONG_PROGRAM); // Graphical element affiliation this.SetProperty(CANV_ELEMENT_PROP_ZORDER,0); // Priority of a graphical object for receiving the event of clicking on a chart this.SetProperty(CANV_ELEMENT_PROP_BOLD_TYPE,FW_NORMAL); // Font width type this.SetProperty(CANV_ELEMENT_PROP_BORDER_STYLE,FRAME_STYLE_NONE); // Control frame style this.SetProperty(CANV_ELEMENT_PROP_BORDER_SIZE_TOP,0); // Control frame top size this.SetProperty(CANV_ELEMENT_PROP_BORDER_SIZE_BOTTOM,0); // Control frame bottom size this.SetProperty(CANV_ELEMENT_PROP_BORDER_SIZE_LEFT,0); // Control frame left size this.SetProperty(CANV_ELEMENT_PROP_BORDER_SIZE_RIGHT,0); // Control frame right size this.SetProperty(CANV_ELEMENT_PROP_BORDER_COLOR,this.BackgroundColor()); // Control frame color this.SetProperty(CANV_ELEMENT_PROP_AUTOSIZE,false); // Flag of the element auto resizing depending on the content this.SetProperty(CANV_ELEMENT_PROP_AUTOSIZE_MODE,CANV_ELEMENT_AUTO_SIZE_MODE_GROW); // Mode of the element auto resizing depending on the content this.SetProperty(CANV_ELEMENT_PROP_AUTOSCROLL,false); // Auto scrollbar flag this.SetProperty(CANV_ELEMENT_PROP_AUTOSCROLL_MARGIN_W,0); // Width of the field inside the element during auto scrolling this.SetProperty(CANV_ELEMENT_PROP_AUTOSCROLL_MARGIN_H,0); // Height of the field inside the element during auto scrolling this.SetProperty(CANV_ELEMENT_PROP_DOCK_MODE,CANV_ELEMENT_DOCK_MODE_NONE); // Mode of binding control borders to the container this.SetProperty(CANV_ELEMENT_PROP_MARGIN_TOP,0); // Top margin between the fields of this and another control this.SetProperty(CANV_ELEMENT_PROP_MARGIN_BOTTOM,0); // Bottom margin between the fields of this and another control this.SetProperty(CANV_ELEMENT_PROP_MARGIN_LEFT,0); // Left margin between the fields of this and another control this.SetProperty(CANV_ELEMENT_PROP_MARGIN_RIGHT,0); // Right margin between the fields of this and another control this.SetProperty(CANV_ELEMENT_PROP_PADDING_TOP,0); // Top margin inside the control this.SetProperty(CANV_ELEMENT_PROP_PADDING_BOTTOM,0); // Bottom margin inside the control this.SetProperty(CANV_ELEMENT_PROP_PADDING_LEFT,0); // Left margin inside the control this.SetProperty(CANV_ELEMENT_PROP_PADDING_RIGHT,0); // Right margin inside the control this.SetProperty(CANV_ELEMENT_PROP_TEXT_ALIGN,ANCHOR_LEFT_UPPER); // Text position within text label boundaries this.SetProperty(CANV_ELEMENT_PROP_CHECK_ALIGN,ANCHOR_LEFT_UPPER); // Position of the checkbox within control borders this.SetProperty(CANV_ELEMENT_PROP_CHECKED,false); // Control checkbox status this.SetProperty(CANV_ELEMENT_PROP_CHECK_STATE,CANV_ELEMENT_CHEK_STATE_UNCHECKED); // Status of a control having a checkbox this.SetProperty(CANV_ELEMENT_PROP_AUTOCHECK,true); // Auto change flag status when it is selected //--- this.SetProperty(CANV_ELEMENT_PROP_CHECK_BACKGROUND_COLOR,CLR_DEF_CHECK_BACK_COLOR); // Color of control checkbox background this.SetProperty(CANV_ELEMENT_PROP_CHECK_BACKGROUND_COLOR_OPACITY,CLR_DEF_CHECK_BACK_OPACITY); // Opacity of the control checkbox background color this.SetProperty(CANV_ELEMENT_PROP_CHECK_BACKGROUND_COLOR_MOUSE_DOWN,CLR_DEF_CHECK_BACK_MOUSE_DOWN);// Color of control checkbox background when clicking on the control this.SetProperty(CANV_ELEMENT_PROP_CHECK_BACKGROUND_COLOR_MOUSE_OVER,CLR_DEF_CHECK_BACK_MOUSE_OVER);// Color of control checkbox background when hovering the mouse over the control this.SetProperty(CANV_ELEMENT_PROP_CHECK_FORE_COLOR,CLR_DEF_CHECK_BORDER_COLOR); // Color of control checkbox frame this.SetProperty(CANV_ELEMENT_PROP_CHECK_FORE_COLOR_OPACITY,CLR_DEF_CHECK_BORDER_OPACITY); // Opacity of the control checkbox frame color this.SetProperty(CANV_ELEMENT_PROP_CHECK_FORE_COLOR_MOUSE_DOWN,CLR_DEF_CHECK_BORDER_MOUSE_DOWN);// Color of control checkbox frame when clicking on the control this.SetProperty(CANV_ELEMENT_PROP_CHECK_FORE_COLOR_MOUSE_OVER,CLR_DEF_CHECK_BORDER_MOUSE_OVER);// Color of control checkbox frame when hovering the mouse over the control this.SetProperty(CANV_ELEMENT_PROP_CHECK_FLAG_COLOR,CLR_DEF_CHECK_FLAG_COLOR); // Control checkbox color this.SetProperty(CANV_ELEMENT_PROP_CHECK_FLAG_COLOR_OPACITY,CLR_DEF_CHECK_FLAG_OPACITY); // Control checkbox color opacity this.SetProperty(CANV_ELEMENT_PROP_CHECK_FLAG_COLOR_MOUSE_DOWN,CLR_DEF_CHECK_FLAG_MOUSE_DOWN); // Control checkbox color when clicking on the control this.SetProperty(CANV_ELEMENT_PROP_CHECK_FLAG_COLOR_MOUSE_OVER,CLR_DEF_CHECK_FLAG_MOUSE_OVER); // Control checkbox color when hovering the mouse over the control this.SetProperty(CANV_ELEMENT_PROP_FORE_COLOR,CLR_DEF_FORE_COLOR); // Default text color for all control objects this.SetProperty(CANV_ELEMENT_PROP_FORE_COLOR_OPACITY,CLR_DEF_FORE_COLOR_OPACITY); // Opacity of the default text color for all control objects this.SetProperty(CANV_ELEMENT_PROP_FORE_COLOR_MOUSE_DOWN,CLR_DEF_FORE_COLOR_MOUSE_DOWN); // Default control text color when clicking on the control this.SetProperty(CANV_ELEMENT_PROP_FORE_COLOR_MOUSE_OVER,CLR_DEF_FORE_COLOR_MOUSE_OVER); // Default control text color when hovering the mouse over the control this.SetProperty(CANV_ELEMENT_PROP_FORE_COLOR_TOGGLE,CLR_DEF_FORE_COLOR); // Text color of the control which is on this.SetProperty(CANV_ELEMENT_PROP_FORE_COLOR_TOGGLE_MOUSE_DOWN,CLR_DEF_FORE_COLOR_MOUSE_DOWN); // Default control text color when clicking on the control which is on this.SetProperty(CANV_ELEMENT_PROP_FORE_COLOR_TOGGLE_MOUSE_OVER,CLR_DEF_FORE_COLOR_MOUSE_OVER); // Default control text color when hovering the mouse over the control which is on this.SetProperty(CANV_ELEMENT_PROP_BACKGROUND_COLOR_MOUSE_DOWN,this.BackgroundColor()); // Control background color when clicking on the control this.SetProperty(CANV_ELEMENT_PROP_BACKGROUND_COLOR_MOUSE_OVER,this.BackgroundColor()); // Control background color when hovering the mouse over the control this.SetProperty(CANV_ELEMENT_PROP_BACKGROUND_COLOR_TOGGLE,CLR_DEF_CONTROL_STD_BACK_COLOR_ON); // Background color of the control which is on this.SetProperty(CANV_ELEMENT_PROP_BACKGROUND_COLOR_TOGGLE_MOUSE_DOWN,CLR_DEF_CONTROL_STD_BACK_DOWN_ON); // Control background color when clicking on the control which is on this.SetProperty(CANV_ELEMENT_PROP_BACKGROUND_COLOR_TOGGLE_MOUSE_OVER,CLR_DEF_CONTROL_STD_BACK_OVER_ON); // Control background color when clicking on the control which is on this.SetProperty(CANV_ELEMENT_PROP_BORDER_COLOR_MOUSE_DOWN,CLR_DEF_BORDER_MOUSE_DOWN); // Control frame color when clicking on the control this.SetProperty(CANV_ELEMENT_PROP_BORDER_COLOR_MOUSE_OVER,CLR_DEF_BORDER_MOUSE_OVER); // Control frame color when hovering the mouse over the control this.SetProperty(CANV_ELEMENT_PROP_BUTTON_TOGGLE,false); // Toggle flag of the control featuring a button this.SetProperty(CANV_ELEMENT_PROP_BUTTON_STATE,false); // Status of the Toggle control featuring a button } else { ::Print(DFUN,CMessage::Text(MSG_LIB_SYS_FAILED_CREATE_ELM_OBJ),": ",this.m_name); } } //+------------------------------------------------------------------+
チェックボックスには独自の色があるため、BorderColorの値がチェックボックスのForceColorプロパティに設定されるようになりました。
2番目のコンストラクタも同様です。ここで検討する意味はありません。
オブジェクト構造体を作成するメソッドで、オブジェクトプロパティを構造体フィールドに保存するようにします。
//+------------------------------------------------------------------+ //| Create the object structure | //+------------------------------------------------------------------+ bool CGCnvElement::ObjectToStruct(void) { //--- Save integer properties this.m_struct_obj.id=(int)this.GetProperty(CANV_ELEMENT_PROP_ID); // Element ID this.m_struct_obj.type=(int)this.GetProperty(CANV_ELEMENT_PROP_TYPE); // Graphical element type //---... //---... this.m_struct_obj.check_flag_color_mouse_down=(color)this.GetProperty(CANV_ELEMENT_PROP_CHECK_FLAG_COLOR_MOUSE_DOWN);// Control checkbox color when clicking on the control this.m_struct_obj.check_flag_color_mouse_over=(color)this.GetProperty(CANV_ELEMENT_PROP_CHECK_FLAG_COLOR_MOUSE_OVER);// Control checkbox color when hovering the mouse over the control this.m_struct_obj.fore_color_mouse_down=(color)this.GetProperty(CANV_ELEMENT_PROP_FORE_COLOR_MOUSE_DOWN); // Default control text color when clicking on the control this.m_struct_obj.fore_color_mouse_over=(color)this.GetProperty(CANV_ELEMENT_PROP_FORE_COLOR_MOUSE_OVER); // Default control text color when hovering the mouse over the control this.m_struct_obj.fore_color_toggle=(color)this.GetProperty(CANV_ELEMENT_PROP_FORE_COLOR_TOGGLE); // Text color of the control which is on this.m_struct_obj.fore_color_toggle_mouse_down=(color)this.GetProperty(CANV_ELEMENT_PROP_FORE_COLOR_TOGGLE_MOUSE_DOWN);// Default control text color when clicking on the control which is on this.m_struct_obj.fore_color_toggle_mouse_over=(color)this.GetProperty(CANV_ELEMENT_PROP_FORE_COLOR_TOGGLE_MOUSE_OVER);// Default control text color when hovering the mouse over the control which is on this.m_struct_obj.background_color_toggle=(color)this.GetProperty(CANV_ELEMENT_PROP_BACKGROUND_COLOR_TOGGLE); // Background color of the control which is on this.m_struct_obj.background_color_toggle_mouse_down=(color)this.GetProperty(CANV_ELEMENT_PROP_BACKGROUND_COLOR_TOGGLE_MOUSE_DOWN);// Control background color when clicking on the control which is on this.m_struct_obj.background_color_toggle_mouse_over=(color)this.GetProperty(CANV_ELEMENT_PROP_BACKGROUND_COLOR_TOGGLE_MOUSE_OVER);// Control background color when hovering the mouse over the control which is on this.m_struct_obj.button_toggle=(bool)this.GetProperty(CANV_ELEMENT_PROP_BUTTON_TOGGLE); // Toggle flag of the control featuring a button this.m_struct_obj.button_state=(bool)this.GetProperty(CANV_ELEMENT_PROP_BUTTON_STATE); // Status of the Toggle control featuring a button //--- Save real properties //--- Save string properties ::StringToCharArray(this.GetProperty(CANV_ELEMENT_PROP_NAME_OBJ),this.m_struct_obj.name_obj); // Graphical element object name ::StringToCharArray(this.GetProperty(CANV_ELEMENT_PROP_NAME_RES),this.m_struct_obj.name_res); // Graphical resource name ::StringToCharArray(this.GetProperty(CANV_ELEMENT_PROP_TEXT),this.m_struct_obj.text); // Graphical element text //--- Save the structure to the uchar array ::ResetLastError(); if(!::StructToCharArray(this.m_struct_obj,this.m_uchar_array)) { CMessage::ToLog(DFUN,MSG_LIB_SYS_FAILED_SAVE_OBJ_STRUCT_TO_UARRAY,true); return false; } return true; } //+------------------------------------------------------------------+
構造体オブジェクトを作成するメソッドで、構造体フィールドからの新しいオブジェクトプロパティを設定するようにします。
//+------------------------------------------------------------------+ //| Create the object from the structure | //+------------------------------------------------------------------+ void CGCnvElement::StructToObject(void) { //--- Save integer properties this.SetProperty(CANV_ELEMENT_PROP_ID,this.m_struct_obj.id); // Element ID this.SetProperty(CANV_ELEMENT_PROP_TYPE,this.m_struct_obj.type); // Graphical element type //---... //---... this.SetProperty(CANV_ELEMENT_PROP_CHECK_FLAG_COLOR_MOUSE_OVER,this.m_struct_obj.check_flag_color_mouse_over); // Control checkbox color when hovering the mouse over the control this.SetProperty(CANV_ELEMENT_PROP_FORE_COLOR_MOUSE_DOWN,this.m_struct_obj.fore_color_mouse_down); // Default control text color when clicking on the control this.SetProperty(CANV_ELEMENT_PROP_FORE_COLOR_MOUSE_OVER,this.m_struct_obj.fore_color_mouse_over); // Default control text color when hovering the mouse over the control this.SetProperty(CANV_ELEMENT_PROP_FORE_COLOR_TOGGLE,this.m_struct_obj.fore_color_toggle); // Text color of the control which is on this.SetProperty(CANV_ELEMENT_PROP_FORE_COLOR_TOGGLE_MOUSE_DOWN,this.m_struct_obj.fore_color_toggle_mouse_down);// Default control text color when clicking on the control which is on this.SetProperty(CANV_ELEMENT_PROP_FORE_COLOR_TOGGLE_MOUSE_OVER,this.m_struct_obj.fore_color_toggle_mouse_over);// Default control text color when hovering the mouse over the control which is on this.SetProperty(CANV_ELEMENT_PROP_BACKGROUND_COLOR_TOGGLE,this.m_struct_obj.background_color_toggle); // Background color of the control which is on this.SetProperty(CANV_ELEMENT_PROP_BACKGROUND_COLOR_TOGGLE_MOUSE_DOWN,this.m_struct_obj.background_color_toggle_mouse_down);// Control background color when clicking on the control which is on this.SetProperty(CANV_ELEMENT_PROP_BACKGROUND_COLOR_TOGGLE_MOUSE_OVER,this.m_struct_obj.background_color_toggle_mouse_over);// Control background color when clicking on the control which is on this.SetProperty(CANV_ELEMENT_PROP_BUTTON_TOGGLE,this.m_struct_obj.button_toggle); // Toggle flag of the control featuring a button this.SetProperty(CANV_ELEMENT_PROP_BUTTON_STATE,this.m_struct_obj.button_state); // Status of the Toggle control featuring a button //--- Save real properties //--- Save string properties this.SetProperty(CANV_ELEMENT_PROP_NAME_OBJ,::CharArrayToString(this.m_struct_obj.name_obj)); // Graphical element object name this.SetProperty(CANV_ELEMENT_PROP_NAME_RES,::CharArrayToString(this.m_struct_obj.name_res)); // Graphical resource name this.SetProperty(CANV_ELEMENT_PROP_TEXT,::CharArrayToString(this.m_struct_obj.text)); // Graphical element text } //+------------------------------------------------------------------+
\MQL5\Include\DoEasy\Objects\Graph\ShadowObj.mqhのシャドウオブジェクトクラスのコンストラクタで、背景色を設定するときに初期色を保存する必要があることを示すフラグを渡します。
//+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CShadowObj::CShadowObj(const long chart_id, const int subwindow, const string name, const int x, const int y, const int w, const int h) : CGCnvElement(GRAPH_ELEMENT_TYPE_SHADOW_OBJ,chart_id,subwindow,name,x,y,w,h) { this.m_type=OBJECT_DE_TYPE_GSHADOW; CGCnvElement::SetBackgroundColor(clrNONE,true); CGCnvElement::SetOpacity(0); CGCnvElement::SetActive(false); this.m_opacity=CLR_DEF_SHADOW_OPACITY; this.m_blur=DEF_SHADOW_BLUR; color gray=CGCnvElement::ChangeColorSaturation(this.ChartBackgroundColor(),-100); this.m_color=CGCnvElement::ChangeColorLightness(gray,-50); this.m_shadow=false; this.m_visible=true; CGCnvElement::Erase(); } //+------------------------------------------------------------------+
ここで完全に透明な色を保存する必要はありませんが、初期化されていないプロパティ値を避けるために保持します。
フォームオブジェクトはグラフィック要素の基本オブジェクトであり、マウスと対話する機能が含まれています。同じフォームオブジェクトで、仮想マウスイベントハンドラと、イベントハンドラによって定義された各イベントの仮想ハンドラを追加します。
継承されたクラスでオーバーライドする必要がある場合、イベントハンドラは仮想になります。一方、特定のマウスイベントの処理は、フォームオブジェクトクラスの継承者であるオブジェクトごとに個別になるため、各マウスイベントのハンドラは仮想である必要があります。カーソルがアクティブ領域を離れた後にオブジェクトの状態とその色を復元するには、そのような状態を処理する(カーソルをオブジェクトから離す)メソッドが必要です。カーソルがオブジェクトから削除された後、別のオブジェクトがアクティブになる(またはオブジェクトがまったくアクティブにならない)ため、すべてのWinFormsオブジェクトを調べて、それらの最後の状態を判断し、最後の状態がその上にマウスがあった場合に備えて処理する必要があります。その後、現在の状態に対応する別の状態に置き換える必要があります。したがって、オブジェクトからのカーソルの削除を一度だけ処理し、オブジェクトを正しい状態に設定します。カーソルはフォームの外にあります。
フォームオブジェクトファイル(\MQL5\Include\DoEasy\Objects\Graph\Form.mqh)のクラスのprotectedセクションで、最後のマウスイベント(最後のイベントハンドラに必要)の格納と初期フォームフレームの色(マウスを操作すると色が変わる可能性があり、元の色を復元する必要があるため)の格納のための2つの変数を宣言します。また、各マウスイベントの仮想ハンドラを宣言します。
protected: CArrayObj m_list_elements; // List of attached elements CArrayObj m_list_interact; // List of interaction elements CAnimations *m_animations; // Pointer to the animation object CShadowObj *m_shadow_obj; // Pointer to the shadow object CMouseState m_mouse; // "Mouse status" class object ENUM_MOUSE_FORM_STATE m_mouse_form_state; // Mouse status relative to the form ENUM_MOUSE_EVENT m_mouse_event_last; // Last mouse event ushort m_mouse_state_flags; // Mouse status flags int m_offset_x; // Offset of the X coordinate relative to the cursor int m_offset_y; // Offset of the Y coordinate relative to the cursor CArrayObj m_list_tmp; // List for storing the pointers int m_init_x; // Newly created form X coordinate int m_init_y; // Newly created form Y coordinate int m_init_w; // Newly created form width int m_init_h; // Newly created form height color m_border_color_init; // Initial color of the control frame //--- Initialize the variables virtual void Initialize(void); void Deinitialize(void); //--- Create a shadow object void CreateShadowObj(const color colour,const uchar opacity); //--- Return the name of the dependent object string CreateNameDependentObject(const string base_name) const { return ::StringSubstr(this.NameObj(),::StringLen(::MQLInfoString(MQL_PROGRAM_NAME))+1)+"_"+base_name; } //--- Update coordinates of bound objects virtual bool MoveDependentObj(const int x,const int y,const bool redraw=false); //--- Create a new bound element and add it to the list of bound objects virtual CGCnvElement *CreateAndAddNewElement(const ENUM_GRAPH_ELEMENT_TYPE element_type, const int x, const int y, const int w, const int h, const color colour, const uchar opacity, const bool activity); //--- Create the list of all interaction objects void CreateListDepInteractObj(CArrayObj *list); //--- Return the flag indicating the presence of the pointer to an object in the list of interaction objects by name bool IsPresentInteractObj(const string name); //--- 'The cursor is outside the form, no mouse buttons are clicked' event handler virtual void MouseOutsideNotPressedHandler(const int id,const long& lparam,const double& dparam,const string& sparam); //--- 'The cursor is outside the form, a mouse button is clicked (any)' event handler virtual void MouseOutsidePressedHandler(const int id,const long& lparam,const double& dparam,const string& sparam); //--- 'The cursor is outside the form, the mouse wheel is being scrolled' event handler virtual void MouseOutsideWhellHandler(const int id,const long& lparam,const double& dparam,const string& sparam); //--- 'The cursor is inside the form, no mouse buttons are clicked' event handler virtual void MouseInsideNotPressedHandler(const int id,const long& lparam,const double& dparam,const string& sparam); //--- 'The cursor is inside the form, a mouse button is clicked (any)' event handler virtual void MouseInsidePressedHandler(const int id,const long& lparam,const double& dparam,const string& sparam); //--- 'The cursor is inside the form, the mouse wheel is being scrolled' event handler virtual void MouseInsideWhellHandler(const int id,const long& lparam,const double& dparam,const string& sparam); //--- 'The cursor is inside the active area, the mouse buttons are not clicked' event handler virtual void MouseActiveAreaNotPressedHandler(const int id,const long& lparam,const double& dparam,const string& sparam); //--- 'The cursor is inside the active area, a mouse button is clicked (any)' event handler virtual void MouseActiveAreaPressedHandler(const int id,const long& lparam,const double& dparam,const string& sparam); //--- 'The cursor is inside the active area, the mouse wheel is being scrolled' event handler virtual void MouseActiveAreaWhellHandler(const int id,const long& lparam,const double& dparam,const string& sparam); //--- 'The cursor is inside the active area, the left mouse button is clicked' event handler virtual void MouseActiveAreaReleasedHandler(const int id,const long& lparam,const double& dparam,const string& sparam); //--- 'The cursor is inside the window scrolling area, no mouse buttons are clicked' event handler virtual void MouseScrollAreaNotPressedHandler(const int id,const long& lparam,const double& dparam,const string& sparam); //--- 'The cursor is inside the window scrolling area, a mouse button is clicked (any)' event handler virtual void MouseScrollAreaPressedHandler(const int id,const long& lparam,const double& dparam,const string& sparam); //--- 'The cursor is inside the window scrolling area, the mouse wheel is being scrolled' event handler virtual void MouseScrollAreaWhellHandler(const int id,const long& lparam,const double& dparam,const string& sparam); public:
クラスのpublicセクションでオブジェクトを再描画するための仮想メソッドを宣言し、マウスステータスを格納する変数を返すメソッドと 最後のマウスイベントを返すメソッドを記述します。
両側のフレームサイズを設定するメソッドは仮想化されています。また、仮想マウスイベントハンドラとその最後のイベントハンドラを宣言しましょう。
public: //--- Redraw the object virtual void Redraw(bool redraw) { return; } //--- Create the list of all interaction objects int CreateListInteractObj(void); //--- Return the pointer to the form object in the list of interaction objects CForm *GetInteractForm(const int index) { return this.m_list_interact.At(index); } //--- Return the initial (1) X and (2) Y coordinate, (3) form width and (4) height int GetCoordXInit(void) const { return this.m_init_x; } int GetCoordYInit(void) const { return this.m_init_y; } int GetWidthInit(void) const { return this.m_init_w; } int GetHeightInit(void) const { return this.m_init_h; } //--- Set the initial (1) X and (2) Y coordinate, (3) form width and (4) height void SetCoordXInit(const int value) { this.m_init_x=value; } void SetCoordYInit(const int value) { this.m_init_y=value; } void SetWidthInit(const int value) { this.m_init_w=value; } void SetHeightInit(const int value) { this.m_init_h=value; } //--- (1) Get and (2) return the mouse status relative to the form, as well as cursor (3) X, (4) Y coordinates and (4) the last mouse event ENUM_MOUSE_FORM_STATE MouseFormState(const int id,const long lparam,const double dparam,const string sparam); ENUM_MOUSE_FORM_STATE GetMouseState(void) const { return this.m_mouse_form_state; } int MouseCursorX(void) const { return this.m_mouse.CoordX(); } int MouseCursorY(void) const { return this.m_mouse.CoordY(); } ENUM_MOUSE_EVENT MouseEventLast(void) const { return this.m_mouse_event_last; } //--- Set the flags of mouse scrolling, context menu and the crosshairs tool for the chart void SetChartTools(const bool flag); //--- (1) Set and (2) return the shift of X and Y coordinates relative to the cursor void SetOffsetX(const int value) { this.m_offset_x=value; } void SetOffsetY(const int value) { this.m_offset_y=value; } int OffsetX(void) const { return this.m_offset_x; } int OffsetY(void) const { return this.m_offset_y; } //--- Return the frame size (1) to the left, (2) at the top, (3) to the right, (4) at the bottom and (5) on all sides int BorderSizeLeft(void) const { return (int)this.GetProperty(CANV_ELEMENT_PROP_BORDER_SIZE_LEFT); } int BorderSizeTop(void) const { return (int)this.GetProperty(CANV_ELEMENT_PROP_BORDER_SIZE_TOP); } int BorderSizeRight(void) const { return (int)this.GetProperty(CANV_ELEMENT_PROP_BORDER_SIZE_RIGHT); } int BorderSizeBottom(void) const { return (int)this.GetProperty(CANV_ELEMENT_PROP_BORDER_SIZE_BOTTOM);} //--- Set the frame size (1) to the left, (2) at the top, (3) to the right, (4) at the bottom and (5) on all sides virtual void SetBorderSizeLeft(const uint value) { this.SetProperty(CANV_ELEMENT_PROP_BORDER_SIZE_LEFT,value); } virtual void SetBorderSizeTop(const uint value) { this.SetProperty(CANV_ELEMENT_PROP_BORDER_SIZE_TOP,value); } virtual void SetBorderSizeRight(const uint value) { this.SetProperty(CANV_ELEMENT_PROP_BORDER_SIZE_RIGHT,value); } virtual void SetBorderSizeBottom(const uint value) { this.SetProperty(CANV_ELEMENT_PROP_BORDER_SIZE_BOTTOM,value); } //--- Update the coordinates (shift the canvas) virtual bool Move(const int x,const int y,const bool redraw=false); //--- Set the priority of a graphical object for receiving the event of clicking on a chart virtual bool SetZorder(const long value,const bool only_prop); //--- Set the object above all virtual void BringToTop(void); //--- Event handler virtual void OnChartEvent(const int id,const long& lparam,const double& dparam,const string& sparam); //--- Mouse event handler virtual void OnMouseEvent(const int id,const long& lparam,const double& dparam,const string& sparam); //--- Last mouse event handler virtual void OnMouseEventPostProcessing(void); //--- Constructors
フラグステータスが初期フレームカラーを保存する必要性を示すように、オブジェクトフレームカラーを設定するメソッドを変更し、初期オブジェクトフレームカラーを設定するメソッドと返すメソッドを記述します。
//+------------------------------------------------------------------+ //| Methods of simplified access to object properties | //+------------------------------------------------------------------+ //--- (1) Set and (2) return the control frame color void SetBorderColor(const color colour,const bool set_init_color) { this.SetProperty(CANV_ELEMENT_PROP_BORDER_COLOR,colour); if(set_init_color) this.SetBorderColorInit(colour); } color BorderColor(void) const { return (color)this.GetProperty(CANV_ELEMENT_PROP_BORDER_COLOR); } //--- (1) Set and (2) return the control frame color when clicking the control void SetBorderColorMouseDown(const color colour) { this.SetProperty(CANV_ELEMENT_PROP_BORDER_COLOR_MOUSE_DOWN,colour); } color BorderColorMouseDown(void) const { return (color)this.GetProperty(CANV_ELEMENT_PROP_BORDER_COLOR_MOUSE_DOWN); } //--- (1) Set and (2) return the control frame color when hovering the mouse over the control void SetBorderColorMouseOver(const color colour) { this.SetProperty(CANV_ELEMENT_PROP_BORDER_COLOR_MOUSE_OVER,colour); } color BorderColorMouseOver(void) const { return (color)this.GetProperty(CANV_ELEMENT_PROP_BORDER_COLOR_MOUSE_OVER); } //--- (1) Set and (2) get the initial color of the control frame void SetBorderColorInit(const color colour) { this.m_border_color_init=colour; } color BorderColorInit(void) const { return (color)this.m_border_color_init; } //--- (1) Set and (2) return the form shadow color
その色を設定するメソッドで必要なフラグを指定することにより、オブジェクトの初期化メソッドで初期フレームカラーを保存し、オブジェクト上にマウスカーソルを置いてオブジェクトをクリックしたときのフレームカラーのデフォルトカラーを設定します。最後のマウスイベントを初期化します。
//+------------------------------------------------------------------+ //| Initialize the variables | //+------------------------------------------------------------------+ void CForm::Initialize(void) { this.m_list_elements.Clear(); this.m_list_elements.Sort(); this.m_list_interact.Clear(); this.m_list_interact.Sort(); this.m_list_tmp.Clear(); this.m_list_tmp.Sort(); this.m_shadow_obj=NULL; this.m_shadow=false; this.SetBorderSizeTop(DEF_FRAME_WIDTH_SIZE); this.SetBorderSizeBottom(DEF_FRAME_WIDTH_SIZE); this.SetBorderSizeLeft(DEF_FRAME_WIDTH_SIZE); this.SetBorderSizeRight(DEF_FRAME_WIDTH_SIZE); this.SetBorderColor(CLR_DEF_BORDER_COLOR,true); this.SetBorderColorMouseDown(CLR_DEF_BORDER_MOUSE_DOWN); this.SetBorderColorMouseOver(CLR_DEF_BORDER_MOUSE_OVER); this.m_gradient_v=true; this.m_gradient_c=false; this.m_mouse_state_flags=0; this.m_mouse_event_last=MOUSE_EVENT_NO_EVENT; this.m_offset_x=0; this.m_offset_y=0; this.m_init_x=0; this.m_init_y=0; this.m_init_w=0; this.m_init_h=0; CGCnvElement::SetInteraction(false); this.m_animations=new CAnimations(CGCnvElement::GetObject()); this.m_list_tmp.Add(this.m_animations); } //+------------------------------------------------------------------+
背景色を必要とするすべてのオブジェクト作成メソッドでフラグを設定します。CreateAndAddNewElement()メソッドでは次のようになります。
obj.SetBackgroundColor(colour,true);
配色を設定するメソッドでは次のようになります。
//+------------------------------------------------------------------+ //| Set the color scheme | //+------------------------------------------------------------------+ void CForm::SetColorTheme(const ENUM_COLOR_THEMES theme,const uchar opacity) { if(this.m_shadow && this.m_shadow_obj!=NULL) this.SetColorShadow(array_color_themes[theme][COLOR_THEME_COLOR_FORM_SHADOW]); this.SetOpacity(opacity); this.SetBackgroundColor(array_color_themes[theme][COLOR_THEME_COLOR_FORM_BG],true); this.SetBorderColor(array_color_themes[theme][COLOR_THEME_COLOR_FORM_FRAME],true); } //+------------------------------------------------------------------+
いずれの場合も、コントロールの元の背景色が保持されるようになります。
フォームに相対的なマウスの状態を設定して返すメソッドでは以前に、マウスの状態を書き込んで変数値を返すローカル変数を宣言していましたが、クラスにこの値を格納する変数ができました。
値を書き込んで、メソッドから戻りましょう。
//+------------------------------------------------------------------+ //| Set and get the mouse status relative to the form | //+------------------------------------------------------------------+ ENUM_MOUSE_FORM_STATE CForm::MouseFormState(const int id,const long lparam,const double dparam,const string sparam) { //--- Get the mouse status relative to the form, as well as the states of mouse buttons and Shift/Ctrl keys this.m_mouse_form_state=MOUSE_FORM_STATE_OUTSIDE_FORM_NOT_PRESSED; ENUM_MOUSE_BUTT_KEY_STATE state=this.m_mouse.ButtonKeyState(id,lparam,dparam,sparam); //--- Get the mouse status flags from the CMouseState class object and save them in the variable this.m_mouse_state_flags=this.m_mouse.GetMouseFlags(); //--- If the cursor is inside the form if(CGCnvElement::CursorInsideElement(m_mouse.CoordX(),m_mouse.CoordY())) { //--- Set bit 8 responsible for the "cursor inside the form" flag this.m_mouse_state_flags |= (0x0001<<8); //--- If the cursor is inside the active area, set bit 9 "cursor inside the active area" if(CGCnvElement::CursorInsideActiveArea(m_mouse.CoordX(),m_mouse.CoordY())) this.m_mouse_state_flags |= (0x0001<<9); //--- otherwise, release the bit "cursor inside the active area" else this.m_mouse_state_flags &=0xFDFF; //--- If one of the mouse buttons is clicked, check the cursor location in the active area and //--- return the appropriate value of the pressed key (in the active area or the form area) if((this.m_mouse_state_flags & 0x0001)!=0 || (this.m_mouse_state_flags & 0x0002)!=0 || (this.m_mouse_state_flags & 0x0010)!=0) this.m_mouse_form_state=((this.m_mouse_state_flags & 0x0200)!=0 ? MOUSE_FORM_STATE_INSIDE_ACTIVE_AREA_PRESSED : MOUSE_FORM_STATE_INSIDE_FORM_PRESSED); //--- otherwise, if not a single mouse button is pressed else { //--- if the mouse wheel is scrolled, return the appropriate wheel scrolling value (in the active area or the form area) if((this.m_mouse_state_flags & 0x0080)!=0) this.m_mouse_form_state=((this.m_mouse_state_flags & 0x0200)!=0 ? MOUSE_FORM_STATE_INSIDE_ACTIVE_AREA_WHEEL : MOUSE_FORM_STATE_INSIDE_FORM_WHEEL); //--- otherwise, return the appropriate value of the unpressed key (in the active area or the form area) else this.m_mouse_form_state=((this.m_mouse_state_flags & 0x0200)!=0 ? MOUSE_FORM_STATE_INSIDE_ACTIVE_AREA_NOT_PRESSED : MOUSE_FORM_STATE_INSIDE_FORM_NOT_PRESSED); } } //--- If the cursor is outside the form else { //--- return the appropriate button value in an inactive area this.m_mouse_form_state= ( ((this.m_mouse_state_flags & 0x0001)!=0 || (this.m_mouse_state_flags & 0x0002)!=0 || (this.m_mouse_state_flags & 0x0010)!=0) ? MOUSE_FORM_STATE_OUTSIDE_FORM_PRESSED : MOUSE_FORM_STATE_OUTSIDE_FORM_NOT_PRESSED ); } return this.m_mouse_form_state; } //+------------------------------------------------------------------+
以下はマウスイベントハンドラです。
//+------------------------------------------------------------------+ //| Mouse event handler | //+------------------------------------------------------------------+ void CForm::OnMouseEvent(const int id,const long &lparam,const double &dparam,const string &sparam) { switch(id) { //--- The cursor is outside the form, the mouse buttons are not clicked //--- The cursor is outside the form, any mouse button is clicked //--- The cursor is outside the form, the mouse wheel is being scrolled case MOUSE_EVENT_OUTSIDE_FORM_NOT_PRESSED : case MOUSE_EVENT_OUTSIDE_FORM_PRESSED : case MOUSE_EVENT_OUTSIDE_FORM_WHEEL : break; //--- The cursor is inside the form, the mouse buttons are not clicked case MOUSE_EVENT_INSIDE_FORM_NOT_PRESSED : this.MouseInsideNotPressedHandler(id,lparam,dparam,sparam); break; //--- The cursor is inside the form, any mouse button is clicked case MOUSE_EVENT_INSIDE_FORM_PRESSED : this.MouseInsidePressedHandler(id,lparam,dparam,sparam); break; //--- The cursor is inside the form, the mouse wheel is being scrolled case MOUSE_EVENT_INSIDE_FORM_WHEEL : this.MouseInsideWhellHandler(id,lparam,dparam,sparam); break; //--- The cursor is inside the active area, the mouse buttons are not clicked case MOUSE_EVENT_INSIDE_ACTIVE_AREA_NOT_PRESSED : this.MouseActiveAreaNotPressedHandler(id,lparam,dparam,sparam); break; //--- The cursor is inside the active area, any mouse button is clicked case MOUSE_EVENT_INSIDE_ACTIVE_AREA_PRESSED : this.MouseActiveAreaPressedHandler(id,lparam,dparam,sparam); break; //--- The cursor is inside the active area, the mouse wheel is being scrolled case MOUSE_EVENT_INSIDE_ACTIVE_AREA_WHEEL : this.MouseActiveAreaWhellHandler(id,lparam,dparam,sparam); break; //--- The cursor is inside the active area, left mouse button is released case MOUSE_EVENT_INSIDE_ACTIVE_AREA_RELEASED : this.MouseActiveAreaReleasedHandler(id,lparam,dparam,sparam); break; //--- The cursor is within the window scrolling area, the mouse buttons are not clicked case MOUSE_EVENT_INSIDE_SCROLL_AREA_NOT_PRESSED : this.MouseScrollAreaNotPressedHandler(id,lparam,dparam,sparam); break; //--- The cursor is within the window scrolling area, any mouse button is clicked case MOUSE_EVENT_INSIDE_SCROLL_AREA_PRESSED : this.MouseScrollAreaPressedHandler(id,lparam,dparam,sparam); break; //--- The cursor is within the window scrolling area, the mouse wheel is being scrolled case MOUSE_EVENT_INSIDE_SCROLL_AREA_WHEEL : this.MouseScrollAreaWhellHandler(id,lparam,dparam,sparam); break; //--- MOUSE_EVENT_NO_EVENT default: break; } this.m_mouse_event_last=(ENUM_MOUSE_EVENT)id; } //+------------------------------------------------------------------+
ここでは、マウスイベントIDに従って、各イベントの適切な処理メソッドを呼び出します。最後に、メソッドに渡されたイベントを最後のマウスイベントを格納する変数に保存します。したがって、まずイベントを処理してから、最後に処理されたものとして設定します。ここで呼び出されるすべてのメソッドは仮想で、継承されたクラスで再定義する必要があります。
以下は、各マウスイベントの仮想ハンドラです。
//+------------------------------------------------------------------+ //| 'The cursor is outside the form, | //| no mouse buttons are clicked' event handler | //+------------------------------------------------------------------+ void CForm::MouseOutsideNotPressedHandler(const int id,const long& lparam,const double& dparam,const string& sparam) { return; } //+------------------------------------------------------------------+ //| 'The cursor is outside the form, | //| a mouse button is clicked (any) | //+------------------------------------------------------------------+ void CForm::MouseOutsidePressedHandler(const int id,const long& lparam,const double& dparam,const string& sparam) { return; } //+------------------------------------------------------------------+ //| 'The cursor is outside the form, | //| the mouse wheel is being scrolled | //+------------------------------------------------------------------+ void CForm::MouseOutsideWhellHandler(const int id,const long& lparam,const double& dparam,const string& sparam) { return; } //+------------------------------------------------------------------+ //| 'The cursor is inside the form, | //| no mouse buttons are clicked' event handler | //+------------------------------------------------------------------+ void CForm::MouseInsideNotPressedHandler(const int id,const long& lparam,const double& dparam,const string& sparam) { return; } //+------------------------------------------------------------------+ //| 'The cursor is inside the form, | //| a mouse button is clicked (any) | //+------------------------------------------------------------------+ void CForm::MouseInsidePressedHandler(const int id,const long& lparam,const double& dparam,const string& sparam) { return; } //+------------------------------------------------------------------+ //| 'The cursor is inside the form, | //| the mouse wheel is being scrolled | //+------------------------------------------------------------------+ void CForm::MouseInsideWhellHandler(const int id,const long& lparam,const double& dparam,const string& sparam) { return; } //+------------------------------------------------------------------+ //| 'The cursor is inside the active area, | //| no mouse buttons are clicked' event handler | //+------------------------------------------------------------------+ void CForm::MouseActiveAreaNotPressedHandler(const int id,const long& lparam,const double& dparam,const string& sparam) { return; } //+------------------------------------------------------------------+ //| 'The cursor is inside the active area, | //| a mouse button is clicked (any) | //+------------------------------------------------------------------+ void CForm::MouseActiveAreaPressedHandler(const int id,const long& lparam,const double& dparam,const string& sparam) { return; } //+------------------------------------------------------------------+ //| 'The cursor is inside the active area, | //| the mouse wheel is being scrolled | //+------------------------------------------------------------------+ void CForm::MouseActiveAreaWhellHandler(const int id,const long& lparam,const double& dparam,const string& sparam) { return; } //+------------------------------------------------------------------+ //| 'The cursor is inside the active area, | //| left mouse button released | //+------------------------------------------------------------------+ void CForm::MouseActiveAreaReleasedHandler(const int id,const long& lparam,const double& dparam,const string& sparam) { return; } //+------------------------------------------------------------------+ //| 'The cursor is inside the window scrolling area, | //| no mouse buttons are clicked' event handler | //+------------------------------------------------------------------+ void CForm::MouseScrollAreaNotPressedHandler(const int id,const long& lparam,const double& dparam,const string& sparam) { return; } //+------------------------------------------------------------------+ //| 'The cursor is inside the window scrolling area, | //| a mouse button is clicked (any) | //+------------------------------------------------------------------+ void CForm::MouseScrollAreaPressedHandler(const int id,const long& lparam,const double& dparam,const string& sparam) { return; } //+------------------------------------------------------------------+ //| 'The cursor is inside the window scrolling area, | //| the mouse wheel is being scrolled | //+------------------------------------------------------------------+ void CForm::MouseScrollAreaWhellHandler(const int id,const long& lparam,const double& dparam,const string& sparam) { return; } //+------------------------------------------------------------------+
各イベントの処理全体は、フォームオブジェクトの子孫オブジェクトごとに個別であるため、このメソッドは何もしません。必要に応じて、継承された各オブジェクトでプロセスを再定義する必要があります。
以下は、最後のマウスイベントの仮想ハンドラです。
//+------------------------------------------------------------------+ //| Last mouse event handler | //+------------------------------------------------------------------+ void CForm::OnMouseEventPostProcessing(void) { ENUM_MOUSE_FORM_STATE state=GetMouseState(); switch(state) { //--- The cursor is outside the form, the mouse buttons are not clicked //--- The cursor is outside the form, any mouse button is clicked //--- The cursor is outside the form, the mouse wheel is being scrolled case MOUSE_FORM_STATE_OUTSIDE_FORM_NOT_PRESSED : case MOUSE_FORM_STATE_OUTSIDE_FORM_PRESSED : case MOUSE_FORM_STATE_OUTSIDE_FORM_WHEEL : if(MouseEventLast()==MOUSE_EVENT_INSIDE_ACTIVE_AREA_NOT_PRESSED) { this.SetBackgroundColor(this.BackgroundColorInit(),false); this.SetBorderColor(this.BorderColorInit(),false); this.Redraw(true); this.m_mouse_event_last=ENUM_MOUSE_EVENT(state+MOUSE_EVENT_NO_EVENT); } break; //--- The cursor is inside the form, the mouse buttons are not clicked case MOUSE_FORM_STATE_INSIDE_FORM_NOT_PRESSED : break; //--- The cursor is inside the form, any mouse button is clicked case MOUSE_FORM_STATE_INSIDE_FORM_PRESSED : break; //--- The cursor is inside the form, the mouse wheel is being scrolled case MOUSE_FORM_STATE_INSIDE_FORM_WHEEL : break; //--- The cursor is inside the active area, the mouse buttons are not clicked case MOUSE_FORM_STATE_INSIDE_ACTIVE_AREA_NOT_PRESSED : break; //--- The cursor is inside the active area, any mouse button is clicked case MOUSE_FORM_STATE_INSIDE_ACTIVE_AREA_PRESSED : break; //--- The cursor is inside the active area, the mouse wheel is being scrolled case MOUSE_FORM_STATE_INSIDE_ACTIVE_AREA_WHEEL : break; //--- The cursor is inside the active area, left mouse button is released case MOUSE_FORM_STATE_INSIDE_ACTIVE_AREA_RELEASED : break; //--- The cursor is within the window scrolling area, the mouse buttons are not clicked case MOUSE_FORM_STATE_INSIDE_SCROLL_AREA_NOT_PRESSED : break; //--- The cursor is within the window scrolling area, any mouse button is clicked case MOUSE_FORM_STATE_INSIDE_SCROLL_AREA_PRESSED : break; //--- The cursor is within the window scrolling area, the mouse wheel is being scrolled case MOUSE_FORM_STATE_INSIDE_SCROLL_AREA_WHEEL : break; //--- MOUSE_EVENT_NO_EVENT default: break; } } //+------------------------------------------------------------------+
このメソッドも仮想です。必要に応じて、継承されたクラスで再定義する必要があります。
オブジェクトのマウスステータスが「カーソルがフォームの外にある」と定義されている場合(ボタンとホイールの状態は重要ではありません)、オブジェクトの最後のマウスイベントを確認します。「カーソルがアクティブ領域内にあり、マウスボタンがクリックされていない」場合、カーソルはオブジェクトから削除されたと見なされます。したがって、適切なイベントを処理します—最初の背景色、最初のオブジェクトフレームの色を設定し、オブジェクトを再描画し、最後のマウスイベントを格納する変数に現在のマウスイベントを書き込みます。.
ENUM_MOUSE_EVENT列挙のすべての定数値が、ENUM_MOUSE_EVENT列挙のMOUSE_EVENT_NO_EVENT定数値によってENUM_MOUSE_FORM_STATE列挙の定数値と異なることを考慮すると(構成と順序が同じである場合)、マウスにMOUSE_EVENT_NO_EVENT定数値を追加する必要があります。ENUM_MOUSE_FORM_STATE状態変数で受信したイベント値を使用して、正しい値を取得します。
フォーム上にあるテキスト(ボタンテキストなど)は、オブジェクトにカーソルを合わせたりクリックしたりすると、その色を変更することもできます。WinFormsオブジェクトのテキストを処理するメソッドは、\MQL5\Include\DoEasy\Objects\Graph\WForms\WinFormBase.mqhの基本WinFormsオブジェクトのクラスにあります。
クラスのprotectedセクションで、オブジェクトの可視性プロパティを格納するための変数を宣言します。publicセクションで、タイプ別のバインドされたオブジェクトのリストを返すメソッド、タイプ別のバインドされたコントロールの数、およびタイプ別のバインドされたオブジェクトへのポインタを返すメソッドを宣言します。
追加のオブジェクトテキストの色を設定および取得するメソッドを記述します。
//+------------------------------------------------------------------+ //| Form object class | //+------------------------------------------------------------------+ class CWinFormBase : public CForm { protected: color m_fore_color_init; // Initial color of the control text private: //--- Return the font flags uint GetFontFlags(void); public: //--- Return by type the (1) list, (2) the number of bound controls, (3) the bound control by index in the list CArrayObj *GetListElementsByType(const ENUM_GRAPH_ELEMENT_TYPE type); int ElementsTotalByType(const ENUM_GRAPH_ELEMENT_TYPE type); CGCnvElement *GetElementByType(const ENUM_GRAPH_ELEMENT_TYPE type,const int index); //--- Clear the element filling it with color and opacity virtual void Erase(const color colour,const uchar opacity,const bool redraw=false); //--- Clear the element with a gradient fill virtual void Erase(color &colors[],const uchar opacity,const bool vgradient,const bool cycle,const bool redraw=false); //--- Clear the element completely virtual void Erase(const bool redraw=false); //--- Redraw the object virtual void Redraw(bool redraw); //--- Set the new size for the (1) current object and (2) the object specified by index virtual bool Resize(const int w,const int h,const bool redraw); virtual bool Resize(const int index,const int w,const int h,const bool redraw); //--- Constructors CWinFormBase(const long chart_id, const int subwindow, const string name, const int x, const int y, const int w, const int h); CWinFormBase(const string name) : CForm(::ChartID(),0,name,0,0,0,0) { this.m_type=OBJECT_DE_TYPE_GWF_BASE; } //--- (1) Set and (2) return the default text color of all panel objects void SetForeColor(const color clr,const bool set_init_color) { this.SetProperty(CANV_ELEMENT_PROP_FORE_COLOR,clr); if(set_init_color) this.SetForeColorInit(clr); } color ForeColor(void) const { return (color)this.GetProperty(CANV_ELEMENT_PROP_FORE_COLOR); } //--- (1) Set and (2) return the initial default text color of all panel objects void SetForeColorInit(const color clr) { this.m_fore_color_init=clr; } color ForeColorInit(void) const { return (color)this.m_fore_color_init; } //--- (1) Set and (2) return the default text color opacity of all panel objects void SetForeColorOpacity(const uchar value) { this.SetProperty(CANV_ELEMENT_PROP_FORE_COLOR_OPACITY,value); } uchar ForeColorOpacity(void) const { return (uchar)this.GetProperty(CANV_ELEMENT_PROP_FORE_COLOR_OPACITY); } //--- (1) Set and (2) return the control text color when clicking the control void SetForeColorMouseDown(const color clr) { this.SetProperty(CANV_ELEMENT_PROP_FORE_COLOR_MOUSE_DOWN,clr); } color ForeColorMouseDown(void) const { return (color)this.GetProperty(CANV_ELEMENT_PROP_FORE_COLOR_MOUSE_DOWN); } //--- (1) Set and (2) return the control text color when hovering the mouse over the control void SetForeColorMouseOver(const color clr) { this.SetProperty(CANV_ELEMENT_PROP_FORE_COLOR_MOUSE_OVER,clr); } color ForeColorMouseOver(void) const { return (color)this.GetProperty(CANV_ELEMENT_PROP_FORE_COLOR_MOUSE_OVER); } //--- (1) Set and (2) return the element text virtual void SetText(const string text) { this.SetProperty(CANV_ELEMENT_PROP_TEXT,text); } string Text(void) const { return this.GetProperty(CANV_ELEMENT_PROP_TEXT); }
クラスコンストラクタでテキストの色を設定するときに初期のテキストの色を保存する必要性を指定します。
//+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CWinFormBase::CWinFormBase(const long chart_id, const int subwindow, const string name, const int x, const int y, const int w, const int h) : CForm(chart_id,subwindow,name,x,y,w,h) { //--- Set the graphical element and library object types as a base WinForms object CGBaseObj::SetTypeElement(GRAPH_ELEMENT_TYPE_WF_BASE); CGCnvElement::SetProperty(CANV_ELEMENT_PROP_TYPE,GRAPH_ELEMENT_TYPE_WF_BASE); this.m_type=OBJECT_DE_TYPE_GWF_BASE; //--- Initialize all variables this.SetText(""); this.SetForeColor(CLR_DEF_FORE_COLOR,true); this.SetForeColorOpacity(CLR_DEF_FORE_COLOR_OPACITY); this.SetFontBoldType(FW_TYPE_NORMAL); this.SetMarginAll(0); this.SetPaddingAll(0); this.SetBorderSizeAll(0); this.SetDockMode(CANV_ELEMENT_DOCK_MODE_NONE,false); this.SetBorderStyle(FRAME_STYLE_NONE); this.SetAutoSize(false,false); CForm::SetCoordXInit(x); CForm::SetCoordYInit(y); CForm::SetWidthInit(w); CForm::SetHeightInit(h); this.m_shadow=false; this.m_gradient_v=true; this.m_gradient_c=false; } //+------------------------------------------------------------------+
要素の整数プロパティの説明を返す際に、新しいWinFormsオブジェクトプロパティの説明を返すためのコードブロックを追加します。
property==CANV_ELEMENT_PROP_FORE_COLOR_OPACITY ? CMessage::Text(MSG_CANV_ELEMENT_PROP_FORE_COLOR_OPACITY)+ (only_prop ? "" : !this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)this.GetProperty(property) ) : property==CANV_ELEMENT_PROP_FORE_COLOR_MOUSE_DOWN ? CMessage::Text(MSG_CANV_ELEMENT_PROP_FORE_COLOR_MOUSE_DOWN)+ (only_prop ? "" : !this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+ColorToString((color)this.GetProperty(property),true) ) : property==CANV_ELEMENT_PROP_FORE_COLOR_MOUSE_OVER ? CMessage::Text(MSG_CANV_ELEMENT_PROP_FORE_COLOR_MOUSE_OVER)+ (only_prop ? "" : !this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+ColorToString((color)this.GetProperty(property),true) ) : property==CANV_ELEMENT_PROP_FORE_COLOR_TOGGLE ? CMessage::Text(MSG_CANV_ELEMENT_PROP_FORE_COLOR_TOGGLE)+ (only_prop ? "" : !this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+ColorToString((color)this.GetProperty(property),true) ) : property==CANV_ELEMENT_PROP_FORE_COLOR_TOGGLE_MOUSE_DOWN ? CMessage::Text(MSG_CANV_ELEMENT_PROP_FORE_COLOR_TOGGLE_MOUSE_DOWN)+ (only_prop ? "" : !this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+ColorToString((color)this.GetProperty(property),true) ) : property==CANV_ELEMENT_PROP_FORE_COLOR_TOGGLE_MOUSE_OVER ? CMessage::Text(MSG_CANV_ELEMENT_PROP_FORE_COLOR_TOGGLE_MOUSE_OVER)+ (only_prop ? "" : !this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+ColorToString((color)this.GetProperty(property),true) ) : property==CANV_ELEMENT_PROP_BACKGROUND_COLOR ? CMessage::Text(MSG_CANV_ELEMENT_PROP_BACKGROUND_COLOR)+ (only_prop ? "" : !this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+ColorToString((color)this.GetProperty(property),true) ) :
...
property==CANV_ELEMENT_PROP_BACKGROUND_COLOR_MOUSE_OVER ? CMessage::Text(MSG_CANV_ELEMENT_PROP_BACKGROUND_COLOR_MOUSE_OVER)+ (only_prop ? "" : !this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+ColorToString((color)this.GetProperty(property),true) ) : property==CANV_ELEMENT_PROP_BACKGROUND_COLOR_TOGGLE ? CMessage::Text(MSG_CANV_ELEMENT_PROP_BACKGROUND_COLOR_TOGGLE)+ (only_prop ? "" : !this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+ColorToString((color)this.GetProperty(property),true) ) : property==CANV_ELEMENT_PROP_BACKGROUND_COLOR_TOGGLE_MOUSE_DOWN ? CMessage::Text(MSG_CANV_ELEMENT_PROP_BACKGROUND_COLOR_TOGGLE_MOUSE_DOWN)+ (only_prop ? "" : !this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+ColorToString((color)this.GetProperty(property),true) ) : property==CANV_ELEMENT_PROP_BACKGROUND_COLOR_TOGGLE_MOUSE_OVER ? CMessage::Text(MSG_CANV_ELEMENT_PROP_BACKGROUND_COLOR_TOGGLE_MOUSE_OVER)+ (only_prop ? "" : !this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+ColorToString((color)this.GetProperty(property),true) ) : property==CANV_ELEMENT_PROP_BOLD_TYPE ? CMessage::Text(MSG_CANV_ELEMENT_PROP_BOLD_TYPE)+ (only_prop ? "" : !this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+FontBoldTypeDescription() ) :
...
property==CANV_ELEMENT_PROP_AUTOCHECK ? CMessage::Text(MSG_CANV_ELEMENT_PROP_AUTOCHECK)+ (only_prop ? "" : !this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)(bool)this.GetProperty(property) ) : property==CANV_ELEMENT_PROP_BUTTON_TOGGLE ? CMessage::Text(MSG_CANV_ELEMENT_PROP_BUTTON_TOGGLE)+ (only_prop ? "" : !this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)(bool)this.GetProperty(property) ) : property==CANV_ELEMENT_PROP_BUTTON_STATE ? CMessage::Text(MSG_CANV_ELEMENT_PROP_BUTTON_STATE)+ (only_prop ? "" : !this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)(bool)this.GetProperty(property) ) : property==CANV_ELEMENT_PROP_CHECK_BACKGROUND_COLOR ? CMessage::Text(MSG_CANV_ELEMENT_PROP_CHECK_BACKGROUND_COLOR)+ (only_prop ? "" : !this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::ColorToString((color)this.GetProperty(property),true) ) : property==CANV_ELEMENT_PROP_CHECK_BACKGROUND_COLOR_OPACITY ? CMessage::Text(MSG_CANV_ELEMENT_PROP_CHECK_BACKGROUND_COLOR_OPACITY)+ (only_prop ? "" : !this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)this.GetProperty(property) ) : property==CANV_ELEMENT_PROP_CHECK_BACKGROUND_COLOR_MOUSE_DOWN ? CMessage::Text(MSG_CANV_ELEMENT_PROP_CHECK_BACKGROUND_COLOR_MOUSE_DOWN)+ (only_prop ? "" : !this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::ColorToString((color)this.GetProperty(property),true) ) : property==CANV_ELEMENT_PROP_CHECK_BACKGROUND_COLOR_MOUSE_OVER ? CMessage::Text(MSG_CANV_ELEMENT_PROP_CHECK_BACKGROUND_COLOR_MOUSE_OVER)+ (only_prop ? "" : !this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::ColorToString((color)this.GetProperty(property),true) ) : property==CANV_ELEMENT_PROP_CHECK_FORE_COLOR ? CMessage::Text(MSG_CANV_ELEMENT_PROP_CHECK_FORE_COLOR)+ (only_prop ? "" : !this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::ColorToString((color)this.GetProperty(property),true) ) : property==CANV_ELEMENT_PROP_CHECK_FORE_COLOR_OPACITY ? CMessage::Text(MSG_CANV_ELEMENT_PROP_CHECK_FORE_COLOR_OPACITY)+ (only_prop ? "" : !this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)this.GetProperty(property) ) : property==CANV_ELEMENT_PROP_CHECK_FORE_COLOR_MOUSE_DOWN ? CMessage::Text(MSG_CANV_ELEMENT_PROP_CHECK_FORE_COLOR_MOUSE_DOWN)+ (only_prop ? "" : !this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::ColorToString((color)this.GetProperty(property),true) ) : property==CANV_ELEMENT_PROP_CHECK_FORE_COLOR_MOUSE_OVER ? CMessage::Text(MSG_CANV_ELEMENT_PROP_CHECK_FORE_COLOR_MOUSE_OVER)+ (only_prop ? "" : !this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::ColorToString((color)this.GetProperty(property),true) ) : property==CANV_ELEMENT_PROP_CHECK_FLAG_COLOR ? CMessage::Text(MSG_CANV_ELEMENT_PROP_CHECK_FLAG_COLOR)+ (only_prop ? "" : !this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::ColorToString((color)this.GetProperty(property),true) ) : property==CANV_ELEMENT_PROP_CHECK_FLAG_COLOR_OPACITY ? CMessage::Text(MSG_CANV_ELEMENT_PROP_CHECK_FLAG_COLOR_OPACITY)+ (only_prop ? "" : !this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)this.GetProperty(property) ) : property==CANV_ELEMENT_PROP_CHECK_FLAG_COLOR_MOUSE_DOWN ? CMessage::Text(MSG_CANV_ELEMENT_PROP_CHECK_FLAG_COLOR_MOUSE_DOWN)+ (only_prop ? "" : !this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::ColorToString((color)this.GetProperty(property),true) ) : property==CANV_ELEMENT_PROP_CHECK_FLAG_COLOR_MOUSE_OVER ? CMessage::Text(MSG_CANV_ELEMENT_PROP_CHECK_FLAG_COLOR_MOUSE_OVER)+ (only_prop ? "" : !this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+::ColorToString((color)this.GetProperty(property),true) ) : "" ); } //+------------------------------------------------------------------+ //| Return the description of the control real property | //+------------------------------------------------------------------+
以下は、タイプ別にバインドされたコントロールのリストを返すメソッドです。
//+------------------------------------------------------------------+ // Return the list of bound controls by type | //+------------------------------------------------------------------+ CArrayObj *CWinFormBase::GetListElementsByType(const ENUM_GRAPH_ELEMENT_TYPE type) { return CSelect::ByGraphCanvElementProperty(this.GetListElements(),CANV_ELEMENT_PROP_TYPE,type,EQUAL); } //+------------------------------------------------------------------+
ここでは指定されたタイプによってバインドされたオブジェクトのリストから選択されたグラフィック要素のリストを返すだけです。
以下は、リスト内のインデックスによってバインドされた要素を(型によって)返すメソッドです。
//+------------------------------------------------------------------+ //| Get (by type) the bound element by index in the list | //+------------------------------------------------------------------+ CGCnvElement *CWinFormBase::GetElementByType(const ENUM_GRAPH_ELEMENT_TYPE type,const int index) { CArrayObj *list=this.GetListElementsByType(type); return list.At(index); } //+------------------------------------------------------------------+
ここでは、上記で考慮された指定されたタイプによってオブジェクトのリストを取得し、指定されたインデックスによって取得されたリスト内のオブジェクトへのポインタを返します。リストが取得されていない場合、またはリストのサイズを超えている場合、メソッドはNULLを返します。
以下は、タイプごとにバインドされた要素のリストを返すメソッドです。
//+------------------------------------------------------------------+ //| Get the list of bound elements by type | //+------------------------------------------------------------------+ int CWinFormBase::ElementsTotalByType(const ENUM_GRAPH_ELEMENT_TYPE type) { CArrayObj *list=this.GetListElementsByType(type); return(list!=NULL ? list.Total() : 0); } //+------------------------------------------------------------------+
指定されたタイプでバインドされたオブジェクトのリストを取得し、リスト内のオブジェクトへのポインタの数を返します。リストの取得に失敗した場合、メソッドはゼロを返します。
\MQL5\Include\DoEasy\Objects\Graph\WForms\Containers\Container.mqhの基本WinFormsコンテナのオブジェクトクラスで、フレーム幅を設定するメソッドの名前を変更します。以前は、名前に「Frame」を使用していましたが、「Border」を使用するようにします。
//--- Set the width of the form frame (1) to the left, (2) at the top, (3) to the right, (4) at the bottom and (5) on all sides of the control virtual void SetBorderSizeLeft(const uint value) { CForm::SetBorderSizeLeft(value); if(this.PaddingLeft()<this.BorderSizeLeft()) this.SetPaddingLeft(this.BorderSizeLeft()); } virtual void SetBorderSizeTop(const uint value) { CForm::SetBorderSizeTop(value); if(this.PaddingTop()<this.BorderSizeTop()) this.SetPaddingTop(this.BorderSizeTop()); } virtual void SetBorderSizeRight(const uint value) { CForm::SetBorderSizeRight(value); if(this.PaddingRight()<this.BorderSizeRight()) this.SetPaddingRight(this.BorderSizeRight()); } virtual void SetBorderSizeBottom(const uint value) { CForm::SetBorderSizeBottom(value); if(this.PaddingBottom()<this.BorderSizeBottom()) this.SetPaddingBottom(this.BorderSizeBottom()); }
以前はこれらのメソッドの名前が異なっていたため、フレーム幅を設定するために親クラスのメソッドを呼び出しても問題は発生しませんでしたが、メソッドが再帰的に自分自身を呼び出すことになってしまいます。したがって、ここでは必要な同名の親クラスメソッドが呼び出されるコンテキストを明示的に指定します。
クラスコンストラクタでテキストの色を保存するときに、要素ラベルの初期色を保存する必要があることを示します。
//--- Constructors CContainer(const long chart_id, const int subwindow, const string name, const int x, const int y, const int w, const int h); CContainer(const string name) : CWinFormBase(::ChartID(),0,name,0,0,0,0) { CGBaseObj::SetTypeElement(GRAPH_ELEMENT_TYPE_WF_CONTAINER); CGCnvElement::SetProperty(CANV_ELEMENT_PROP_TYPE,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(); } //--- Destructor ~CContainer(); }; //+------------------------------------------------------------------+ //| Constructor indicating the chart and subwindow ID | //+------------------------------------------------------------------+ CContainer::CContainer(const long chart_id, const int subwindow, const string name, const int x, const int y, const int w, const int h) : CWinFormBase(chart_id,subwindow,name,x,y,w,h) { CGBaseObj::SetTypeElement(GRAPH_ELEMENT_TYPE_WF_CONTAINER); CGCnvElement::SetProperty(CANV_ELEMENT_PROP_TYPE,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); } //+------------------------------------------------------------------+
新しいバインドされた要素を作成するメソッドで元の色をどこにでも保存する必要があることを示します。
//+------------------------------------------------------------------+ //| Create a new attached element | //+------------------------------------------------------------------+ bool CContainer::CreateNewElement(const ENUM_GRAPH_ELEMENT_TYPE element_type, const int x, const int y, const int w, const int h, const color colour, const uchar opacity, const bool activity, const bool redraw) { //--- If the object type is less than the base WinForms object if(element_type<GRAPH_ELEMENT_TYPE_WF_BASE) { //--- report the error and return 'false' CMessage::ToLog(DFUN,MSG_PANEL_OBJECT_ERR_OBJ_MUST_BE_WFBASE); return false; } //--- If failed to create a new graphical element, return 'false' CWinFormBase *obj=CForm::CreateAndAddNewElement(element_type,x,y,w,h,colour,opacity,activity); if(obj==NULL) return false; //--- Set the text color of the created object as that of the base panel obj.SetForeColor(this.ForeColor(),true); //--- Depending on the created 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 : //--- set the frame color equal to the background color obj.SetBorderColor(obj.BackgroundColor(),true); break; //--- For the Text Label, CheckBox and RadioButton WinForms objects case GRAPH_ELEMENT_TYPE_WF_LABEL : case GRAPH_ELEMENT_TYPE_WF_CHECKBOX : case GRAPH_ELEMENT_TYPE_WF_RADIOBUTTON : //--- set the object text color depending on the one passed to the method: //--- either the container text color, or the one passed to the method. //--- The frame color is set equal to the text color obj.SetForeColor(colour==clrNONE ? this.ForeColor() : colour,true); obj.SetBorderColor(obj.ForeColor(),true); break; //--- For the Button WinForms object case GRAPH_ELEMENT_TYPE_WF_BUTTON : //--- set the object text color as a container text color depending on the one passed to the method: //--- set the background color depending on the one passed to the method: //--- either the default standard control background color, or the one passed to the method. //--- The frame color is set equal to the text color 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; default: break; } //--- If the panel has auto resize enabled and features bound objects, call the resize method if(this.AutoSize() && this.ElementsTotal()>0) this.AutoSizeProcess(redraw); //--- Redraw the panel and all added objects, and return 'true' this.Redraw(redraw); return true; } //+------------------------------------------------------------------+
GroupBoxWinFormsオブジェクトクラスファイル(\MQL5\Include\DoEasy\Objects\Graph\WForms\Containers\GroupBox.mqh)のInitialize()初期化メソッドでデフォルト色を設定するときに初期色を保存する必要性を設定します。
//--- Create an animation object and add it to the list for storing such objects this.m_animations=new CAnimations(CGCnvElement::GetObject()); this.m_list_tmp.Add(this.m_animations); //--- Set a transparent background for the object background and the default color for the frame this.SetBackgroundColor(CLR_CANV_NULL,true); this.SetOpacity(0); this.SetBorderColor(CLR_DEF_FRAME_GBOX_COLOR,true); //--- Set the default color and text opacity, as well as the absence of the object frame this.SetForeColor(CLR_DEF_FORE_COLOR,true); this.SetForeColorOpacity(CLR_DEF_FORE_COLOR_OPACITY); this.SetBorderStyle(FRAME_STYLE_SIMPLE); //--- Set the default text parameters
基本標準WinFormsオブジェクトのファイル(\MQL5\Include\DoEasy\Objects\Graph\WForms\CommonControls\CommonBase.mqh)のInitialize()初期化メソッドでデフォルトを設定するときに初期色を保存する必要性を設定します。
//--- Create an animation object and add it to the list for storing such objects this.m_animations=new CAnimations(CGCnvElement::GetObject()); this.m_list_tmp.Add(this.m_animations); //--- Set the transparent color for the object background this.SetBackgroundColor(CLR_CANV_NULL,true); this.SetOpacity(0); //--- Set the default color and text opacity, as well as the absence of the object frame this.SetForeColor(CLR_DEF_FORE_COLOR,true); this.SetForeColorOpacity(CLR_DEF_FORE_COLOR_OPACITY); this.SetBorderStyle(FRAME_STYLE_NONE); //--- Set the default text parameters
CheckBoxWinFormsオブジェクトは、チェックボックスとテキストを含むフィールドで構成されます。マウスカーソルを合わせてボタンをクリックすると、フィールド、そのフレームとチェックボックスの色が変更されます。したがって、初期色を格納するためのすべてのコンポーネントの変数と、マウスイベントに対応する色を設定するためのメソッドを作成する必要があります。
\MQL5\Include\DoEasy\Objects\Graph\WForms\CommonControls\CheckBox.mqhのクラスのprotectedセクションで、初期色を格納するための変数とマウスイベントを処理する仮想メソッドを宣言します。
//+------------------------------------------------------------------+ //| CheckBox object class of the WForms controls | //+------------------------------------------------------------------+ class CCheckBox : public CLabel { private: //--- Set X and Y checkbox coordinates void SetCheckFlagCoords(int &x,int &y); //--- Set the corrected text coordinates depending on the text alignment and checkbox void SetCorrectTextCoords(void); protected: int m_text_x; // Text X coordinate int m_text_y; // Text Y coordinate int m_check_x; // Checkbox X coordinate int m_check_y; // Checkbox Y coordinate int m_check_w; // Checkbox width int m_check_h; // Checkbox height color m_check_back_color_init; // Initial color of the checkbox background color m_check_border_color_init; // Initial color of the checkbox background frame color m_check_flag_color_init; // Initial color of the checkbox //--- Set the element width and height automatically virtual bool AutoSetWH(void); //--- Displays the checkbox for the specified state virtual void ShowControlFlag(const ENUM_CANV_ELEMENT_CHEK_STATE state); //--- (1) Set and (2) return the checkbox size on the element void SetCheckWidth(const int width) { this.m_check_w=(width<5 ? 5 : width); } void SetCheckHeight(const int height) { this.m_check_h=(height<5 ? 5 : height); } int CheckWidth(void) const { return this.m_check_w; } int CheckHeight(void) const { return this.m_check_h; } //--- 'The cursor is inside the active area, the mouse buttons are not clicked' event handler virtual void MouseActiveAreaNotPressedHandler(const int id,const long& lparam,const double& dparam,const string& sparam); //--- 'The cursor is inside the active area, a mouse button is clicked (any)' event handler virtual void MouseActiveAreaPressedHandler(const int id,const long& lparam,const double& dparam,const string& sparam); //--- 'The cursor is inside the active area, the left mouse button is clicked' event handler virtual void MouseActiveAreaReleasedHandler(const int id,const long& lparam,const double& dparam,const string& sparam); public:
チェックボックスの背景色、フィールドフレーム、およびチェックボックス自体を設定するメソッドを変更して、フラグ値によって元のフィールドの色を保持できるようにします。初期色を設定および取得するためのメソッドを追加し最後のマウスイベントのハンドラを宣言します。
//--- (1) Set and (2) return the flag of the checkbox auto change when it is selected void SetAutoCheck(const bool flag) { this.SetProperty(CANV_ELEMENT_PROP_AUTOCHECK,flag); } bool AutoCheck(void) const { return (bool)this.GetProperty(CANV_ELEMENT_PROP_AUTOCHECK); } //--- (1) Set and (2) return the control verification checkbox background color void SetCheckBackgroundColor(const color clr,const bool set_init_color) { this.SetProperty(CANV_ELEMENT_PROP_CHECK_BACKGROUND_COLOR,clr); if(set_init_color) this.SetCheckBackgroundColorInit(clr); } color CheckBackgroundColor(void) const { return (color)this.GetProperty(CANV_ELEMENT_PROP_CHECK_BACKGROUND_COLOR); } //--- (1) Set and (2) return the control verification checkbox background color opacity void SetCheckBackgroundColorOpacity(const uchar value) { this.SetProperty(CANV_ELEMENT_PROP_CHECK_BACKGROUND_COLOR_OPACITY,value); } uchar CheckBackgroundColorOpacity(void) const { return (uchar)this.GetProperty(CANV_ELEMENT_PROP_CHECK_BACKGROUND_COLOR_OPACITY); } //--- (1) Set and (2) return the color of control checkbox background when clicking the control void SetCheckBackgroundColorMouseDown(const color clr) { this.SetProperty(CANV_ELEMENT_PROP_CHECK_BACKGROUND_COLOR_MOUSE_DOWN,clr); } color CheckBackgroundColorMouseDown(void) const { return (color)this.GetProperty(CANV_ELEMENT_PROP_CHECK_BACKGROUND_COLOR_MOUSE_DOWN);} //--- (1) Set and (2) return the color of control checkbox background when hovering the mouse over the control void SetCheckBackgroundColorMouseOver(const color clr) { this.SetProperty(CANV_ELEMENT_PROP_CHECK_BACKGROUND_COLOR_MOUSE_OVER,clr); } color CheckBackgroundColorMouseOver(void) const { return (color)this.GetProperty(CANV_ELEMENT_PROP_CHECK_BACKGROUND_COLOR_MOUSE_OVER);} //--- (1) Set and (2) return the initial color of the control verification checkbox background void SetCheckBackgroundColorInit(const color clr) { this.m_check_back_color_init=clr; } color CheckBackgroundColorInit(void) const { return (color)this.m_check_back_color_init; } //--- (1) Set and (2) return the control checkbox frame color void SetCheckBorderColor(const color clr,const bool set_init_color) { this.SetProperty(CANV_ELEMENT_PROP_CHECK_FORE_COLOR,clr); if(set_init_color) this.SetCheckBorderColorInit(clr); } color CheckBorderColor(void) const { return (color)this.GetProperty(CANV_ELEMENT_PROP_CHECK_FORE_COLOR); } //--- (1) Set and (2) return the control checkbox frame color opacity void SetCheckBorderColorOpacity(const uchar value) { this.SetProperty(CANV_ELEMENT_PROP_CHECK_FORE_COLOR_OPACITY,value); } uchar CheckBorderColorOpacity(void) const { return (uchar)this.GetProperty(CANV_ELEMENT_PROP_CHECK_FORE_COLOR_OPACITY); } //--- (1) Set and (2) return the color of control checkbox frame color when clicking on the control void SetCheckBorderColorMouseDown(const color clr) { this.SetProperty(CANV_ELEMENT_PROP_CHECK_FORE_COLOR_MOUSE_DOWN,clr); } color CheckBorderColorMouseDown(void) const { return (color)this.GetProperty(CANV_ELEMENT_PROP_CHECK_FORE_COLOR_MOUSE_DOWN); } //--- (1) Set and (2) return the color of the control checkbox frame color when hovering the mouse over the control void SetCheckBorderColorMouseOver(const color clr) { this.SetProperty(CANV_ELEMENT_PROP_CHECK_FORE_COLOR_MOUSE_OVER,clr); } color CheckBorderColorMouseOver(void) const { return (color)this.GetProperty(CANV_ELEMENT_PROP_CHECK_FORE_COLOR_MOUSE_OVER); } //--- (1) Set and (2) return the initial color of the control verification checkbox frame void SetCheckBorderColorInit(const color clr) { this.m_check_border_color_init=clr; } color CheckBorderColorInit(void) const { return (color)this.m_check_border_color_init; } //--- (1) Set and (2) return the control verification checkbox color void SetCheckFlagColor(const color clr,const bool set_init_color) { this.SetProperty(CANV_ELEMENT_PROP_CHECK_FLAG_COLOR,clr); if(set_init_color) this.SetCheckFlagColorInit(clr); } color CheckFlagColor(void) const { return (color)this.GetProperty(CANV_ELEMENT_PROP_CHECK_FLAG_COLOR); } //--- (1) Set and (2) return the control verification checkbox color opacity void SetCheckFlagColorOpacity(const uchar value) { this.SetProperty(CANV_ELEMENT_PROP_CHECK_FLAG_COLOR_OPACITY,value); } uchar CheckFlagColorOpacity(void) const { return (uchar)this.GetProperty(CANV_ELEMENT_PROP_CHECK_FLAG_COLOR_OPACITY); } //--- (1) Set and (2) return the color of control checkbox when clicking on the control void SetCheckFlagColorMouseDown(const color clr) { this.SetProperty(CANV_ELEMENT_PROP_CHECK_FLAG_COLOR_MOUSE_DOWN,clr); } color CheckFlagColorMouseDown(void) const { return (color)this.GetProperty(CANV_ELEMENT_PROP_CHECK_FLAG_COLOR_MOUSE_DOWN); } //--- (1) Set and (2) return the color of the control checkbox when hovering the mouse over the control void SetCheckFlagColorMouseOver(const color clr) { this.SetProperty(CANV_ELEMENT_PROP_CHECK_FLAG_COLOR_MOUSE_OVER,clr); } color CheckFlagColorMouseOver(void) const { return (color)this.GetProperty(CANV_ELEMENT_PROP_CHECK_FLAG_COLOR_MOUSE_OVER); } //--- (1) Set and (2) return the initial color of the control verification checkbox void SetCheckFlagColorInit(const color clr) { this.m_check_flag_color_init=clr; } color CheckFlagColorInit(void) const { return (color)this.m_check_flag_color_init; } //--- Last mouse event handler virtual void OnMouseEventPostProcessing(void); //--- Redraw the object virtual void Redraw(bool redraw); //--- Constructor
クラスコンストラクタで、さまざまなイベントとマウスの状態の既定の色を設定します。
//+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CCheckBox::CCheckBox(const long chart_id, const int subwindow, const string name, const int x, const int y, const int w, const int h) : CLabel(chart_id,subwindow,name,x,y,w,h) { CGBaseObj::SetTypeElement(GRAPH_ELEMENT_TYPE_WF_CHECKBOX); CGCnvElement::SetProperty(CANV_ELEMENT_PROP_TYPE,GRAPH_ELEMENT_TYPE_WF_CHECKBOX); this.m_type=OBJECT_DE_TYPE_GWF_COMMON; this.SetCoordX(x); this.SetCoordY(y); this.SetCheckWidth(DEF_CHECK_SIZE); this.SetCheckHeight(DEF_CHECK_SIZE); this.SetWidth(w); this.SetHeight(h); this.Initialize(); this.SetForeColorMouseDown(CLR_DEF_FORE_COLOR_MOUSE_DOWN); this.SetForeColorMouseOver(CLR_DEF_FORE_COLOR_MOUSE_OVER); this.SetCheckBackgroundColor(CLR_DEF_CHECK_BACK_COLOR,true); this.SetCheckBackgroundColorMouseDown(CLR_DEF_CHECK_BACK_MOUSE_DOWN); this.SetCheckBackgroundColorMouseOver(CLR_DEF_CHECK_BACK_MOUSE_OVER); this.SetCheckBorderColor(CLR_DEF_CHECK_BORDER_COLOR,true); this.SetCheckBorderColorMouseDown(CLR_DEF_CHECK_BORDER_MOUSE_DOWN); this.SetCheckBorderColorMouseOver(CLR_DEF_CHECK_BORDER_MOUSE_OVER); this.SetCheckFlagColor(CLR_DEF_CHECK_FLAG_COLOR,true); this.SetCheckFlagColorMouseDown(CLR_DEF_CHECK_FLAG_MOUSE_DOWN); this.SetCheckFlagColorMouseOver(CLR_DEF_CHECK_FLAG_MOUSE_OVER); this.SetWidthInit(this.Width()); this.SetHeightInit(this.Height()); this.SetCoordXInit(x); this.SetCoordYInit(y); this.SetTextAlign(ANCHOR_LEFT); this.m_text_x=0; this.m_text_y=0; this.m_check_x=0; this.m_check_y=0; this.Redraw(false); } //+------------------------------------------------------------------+
すべてのマウスイベントハンドラをここで再定義する必要はありません。親クラスの再定義されたメソッドを考えてみましょう。
以下は、「カーソルがアクティブ領域内にあり、マウスボタンがクリックされていない」イベントのハンドラです。
//+------------------------------------------------------------------+ //| 'The cursor is inside the active area, | //| no mouse buttons are clicked' event handler | //+------------------------------------------------------------------+ void CCheckBox::MouseActiveAreaNotPressedHandler(const int id,const long& lparam,const double& dparam,const string& sparam) { this.SetCheckBackgroundColor(this.CheckBackgroundColorMouseOver(),false); this.SetCheckBorderColor(this.CheckBorderColorMouseOver(),false); this.SetCheckFlagColor(this.CheckFlagColorMouseOver(),false); this.Redraw(true); } //+------------------------------------------------------------------+
マウスカーソルがオブジェクトのアクティブ領域に合わせられている場合、チェックボックス、そのフレーム、およびフラグ自体に新しい背景色(現在のマウスおよびオブジェクトのステータスに対して指定)を設定し、オブジェクトを再描画します。
以下は、「カーソルがアクティブ領域内にあり、任意のマウスボタンがクリックされた」イベントのハンドラです。
//+------------------------------------------------------------------+ //| 'The cursor is inside the active area, | //| a mouse button is clicked (any) | //+------------------------------------------------------------------+ void CCheckBox::MouseActiveAreaPressedHandler(const int id,const long& lparam,const double& dparam,const string& sparam) { this.SetCheckBackgroundColor(this.CheckBackgroundColorMouseDown(),false); this.SetCheckBorderColor(this.CheckBorderColorMouseDown(),false); this.SetCheckFlagColor(this.CheckFlagColorMouseDown(),false); this.Redraw(false); } //+------------------------------------------------------------------+
マウスカーソルがオブジェクトのアクティブ領域に合わせられている場合、チェックボックス、そのフレーム、およびフラグ自体に新しい背景色(現在のマウスおよびオブジェクトのステータスに対して指定)を設定し、オブジェクトを再描画します。
以下は、「カーソルがアクティブ領域内にあり、マウスの左ボタンがクリックされた」イベントのハンドラです。
//+------------------------------------------------------------------+ //| 'The cursor is inside the active area, | //| left mouse button released | //+------------------------------------------------------------------+ void CCheckBox::MouseActiveAreaReleasedHandler(const int id,const long& lparam,const double& dparam,const string& sparam) { //--- The mouse button released outside the element means refusal to interact with the element if(lparam<this.CoordX() || lparam>this.RightEdge() || dparam<this.CoordY() || dparam>this.BottomEdge()) { this.SetCheckBackgroundColor(this.BackgroundColorInit(),false); this.SetCheckBorderColor(this.CheckBorderColorInit(),false); this.SetCheckFlagColor(this.CheckFlagColorInit(),false); //--- Send a test entry to the journal Print(DFUN_ERR_LINE,TextByLanguage("Отмена","Cancel")); } //--- The mouse button released within the element means a click on the control else { this.SetCheckBackgroundColor(this.CheckBackgroundColorMouseOver(),false); this.SetCheckBorderColor(this.CheckBorderColorMouseOver(),false); this.SetCheckFlagColor(this.CheckFlagColorInit(),false); this.SetChecked(!this.Checked()); //--- Send a test entry to the journal Print(DFUN_ERR_LINE,TextByLanguage("Щелчок","Click")); } this.Redraw(false); } //+------------------------------------------------------------------+
ここでは2つの状態が処理されます。
マウスボタンが離され、カーソルがオブジェクトのアクティブ領域外にある場合および
マウスボタンが離され、カーソルがオブジェクトのアクティブ領域内にある場合です。
カーソルがオブジェクトの外にあるということは、ユーザーがボタンをクリックし、カーソルを離してボタンを離したということです。この場合、オブジェクトとの対話を拒否することを意味するため、チェックボックスのステータスは変更しません。したがって、オブジェクトの初期フラグとフィールドの色を設定しましょう。
カーソルがオブジェクト内にある場合、ユーザーはボタンをクリックして離したことになります。これにより、チェックボックスのステータスが変更されます。そのため、アクティブ領域にカーソルを置いたときに、フィールド、フレーム、およびチェックボックスの色をオブジェクトに設定されている色に変更して(マウスボタンを離してもカーソルがオブジェクトの上に残っていたので、オブジェクトの上にカーソルを置いたときと同じ色になるはずです)、反対のチェックボックスのステータスを設定します。
最後にオブジェクトを再描画します。処理された各状況のチェックボックスのステータスに関するテストエントリを送信します。後でチェックボックスがトリガーされたときに、操作ログへのエントリの送信を、その後の処理のためにイベントの送信に置き換えます。
以下は、最後のマウスイベントの仮想ハンドラです。
//+------------------------------------------------------------------+ //| Last mouse event handler | //+------------------------------------------------------------------+ void CCheckBox::OnMouseEventPostProcessing(void) { ENUM_MOUSE_FORM_STATE state=GetMouseState(); switch(state) { //--- The cursor is outside the form, the mouse buttons are not clicked //--- The cursor is outside the form, any mouse button is clicked //--- The cursor is outside the form, the mouse wheel is being scrolled case MOUSE_FORM_STATE_OUTSIDE_FORM_NOT_PRESSED : case MOUSE_FORM_STATE_OUTSIDE_FORM_PRESSED : case MOUSE_FORM_STATE_OUTSIDE_FORM_WHEEL : if(MouseEventLast()==MOUSE_EVENT_INSIDE_ACTIVE_AREA_NOT_PRESSED) { this.SetBackgroundColor(this.BackgroundColorInit(),false); this.SetBorderColor(this.BorderColorInit(),false); this.SetCheckBackgroundColor(this.CheckBackgroundColorInit(),false); this.SetCheckBorderColor(this.CheckBorderColorInit(),false); this.SetCheckFlagColor(this.CheckFlagColorInit(),false); this.m_mouse_event_last=ENUM_MOUSE_EVENT(state+MOUSE_EVENT_NO_EVENT); this.Redraw(false); } break; //--- The cursor is inside the form, the mouse buttons are not clicked case MOUSE_FORM_STATE_INSIDE_FORM_NOT_PRESSED : break; //--- The cursor is inside the form, any mouse button is clicked case MOUSE_FORM_STATE_INSIDE_FORM_PRESSED : break; //--- The cursor is inside the form, the mouse wheel is being scrolled case MOUSE_FORM_STATE_INSIDE_FORM_WHEEL : break; //--- The cursor is inside the active area, the mouse buttons are not clicked case MOUSE_FORM_STATE_INSIDE_ACTIVE_AREA_NOT_PRESSED : break; //--- The cursor is inside the active area, any mouse button is clicked case MOUSE_FORM_STATE_INSIDE_ACTIVE_AREA_PRESSED : break; //--- The cursor is inside the active area, the mouse wheel is being scrolled case MOUSE_FORM_STATE_INSIDE_ACTIVE_AREA_WHEEL : break; //--- The cursor is inside the active area, left mouse button is released case MOUSE_FORM_STATE_INSIDE_ACTIVE_AREA_RELEASED : break; //--- The cursor is within the window scrolling area, the mouse buttons are not clicked case MOUSE_FORM_STATE_INSIDE_SCROLL_AREA_NOT_PRESSED : break; //--- The cursor is within the window scrolling area, any mouse button is clicked case MOUSE_FORM_STATE_INSIDE_SCROLL_AREA_PRESSED : break; //--- The cursor is within the window scrolling area, the mouse wheel is being scrolled case MOUSE_FORM_STATE_INSIDE_SCROLL_AREA_WHEEL : break; //--- MOUSE_EVENT_NO_EVENT default: break; } } //+------------------------------------------------------------------+
ここでは、マウスカーソルがオブジェクトの外にある状況のみを扱います。以前の状態は、「カーソルがアクティブ領域内にあり、マウスボタンはクリックされていない」でした。この場合、すべての変更可能なオブジェクトカラープロパティの初期値を設定し、現在のステータスを最後のマウスイベントに割り当てます。
\MQL5\Include\DoEasy\Objects\Graph\WForms\CommonControls\RadioButton.mqhのWinFormsオブジェクトのRadioButtonクラスは、新しく変更されたCheckBoxオブジェクトクラスから継承されるため、必要な変更は少なくなります。
このオブジェクトでは、フラグは常にアクティブです。チェックを外すことは、連携して動作する別の同様のオブジェクトに依存します。チェックボックスが1つのオブジェクトで設定されている場合、別のオブジェクトではチェックされていません。ここでは、親クラスの単一の仮想メソッドを再定義するだけで済みます。
//+------------------------------------------------------------------+ //| CheckBox object class of the WForms controls | //+------------------------------------------------------------------+ class CRadioButton : public CCheckBox { private: protected: //--- Displays the checkbox for the specified state virtual void ShowControlFlag(const ENUM_CANV_ELEMENT_CHEK_STATE state); //--- 'The cursor is inside the active area, the left mouse button is clicked' event handler virtual void MouseActiveAreaReleasedHandler(const int id,const long& lparam,const double& dparam,const string& sparam); public:
以下は、「カーソルがアクティブ領域内にあり、マウスの左ボタンがクリックされた」イベントのハンドラです。
//+------------------------------------------------------------------+ //| 'The cursor is inside the active area, | //| left mouse button released | //+------------------------------------------------------------------+ void CRadioButton::MouseActiveAreaReleasedHandler(const int id,const long& lparam,const double& dparam,const string& sparam) { //--- The mouse button released outside the element means refusal to interact with the element if(lparam<this.CoordX() || lparam>this.RightEdge() || dparam<this.CoordY() || dparam>this.BottomEdge()) { this.SetCheckBackgroundColor(this.BackgroundColorInit(),false); this.SetCheckBorderColor(this.CheckBorderColorInit(),false); this.SetCheckFlagColor(this.CheckFlagColorInit(),false); Print(DFUN_ERR_LINE,TextByLanguage("Отмена","Cancel")); } //--- The mouse button released within the element means a click on the control else { this.SetCheckBackgroundColor(this.CheckBackgroundColorMouseOver(),false); this.SetCheckBorderColor(this.CheckBorderColorMouseOver(),false); this.SetCheckFlagColor(this.CheckFlagColorInit(),false); Print(DFUN_ERR_LINE,TextByLanguage("Щелчок","Click")); } this.Redraw(false); } //+------------------------------------------------------------------+
このメソッドは、オブジェクトのアクティブ領域内でボタンを解放するブロック処理でフラグを反対の値に設定する必要がないことを除いて、CheckBoxオブジェクトクラスで考慮されたものと似ています。
Button WinFormsオブジェクトのボタンには次の2つのタイプがあります。
- クリックすると、ボタンがトリガーされて初期状態に戻る
- クリックすると、ボタンがトリガーされて押されたままになり、2回目のクリックでステータスが反対の状態に切り替わる(トリガーはトグルボタン)
どちらのボタンであるかを定義するフラグと、トリガーボタン(押された/離された)を定義するフラグ、そしてもちろん、クリックされたときのボタンの色(背景色、カーソルを合わせたときの色、クリックしたときの色)を決定するための別のセットが必要です。
\MQL5\Include\DoEasy\Objects\Graph\WForms\CommonControls\Button.mqhのクラスのprivateセクションで、新しいボタンの状態の色を格納するための配列を宣言します。
//+------------------------------------------------------------------+ //| Label object class of WForms controls | //+------------------------------------------------------------------+ class CButton : public CLabel { private: int m_text_x; // Text X coordinate int m_text_y; // Text Y coordinate color m_array_colors_bg_tgl[]; // Array of element background colors for the 'enabled' state color m_array_colors_bg_tgl_dwn[]; // Array of control background colors for the 'enabled' state when clicking on the control color m_array_colors_bg_tgl_ovr[]; // Array of control background colors for the 'enabled' state when hovering the mouse over the control color m_array_colors_bg_tgl_init[]; // Array of initial element background colors for the 'enabled' state protected:
クラスのprotectedセクションで、ここで再定義する必要がある親クラスのマウスイベントのハンドラを宣言します。
protected: //--- Set the element width and height automatically virtual bool AutoSetWH(void); //--- 'The cursor is inside the active area, the mouse buttons are not clicked' event handler virtual void MouseActiveAreaNotPressedHandler(const int id,const long& lparam,const double& dparam,const string& sparam); //--- 'The cursor is inside the active area, a mouse button is clicked (any)' event handler virtual void MouseActiveAreaPressedHandler(const int id,const long& lparam,const double& dparam,const string& sparam); //--- 'The cursor is inside the active area, the left mouse button is clicked' event handler virtual void MouseActiveAreaReleasedHandler(const int id,const long& lparam,const double& dparam,const string& sparam); public:
クラスのpublicセクションで、トリガーボタンフラグを設定して返すメソッド、トリガーボタンステータスを設定して返すメソッド、新しいボタンステータスカラーを処理するメソッドを記述し、最後のマウスイベントを処理するメソッドを宣言します。
public: //--- Redraw the object virtual void Redraw(bool redraw); //--- (1) Set and (2) return the mode of the element auto resizing depending on the content void SetAutoSizeMode(const ENUM_CANV_ELEMENT_AUTO_SIZE_MODE mode,const bool redraw) { ENUM_CANV_ELEMENT_AUTO_SIZE_MODE prev=this.AutoSizeMode(); if(prev==mode) return; this.SetProperty(CANV_ELEMENT_PROP_AUTOSIZE_MODE,mode); } ENUM_CANV_ELEMENT_AUTO_SIZE_MODE AutoSizeMode(void) const { return (ENUM_CANV_ELEMENT_AUTO_SIZE_MODE)this.GetProperty(CANV_ELEMENT_PROP_AUTOSIZE_MODE); } //--- (1) Set and (2) return the control Toggle flag void SetToggleFlag(const bool flag) { this.SetProperty(CANV_ELEMENT_PROP_BUTTON_TOGGLE,flag); if(this.Toggle()) this.SetColorsToggleON(CLR_DEF_CONTROL_STD_BACK_COLOR_ON,CLR_DEF_CONTROL_STD_BACK_DOWN_ON,CLR_DEF_CONTROL_STD_BACK_OVER_ON,true); } bool Toggle(void) const { return (bool)this.GetProperty(CANV_ELEMENT_PROP_BUTTON_TOGGLE); } //--- (1) Set and (2) return the Toggle control status void SetState(const bool flag) { this.SetProperty(CANV_ELEMENT_PROP_BUTTON_STATE,flag); } bool State(void) const { return (bool)this.GetProperty(CANV_ELEMENT_PROP_BUTTON_STATE); } //--- (1,2) Set and (3) return the main background color for the 'enabled' status void SetBackgroundColorToggleON(const color colour,const bool set_init_color) { this.SetProperty(CANV_ELEMENT_PROP_BACKGROUND_COLOR_TOGGLE,colour); color arr[1]; arr[0]=colour; this.CopyArraysColors(this.m_array_colors_bg_tgl,arr,DFUN); if(set_init_color) this.CopyArraysColors(this.m_array_colors_bg_tgl_init,arr,DFUN); } void SetBackgroundColorsToggleON(color &colors[],const bool set_init_colors) { this.CopyArraysColors(this.m_array_colors_bg_tgl,colors,DFUN); this.SetProperty(CANV_ELEMENT_PROP_BACKGROUND_COLOR_TOGGLE,this.m_array_colors_bg_tgl[0]); if(set_init_colors) this.CopyArraysColors(this.m_array_colors_bg_tgl_init,colors,DFUN); } color BackgroundColorToggleON(void) const { return (color)this.GetProperty(CANV_ELEMENT_PROP_BACKGROUND_COLOR_TOGGLE); } //--- (1,2) Set and (3) return the background color when clicking on the control for the 'enabled' status void SetBackgroundColorToggleONMouseDown(const color colour) { this.SetProperty(CANV_ELEMENT_PROP_BACKGROUND_COLOR_TOGGLE_MOUSE_DOWN,colour); color arr[1]; arr[0]=colour; this.CopyArraysColors(this.m_array_colors_bg_tgl_dwn,arr,DFUN); } void SetBackgroundColorsToggleONMouseDown(color &colors[]) { this.CopyArraysColors(this.m_array_colors_bg_tgl_dwn,colors,DFUN); this.SetProperty(CANV_ELEMENT_PROP_BACKGROUND_COLOR_TOGGLE_MOUSE_DOWN,this.m_array_colors_bg_dwn[0]); } color BackgroundColorToggleONMouseDown(void) const { return (color)this.GetProperty(CANV_ELEMENT_PROP_BACKGROUND_COLOR_TOGGLE_MOUSE_DOWN); } //--- (1,2) Set and (3) return the background color when hovering the mouse over the control for the 'enabled' status void SetBackgroundColorToggleONMouseOver(const color colour) { this.SetProperty(CANV_ELEMENT_PROP_BACKGROUND_COLOR_TOGGLE_MOUSE_OVER,colour); color arr[1]; arr[0]=colour; this.CopyArraysColors(this.m_array_colors_bg_tgl_ovr,arr,DFUN); } void SetBackgroundColorsToggleONMouseOver(color &colors[]) { this.CopyArraysColors(this.m_array_colors_bg_tgl_ovr,colors,DFUN); this.SetProperty(CANV_ELEMENT_PROP_BACKGROUND_COLOR_TOGGLE_MOUSE_OVER,this.m_array_colors_bg_ovr[0]); } color BackgroundColorToggleONMouseOver(void) const { return (color)this.GetProperty(CANV_ELEMENT_PROP_BACKGROUND_COLOR_TOGGLE_MOUSE_OVER); } //--- Return the initial main background color for the 'enabled' status color BackgroundColorToggleONInit(void) const { return this.m_array_colors_bg_tgl_init[0]; } //--- Set the colors for the 'enabled' status void SetColorsToggleON(const color back,const color back_down,const color back_over,const bool set_init_color); //--- Last mouse event handler virtual void OnMouseEventPostProcessing(void); //--- Constructor CButton(const long chart_id, const int subwindow, const string name, const int x, const int y, const int w, const int h); }; //+------------------------------------------------------------------+
これらのメソッドは、上で検討した他のクラスのオブジェクトの色を設定メソッドや返すメソッドと同じです。
クラスコンストラクタで、オブジェクトの背景色、オブジェクトの不透明度の値、およびボタンにカーソルを合わせてクリックしたときの背景色のデフォルトの色を設定します。通常のボタン(トグルではない)フラグを設定し、トグルボタンのステータスをfalseに設定します。
//+------------------------------------------------------------------+ //| Constructor | //+------------------------------------------------------------------+ CButton::CButton(const long chart_id, const int subwindow, const string name, const int x, const int y, const int w, const int h) : CLabel(chart_id,subwindow,name,x,y,w,h) { CGBaseObj::SetTypeElement(GRAPH_ELEMENT_TYPE_WF_BUTTON); CGCnvElement::SetProperty(CANV_ELEMENT_PROP_TYPE,GRAPH_ELEMENT_TYPE_WF_BUTTON); this.m_type=OBJECT_DE_TYPE_GWF_COMMON; this.SetCoordX(x); this.SetCoordY(y); this.SetWidth(w); this.SetHeight(h); this.Initialize(); this.SetBackgroundColor(CLR_DEF_CONTROL_STD_BACK_COLOR,true); this.SetBackgroundColorMouseDown(CLR_DEF_CONTROL_STD_MOUSE_DOWN); this.SetBackgroundColorMouseOver(CLR_DEF_CONTROL_STD_MOUSE_OVER); this.SetOpacity(CLR_DEF_CONTROL_STD_OPACITY); this.SetTextAlign(ANCHOR_CENTER); this.SetMarginAll(3); this.SetWidthInit(this.Width()); this.SetHeightInit(this.Height()); this.SetCoordXInit(x); this.SetCoordYInit(y); this.SetToggleFlag(false); this.SetState(false); this.Redraw(false); } //+------------------------------------------------------------------+
マウスイベントハンドラを再定義します。
以下は、「カーソルがアクティブ領域内にあり、マウスボタンがクリックされていない」イベントのハンドラです。
//+------------------------------------------------------------------+ //| 'The cursor is inside the active area, | //| no mouse buttons are clicked' event handler | //+------------------------------------------------------------------+ void CButton::MouseActiveAreaNotPressedHandler(const int id,const long& lparam,const double& dparam,const string& sparam) { //--- If this is a simple button, set the color for the "The cursor is over the active area, the mouse button is not clicked" status if(!this.Toggle()) this.SetBackgroundColor(this.BackgroundColorMouseOver(),false); //--- If this is the toggle button, set the color for the status depending on whether the button is pressed or not else this.SetBackgroundColor(this.State() ? this.BackgroundColorToggleONMouseOver() : this.BackgroundColorMouseOver(),false); //--- Set the frame color for the status this.SetBorderColor(this.BorderColorMouseOver(),false); //--- Redraw the object this.Redraw(false); } //+------------------------------------------------------------------+
以下は、「カーソルがアクティブ領域内にあり、任意のマウスボタンがクリックされた」イベントのハンドラです。
//+------------------------------------------------------------------+ //| 'The cursor is inside the active area, | //| a mouse button is clicked (any) | //+------------------------------------------------------------------+ void CButton::MouseActiveAreaPressedHandler(const int id,const long& lparam,const double& dparam,const string& sparam) { //--- If this is a simple button, set the color for the "The cursor is over the active area, the mouse button is clicked" status if(!this.Toggle()) this.SetBackgroundColor(this.BackgroundColorMouseDown(),false); //--- If this is the toggle button, set the color for the status depending on whether the button is pressed or not else this.SetBackgroundColor(this.State() ? this.BackgroundColorToggleONMouseDown() : this.BackgroundColorMouseDown(),false); //--- Set the frame color for the status this.SetBorderColor(this.BorderColorMouseDown(),false); //--- Redraw the object this.Redraw(false); } //+------------------------------------------------------------------+
以下は、「カーソルがアクティブ領域内にあり、マウスの左ボタンがクリックされた」イベントのハンドラです。
//+------------------------------------------------------------------+ //| 'The cursor is inside the active area, | //| left mouse button released | //+------------------------------------------------------------------+ void CButton::MouseActiveAreaReleasedHandler(const int id,const long& lparam,const double& dparam,const string& sparam) { //--- The mouse button released outside the element means refusal to interact with the element if(lparam<this.CoordX() || lparam>this.RightEdge() || dparam<this.CoordY() || dparam>this.BottomEdge()) { //--- If this is a simple button, set the initial background color if(!this.Toggle()) this.SetBackgroundColor(this.BackgroundColorInit(),false); //--- If this is the toggle button, set the initial color depending on whether the button is pressed or not else this.SetBackgroundColor(!this.State() ? this.BackgroundColorInit() : this.BackgroundColorToggleONInit(),false); //--- Set the initial frame color this.SetBorderColor(this.BorderColorInit(),false); //--- Send the test message to the journal Print(DFUN_ERR_LINE,TextByLanguage("Отмена","Cancel")); } //--- The mouse button released within the element means a click on the control else { //--- If this is a simple button, set the color for "The cursor is over the active area" status if(!this.Toggle()) this.SetBackgroundColor(this.BackgroundColorMouseOver(),false); //--- If this is the toggle button, else { //--- set the button status to the opposite one this.SetState(!this.State()); //--- set the background color for "The cursor is over the active area" status depending on whether the button is clicked or not this.SetBackgroundColor(this.State() ? this.BackgroundColorToggleONMouseOver() : this.BackgroundColorMouseOver(),false); } //--- Send the test message to the journal Print(DFUN_ERR_LINE,TextByLanguage("Щелчок","Click")); //--- Set the frame color for "The cursor is over the active area" status this.SetBorderColor(this.BorderColorMouseOver(),false); } //--- Redraw the object this.Redraw(false); } //+------------------------------------------------------------------+
メソッドロジックはコードコメントで詳細に説明されており、説明は不要です。
以下は、最後のマウスイベントハンドラです。
//+------------------------------------------------------------------+ //| Last mouse event handler | //+------------------------------------------------------------------+ void CButton::OnMouseEventPostProcessing(void) { ENUM_MOUSE_FORM_STATE state=GetMouseState(); switch(state) { //--- The cursor is outside the form, the mouse buttons are not clicked //--- The cursor is outside the form, any mouse button is clicked //--- The cursor is outside the form, the mouse wheel is being scrolled case MOUSE_FORM_STATE_OUTSIDE_FORM_NOT_PRESSED : case MOUSE_FORM_STATE_OUTSIDE_FORM_PRESSED : case MOUSE_FORM_STATE_OUTSIDE_FORM_WHEEL : if(MouseEventLast()==MOUSE_EVENT_INSIDE_ACTIVE_AREA_NOT_PRESSED) { this.SetBackgroundColor(this.State() ? this.BackgroundColorToggleON() : this.BackgroundColorInit(),false); this.SetBorderColor(this.BorderColorInit(),false); this.m_mouse_event_last=ENUM_MOUSE_EVENT(state+MOUSE_EVENT_NO_EVENT); this.Redraw(false); } break; //--- The cursor is inside the form, the mouse buttons are not clicked case MOUSE_FORM_STATE_INSIDE_FORM_NOT_PRESSED : break; //--- The cursor is inside the form, any mouse button is clicked case MOUSE_FORM_STATE_INSIDE_FORM_PRESSED : break; //--- The cursor is inside the form, the mouse wheel is being scrolled case MOUSE_FORM_STATE_INSIDE_FORM_WHEEL : break; //--- The cursor is inside the active area, the mouse buttons are not clicked case MOUSE_FORM_STATE_INSIDE_ACTIVE_AREA_NOT_PRESSED : break; //--- The cursor is inside the active area, any mouse button is clicked case MOUSE_FORM_STATE_INSIDE_ACTIVE_AREA_PRESSED : break; //--- The cursor is inside the active area, the mouse wheel is being scrolled case MOUSE_FORM_STATE_INSIDE_ACTIVE_AREA_WHEEL : break; //--- The cursor is inside the active area, left mouse button is released case MOUSE_FORM_STATE_INSIDE_ACTIVE_AREA_RELEASED : break; //--- The cursor is within the window scrolling area, the mouse buttons are not clicked case MOUSE_FORM_STATE_INSIDE_SCROLL_AREA_NOT_PRESSED : break; //--- The cursor is within the window scrolling area, any mouse button is clicked case MOUSE_FORM_STATE_INSIDE_SCROLL_AREA_PRESSED : break; //--- The cursor is within the window scrolling area, the mouse wheel is being scrolled case MOUSE_FORM_STATE_INSIDE_SCROLL_AREA_WHEEL : break; //--- MOUSE_EVENT_NO_EVENT default: break; } } //+------------------------------------------------------------------+
このメソッドでは、マウスカーソルがフォームの外にあり、最後のマウスイベントがフォームの上にカーソルがあり、マウスボタンがクリックされていない状況のみを処理します。ボタンの初期色は、ボタンが押されているかどうかに応じてボタンの背景色に設定されます(State()メソッドによって返される単純なボタンの値は常にfalseです)。
以下は、トグルボタンの「有効」ステータスの色を設定するメソッドです。
//+------------------------------------------------------------------+ //| Set the colors for the toggle element 'enabled' status | //+------------------------------------------------------------------+ void CButton::SetColorsToggleON(const color back,const color back_down,const color back_over,const bool set_init_color) { this.SetBackgroundColorToggleON(back,set_init_color); this.SetBackgroundColorToggleONMouseDown(back_down); this.SetBackgroundColorToggleONMouseOver(back_over); } //+------------------------------------------------------------------+
このメソッドは、3つのボタン状態の色を受け取ります。それらは対応する変数に設定されます。set_init_colorフラグを使用すると、最初のボタンの背景色を保存するかどうかを定義できます。
\MQL5\Include\DoEasy\Collections\GraphElementsCollection.mqhのグラフィック要素のコレクションクラスを改善しましょう。
GetFormUnderCursor()メソッドには2つの同一のコードブロックがあり、フォームにバインドされ、カーソルの下にあるオブジェクトが検索されます。このコードブロックを別のメソッドに移動して、メソッドコードを短縮し、そのロジックをより視覚的に表現します。
クラスのprivateセクションで、メソッドとカーソルが移動したフォームのイベントを処理するメソッドを宣言します。
//--- Add (1) the standard graphical object and (2) the graphical element on canvas to the collection bool AddGraphObjToCollection(const string source,CChartObjectsControl *obj_control); //--- Search for interaction objects CForm *SearchInteractObj(CForm *form,const int id,const long &lparam,const double &dparam,const string &sparam); //--- Return the pointer to the form located under the cursor CForm *GetFormUnderCursor(const int id, const long &lparam, const double &dparam, const string &sparam, ENUM_MOUSE_FORM_STATE &mouse_state, long &obj_ext_id, int &form_index); //--- Reset all interaction flags for all forms except the specified one void ResetAllInteractionExeptOne(CGCnvElement *form); //--- Post-processing of the former active form under the cursor void FormPostProcessing(void); //--- Add the element to the collection list bool AddCanvElmToCollection(CGCnvElement *element);
さまざまなグラフィック要素を作成するすべてのメソッドでは、初期色を保存するためのフラグを含む色を設定するメソッドで、フラグが既に設定されています(オブジェクトの作成時に初期色を保存する必要があるため、trueを渡します)。これらの変更はすべてクラスに対して既におこなわれているため、ここでは詳しく説明しません。
たとえば、指定されたチャートとサブウィンドウのキャンバスにグラフィカルフォームオブジェクトを作成するメソッドは次のとおりです。
//--- Create a graphical form object on canvas on a specified chart and subwindow int CreateForm(const long chart_id, const int subwindow, const string name, const int x, const int y, const int w, const int h, const color clr, const uchar opacity, const bool movable, const bool activity, const bool shadow=false, const bool redraw=false) { int id=this.m_list_all_canv_elm_obj.Total(); CForm *obj=new CForm(chart_id,subwindow,name,x,y,w,h); ENUM_ADD_OBJ_RET_CODE res=this.AddOrGetCanvElmToCollection(obj,id); if(res==ADD_OBJ_RET_CODE_ERROR) return WRONG_VALUE; obj.SetID(id); obj.SetActive(activity); obj.SetMovable(movable); obj.SetBackgroundColor(clr,true); obj.SetBorderColor(clr,true); obj.SetOpacity(opacity,false); obj.SetShadow(shadow); obj.DrawRectangle(0,0,obj.Width()-1,obj.Height()-1,obj.BorderColor(),obj.Opacity()); obj.Done(); obj.Erase(clr,opacity,redraw); return obj.ID(); }
色が設定されるすべてのメソッドに同様の変更が加えられました。
以下は、インタラクションオブジェクトを検索するメソッドです。
//+------------------------------------------------------------------+ //| Search for interaction objects | //+------------------------------------------------------------------+ CForm *CGraphElementsCollection::SearchInteractObj(CForm *form,const int id,const long &lparam,const double &dparam,const string &sparam) { //--- If a non-empty pointer is passed if(form!=NULL) { //--- Create the list of interaction objects int total=form.CreateListInteractObj(); //--- In the loop by the created list for(int i=total-1;i>WRONG_VALUE;i--) { //--- get the next form object CForm *obj=form.GetInteractForm(i); //--- If the object is received and the mouse cursor is located above the object, return the pointer to the found object if(obj!=NULL && obj.MouseFormState(id,lparam,dparam,sparam)>MOUSE_FORM_STATE_OUTSIDE_FORM_WHEEL) return obj; } } //--- Return the same pointer return form; } //+------------------------------------------------------------------+
前回の記事では、メソッドロジックを検討しましたが、コードはGetFormUnderCursor()メソッド内にありました。
ここでは、コードブロックの代わりにメソッドの呼び出しを追加するだけです。
//+------------------------------------------------------------------+ //| Return the pointer to the form located under the cursor | //+------------------------------------------------------------------+ CForm *CGraphElementsCollection::GetFormUnderCursor(const int id, const long &lparam, const double &dparam, const string &sparam, ENUM_MOUSE_FORM_STATE &mouse_state, long &obj_ext_id, int &form_index) { //--- Set the ID of the extended standard graphical object to -1 //--- and the index of the anchor point managed by the form to -1 obj_ext_id=WRONG_VALUE; form_index=WRONG_VALUE; //--- Initialize the mouse status relative to the form mouse_state=MOUSE_FORM_STATE_NONE; //--- Declare the pointers to graphical element collection class objects CGCnvElement *elm=NULL; CForm *form=NULL; //--- Get the list of objects the interaction flag is set for (there should be only one object) CArrayObj *list=CSelect::ByGraphCanvElementProperty(GetListCanvElm(),CANV_ELEMENT_PROP_INTERACTION,true,EQUAL); //--- If managed to obtain the list and it is not empty, if(list!=NULL && list.Total()>0) { //--- Get the only graphical element there elm=list.At(0); //--- If the element is a form object or its descendants if(elm.TypeGraphElement()>=GRAPH_ELEMENT_TYPE_WF_BASE) { //--- Assign the pointer to the element for the form object pointer form=elm; //--- Get the mouse status relative to the form mouse_state=form.MouseFormState(id,lparam,dparam,sparam); //--- If the cursor is inside the form, if(mouse_state>MOUSE_FORM_STATE_OUTSIDE_FORM_WHEEL) { //--- Find the interaction object. //--- This will be either the found object or the same form form=this.SearchInteractObj(form,id,lparam,dparam,sparam); //--- Return the form object return form; } } } //--- If there is no a single form object with a specified interaction flag, //--- in the loop by all graphical element collection class objects int total=this.m_list_all_canv_elm_obj.Total(); for(int i=0;i<total;i++) { //--- get the next element elm=this.m_list_all_canv_elm_obj.At(i); if(elm==NULL) continue; //--- if the obtained element is a form object or its descendants if(elm.TypeGraphElement()>=GRAPH_ELEMENT_TYPE_WF_BASE) { //--- Assign the pointer to the element for the form object pointer form=elm; //--- Get the mouse status relative to the form mouse_state=form.MouseFormState(id,lparam,dparam,sparam); //--- If the cursor is within the form, return the pointer to the form if(mouse_state>MOUSE_FORM_STATE_OUTSIDE_FORM_WHEEL) { //--- Find the interaction object. //--- This will be either the found object or the same form form=this.SearchInteractObj(form,id,lparam,dparam,sparam); //--- Return the form object return form; } } } //--- If there is no a single form object from the collection list //--- Get the list of extended standard graphical objects list=this.GetListStdGraphObjectExt(); if(list!=NULL) { //--- in the loop by all extended standard graphical objects for(int i=0;i<list.Total();i++) { //--- get the next graphical object, CGStdGraphObj *obj_ext=list.At(i); if(obj_ext==NULL) continue; //--- get the object of its toolkit, CGStdGraphObjExtToolkit *toolkit=obj_ext.GetExtToolkit(); if(toolkit==NULL) continue; //--- handle the event of changing the chart for the current graphical object obj_ext.OnChartEvent(CHARTEVENT_CHART_CHANGE,lparam,dparam,sparam); //--- Get the total number of form objects created for the current graphical object total=toolkit.GetNumControlPointForms(); //--- In the loop by all form objects for(int j=0;j<total;j++) { //--- get the next form object, form=toolkit.GetControlPointForm(j); if(form==NULL) continue; //--- get the mouse status relative to the form mouse_state=form.MouseFormState(id,lparam,dparam,sparam); //--- If the cursor is inside the form, if(mouse_state>MOUSE_FORM_STATE_OUTSIDE_FORM_WHEEL) { //--- set the object ID and form index //--- and return the pointer to the form obj_ext_id=obj_ext.ObjectID(); form_index=j; return form; } } } } //--- Nothing is found - return NULL return NULL; } //+------------------------------------------------------------------+
このような小さな改善のおかげで、メソッドコードはより読みやすくなりました。
以下は、カーソル下の以前のアクティブフォームのマウスイベントを処理するメソッドです。
//+------------------------------------------------------------------+ //| Post-processing of the former active form under the cursor | //+------------------------------------------------------------------+ void CGraphElementsCollection::FormPostProcessing(void) { //--- Get all the elements of the CForm type and above CArrayObj *list=GetList(CANV_ELEMENT_PROP_TYPE,GRAPH_ELEMENT_TYPE_FORM,EQUAL_OR_MORE); if(list==NULL) return; //--- In the loop by the list of received elements int total=list.Total(); for(int i=0;i<total;i++) { //--- get the pointer to the object CForm *obj=list.At(i); //--- if failed to get the pointer, move on to the next one in the list if(obj==NULL) continue; //--- Create the list of interaction objects and get their number int count=obj.CreateListInteractObj(); //--- In the loop by the obtained list for(int j=0;j<count;j++) { //--- get the next object CForm *elm=obj.GetInteractForm(j); if(elm==NULL) continue; //--- and call its method of handling mouse events elm.OnMouseEventPostProcessing(); } } } //+------------------------------------------------------------------+
カーソルをチャート上のフォームオブジェクトから離すと、このオブジェクトはフォーカスを失い、カーソルの下にある別のオブジェクトが自動的に選択されます。カーソルの下に他のオブジェクトがない場合、以前に無効化されていたすべてのチャート機能(スクロール、コンテキストメニューなど)が有効になります。ただし、オブジェクトの色を変更する必要がある場合や、元の色に戻す必要がある場合など、オブジェクトからのカーソルの削除を処理する必要がある場合があります。これはまさにこのメソッドがおこなうことです。「フォーム」タイプ以上のすべてのグラフィック要素を循環し、各要素にバインドされたオブジェクトのリストを作成し、これらのオブジェクトによってループ内で上記のマウスイベント処理メソッドを呼び出します。したがって、チャートの各フォームにある各オブジェクトが処理されますが、最後のマウスイベントが必要な場合(カーソルがオブジェクトの上にあり、マウスボタンがクリックされていない場合)に限られます。イベントを処理した後、現在のステータス(カーソルがフォームの外にある)をオブジェクトの最後のマウスイベントに割り当てます。1つのオブジェクト(カーソルが最後に移動されたオブジェクト)のみが1回処理されます。
//--- If this is a mouse movement event and the movement flag is active, move the form, above which the cursor is located (if the pointer to it is valid) if(id==CHARTEVENT_MOUSE_MOVE && move) { if(form!=NULL) { //---... //---...
移動フラグが削除されたが、マウスが移動している場合(保持フラグが設定されている間)を判断できるように、それらの検証を分離する必要があります。マウスボタンが離されると、MOUSE_FORM_STATE_NONEイベントが登録されます。このイベントは、このような状況の処理をまだ追加していないため、この場合にのみ表示されますが、これはマウスボタンのリリースイベントです。
したがって、カーソル移動イベントと有効な移動フラグを確認するイベントを分離する必要があります。移動フラグが無効になっている場合は、MOUSE_FORM_STATE_NONEイベントを定義し、新しいもの(MOUSE_FORM_STATE_INSIDE_ACTIVE_AREA_RELEASED)に置き換える必要があります。
以下は、上記のように修正されたコードセグメントです。ここでは、個別の検証のために2つのイベントを分離しました。
if(id==CHARTEVENT_MOUSE_MOVE) { //--- If the cursor is above the form if(form!=NULL) { //--- If the move flag is set, shift the form following the cursor if(move) { //--- calculate the cursor movement relative to the form coordinate origin int x=this.m_mouse.CoordX()-form.OffsetX(); int y=this.m_mouse.CoordY()-form.OffsetY(); //--- get the width and height of the chart the form is located at int chart_width=(int)::ChartGetInteger(form.ChartID(),CHART_WIDTH_IN_PIXELS,form.SubWindow()); int chart_height=(int)::ChartGetInteger(form.ChartID(),CHART_HEIGHT_IN_PIXELS,form.SubWindow()); //--- If the form is not within an extended standard graphical object if(form_index==WRONG_VALUE) { //--- Adjust the calculated form coordinates if the form is out of the chart range if(x<0) x=0; if(x>chart_width-form.Width()) x=chart_width-form.Width(); if(y<0) y=0; if(y>chart_height-form.Height()) y=chart_height-form.Height(); //--- If the one-click trading panel is not present on the chart, if(!::ChartGetInteger(form.ChartID(),CHART_SHOW_ONE_CLICK)) { //--- calculate the form coordinates so that the form does not overlap with the one-click trading panel button if(y<17 && x<41) y=17; } //--- If the one-click trading panel is on the chart, else { //--- calculate the form coordinates so that the form does not overlap with the one-click trading panel if(y<80 && x<192) y=80; } } //--- If the form is included into the extended standard graphical object else { if(graph_obj_id>WRONG_VALUE) { //--- Get the list of objects by object ID (there should be one object) CArrayObj *list_ext=CSelect::ByGraphicStdObjectProperty(GetListStdGraphObjectExt(),GRAPH_OBJ_PROP_ID,0,graph_obj_id,EQUAL); //--- If managed to obtain the list and it is not empty, if(list_ext!=NULL && list_ext.Total()>0) { //--- get the graphical object from the list CGStdGraphObj *ext=list_ext.At(0); //--- If the pointer to the object has been received, if(ext!=NULL) { //--- get the object type ENUM_OBJECT type=ext.GraphObjectType(); //--- If the object is built using screen coordinates, set the coordinates to the object if(type==OBJ_LABEL || type==OBJ_BUTTON || type==OBJ_BITMAP_LABEL || type==OBJ_EDIT || type==OBJ_RECTANGLE_LABEL) { ext.SetXDistance(x); ext.SetYDistance(y); } //--- otherwise, if the object is built based on time/price coordinates, else { //--- calculate the shift from the form coordinate origin to its center int shift=(int)::ceil(form.Width()/2)+1; //--- If the form is located on one of the graphical object pivot points, if(form_index<ext.Pivots()) { //--- limit the form coordinates so that they do not move beyond the chart borders if(x+shift<0) x=-shift; if(x+shift>chart_width) x=chart_width-shift; if(y+shift<0) y=-shift; if(y+shift>chart_height) y=chart_height-shift; //--- set the calculated coordinates to the object ext.ChangeCoordsExtendedObj(x+shift,y+shift,form_index); } //--- If the form is central for managing all pivot points of a graphical object else { //--- Get screen coordinates of all object pivot points and write them to the m_data_pivot_point structure if(this.GetPivotPointCoordsAll(ext,m_data_pivot_point)) { //--- In the loop by the number of object pivot points, for(int i=0;i<(int)this.m_data_pivot_point.Size();i++) { //--- limit the screen coordinates of the current pivot point so that they do not move beyond the chart borders //--- By X coordinate if(x+shift-::fabs(this.m_data_pivot_point[i].ShiftX)<0) x=-shift+::fabs(m_data_pivot_point[i].ShiftX); if(x+shift+::fabs(this.m_data_pivot_point[i].ShiftX)>chart_width) x=chart_width-shift-::fabs(this.m_data_pivot_point[i].ShiftX); //--- By Y coordinate if(y+shift-::fabs(this.m_data_pivot_point[i].ShiftY)<0) y=-shift+::fabs(this.m_data_pivot_point[i].ShiftY); if(y+shift+::fabs(this.m_data_pivot_point[i].ShiftY)>chart_height) y=chart_height-shift-::fabs(this.m_data_pivot_point[i].ShiftY); //--- set the calculated coordinates to the current object pivot point ext.ChangeCoordsExtendedObj(x+shift+this.m_data_pivot_point[i].ShiftX,y+shift+this.m_data_pivot_point[i].ShiftY,i); } } } } } } } } //--- Move the form by the obtained coordinates if(form.IsMain()) form.Move(x,y,true); } //--- If the move flag is disabled else { //--- The undefined mouse status in mouse_state means releasing the left button //--- Assign the new mouse status to the variable if(mouse_state==MOUSE_FORM_STATE_NONE) mouse_state=MOUSE_FORM_STATE_INSIDE_ACTIVE_AREA_RELEASED; //--- Handle moving the cursor mouse away from the graphical element this.FormPostProcessing(); } } }
これで、移動フラグが解放された場合に新しいマウスイベントを「キャッチ」し、アクティブフォームオブジェクトのオブジェクトからカーソルを離すイベントをすぐに処理できるようになりました。
同じOnChartEvent()イベントハンドラ、つまりマウスイベントハンドラブロックで、以前に見つかったイベントを示しながら、オブジェクトのマウスイベントハンドラを呼び出します。
//--- If the cursor is above the form else { //--- If the button is still pressed and held on the chart, exit if(pressed_chart) { return; } //--- If the flag of holding the button on the form is not set yet if(!pressed_form) { pressed_chart=false; // The button is not pressed on the chart this.SetChartTools(form.ChartID(),false); //+---------------------------------------------------------------------------------------------+ //| 'The cursor is inside the form, no mouse buttons are clicked' event handler | //+---------------------------------------------------------------------------------------------+ if(mouse_state==MOUSE_FORM_STATE_INSIDE_FORM_NOT_PRESSED) { form.OnMouseEvent(MOUSE_EVENT_INSIDE_FORM_NOT_PRESSED,lparam,dparam,sparam); //--- If the cursor is above the form for managing the pivot point of an extended graphical object, if(graph_obj_id>WRONG_VALUE) { //--- get the object by its ID and by the chart ID CGStdGraphObj *graph_obj=this.GetStdGraphObjectExt(graph_obj_id,form.ChartID()); if(graph_obj!=NULL) { //--- Get the toolkit of an extended standard graphical object CGStdGraphObjExtToolkit *toolkit=graph_obj.GetExtToolkit(); if(toolkit!=NULL) { //--- Draw a point with a circle on the form and delete it on all other forms toolkit.DrawOneControlPoint(form); } } } } //+---------------------------------------------------------------------------------------------+ //| 'The cursor is inside the form, a mouse button is clicked (any)' event handler | //+---------------------------------------------------------------------------------------------+ if(mouse_state==MOUSE_FORM_STATE_INSIDE_FORM_PRESSED) { this.SetChartTools(::ChartID(),false); //--- If the flag of holding the form is not set yet if(!pressed_form) { pressed_form=true; // set the flag of pressing on the form pressed_chart=false; // disable the flag of pressing on the form } form.OnMouseEvent(MOUSE_EVENT_INSIDE_FORM_PRESSED,lparam,dparam,sparam); } //+---------------------------------------------------------------------------------------------+ //| 'The cursor is inside the form, the mouse wheel is being scrolled' event handler | //+---------------------------------------------------------------------------------------------+ if(mouse_state==MOUSE_FORM_STATE_INSIDE_FORM_WHEEL) { form.OnMouseEvent(MOUSE_EVENT_INSIDE_FORM_WHEEL,lparam,dparam,sparam); } //+---------------------------------------------------------------------------------------------+ //| 'The cursor is inside the active area, the mouse buttons are not clicked' event handler | //+---------------------------------------------------------------------------------------------+ if(mouse_state==MOUSE_FORM_STATE_INSIDE_ACTIVE_AREA_NOT_PRESSED) { //--- Set the cursor shift relative to the form initial coordinates form.SetOffsetX(this.m_mouse.CoordX()-form.CoordX()); form.SetOffsetY(this.m_mouse.CoordY()-form.CoordY()); form.OnMouseEvent(MOUSE_EVENT_INSIDE_ACTIVE_AREA_NOT_PRESSED,lparam,dparam,sparam); //--- If the cursor is above the active area of the form for managing the pivot point of an extended graphical object, if(graph_obj_id>WRONG_VALUE) { //--- get the object by its ID and by the chart ID CGStdGraphObj *graph_obj=this.GetStdGraphObjectExt(graph_obj_id,form.ChartID()); if(graph_obj!=NULL) { //--- Get the toolkit of an extended standard graphical object CGStdGraphObjExtToolkit *toolkit=graph_obj.GetExtToolkit(); if(toolkit!=NULL) { //--- Draw a point with a circle on the form and delete it on all other forms toolkit.DrawOneControlPoint(form); } } } } //+---------------------------------------------------------------------------------------------+ //| 'The cursor is inside the active area, any mouse button is clicked' event handler | //+---------------------------------------------------------------------------------------------+ if(mouse_state==MOUSE_FORM_STATE_INSIDE_ACTIVE_AREA_PRESSED && !move) { pressed_form=true; // the flag of holding the mouse button on the form //--- If the left mouse button is pressed if(this.m_mouse.IsPressedButtonLeft()) { //--- Set flags and form parameters move=true; // movement flag form.SetInteraction(true); // flag of the form interaction with the environment form.BringToTop(); // form on the background - above all others form.SetOffsetX(this.m_mouse.CoordX()-form.CoordX()); // Cursor shift relative to the X coordinate form.SetOffsetY(this.m_mouse.CoordY()-form.CoordY()); // Cursor shift relative to the Y coordinate this.ResetAllInteractionExeptOne(form); // Reset interaction flags for all forms except the current one //--- Get the maximum ZOrder long zmax=this.GetZOrderMax(); //--- If the maximum ZOrder has been received and the form's ZOrder is less than the maximum one or the maximum ZOrder of all forms is equal to zero if(zmax>WRONG_VALUE && (form.Zorder()<zmax || zmax==0)) { //--- If the form is not a control point for managing an extended standard graphical object, //--- set the form's ZOrder above all others if(form.Type()!=OBJECT_DE_TYPE_GFORM_CONTROL) this.SetZOrderMAX(form); } } form.OnMouseEvent(MOUSE_EVENT_INSIDE_ACTIVE_AREA_PRESSED,lparam,dparam,sparam); } //+---------------------------------------------------------------------------------------------+ //| 'The cursor is inside the active area, the mouse wheel is being scrolled' event handler | //+---------------------------------------------------------------------------------------------+ if(mouse_state==MOUSE_FORM_STATE_INSIDE_ACTIVE_AREA_WHEEL) { form.OnMouseEvent(MOUSE_EVENT_INSIDE_ACTIVE_AREA_WHEEL,lparam,dparam,sparam); } //+---------------------------------------------------------------------------------------------+ //| 'The cursor is inside the active area, the left mouse button is clicked' event handler | //+---------------------------------------------------------------------------------------------+ if(mouse_state==MOUSE_FORM_STATE_INSIDE_ACTIVE_AREA_RELEASED) { form.OnMouseEvent(MOUSE_EVENT_INSIDE_ACTIVE_AREA_RELEASED,lparam,dparam,sparam); } //+---------------------------------------------------------------------------------------------+ //| 'The cursor is inside the window scrolling area, no mouse buttons are clicked' event handler| //+---------------------------------------------------------------------------------------------+ if(mouse_state==MOUSE_FORM_STATE_INSIDE_SCROLL_AREA_NOT_PRESSED) { form.OnMouseEvent(MOUSE_EVENT_INSIDE_SCROLL_AREA_NOT_PRESSED,lparam,dparam,sparam); } //+------------------------------------------------------------------------------------------------+ //| 'The cursor is inside the window scrolling area, a mouse button is clicked (any)' event handler| //+------------------------------------------------------------------------------------------------+ if(mouse_state==MOUSE_FORM_STATE_INSIDE_SCROLL_AREA_PRESSED) { form.OnMouseEvent(MOUSE_EVENT_INSIDE_SCROLL_AREA_PRESSED,lparam,dparam,sparam); } //+--------------------------------------------------------------------------------------------------+ //| 'The cursor is inside the window scrolling area, the mouse wheel is being scrolled' event handler| //+--------------------------------------------------------------------------------------------------+ if(mouse_state==MOUSE_FORM_STATE_INSIDE_SCROLL_AREA_WHEEL) { form.OnMouseEvent(MOUSE_EVENT_INSIDE_SCROLL_AREA_WHEEL,lparam,dparam,sparam); } } } } }
ここでは、マウスボタンを離すイベントを処理するための新しいハンドラも追加します。
指定されたチャートのマウススクロール、コンテキストメニュー、十字線フラグを設定するメソッドで、すでに設定されているフラグのチェックを追加して、チャートに以前に設定された同じステータスを常に設定しないようにします。
//+------------------------------------------------------------------+ //| Set the flags of scrolling a chart | //| context menu and crosshairs for the chart | //+------------------------------------------------------------------+ void CGraphElementsCollection::SetChartTools(const long chart_id,const bool flag) { if(::ChartGetInteger(chart_id,CHART_MOUSE_SCROLL)==flag) return; ::ChartSetInteger(chart_id,CHART_MOUSE_SCROLL,flag); ::ChartSetInteger(chart_id,CHART_CONTEXT_MENU,flag); ::ChartSetInteger(chart_id,CHART_CROSSHAIR_TOOL,flag); } //+------------------------------------------------------------------+
現在、ライブラリクラスの改善はこれですべてです。
検証
テストを実行するには、前の記事のEAを\MQL5\Experts\TestDoEasy\Part110\でTestDoEasyPart110.mq5として保存します。
以前のEAのすべてのオブジェクトは「そのまま」残し、ボタンのサイズと位置を少し変更して、メソッド操作をテストするためにオブジェクトへのポインタをタイプごとに取得する機能を追加します。
トグルボタンフラグをEA入力に追加し、デフォルトパラメータを変更します。
//--- input parameters sinput bool InpMovable = true; // Panel Movable flag sinput ENUM_INPUT_YES_NO InpAutoSize = INPUT_YES; // Panel Autosize sinput ENUM_AUTO_SIZE_MODE InpAutoSizeMode = AUTO_SIZE_MODE_GROW; // Panel Autosize mode sinput ENUM_BORDER_STYLE InpFrameStyle = BORDER_STYLE_SIMPLE; // Label border style sinput ENUM_ANCHOR_POINT InpTextAlign = ANCHOR_CENTER; // Label text align sinput ENUM_INPUT_YES_NO InpTextAutoSize = INPUT_NO; // Label autosize sinput ENUM_ANCHOR_POINT InpCheckAlign = ANCHOR_LEFT; // Check flag align sinput ENUM_ANCHOR_POINT InpCheckTextAlign = ANCHOR_LEFT; // Check label text align sinput ENUM_CHEK_STATE InpCheckState = CHEK_STATE_UNCHECKED; // Check flag state sinput ENUM_INPUT_YES_NO InpCheckAutoSize = INPUT_YES; // CheckBox autosize sinput ENUM_BORDER_STYLE InpCheckFrameStyle = BORDER_STYLE_NONE; // CheckBox border style sinput ENUM_ANCHOR_POINT InpButtonTextAlign = ANCHOR_CENTER; // Button text align sinput ENUM_INPUT_YES_NO InpButtonAutoSize = INPUT_YES; // Button autosize sinput ENUM_AUTO_SIZE_MODE InpButtonAutoSizeMode= AUTO_SIZE_MODE_GROW; // Button Autosize mode sinput ENUM_BORDER_STYLE InpButtonFrameStyle = BORDER_STYLE_NONE; // Button border style sinput bool InpButtonToggle = false; // Button toggle flag //--- global variables
OnInit()ハンドラには次のコードがあります。
//+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- Set EA global variables ArrayResize(array_clr,2); // Array of gradient filling colors array_clr[0]=C'26,100,128'; // Original ≈Dark-azure color array_clr[1]=C'35,133,169'; // Lightened original color //--- Create the array with the current symbol and set it to be used in the library string array[1]={Symbol()}; engine.SetUsedSymbols(array); //--- Create the timeseries object for the current symbol and period, and show its description in the journal engine.SeriesCreate(Symbol(),Period()); engine.GetTimeSeriesCollection().PrintShort(false); // Short descriptions //--- Create WinForms Panel object CPanel *pnl=NULL; pnl=engine.CreateWFPanel("WFPanel",50,50,230,150,array_clr,200,true,true,false,-1,FRAME_STYLE_BEVEL,true,false); if(pnl!=NULL) { //--- Set Padding to 4 pnl.SetPaddingAll(4); //--- Set the flags of relocation, auto resizing and auto changing mode from the inputs pnl.SetMovable(InpMovable); pnl.SetAutoSize(InpAutoSize,false); pnl.SetAutoSizeMode((ENUM_CANV_ELEMENT_AUTO_SIZE_MODE)InpAutoSizeMode,false); //--- In the loop, create 2 bound panel objects CPanel *obj=NULL; for(int i=0;i<2;i++) { //--- create the panel object with calculated coordinates, width of 90 and height of 40 CPanel *prev=pnl.GetElement(i-1); int xb=0, yb=0; int x=(prev==NULL ? xb : xb+prev.Width()+20); int y=0; if(pnl.CreateNewElement(GRAPH_ELEMENT_TYPE_WF_PANEL,x,y,90,40,C'0xCD,0xDA,0xD7',200,true,false)) { obj=pnl.GetElement(i); if(obj==NULL) continue; obj.SetBorderSizeAll(3); obj.SetBorderStyle(FRAME_STYLE_BEVEL); obj.SetBackgroundColor(obj.ChangeColorLightness(obj.BackgroundColor(),4*i),true); obj.SetForeColor(clrRed,true); //--- Calculate the width and height of the future text label object int w=obj.Width()-obj.BorderSizeLeft()-obj.BorderSizeRight(); int h=obj.Height()-obj.BorderSizeTop()-obj.BorderSizeBottom(); //--- Create a text label object obj.CreateNewElement(GRAPH_ELEMENT_TYPE_WF_LABEL,0,0,w,h,clrNONE,255,false,false); //--- Get the pointer to a newly created object CLabel *lbl=obj.GetElement(0); if(lbl!=NULL) { //--- If the object has an even or zero index in the list, set the default text color for it if(i % 2==0) lbl.SetForeColor(CLR_DEF_FORE_COLOR,true); //--- If the object index in the list is odd, set the object opacity to 127 else lbl.SetForeColorOpacity(127); //--- Set the font Black width type and //--- specify the text alignment from the EA settings lbl.SetFontBoldType(FW_TYPE_BLACK); lbl.SetTextAlign(InpTextAlign); lbl.SetAutoSize((bool)InpTextAutoSize,false); //--- For an object with an even or zero index, specify the Bid price for the text, otherwise - the Ask price of the symbol lbl.SetText(GetPrice(i % 2==0 ? SYMBOL_BID : SYMBOL_ASK)); //--- Set the frame width, type and color for a text label and update the modified object lbl.SetBorderSizeAll(1); lbl.SetBorderStyle((ENUM_FRAME_STYLE)InpFrameStyle); lbl.SetBorderColor(CLR_DEF_BORDER_COLOR,true); lbl.Update(true); } } } //--- Create the 'GroupBox' WinForms object CGroupBox *gbox=NULL; //--- Indent from attached panels by 6 pixels is a Y coordinate for GroupBox int w=pnl.GetUnderlay().Width(); int y=obj.BottomEdgeRelative()+6; //--- If the attached GroupBox object is created if(pnl.CreateNewElement(GRAPH_ELEMENT_TYPE_WF_GROUPBOX,0,y,210,110,C'0x91,0xAA,0xAE',0,true,false)) { //--- get the pointer to the GroupBox object by its index in the list of bound GroupBox type objects gbox=pnl.GetElementByType(GRAPH_ELEMENT_TYPE_WF_GROUPBOX,0); if(gbox!=NULL) { //--- set the "indented frame" type, the frame color matches the main panel background color, //--- while the text color is the background color of the last attached panel darkened by 1 gbox.SetBorderStyle(FRAME_STYLE_STAMP); gbox.SetBorderColor(pnl.BackgroundColor(),true); gbox.SetForeColor(gbox.ChangeColorLightness(obj.BackgroundColor(),-1),true); //--- Create the CheckBox object gbox.CreateNewElement(GRAPH_ELEMENT_TYPE_WF_CHECKBOX,2,10,50,20,clrNONE,255,true,false); //--- get the pointer to the CheckBox object by its index in the list of bound CheckBox type objects CCheckBox *cbox=gbox.GetElementByType(GRAPH_ELEMENT_TYPE_WF_CHECKBOX,0); //--- If CheckBox is created and the pointer to it is received if(cbox!=NULL) { //--- Set the CheckBox parameters from the EA inputs cbox.SetAutoSize((bool)InpCheckAutoSize,false); cbox.SetCheckAlign(InpCheckAlign); cbox.SetTextAlign(InpCheckTextAlign); //--- Set the displayed text, frame style and color, as well as checkbox status cbox.SetText("CheckBox"); cbox.SetBorderStyle((ENUM_FRAME_STYLE)InpCheckFrameStyle); cbox.SetBorderColor(CLR_DEF_BORDER_COLOR,true); cbox.SetChecked(true); cbox.SetCheckState((ENUM_CANV_ELEMENT_CHEK_STATE)InpCheckState); } //--- Create the RadioButton object gbox.CreateNewElement(GRAPH_ELEMENT_TYPE_WF_RADIOBUTTON,2,cbox.BottomEdgeRelative()+4,50,20,clrNONE,255,true,false); //--- get the pointer to the RadioButton object by its index in the list of bound RadioButton type objects CRadioButton *rbtn=gbox.GetElementByType(GRAPH_ELEMENT_TYPE_WF_RADIOBUTTON,0); //--- If RadioButton is created and the pointer to it is received if(rbtn!=NULL) { //--- Set the RadioButton parameters from the EA inputs rbtn.SetAutoSize((bool)InpCheckAutoSize,false); rbtn.SetCheckAlign(InpCheckAlign); rbtn.SetTextAlign(InpCheckTextAlign); //--- Set the displayed text, frame style and color, as well as checkbox status rbtn.SetText("RadioButton"); rbtn.SetBorderStyle((ENUM_FRAME_STYLE)InpCheckFrameStyle); rbtn.SetBorderColor(CLR_DEF_BORDER_COLOR,true); rbtn.SetChecked(true); } //--- Create the Button object gbox.CreateNewElement(GRAPH_ELEMENT_TYPE_WF_BUTTON,(int)fmax(rbtn.RightEdgeRelative(),cbox.RightEdgeRelative())+10,14,60,36,clrNONE,255,true,false); //--- get the pointer to the Button object by its index in the list of bound Button type objects CButton *butt=gbox.GetElementByType(GRAPH_ELEMENT_TYPE_WF_BUTTON,0); //--- If Button is created and the pointer to it is received if(butt!=NULL) { //--- Set the Button parameters from the EA inputs butt.SetAutoSize((bool)InpButtonAutoSize,false); butt.SetAutoSizeMode((ENUM_CANV_ELEMENT_AUTO_SIZE_MODE)InpButtonAutoSizeMode,false); butt.SetTextAlign(InpButtonTextAlign); //--- Set the text color, as well as frame style and color butt.SetForeColor(butt.ChangeColorLightness(CLR_DEF_FORE_COLOR,2),true); butt.SetBorderStyle((ENUM_FRAME_STYLE)InpButtonFrameStyle); butt.SetBorderColor(butt.ChangeColorLightness(butt.BackgroundColor(),-10),true); //--- Set the 'toggle' mode depending on the settings butt.SetToggleFlag(InpButtonToggle); //--- Set the displayed text on the button depending on the 'toggle' flag if(butt.Toggle()) butt.SetText("Toggle-Button"); else butt.SetText("Button"); } } } //--- Redraw all objects according to their hierarchy pnl.Redraw(true); } //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+
実際、ここにはすべてがそのままです。ライブラリで名前が変更されたメソッドは名前変更しました。初期色を維持するためのフラグ(true)は、色を設定するメソッドで渡されるようになりました。選択されたボタンモードは、適切なボタンにテキストとして表示されるようになりました。
すべての変更は以下に添付されているファイルでご覧になれます。
EAをコンパイルし、銘柄チャートで起動します。
ご覧のとおり、マウスを操作すると、オブジェクトの視覚コンポーネント全体が正しく機能します。
次の段階
次回の記事では、ライブラリのWinFormsオブジェクトの対話性に関する作業を続けます。
**連載のこれまでの記事:
DoEasyコントロール(第1部):最初のステップ
DoEasyコントロール(第2部):CPanelクラスでの作業
DoEasyコントロール(第3部):バインドされたコントロールの作成
DoEasyコントロール(第4部):パネルコントロール、Padding、Dockパラメータ
DoEasyコントロール(第5部):WinForms基本オブジェクト、Panelコントロール、AutoSizeパラメータ
DoEasyコントロール(第6部):パネルコントロール、内部コンテンツに合わせたコンテナサイズの自動変更
DoEasy.コントロール(第7部):テキストラベルコントロール
DoEasy.コントロール(第8部):カテゴリ(GroupBoxおよびCheckBoxのコントロール)による基本WinFormsオブジェクト
DoEasy.コントロール(第9部):WinFormsオブジェクトメソッド、RadioButtonおよびButtonコントロールの再配置
MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/11173
- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索