DoEasy. 控件 (第 21 部分): SplitContainer 控件 面板隔板·进阶篇
🧩

DoEasy. 控件 (第 21 部分): SplitContainer 控件 面板隔板·进阶篇

(2/3)· MQL5 原生不支持光标变形,如何用阴影区模拟可拖拽隔板并实时改尺寸

含代码示例实战向 第 2/3 篇
很多交易终端面板布局写死,想按屏幕随时调比例却卡在 MQL5 无法改鼠标光标。硬等官方 API 只会拖慢你的 UI 迭代,其实用阴影覆盖就能绕开限制。

◍ 画布控件的坐标与滚动区枚举拆解

在 MT5 自定义画布 UI 里,图形元素不止有可见区域,还划分了控制区与双向滚动区。下面这段枚举把整数属性从 ID、类型一路列到边框与滚动区尺寸,是后续写面板必须对照的底层字段表。 先看清事件码衔接:最后一个图形元素事件之后,用 WF_CONTROL_EVENT_SPLITTER_MOVE+1 定义下一个事件码,保证自定义事件不与原生事件冲突。分隔条方向则单独用 ENUM_CANV_ELEMENT_SPLITTER_ORIENTATION 区分纵向与横向两种布局。 整数属性枚举 ENUM_CANV_ELEMENT_PROP_INTEGER 中,CANV_ELEMENT_PROP_ID=0 打头,紧接 TYPE;中段出现 VISIBLE_AREA_WIDTH / HEIGHT 控制裁剪范围。后半段高密度出现 CONTROL_AREA_X/Y/WIDTH/HEIGHT 与右、下两个滚动区各四项坐标尺寸,以及 LEFT 边框宽度——这些正是鼠标命中测试和拖拽响应的判断依据。 开 MT5 新建 canvas 面板时,直接抄这套枚举命名,能少踩一半坐标错乱的坑;外汇与贵金属图表上挂此类 EA 前请记得,自定义 UI 失控可能引发误触下单,属高风险操作。

MQL5 / C++
class="macro">#define WF_CONTROL_EVENTS_NEXT_CODE(WF_CONTROL_EVENT_SPLITTER_MOVE+class="num">1)   class=class="str">"cmt">// The code of the next event after the last graphical element event code
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| Separator location in Split Container                              |
class=class="str">"cmt">//+------------------------------------------------------------------+
enum ENUM_CANV_ELEMENT_SPLITTER_ORIENTATION
  {
   CANV_ELEMENT_SPLITTER_ORIENTATION_VERTICAL,        class=class="str">"cmt">// Vertical
   CANV_ELEMENT_SPLITTER_ORIENTATION_HORISONTAL,      class=class="str">"cmt">// Horizontal
  };
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| Integer properties of the graphical element on the canvas          |
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| Integer properties of the graphical element on the canvas          |
class=class="str">"cmt">//+------------------------------------------------------------------+
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
class=class="str">"cmt">//---...
class=class="str">"cmt">//---...
   CANV_ELEMENT_PROP_VISIBLE_AREA_WIDTH,              class=class="str">"cmt">// Visibility scope width
   CANV_ELEMENT_PROP_VISIBLE_AREA_HEIGHT,             class=class="str">"cmt">// Visibility scope height
   CANV_ELEMENT_PROP_CONTROL_AREA_X,                  class=class="str">"cmt">// Control area X coordinate
   CANV_ELEMENT_PROP_CONTROL_AREA_Y,                  class=class="str">"cmt">// Control area Y coordinate
   CANV_ELEMENT_PROP_CONTROL_AREA_WIDTH,              class=class="str">"cmt">// Control area width
   CANV_ELEMENT_PROP_CONTROL_AREA_HEIGHT,             class=class="str">"cmt">// Control area height
   CANV_ELEMENT_PROP_SCROLL_AREA_X_RIGHT,             class=class="str">"cmt">// Right scroll area X coordinate
   CANV_ELEMENT_PROP_SCROLL_AREA_Y_RIGHT,             class=class="str">"cmt">// Right scroll area Y coordinate
   CANV_ELEMENT_PROP_SCROLL_AREA_WIDTH_RIGHT,         class=class="str">"cmt">// Right scroll area width
   CANV_ELEMENT_PROP_SCROLL_AREA_HEIGHT_RIGHT,        class=class="str">"cmt">// Right scroll area height
   CANV_ELEMENT_PROP_SCROLL_AREA_X_BOTTOM,            class=class="str">"cmt">// Bottom scroll area X coordinate
   CANV_ELEMENT_PROP_SCROLL_AREA_Y_BOTTOM,            class=class="str">"cmt">// Bottom scroll area Y coordinate
   CANV_ELEMENT_PROP_SCROLL_AREA_WIDTH_BOTTOM,        class=class="str">"cmt">// Bottom scroll area width
   CANV_ELEMENT_PROP_SCROLL_AREA_HEIGHT_BOTTOM,       class=class="str">"cmt">// Bottom scroll area height
   CANV_ELEMENT_PROP_BORDER_LEFT_AREA_WIDTH,          class=class="str">"cmt">// Left edge area width

画布控件枚举里的边距与分隔条属性

在 MT5 自定义画布(Canvas)框架里,图形元素的整数属性枚举覆盖边框可点击区域、显示标志以及分隔容器参数。下面这几行直接定义了底部、右侧、顶部边缘区域的宽度,以及分隔条的距离、宽度和方向: CANV_ELEMENT_PROP_BORDER_BOTTOM_AREA_WIDTH, // 底部边缘区域宽度 CANV_ELEMENT_PROP_BORDER_RIGHT_AREA_WIDTH, // 右侧边缘区域宽度 CANV_ELEMENT_PROP_BORDER_TOP_AREA_WIDTH, // 顶部边缘区域宽度 CANV_ELEMENT_PROP_SPLIT_CONTAINER_SPLITTER_DISTANCE, // 边缘到分隔条的距离 CANV_ELEMENT_PROP_SPLIT_CONTAINER_SPLITTER_WIDTH, // 分隔条宽度 CANV_ELEMENT_PROP_SPLIT_CONTAINER_SPLITTER_ORIENTATION, // 分隔条位置 宏定义给出整数属性总数为 122(CANV_ELEMENT_PROP_INTEGER_TOTAL),不参与排序的跳过数为 0。据此可推算首个双精度属性索引 FIRST_CANV_ELEMENT_DBL_PROP = 122,首个字符串属性索引在此基础上再加双精度总数减跳过数。 排序枚举 ENUM_SORT_CANV_ELEMENT_MODE 支持按控件区域坐标与尺寸排列,例如 SORT_BY_CANV_ELEMENT_CONTROL_AREA_X/Y/WIDTH/HEIGHT 以及右侧滚动区坐标。实盘做面板布局时,依据这些枚举对元素排序,可能让重叠控件的点击命中更可控;外汇与贵金属图表插件开发属高风险改造,建议先在策略测试器沙盘验证。

MQL5 / C++
CANV_ELEMENT_PROP_BORDER_BOTTOM_AREA_WIDTH,           class=class="str">"cmt">// Bottom edge area width
CANV_ELEMENT_PROP_BORDER_RIGHT_AREA_WIDTH,            class=class="str">"cmt">// Right edge area width
CANV_ELEMENT_PROP_BORDER_TOP_AREA_WIDTH,              class=class="str">"cmt">// Upper edge area width
CANV_ELEMENT_PROP_DISPLAYED,                          class=class="str">"cmt">// Non-hidden control display flag
CANV_ELEMENT_PROP_GROUP,                              class=class="str">"cmt">// Group the graphical element belongs to
CANV_ELEMENT_PROP_SPLIT_CONTAINER_SPLITTER_DISTANCE,  class=class="str">"cmt">// Distance from edge to separator
CANV_ELEMENT_PROP_SPLIT_CONTAINER_SPLITTER_WIDTH,     class=class="str">"cmt">// Separator width
CANV_ELEMENT_PROP_SPLIT_CONTAINER_SPLITTER_ORIENTATION, class=class="str">"cmt">// Separator location
CANV_ELEMENT_PROP_SPLIT_CONTAINER_PANEL1_COLLAPSED,   class=class="str">"cmt">// Flag for collapsed panel class="num">1
CANV_ELEMENT_PROP_SPLIT_CONTAINER_PANEL1_MIN_SIZE,    class=class="str">"cmt">// Panel class="num">1 minimum size
CANV_ELEMENT_PROP_SPLIT_CONTAINER_PANEL2_COLLAPSED,   class=class="str">"cmt">// Flag for collapsed panel class="num">2
CANV_ELEMENT_PROP_SPLIT_CONTAINER_PANEL2_MIN_SIZE,    class=class="str">"cmt">// Panel class="num">2 minimum size
};
class="macro">#define CANV_ELEMENT_PROP_INTEGER_TOTAL(class="num">122)          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
class="macro">#define FIRST_CANV_ELEMENT_DBL_PROP(CANV_ELEMENT_PROP_INTEGER_TOTAL-CANV_ELEMENT_PROP_INTEGER_SKIP)
class="macro">#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_CANV_ELEMENT_ID = class="num">0,
  SORT_BY_CANV_ELEMENT_TYPE,
  SORT_BY_CANV_ELEMENT_VISIBLE_AREA_WIDTH,
  SORT_BY_CANV_ELEMENT_VISIBLE_AREA_HEIGHT,
  SORT_BY_CANV_ELEMENT_CONTROL_AREA_X,
  SORT_BY_CANV_ELEMENT_CONTROL_AREA_Y,
  SORT_BY_CANV_ELEMENT_CONTROL_AREA_WIDTH,
  SORT_BY_CANV_ELEMENT_CONTROL_AREA_HEIGHT,
  SORT_BY_CANV_ELEMENT_SCROLL_AREA_X_RIGHT,
  SORT_BY_CANV_ELEMENT_SCROLL_AREA_Y_RIGHT,
  };

「Canvas 元素排序枚举的隐藏字段」

在 MQL5 的 CCanvas 图形库里,元素排序枚举 ENUM_CANV_ELEMENT_SORT 远不止按坐标和尺寸排。上面这组高亮与未高亮的常量,覆盖了滚动区、边框区、分隔容器以及字符串属性四类维度,开 MT5 搜 SORT_BY_CANV_ELEMENT 能直接看到完整列表。 比如 SORT_BY_CANV_ELEMENT_SCROLL_AREA_WIDTH_RIGHT 是按右侧滚动区宽度排序,SORT_BY_CANV_ELEMENT_BORDER_TOP_AREA_WIDTH 是按上边缘区宽度排序;分隔容器相关还有 SORT_BY_CANV_ELEMENT_SPLIT_CONTAINER_SPLITTER_ORIENTATION 按分隔条方位排,以及 PANEL1_MIN_SIZE / PANEL2_MIN_SIZE 按面板最小尺寸排。 字符串类排序从 FIRST_CANV_ELEMENT_STR_PROP 起算:SORT_BY_CANV_ELEMENT_NAME_OBJ 按对象名、SORT_BY_CANV_ELEMENT_TEXT 按元素文本、SORT_BY_CANV_ELEMENT_DESCRIPTION 按描述排。写自定义面板时若要对齐多个控件,改一个排序枚举就能重排层级,不用手算坐标。 顺带一提,MSG_LIB_TEXT_TOP / BOTTOM / LEFT / RIGHT 这组是库内方位文本宏,常和上面的排序逻辑配合做界面标注,不属于排序枚举本身但同文件紧邻。

MQL5 / C++
SORT_BY_CANV_ELEMENT_SCROLL_AREA_WIDTH_RIGHT,      class=class="str">"cmt">// Sort by right scroll area width
SORT_BY_CANV_ELEMENT_SCROLL_AREA_HEIGHT_RIGHT,     class=class="str">"cmt">// Sort by right scroll area height
SORT_BY_CANV_ELEMENT_SCROLL_AREA_X_BOTTOM,         class=class="str">"cmt">// Sort by bottom scroll area X coordinate
SORT_BY_CANV_ELEMENT_SCROLL_AREA_Y_BOTTOM,         class=class="str">"cmt">// Sort by bottom scroll area Y coordinate
SORT_BY_CANV_ELEMENT_SCROLL_AREA_WIDTH_BOTTOM,     class=class="str">"cmt">// Sort by bottom scroll area width
SORT_BY_CANV_ELEMENT_SCROLL_AREA_HEIGHT_BOTTOM,    class=class="str">"cmt">// Sort by bottom scroll area height
SORT_BY_CANV_ELEMENT_BORDER_LEFT_AREA_WIDTH,       class=class="str">"cmt">// Sort by left edge area width
SORT_BY_CANV_ELEMENT_BORDER_BOTTOM_AREA_WIDTH,     class=class="str">"cmt">// Sort by bottom edge area width
SORT_BY_CANV_ELEMENT_BORDER_RIGHT_AREA_WIDTH,      class=class="str">"cmt">// Sort by right edge area width
SORT_BY_CANV_ELEMENT_BORDER_TOP_AREA_WIDTH,        class=class="str">"cmt">// Sort by upper edge area width
SORT_BY_CANV_ELEMENT_DISPLAYED,                    class=class="str">"cmt">// Sort by non-hidden control display flag
SORT_BY_CANV_ELEMENT_GROUP,                        class=class="str">"cmt">// Sort by a group the graphical element belongs to
SORT_BY_CANV_ELEMENT_SPLIT_CONTAINER_SPLITTER_DISTANCE, class=class="str">"cmt">// Sort by distance from edge to separator
SORT_BY_CANV_ELEMENT_SPLIT_CONTAINER_SPLITTER_WIDTH,    class=class="str">"cmt">// Sort by separator width
SORT_BY_CANV_ELEMENT_SPLIT_CONTAINER_SPLITTER_ORIENTATION, class=class="str">"cmt">// Sort by separator location
SORT_BY_CANV_ELEMENT_SPLIT_CONTAINER_PANEL1_COLLAPSED,   class=class="str">"cmt">// Sort by flag for collapsed panel class="num">1
SORT_BY_CANV_ELEMENT_SPLIT_CONTAINER_PANEL1_MIN_SIZE,    class=class="str">"cmt">// Sort by panel class="num">1 minimum size
SORT_BY_CANV_ELEMENT_SPLIT_CONTAINER_PANEL2_COLLAPSED,   class=class="str">"cmt">// Sort by flag for collapsed panel class="num">2
SORT_BY_CANV_ELEMENT_SPLIT_CONTAINER_PANEL2_MIN_SIZE,    class=class="str">"cmt">// Sort by panel class="num">2 minimum size
SORT_BY_CANV_ELEMENT_NAME_OBJ = FIRST_CANV_ELEMENT_STR_PROP, class=class="str">"cmt">// Sort by an element object name
SORT_BY_CANV_ELEMENT_NAME_RES,                     class=class="str">"cmt">// Sort by the graphical resource name
SORT_BY_CANV_ELEMENT_TEXT,                         class=class="str">"cmt">// Sort by graphical element text
SORT_BY_CANV_ELEMENT_DESCRIPTION,                  class=class="str">"cmt">// Sort by graphical element description
MSG_LIB_TEXT_TOP,                                  class=class="str">"cmt">// Top
MSG_LIB_TEXT_BOTTOM,                               class=class="str">"cmt">// Bottom
MSG_LIB_TEXT_LEFT,                                 class=class="str">"cmt">// Left
MSG_LIB_TEXT_RIGHT                                 class=class="str">"cmt">// Right

◍ 控件属性枚举里的坐标与边距字段

在 MQL5 标准库的消息枚举段里,有一批以 MSG_CANV_ELEMENT_PROP_ 开头的常量,专门描述画布控件的可视区域与控制区域几何属性。 其中 MSG_CANV_ELEMENT_PROP_CONTROL_AREA_X / Y / WIDTH / HEIGHT 四个常量对应控件区域左上角坐标与宽高,而 MSG_CANV_ELEMENT_PROP_VISIBLE_AREA_WIDTH / HEIGHT 描述可见范围尺寸,二者通常不等——控件可能超出可见区被裁剪。 滚动区则分右端与底部两组:MSG_CANV_ELEMENT_PROP_SCROLL_AREA_X_RIGHT 等 4 个常量定义右侧滚动条占位,MSG_CANV_ELEMENT_PROP_SCROLL_AREA_X_BOTTOM 等 4 个定义底部滚动条占位。边框宽度由 MSG_CANV_ELEMENT_PROP_BORDER_LEFT_AREA_WIDTH 等四个方向常量独立控制,左右上下边距可分别设置。 如果你在写自定义面板,直接引用这些枚举做多语言文本映射,可以避免硬写中文字符串;开 MT5 在 Include/Canvas 相关头文件里搜 MSG_CANV_ELEMENT_PROP_ 即可核对全部 20 余个字段。

MQL5 / C++
MSG_LIB_TEXT_VERTICAL,                                                                       class=class="str">"cmt">// Vertically
MSG_LIB_TEXT_HORISONTAL,                                                                     class=class="str">"cmt">// Horizontally
MSG_GRAPH_ELEMENT_TYPE_WF_SPLIT_CONTAINER_PANEL,                                              class=class="str">"cmt">// SplitContainer control panel
MSG_GRAPH_ELEMENT_TYPE_WF_SPLIT_CONTAINER,                                                    class=class="str">"cmt">// SplitContainer control
MSG_GRAPH_ELEMENT_TYPE_WF_SPLITTER,                                                           class=class="str">"cmt">// Splitter control
MSG_GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON,                                                       class=class="str">"cmt">// ArrowButton control
MSG_GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_UP,                                                    class=class="str">"cmt">// UpArrowButton control
MSG_CANV_ELEMENT_PROP_VISIBLE_AREA_WIDTH,                                                     class=class="str">"cmt">// Visibility scope width
MSG_CANV_ELEMENT_PROP_VISIBLE_AREA_HEIGHT,                                                    class=class="str">"cmt">// Visibility scope height
MSG_CANV_ELEMENT_PROP_CONTROL_AREA_X,                                                         class=class="str">"cmt">// Control area X coordinate
MSG_CANV_ELEMENT_PROP_CONTROL_AREA_Y,                                                         class=class="str">"cmt">// Control area Y coordinate
MSG_CANV_ELEMENT_PROP_CONTROL_AREA_WIDTH,                                                     class=class="str">"cmt">// Control area width
MSG_CANV_ELEMENT_PROP_CONTROL_AREA_HEIGHT,                                                    class=class="str">"cmt">// Control area height
MSG_CANV_ELEMENT_PROP_SCROLL_AREA_X_RIGHT,                                                    class=class="str">"cmt">// Right scroll area X coordinate
MSG_CANV_ELEMENT_PROP_SCROLL_AREA_Y_RIGHT,                                                    class=class="str">"cmt">// Right scroll area Y coordinate
MSG_CANV_ELEMENT_PROP_SCROLL_AREA_WIDTH_RIGHT,                                                class=class="str">"cmt">// Right scroll area width
MSG_CANV_ELEMENT_PROP_SCROLL_AREA_HEIGHT_RIGHT,                                               class=class="str">"cmt">// Right scroll area height
MSG_CANV_ELEMENT_PROP_SCROLL_AREA_X_BOTTOM,                                                   class=class="str">"cmt">// Bottom scroll area X coordinate
MSG_CANV_ELEMENT_PROP_SCROLL_AREA_Y_BOTTOM,                                                   class=class="str">"cmt">// Bottom scroll area Y coordinate
MSG_CANV_ELEMENT_PROP_SCROLL_AREA_WIDTH_BOTTOM,                                               class=class="str">"cmt">// Bottom scroll area width
MSG_CANV_ELEMENT_PROP_SCROLL_AREA_HEIGHT_BOTTOM,                                              class=class="str">"cmt">// Bottom scroll area height
MSG_CANV_ELEMENT_PROP_BORDER_LEFT_AREA_WIDTH,                                                 class=class="str">"cmt">// Left edge area width
MSG_CANV_ELEMENT_PROP_BORDER_BOTTOM_AREA_WIDTH,                                               class=class="str">"cmt">// Bottom edge area width
MSG_CANV_ELEMENT_PROP_BORDER_RIGHT_AREA_WIDTH,                                                class=class="str">"cmt">// Right edge area width
MSG_CANV_ELEMENT_PROP_BORDER_TOP_AREA_WIDTH,                                                  class=class="str">"cmt">// Upper edge area width
MSG_CANV_ELEMENT_PROP_DISPLAYED,                                                              class=class="str">"cmt">// Non-hidden control display flag
MSG_CANV_ELEMENT_PROP_ENABLED,                                                                class=class="str">"cmt">// Element availability flag
MSG_CANV_ELEMENT_PROP_SPLIT_CONTAINER_SPLITTER_DISTANCE,                                      class=class="str">"cmt">// Distance from edge to separator
MSG_CANV_ELEMENT_PROP_SPLIT_CONTAINER_SPLITTER_WIDTH,                                         class=class="str">"cmt">// Separator width

拆分容器控件的属性枚举与多语映射

在 MT5 自定义图形界面里,SplitContainer 这类复合控件的本地化文本和属性标识是靠一张枚举-字符串表撑起来的。上面这段定义里,MSG_CANV_ELEMENT_PROP_SPLIT_CONTAINER_SPLITTER_ORIENTATION 管分隔条方向,后面紧跟的「Top/Bottom/Left/Right」四个俄语-英语对,就是界面上折叠面板方位的下拉选项源。 绿色高亮的那几行值得单独看:Vertical/Horisontal 决定了分隔条是竖切还是横切;X/Y 坐标加宽高四组参数,精确框定了控制区、右侧滚动区、底部滚动区各自的像素占位。实际写面板布局时,若右侧滚动区宽度设成 0,滚动条就不会渲染,这是很多自定义指标界面“少了根条”的直接原因。 边框区域四项(左/下/右/上)宽度独立可调,意味着你可以做非对称边框。外汇与贵金属图表挂这类 Canvas 控件时,需注意高 DPI 屏下这些像素值可能需乘以系统缩放系数,否则控件会偏小——这属于 MT5 界面层的高风险适配坑,建议开 MT5 用 Comment() 打印实际坐标验证。

MQL5 / C++
MSG_CANV_ELEMENT_PROP_SPLIT_CONTAINER_SPLITTER_ORIENTATION, class=class="str">"cmt">// Separator location
MSG_CANV_ELEMENT_PROP_SPLIT_CONTAINER_PANEL1_COLLAPSED,  class=class="str">"cmt">// Flag for collapsed panel class="num">1
MSG_CANV_ELEMENT_PROP_SPLIT_CONTAINER_PANEL1_MIN_SIZE,   class=class="str">"cmt">// Panel class="num">1 minimum size
{"Сверху","Top"},
{"Снизу","Bottom"},
{"Слева","Left"},
{"Справа","Right"},
{"Вертикально","Vertical"},
{"Горизонтально","Horisontal"},
{"Панель элемента управления \"SplitContainer\"","Panel of the Control element \"SplitContainer\""},
{"Элемент управления \"SplitContainer\"","Control element \"SplitContainer\""},
{"Элемент управления \"Splitter\"","Control element \"Splitter\""},
{"Элемент управления \"ArrowButton\"","Control element \"ArrowButton\""},
{"Элемент управления \"UpArrowButton\"","Control element \"UpArrowButton\""},
{"Ширина области видимости","Width of object visibility area"},
{"Высота области видимости","Height of object visibility area"},
{"X-координата области управления","X-coordinate of the control area"},
{"Y-координата области управления","Y-coordinate of the control area"},
{"Ширина области управления","Control area width"},
{"Высота области управления","Control area height"},
{"X-координата области прокрутки справа","X-coordinate of the right scroll area"},
{"Y-координата области прокрутки справа","Y-coordinate of the right scroll area"},
{"Ширина области прокрутки справа","Width of the right scroll area"},
{"Высота области прокрутки справа","Height of the right scroll area"},
{"X-координата области прокрутки снизу","X-coordinate of the bottom scroll area"},
{"Y-координата области прокрутки снизу","Y-coordinate of the bottom scroll area"},
{"Ширина области прокрутки снизу","Width of the bottom scroll area"},
{"Высота области прокрутки снизу","Height of the bottom scroll area"},
{"Ширина области левой грани","Width of the left border area"},
{"Ширина области нижней грани","Width of the bottom border area"},
{"Ширина области правой грани","Width of the right border area"},
{"Ширина области верхней грани","Width of the top border area"},
{"Флаг отображения не скрытого элемента управления","Flag that sets the display of a non-hidden control"},
{"Флаг доступности элемента","Element Availability Flag"},
{"Расстояние от края до разделителя","Distance from edge to splitter"},
{"Толщина разделителя","Splitter Width"}

「图形元素类型的描述映射逻辑」

在自定义 GUI 库里,每一个图形元素都需要一个可读的类型说明,方便调试时直接在日志里看清楚当前对象是什么。CGBaseObj::TypeElementDescription 就是干这个的:传入 ENUM_GRAPH_ELEMENT_TYPE 枚举,返回对应的本地化文本。 实现上它用了一长串三元运算符,从 GRAPH_ELEMENT_TYPE_STANDARD 一路比到 GRAPH_ELEMENT_TYPE_WF_LABEL,中间还分了 WinForms 底层的 UNDERLAY / BASE,以及容器类的 CONTAINER / GROUPBOX / PANEL / TAB_CONTROL / SPLIT_CONTAINER。你在 MT5 里若看到某面板日志打出 'Split Container',就能反查到是 GRAPH_ELEMENT_TYPE_WF_SPLIT_CONTAINER 这个分支。 顺带一提,同文件上方还有三组配置项字符串:'Splitter orientation' 管分隔条方向,'Flag to indicate that panel 1 is collapsed' 记录面板1是否收起,'Min size of Panel 1' 锁死面板1最小尺寸。改面板布局时,这三个值最好一起核,否则可能出现拖不动分隔条或者收起后展不开的情况。

MQL5 / C++
  {"Расположение разделителя","Splitter orientation"},
  {"Флаг свёрнутости панели class="num">1","Flag to indicate that panel class="num">1 is collapsed"},
  {"Минимальный размер панели class="num">1","Min size of Panel class="num">1"},
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)              :
      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)             :
把隔板状态判定交给小布
这些鼠标悬停与区域重绘的诊断,小布盯盘的 AIGC 已内置,打开对应品种页即可看到面板交互是否按预期触发。

常见问题

MQL5 未提供运行时更改鼠标外观的接口,只能以阴影区或虚线矩形等图形元素提示可拖拽状态。
只针对隔板派生类重写清除与重绘,可见性由 SplitContainer 事件管理,不波及无关对象。
实时改尺寸在移动中立即生效,逻辑更简单;虚线预览先描边再落位,接近 MS 原版但代码更重。
小布支持接入自有 Include 库做诊断,把 DoEasy 控件事件挂到品种页即可观察隔板交互。
本篇先预留顶部底部左侧右侧的鼠标状态 ID,实际靠鼠标调窗体尺寸仍需后续篇补全。