DoEasy. 控件(第三十部分):动画态滚动条控件·进阶篇
🖱️

DoEasy. 控件(第三十部分):动画态滚动条控件·进阶篇

(2/3)· 沿用按钮基类造出独立滑块类型,把八向缩放与悬浮边框的脏活提前铺好

案例拆解 第 2/3 篇
直接拿普通按钮当滚动条滑块,事件类型混在一起,后期鼠标交互必然漏判。很多人忽略奇数像素活动区,箭头三角绘制歪斜还不自知。先把捕获区域独立成派生类,后续才不会在交互逻辑里反复返工。

◍ 鼠标事件枚举的界面分区映射

在 MT5 自定义指标或 EA 的图表交互里,鼠标状态被拆成了非常细的枚举值。光「活动区」就有 4 种:光标在内未按键、在内按下任意键、在内滚轮滚动、在内左键释放,分别对应后台监听的不同触发分支。 窗口右侧与底部的滚动区也各自挂了 3 个状态:未按键、按下任意键、滚轮滚动。这意味着你写 OnChartEvent 时,若想区分用户是在看图还是拉滚动条,可直接比对 MOUSE_EVENT_INSIDE_SCROLL_AREA_RIGHT_WHEEL 这类常量,不必自己算坐标。 缩放区更碎,顶、底、左、右、左上五个方位,每个方位又分未按键 / 按下 / 滚轮三组。合计仅缩放相关就已 15 个枚举,加上活动区与滚动区共 25 个鼠标位置态。外汇与贵金属图表波动快、拖拽频繁,这类细分对做悬浮面板工具尤其有用,但杠杆品种高风险,交互逻辑出错可能误发订单。

MQL5 / C++
  MOUSE_EVENT_INSIDE_ACTIVE_AREA_NOT_PRESSED,              class=class="str">"cmt">// The cursor is inside the active area, the mouse buttons are not clicked
  MOUSE_EVENT_INSIDE_ACTIVE_AREA_PRESSED,                  class=class="str">"cmt">// The cursor is inside the active area, any mouse button is clicked
  MOUSE_EVENT_INSIDE_ACTIVE_AREA_WHEEL,                   class=class="str">"cmt">// The cursor is inside the active area, the mouse wheel is being scrolled
  MOUSE_EVENT_INSIDE_ACTIVE_AREA_RELEASED,                class=class="str">"cmt">// The cursor is inside the active area, left mouse button is released
class=class="str">"cmt">//--- Within the window scrolling area to the right
  MOUSE_EVENT_INSIDE_SCROLL_AREA_RIGHT_NOT_PRESSED,       class=class="str">"cmt">// The cursor is within the window scrolling area to the right, the mouse buttons are not clicked
  MOUSE_EVENT_INSIDE_SCROLL_AREA_RIGHT_PRESSED,           class=class="str">"cmt">// The cursor is within the window scrolling area to the right, the mouse button(any) is clicked
  MOUSE_EVENT_INSIDE_SCROLL_AREA_RIGHT_WHEEL,             class=class="str">"cmt">// The cursor is within the window scrolling area to the right, the mouse wheel is being scrolled
class=class="str">"cmt">//--- Within the window scrolling area at the bottom
  MOUSE_EVENT_INSIDE_SCROLL_AREA_BOTTOM_NOT_PRESSED,      class=class="str">"cmt">// The cursor is within the window scrolling area at the bottom, the mouse buttons are not clicked
  MOUSE_EVENT_INSIDE_SCROLL_AREA_BOTTOM_PRESSED,          class=class="str">"cmt">// The cursor is within the window scrolling area at the bottom, the mouse button(any) is clicked
  MOUSE_EVENT_INSIDE_SCROLL_AREA_BOTTOM_WHEEL,            class=class="str">"cmt">// The cursor is within the window scrolling area at the bottom, the mouse wheel is being scrolled
class=class="str">"cmt">//--- Within the window resizing area at the top
  MOUSE_EVENT_INSIDE_RESIZE_TOP_AREA_NOT_PRESSED,         class=class="str">"cmt">// The cursor is within the window resizing area at the top, the mouse buttons are not clicked
  MOUSE_EVENT_INSIDE_RESIZE_TOP_AREA_PRESSED,             class=class="str">"cmt">// The cursor is within the window resizing area at the top, the mouse button(any) is clicked
  MOUSE_EVENT_INSIDE_RESIZE_TOP_AREA_WHEEL,               class=class="str">"cmt">// The cursor is within the window resizing area at the top, the mouse wheel is being scrolled
class=class="str">"cmt">//--- Within the window resizing area at the bottom
  MOUSE_EVENT_INSIDE_RESIZE_BOTTOM_AREA_NOT_PRESSED,      class=class="str">"cmt">// The cursor is within the window resizing area at the bottom, the mouse buttons are not clicked
  MOUSE_EVENT_INSIDE_RESIZE_BOTTOM_AREA_PRESSED,          class=class="str">"cmt">// The cursor is within the window resizing area at the bottom, the mouse button(any) is clicked
  MOUSE_EVENT_INSIDE_RESIZE_BOTTOM_AREA_WHEEL,            class=class="str">"cmt">// The cursor is within the window resizing area at the bottom, the mouse wheel is being scrolled
class=class="str">"cmt">//--- Within the window resizing area to the left
  MOUSE_EVENT_INSIDE_RESIZE_LEFT_AREA_NOT_PRESSED,        class=class="str">"cmt">// The cursor is within the window resizing area to the left, the mouse buttons are not clicked
  MOUSE_EVENT_INSIDE_RESIZE_LEFT_AREA_PRESSED,            class=class="str">"cmt">// The cursor is within the window resizing area to the left, the mouse button(any) is clicked
  MOUSE_EVENT_INSIDE_RESIZE_LEFT_AREA_WHEEL,              class=class="str">"cmt">// The cursor is within the window resizing area to the left, the mouse wheel is being scrolled
class=class="str">"cmt">//--- Within the window resizing area to the right
  MOUSE_EVENT_INSIDE_RESIZE_RIGHT_AREA_NOT_PRESSED,       class=class="str">"cmt">// The cursor is within the window resizing area to the right, the mouse buttons are not clicked
  MOUSE_EVENT_INSIDE_RESIZE_RIGHT_AREA_PRESSED,           class=class="str">"cmt">// The cursor is within the window resizing area to the right, the mouse button(any) is clicked
  MOUSE_EVENT_INSIDE_RESIZE_RIGHT_AREA_WHEEL,             class=class="str">"cmt">// The cursor is within the window resizing area to the right, the mouse wheel is being scrolled
class=class="str">"cmt">//--- Within the window resizing area to the top-left
  MOUSE_EVENT_INSIDE_RESIZE_TOP_LEFT_AREA_NOT_PRESSED,    class=class="str">"cmt">// The cursor is within the window resizing area at the top-left, the mouse buttons are not clicked
  MOUSE_EVENT_INSIDE_RESIZE_TOP_LEFT_AREA_PRESSED,        class=class="str">"cmt">// The cursor is within the window resizing area at the top-left, the mouse button(any) is clicked

鼠标事件枚举与图元类型的底层划分

在自定义控件库里,鼠标状态被拆得很细:窗口四个角的拉伸区各自分了三种状态——未按键、按住任意键、滚轮滚动。比如 MOUSE_EVENT_INSIDE_RESIZE_TOP_LEFT_AREA_WHEEL 表示光标在左上拉伸区且正在滚轮,这种粒度能让你在 EA 面板里精确区分“用户想改尺寸”还是“想滚动内容”。 控制区(CONTROL_AREA)同样有 NOT_PRESSED / PRESSED / WHEEL 三态,和四角拉伸区并列。宏 MOUSE_EVENT_NEXT_CODE 取最后一个鼠标事件码 +1,用作自定义事件分配的起点,避免和内置事件冲突。 图元类型枚举 ENUM_GRAPH_ELEMENT_TYPE 从 STANDARD 到 WF_CONTAINER 共 10 个值,其中 GRAPH_ELEMENT_TYPE_WF_CONTAINER 被注释为“下方放置的容器类对象”,说明扩展 WinForms 体系时容器需单独归类。 开 MT5 新建一个 include,把下面枚举原样贴入,编译后鼠标移到面板四角看 EventMouse 返回值,就能验证你抓到的事件码是否和定义一一对应。外汇与贵金属界面定制属高风险开发,事件误判可能导致下单面板失控。

MQL5 / C++
  MOUSE_EVENT_INSIDE_RESIZE_TOP_LEFT_AREA_WHEEL,        class=class="str">"cmt">// The cursor is within the window resizing area at the top-left, the mouse wheel is being scrolled
class=class="str">"cmt">//--- Within the window resizing area to the top-right
  MOUSE_EVENT_INSIDE_RESIZE_TOP_RIGHT_AREA_NOT_PRESSED,class=class="str">"cmt">// The cursor is within the window resizing area at the top-right, the mouse buttons are not clicked
  MOUSE_EVENT_INSIDE_RESIZE_TOP_RIGHT_AREA_PRESSED,   class=class="str">"cmt">// The cursor is within the window resizing area at the top-right, the mouse button(any) is clicked
  MOUSE_EVENT_INSIDE_RESIZE_TOP_RIGHT_AREA_WHEEL,     class=class="str">"cmt">// The cursor is within the window resizing area at the top-right, the mouse wheel is being scrolled
class=class="str">"cmt">//--- Within the window resizing area at the bottom left
  MOUSE_EVENT_INSIDE_RESIZE_BOTTOM_LEFT_AREA_NOT_PRESSED,class=class="str">"cmt">// The cursor is within the window resizing area at the bottom-left, the mouse buttons are not clicked
  MOUSE_EVENT_INSIDE_RESIZE_BOTTOM_LEFT_AREA_PRESSED,class=class="str">"cmt">// The cursor is within the window resizing area at the bottom-left, the mouse button(any) is clicked
  MOUSE_EVENT_INSIDE_RESIZE_BOTTOM_LEFT_AREA_WHEEL,  class=class="str">"cmt">// The cursor is within the window resizing area at the bottom-left, the mouse wheel is being scrolled
class=class="str">"cmt">//--- Within the window resizing area at the bottom-right
  MOUSE_EVENT_INSIDE_RESIZE_BOTTOM_RIGHT_AREA_NOT_PRESSED,class=class="str">"cmt">// The cursor is within the window resizing area at the bottom-right, the mouse buttons are not clicked
  MOUSE_EVENT_INSIDE_RESIZE_BOTTOM_RIGHT_AREA_PRESSED,class=class="str">"cmt">// The cursor is within the window resizing area at the bottom-right, the mouse button(any) is clicked
  MOUSE_EVENT_INSIDE_RESIZE_BOTTOM_RIGHT_AREA_WHEEL, class=class="str">"cmt">// The cursor is within the window resizing area at the bottom-right, the mouse wheel is being scrolled
class=class="str">"cmt">//--- Within the control area
  MOUSE_EVENT_INSIDE_CONTROL_AREA_NOT_PRESSED,        class=class="str">"cmt">// The cursor is within the control area, the mouse buttons are not clicked
  MOUSE_EVENT_INSIDE_CONTROL_AREA_PRESSED,            class=class="str">"cmt">// The cursor is within the control area, the mouse button(any) is clicked
  MOUSE_EVENT_INSIDE_CONTROL_AREA_WHEEL,              class=class="str">"cmt">// The cursor is within the control area, the mouse wheel is being scrolled
  };
class="macro">#define MOUSE_EVENT_NEXT_CODE(MOUSE_EVENT_INSIDE_CONTROL_AREA_WHEEL+class="num">1)   class=class="str">"cmt">// The code of the next event after the last mouse event code
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//+--------------------------------------------+
class=class="str">"cmt">//| The list of graphical element types         |
class=class="str">"cmt">//+--------------------------------------------+
enum ENUM_GRAPH_ELEMENT_TYPE
  {
  GRAPH_ELEMENT_TYPE_STANDARD,                      class=class="str">"cmt">// Standard graphical object
  GRAPH_ELEMENT_TYPE_STANDARD_EXTENDED,             class=class="str">"cmt">// Extended standard graphical object
  GRAPH_ELEMENT_TYPE_SHADOW_OBJ,                    class=class="str">"cmt">// Shadow object
  GRAPH_ELEMENT_TYPE_ELEMENT,                       class=class="str">"cmt">// Element
  GRAPH_ELEMENT_TYPE_FORM,                          class=class="str">"cmt">// Form
  GRAPH_ELEMENT_TYPE_WINDOW,                        class=class="str">"cmt">// Window
  class=class="str">"cmt">//--- WinForms
  GRAPH_ELEMENT_TYPE_WF_UNDERLAY,                  class=class="str">"cmt">// Panel object underlay
  GRAPH_ELEMENT_TYPE_WF_BASE,                      class=class="str">"cmt">// Windows Forms Base
  class=class="str">"cmt">//--- &class="macro">#x27;Container&class="macro">#x27; object types are to be set below
  GRAPH_ELEMENT_TYPE_WF_CONTAINER,                 class=class="str">"cmt">// Windows Forms container base object

「WinForms 图形元素枚举的容器与控件分支」

在 MT5 的图形库底层,GRAPH_ELEMENT_TYPE 枚举把 WinForms 风格的界面元素拆成了容器类、标准控件类与辅助元素类三层。上面这段代码只列了其中一部分:先出现的是 Panel、GroupBox、TabControl、SplitContainer 这四类容器,注释里写明了它们是 Windows Forms 的对应组件。 紧接着的 WF_COMMON_BASE 是标准控件的基类,其下挂了 Label、Button、CheckBox、RadioButton 等常用件,以及 ListBox 系列(含 CheckedListBox、ButtonListBox)和 ToolTip、ProgressBar。这类枚举值在你用标准库画面板时,会决定 CGraphElement 派生类实际构造出什么控件。 最后的辅助元素段容易被忽略:ListBoxItem、TabHeader、TabField、Splitter、四个方向的 ArrowButton 以及左右/上下箭头组合框,都是容器或列表控件的子部件。调界面样式时若发现某箭头不响应,先确认是不是漏判了 WF_ARROW_BUTTON_RIGHT 这类细分类型,而不是去改主按钮逻辑。

MQL5 / C++
  GRAPH_ELEMENT_TYPE_WF_PANEL,                                            class=class="str">"cmt">// Windows Forms Panel
  GRAPH_ELEMENT_TYPE_WF_GROUPBOX,                                          class=class="str">"cmt">// Windows Forms GroupBox
  GRAPH_ELEMENT_TYPE_WF_TAB_CONTROL,                                      class=class="str">"cmt">// Windows Forms TabControl
  GRAPH_ELEMENT_TYPE_WF_SPLIT_CONTAINER,                                   class=class="str">"cmt">// Windows Forms SplitContainer
  class=class="str">"cmt">//--- &class="macro">#x27;Standard control&class="macro">#x27; object types are to be set below
  GRAPH_ELEMENT_TYPE_WF_COMMON_BASE,                                       class=class="str">"cmt">// Windows Forms base standard control
  GRAPH_ELEMENT_TYPE_WF_LABEL,                                             class=class="str">"cmt">// Windows Forms Label
  GRAPH_ELEMENT_TYPE_WF_BUTTON,                                            class=class="str">"cmt">// Windows Forms Button
  GRAPH_ELEMENT_TYPE_WF_CHECKBOX,                                          class=class="str">"cmt">// Windows Forms CheckBox
  GRAPH_ELEMENT_TYPE_WF_RADIOBUTTON,                                       class=class="str">"cmt">// Windows Forms RadioButton
  GRAPH_ELEMENT_TYPE_WF_ELEMENTS_LIST_BOX,                                 class=class="str">"cmt">// Base list object of Windows Forms elements
  GRAPH_ELEMENT_TYPE_WF_LIST_BOX,                                          class=class="str">"cmt">// Windows Forms ListBox
  GRAPH_ELEMENT_TYPE_WF_CHECKED_LIST_BOX,                                  class=class="str">"cmt">// Windows Forms CheckedListBox
  GRAPH_ELEMENT_TYPE_WF_BUTTON_LIST_BOX,                                   class=class="str">"cmt">// Windows Forms ButtonListBox
  GRAPH_ELEMENT_TYPE_WF_TOOLTIP,                                           class=class="str">"cmt">// Windows Forms ToolTip
  GRAPH_ELEMENT_TYPE_WF_PROGRESS_BAR,                                      class=class="str">"cmt">// Windows Forms ProgressBar
  class=class="str">"cmt">//--- Auxiliary elements of WinForms objects
  GRAPH_ELEMENT_TYPE_WF_LIST_BOX_ITEM,                                     class=class="str">"cmt">// Windows Forms ListBoxItem
  GRAPH_ELEMENT_TYPE_WF_TAB_HEADER,                                        class=class="str">"cmt">// Windows Forms TabHeader
  GRAPH_ELEMENT_TYPE_WF_TAB_FIELD,                                         class=class="str">"cmt">// Windows Forms TabField
  GRAPH_ELEMENT_TYPE_WF_SPLIT_CONTAINER_PANEL,                             class=class="str">"cmt">// Windows Forms SplitContainerPanel
  GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON,                                      class=class="str">"cmt">// Windows Forms ArrowButton
  GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_UP,                                    class=class="str">"cmt">// Windows Forms UpArrowButton
  GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_DOWN,                                  class=class="str">"cmt">// Windows Forms DownArrowButton
  GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_LEFT,                                 class=class="str">"cmt">// Windows Forms LeftArrowButton
  GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_RIGHT,                                class=class="str">"cmt">// Windows Forms RightArrowButton
  GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTONS_UD_BOX,                             class=class="str">"cmt">// Windows Forms UpDownArrowButtonsBox
  GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTONS_LR_BOX,                             class=class="str">"cmt">// Windows Forms LeftRightArrowButtonsBox
  GRAPH_ELEMENT_TYPE_WF_SPLITTER,                                          class=class="str">"cmt">// Windows Forms Splitter
  GRAPH_ELEMENT_TYPE_WF_HINT_BASE,                                         class=class="str">"cmt">// Windows Forms HintBase
  GRAPH_ELEMENT_TYPE_WF_HINT_MOVE_LEFT                                     class=class="str">"cmt">// Windows Forms HintMoveLeft

◍ 画布控件的枚举与整型属性边界

在 MT5 自定义图形界面开发里,图形元素类型用一组 GRAPH_ELEMENT_TYPE_WF_* 枚举区分,从 HintMove 系列到 ScrollBar 垂直/水平变体,覆盖了 Windows Forms 风格控件的映射。其中 GRAPH_ELEMENT_TYPE_WF_SCROLL_BAR_THUMB 专门指代滚动条的可拖拽滑块区域,做自定义面板交互时要单独处理它的命中检测。 整型属性枚举 ENUM_CANV_ELEMENT_PROP_INTEGER 从 CANV_ELEMENT_PROP_ID=0 起步,顺次定义类型、Z 轴顺序、可用性与可缩放标志(CANV_ELEMENT_PROP_RESIZABLE)、文字色与透明度,再到进度条当前值与跑马灯动画速度、按钮箭头尺寸(CANV_ELEMENT_PROP_BUTTON_ARROW_SIZE)。这些属性直接决定控件在画布上的响应逻辑。 宏定义给出硬上限:CANV_ELEMENT_PROP_INTEGER_TOTAL 为 140,即整型属性总数固定为 140 个;CANV_ELEMENT_PROP_INTEGER_SKIP 为 0,说明没有预留不参与排序的属性槽。开 MT5 头文件搜这两个宏,能确认你用的终端版本是否与之一致。 消息侧枚举 MSG_GRAPH_ELEMENT_TYPE_WF_SCROLL_BAR_THUMB 对应滚动条捕获区事件,和前面的类型枚举成对出现。写 CCanvas 派生类时,若漏掉 Thumb 消息分支,拖拽滚动条会静默失效。

MQL5 / C++
enum ENUM_CANV_ELEMENT_PROP_INTEGER
  {
  CANV_ELEMENT_PROP_ID = class="num">0,                 class=class="str">"cmt">// Element ID
  CANV_ELEMENT_PROP_TYPE,                   class=class="str">"cmt">// Graphical element type
  CANV_ELEMENT_PROP_ZORDER,                 class=class="str">"cmt">// Priority of a graphical object for receiving the event of clicking on a chart
  CANV_ELEMENT_PROP_ENABLED,                class=class="str">"cmt">// Element availability flag
  CANV_ELEMENT_PROP_RESIZABLE,              class=class="str">"cmt">// Resizable element flag
  CANV_ELEMENT_PROP_FORE_COLOR,             class=class="str">"cmt">// Default text class="type">color for all control objects
  CANV_ELEMENT_PROP_FORE_COLOR_OPACITY,     class=class="str">"cmt">// Default text class="type">color opacity for all control objects
  CANV_ELEMENT_PROP_PROGRESS_BAR_VALUE,     class=class="str">"cmt">// Current ProgressBar value from Min to Max
  CANV_ELEMENT_PROP_PROGRESS_BAR_MARQUEE_ANIM_SPEED, class=class="str">"cmt">// Progress bar animation speed in case of Marquee style
  CANV_ELEMENT_PROP_BUTTON_ARROW_SIZE,      class=class="str">"cmt">// Size of the arrow drawn on the button
  };
class="macro">#define CANV_ELEMENT_PROP_INTEGER_TOTAL(class="num">140)      class=class="str">"cmt">// Total number of integer properties
class="macro">#define CANV_ELEMENT_PROP_INTEGER_SKIP(class="num">0)        class=class="str">"cmt">// Number of integer properties not used in sorting

GUI 控件属性枚举与类型描述函数

在 MT5 自定义图形界面库里,滚动条、进度条、按钮箭头等控件都有一套内部消息枚举来做多语言描述。下面这段枚举定义了垂直/水平滚动条、控件显示时长、是否可用、是否可缩放、前景色及透明度、进度条当前值与 Marquee 动画速度、按钮箭头尺寸等属性标识。 其中 MSG_CANV_ELEMENT_PROP_RESIZABLE 控制元素能否被用户拖拽改尺寸,MSG_CANV_ELEMENT_PROP_BUTTON_ARROW_SIZE 则决定按钮上绘制箭头的像素大小——这两个在实盘面板里最常调。 紧随其后的字符串数组把俄文与英文描述成对,例如 "Элемент управления ScrollBar" 对应 "Control element ScrollBar","Флаг изменяемости размеров элемента" 对应 "Element Resizable flag",本地化时直接改这套映射即可。 类型描述由 CGBaseObj::TypeElementDescription 按 ENUM_GRAPH_ELEMENT_TYPE 分支返回对应文本,用三元运算符逐级判断,从 GRAPH_ELEMENT_TYPE_STANDARD 到 GRAPH_ELEMENT_TYPE_ELEMENT 依次匹配 CMessage::Text 取描述。 开 MT5 把这段枚举和函数塞进你的 EA 面板基类,改 MSG_CANV_ELEMENT_PROP_BUTTON_ARROW_SIZE 对应的描述或数值,编译后能在控件上直观看到箭头粗细变化。外汇与贵金属界面开发同样受平台稳定性约束,修改后需在策略测试器里验证无报错。

MQL5 / C++
  MSG_GRAPH_ELEMENT_TYPE_WF_SCROLL_BAR_VERTICAL,       class=class="str">"cmt">// ScrollBarVertical control
  MSG_GRAPH_ELEMENT_TYPE_WF_SCROLL_BAR_HORISONTAL,     class=class="str">"cmt">// ScrollBarHorisontal control
  MSG_CANV_ELEMENT_PROP_DISPLAY_DURATION,              class=class="str">"cmt">// Control display duration
  MSG_CANV_ELEMENT_PROP_ENABLED,                       class=class="str">"cmt">// Element availability flag
  MSG_CANV_ELEMENT_PROP_RESIZABLE,                     class=class="str">"cmt">// Control size changeability flag
  MSG_CANV_ELEMENT_PROP_FORE_COLOR,                    class=class="str">"cmt">// Default text class="type">color for all control objects
  MSG_CANV_ELEMENT_PROP_FORE_COLOR_OPACITY,            class=class="str">"cmt">// Default text class="type">color opacity for all control objects
  MSG_CANV_ELEMENT_PROP_PROGRESS_BAR_VALUE,            class=class="str">"cmt">// Current ProgressBar value from Min to Max
  MSG_CANV_ELEMENT_PROP_PROGRESS_BAR_MARQUEE_ANIM_SPEED,class=class="str">"cmt">// Progress bar animation speed in case of Marquee style
  MSG_CANV_ELEMENT_PROP_BUTTON_ARROW_SIZE,             class=class="str">"cmt">// Size of the arrow drawn on the button
class=class="str">"cmt">//--- Real properties of graphical elements
class=class="str">"cmt">//--- String properties of graphical elements
  {"Элемент управления \"ProgressBar\"","Control element \"ProgressBar\""},
  {"Элемент управления \"ScrollBar\"","Control element \"ScrollBar\""},
  {"Область захвата элемента управления \"ScrollBar\"","The grip area of the \"ScrollBar\" control"},
  {"Элемент управления \"ScrollBarVertical\"","Control element \"ScrollBarVertical\""},
  {"Элемент управления \"ScrollBarHorisontal\"","Control element \"ScrollBarHorisontal\""},
  {"Продолжительность процесса отображения элемента управления","Duration of the process of displaying the control"},
  {"Флаг доступности элемента","Element Availability flag"},
  {"Флаг изменяемости размеров элемента","Element Resizable flag"},
  {"Цвет текста по умолчанию для всех объектов элемента управления","Default text class="type">color for all objects in the control"},
  {"Непрозрачность цвета текста по умолчанию для всех объектов элемента управления","Default text class="type">color opacity for all objects in the control"},
  {"Текущее начение элемента ProgressBar в диапазоне от Min до Max","Current value of the ProgressBar in the range from Min to Max"},
  {"Скорость анимации полосы прогресса при стиле Marquee","Marquee style progress bar animation speed"},
  {"Размер стрелки, рисуемой на кнопке","Size of arrow drawn on the button"},
class=class="str">"cmt">//--- String properties of graphical elements
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| Return the description of the graphical element type             |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">class="kw">string CGBaseObj::TypeElementDescription(const ENUM_GRAPH_ELEMENT_TYPE type)
  {
   class="kw">return
     (
       type==GRAPH_ELEMENT_TYPE_STANDARD                 ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_STANDARD)               :
       type==GRAPH_ELEMENT_TYPE_STANDARD_EXTENDED        ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_STANDARD_EXTENDED)     :
       type==GRAPH_ELEMENT_TYPE_ELEMENT                 ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_ELEMENT)               :

「图形元素类型的字符串映射写法」

在 MT5 自定义指标或 EA 的 GUI 调试里,经常需要把枚举型 type 转成可读文本。上面这段三元表达式链就是典型做法:按 GRAPH_ELEMENT_TYPE_* 逐一比对,命中后调 CMessage::Text() 取对应多语言文案。 从片段能看到分层逻辑——先处理基础图元(SHADOW_OBJ、FORM、WINDOW),再切到 WinForms 体系:底层 UNDERLAY / BASE,容器类 CONTAINER / GROUPBOX / PANEL / TAB_CONTROL / SPLIT_CONTAINER,最后是标准控件 LABEL、CHECKBOX、RADIOBUTTON、BUTTON 及各种 LIST_BOX 变体。 这种写法没有 default 分支收口,若传入未列出的类型会返回空串,调试时容易漏看。开 MT5 把这段塞进 GraphElementTypeToString() 之类的辅助函数,断点跑一遍就能确认自己面板对象落在哪一类。

MQL5 / C++
type==GRAPH_ELEMENT_TYPE_SHADOW_OBJ ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_SHADOW_OBJ) :
type==GRAPH_ELEMENT_TYPE_FORM ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_FORM) :
type==GRAPH_ELEMENT_TYPE_WINDOW ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WINDOW) :
class=class="str">"cmt">//--- WinForms
type==GRAPH_ELEMENT_TYPE_WF_UNDERLAY ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_UNDERLAY) :
type==GRAPH_ELEMENT_TYPE_WF_BASE ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_BASE) :
class=class="str">"cmt">//--- Containers
type==GRAPH_ELEMENT_TYPE_WF_CONTAINER ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_CONTAINER) :
type==GRAPH_ELEMENT_TYPE_WF_GROUPBOX ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_GROUPBOX) :
type==GRAPH_ELEMENT_TYPE_WF_PANEL ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_PANEL) :
type==GRAPH_ELEMENT_TYPE_WF_TAB_CONTROL ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_TAB_CONTROL) :
type==GRAPH_ELEMENT_TYPE_WF_SPLIT_CONTAINER ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_SPLIT_CONTAINER) :
class=class="str">"cmt">//--- Standard controls
type==GRAPH_ELEMENT_TYPE_WF_COMMON_BASE ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_COMMON_BASE) :
type==GRAPH_ELEMENT_TYPE_WF_LABEL ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_LABEL) :
type==GRAPH_ELEMENT_TYPE_WF_CHECKBOX ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_CHECKBOX) :
type==GRAPH_ELEMENT_TYPE_WF_RADIOBUTTON ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_RADIOBUTTON) :
type==GRAPH_ELEMENT_TYPE_WF_BUTTON ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_BUTTON) :
type==GRAPH_ELEMENT_TYPE_WF_ELEMENTS_LIST_BOX ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_ELEMENTS_LIST_BOX) :
type==GRAPH_ELEMENT_TYPE_WF_LIST_BOX ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_LIST_BOX) :
type==GRAPH_ELEMENT_TYPE_WF_LIST_BOX_ITEM ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_LIST_BOX_ITEM) :
type==GRAPH_ELEMENT_TYPE_WF_CHECKED_LIST_BOX ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_CHECKED_LIST_BOX) :
type==GRAPH_ELEMENT_TYPE_WF_BUTTON_LIST_BOX ? CMessage::Text(MSG_GRAPH_ELEMENT_TYPE_WF_BUTTON_LIST_BOX) :
把鼠标状态枚举交给小布盯盘校验
八向缩放与悬浮边框的状态常量容易漏写,这些诊断小布盯盘的 AIGC 已内置,打开对应品种页即可看到差异提示,你专注控件行为本身。

常见问题

派生能继承按钮已有属性与绘制逻辑,只需追加唯一对象类型和滑块事件处理,避免重复造轮子,也方便统一管理层级。
可以,小布盯盘内置的 AIGC 诊断能比对枚举覆盖情况,标出未定义的边角缩放状态,减少手动核对成本。
11 像素总宽减两侧各 1 像素边框剩 9 像素,奇数能绕中心轴均匀绘制箭头三角,造型对称不偏色。
通常先判边角再判四边,右下角等重叠区归属可在捕获区域类里用优先级常量控制,具体见本篇测试节。