DoEasy. 控件 (第 25 部分): Tooltip WinForms 对象(基础篇)
◍ 给控件挂上悬浮提示框
在 DoEasy 库里补一层 ToolTip WinForms 对象,能让任意控件在鼠标悬停时弹出轻量说明,省去交易者盯盘时反复翻面板查字段含义的麻烦。该实现随 2023 年 2 月 24 日发布的系列第 25 部分一同放出,原文示例在 MT5 里可直接挂载观察。 外汇与贵金属市场波动剧烈、杠杆风险高,这类界面增强只解决信息可读性问题,不改变任何下单逻辑或胜率。 实际落地时,先在库里继承出 ToolTip 类,绑定到目标控件的鼠标事件;MT5 里编译后把 EA 拖到图表,悬停按钮即可看到提示文本。下一步是按自己品种缩写习惯改提示内容,别照抄默认文案。
图形元素如何挂上工具提示
在 MT5 自定义控件库里,每个图形对象都具备设置工具提示(ToolTip)的能力,但并非所有元素默认都显示。核心思路是:容器类对象负责创建 ToolTip 控件,再把它指派给需要提示的图形元素,后者只持有一个指向该 ToolTip 的指针。 库里的图形元素彼此之间不需要互相“认识”。它们都被放进 ArrayObj 集合类,这个类接受任何从标准库基类派生的对象,所以一个控件可以静默附着到另一个控件上,可视化调度不会出问题。 典型交互是光标悬停一段时间后提示浮现;若同一对象绑定了多个提示,第一个出现后,后续提示几乎零延迟接续显示——这套多级提示逻辑留到后面文章展开,本节只做实基础:创建 ToolTip 并分配出去。 顺带扩展了函数库的绘图基元:标准图标、左右与上下箭头都能直接画。这些预定义图像不仅 ToolTip 能用,之前做的按钮、标签等元素也能“按原样”调用,后续会逐步铺开到全部图形组件。外汇与贵金属面板开发属高风险改造,建议在策略测试器里先验证控件附着逻辑再上真仓。
「给 DoEasy 库补上标准图标与工具提示骨架」
要在 MT5 的 DoEasy 函数库里画出信息、警告、错误等标准图标,第一步是扩展类型枚举与属性表。整数型图形元素属性从 122 扩到 129,字符串型属性总数增到 6,画布排序准则也加了新项,这样后续才能按新属性筛选和排序控件。 GBaseObj.mqh 的 TypeElementDescription() 方法需补一段:根据传入的对象类型,从 Data.mqh 新加的消息索引里回文本说明。GCnvElement.mqh 里重新加回写入基准对象指针的方法——之前删掉后发现工具提示仍需要它来绑定触发元素。 标准图标的绘制全在类外方法里硬画。信息图标先算圆心画填充圆加 Wu 平滑圆,再用两个矩形拼出“i”;警告图标画填充三角加偏移顶点让“i”视觉居中;错误图标是双圆加 X 线;四个方向箭头则按状态改色,非活动时画成灰色。 阴影对象引入 SetOpacityDraw() 单独管绘制不透明度,背景永远零透明。ShadowObj.mqh 里重命名旧方法并设模糊度默认值,WinFormBase.mqh 改重绘逻辑避免阴影被误擦。ArrowXButton 四个类直接调基类箭头方法,左键类调左箭头,以此类推。 外汇与贵金属图表加载这类自定义库属高风险操作,参数改错可能令 EA 在实盘中断连,建议先在策略测试器跑一遍。
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 GRAPH_ELEMENT_TYPE_WF_PANEL, class=class="str">"cmt">// Windows Forms Panel
◍ WinForms 图形元素枚举的底层类型清单
在 MT5 的自定义图形接口里,所有 Windows Forms 风格控件都靠一组 GRAPH_ELEMENT_TYPE_WF_* 枚举值来标识。从容器类的 GroupBox、TabControl、SplitContainer,到标准控件 Label、Button、CheckBox、RadioButton,均在这一体系内逐一映射。 下面这段代码列出了部分核心枚举常量,注释直接对应 WinForms 的原生组件: GRAPH_ELEMENT_TYPE_WF_GROUPBOX 是 GroupBox 容器,GRAPH_ELEMENT_TYPE_WF_TAB_CONTROL 对应多页签 TabControl,GRAPH_ELEMENT_TYPE_WF_SPLIT_CONTAINER 则是可拖拽分隔的 SplitContainer。标准控件基类 GRAPH_ELEMENT_TYPE_WF_COMMON_BASE 之下的 Label、Button、CheckBox 等,都继承其通用属性。 辅助元素容易被忽略:比如 GRAPH_ELEMENT_TYPE_WF_LIST_BOX_ITEM 只是 ListBox 里的单行项,GRAPH_ELEMENT_TYPE_WF_TAB_HEADER 和 GRAPH_ELEMENT_TYPE_WF_TAB_FIELD 分别管页签头与页签内容区。箭头按钮更细,上下左右各有独立枚举(GRAPH_ELEMENT_TYPE_WF_ARROW_BUTTON_UP / DOWN / LEFT / RIGHT),还有 UD / LR 的组合箭头盒。 开 MT5 按 F4 进 MetaEditor,在包含文件里搜 GRAPH_ELEMENT_TYPE_WF_ 就能看到全量定义;写 CCanvas 或自定义面板时,用对枚举值才能正确捕获鼠标命中区域。外汇与贵金属交易界面自动化高风险,枚举用错可能让面板无响应。
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 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 GRAPH_ELEMENT_TYPE_WF_HINT_MOVE_RIGHT, class=class="str">"cmt">// Windows Forms HintMoveRight GRAPH_ELEMENT_TYPE_WF_HINT_MOVE_UP, class=class="str">"cmt">// Windows Forms HintMoveUp
画布控件枚举与提示框延时参数
在 MT5 自定义画布(Canvas)界面开发里,控件类型与布局方向都用枚举固化。比如分割容器方向只有垂直与水平两种:ENUM_CANV_ELEMENT_SPLITTER_ORIENTATION 中 VERTICAL 对应纵向切分,HORISONTAL 负责横向排布,写面板布局时选错常量会导致子控件直接重叠。 预定义提示图标枚举 ENUM_CANV_ELEMENT_TOOLTIP_ICON 给了 5 个档位:NONE、INFO、WARNING、ERROR、USER。实盘挂单面板用 WARNING 标平价保护触发,比纯文字更抓眼。 整数属性枚举 ENUM_CANV_ELEMENT_PROP_INTEGER 末尾集中了 8 个 Tooltip 相关项。INITIAL_DELAY 管鼠标悬停多久才弹提示,AUTO_POP_DELAY 管停留时长,RESHOW_DELAY 管移到同窗另一控件后的再弹间隔;IS_BALLOON 切气泡样式,USE_FADING 控淡入淡出。 宏 CANV_ELEMENT_PROP_INTEGER_TOTAL 写死为 129,意味着整套画布整数属性目前封顶 129 个。开 MT5 在 Include 里搜这个宏,能反推你用的标准库版本是否含后续新增的 tooltip 字段。
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 }; enum ENUM_CANV_ELEMENT_TOOLTIP_ICON { CANV_ELEMENT_TOOLTIP_ICON_NONE, class=class="str">"cmt">// None CANV_ELEMENT_TOOLTIP_ICON_INFO, class=class="str">"cmt">// Info CANV_ELEMENT_TOOLTIP_ICON_WARNING, class=class="str">"cmt">// Warning CANV_ELEMENT_TOOLTIP_ICON_ERROR, class=class="str">"cmt">// Error CANV_ELEMENT_TOOLTIP_ICON_USER, class=class="str">"cmt">// User }; 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_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 CANV_ELEMENT_PROP_TOOLTIP_INITIAL_DELAY, class=class="str">"cmt">// Tooltip display delay CANV_ELEMENT_PROP_TOOLTIP_AUTO_POP_DELAY, class=class="str">"cmt">// Tooltip display duration CANV_ELEMENT_PROP_TOOLTIP_RESHOW_DELAY, class=class="str">"cmt">// One element new tooltip display delay CANV_ELEMENT_PROP_TOOLTIP_SHOW_ALWAYS, class=class="str">"cmt">// Display a tooltip in inactive window CANV_ELEMENT_PROP_TOOLTIP_ICON, class=class="str">"cmt">// Icon displayed in tooltip CANV_ELEMENT_PROP_TOOLTIP_IS_BALLOON, class=class="str">"cmt">// Tooltip in the form of a "cloud" CANV_ELEMENT_PROP_TOOLTIP_USE_FADING, class=class="str">"cmt">// Fade when showing/hiding a tooltip }; class="macro">#define CANV_ELEMENT_PROP_INTEGER_TOTAL(class="num">129) class=class="str">"cmt">// Total number of integer properties
「画布元素的字符串属性与排序枚举」
在 MT5 自定义画布上管理图形元素时,除了整型和双精度属性,字符串属性用来承载名称、文本与提示框内容。上面这段枚举 ENUM_CANV_ELEMENT_PROP_STRING 定义了 6 个字符串属性,其中 CANV_ELEMENT_PROP_TOOLTIP_TITLE 与 CANV_ELEMENT_PROP_TOOLTIP_TEXT 是后来补上的 tooltip 相关字段,专门控制悬停提示的标题与正文。 排序枚举 ENUM_SORT_CANV_ELEMENT_MODE 把整型、双精度、字符串三类属性统一编成连续索引。宏 FIRST_CANV_ELEMENT_STR_PROP 用「整型总数减跳过数 + 双精度总数减跳过数」算出字符串属性在排序表中的起始偏移,写库时改了属性总数就得同步这个宏,否则排序索引会错位。 tooltip 系列的排序键值得留意:SORT_BY_CANV_ELEMENT_TOOLTIP_INITIAL_DELAY 控制首次延迟,AUTO_POP_DELAY 管显示时长,RESHOW_DELAY 管同元素再次弹出的间隔。做面板时若想让某些控件优先响应悬停,直接按这些键排序图层就可能改变拾取顺序。外汇与贵金属图表挂这类自定义 UI 属高风险操作,参数乱改可能让 EA 界面卡死。
class="macro">#define CANV_ELEMENT_PROP_INTEGER_SKIP(class="num">0) class=class="str">"cmt">// Number of integer properties not used in sorting class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| String properties of the graphical element on the canvas | class=class="str">"cmt">//+------------------------------------------------------------------+ enum ENUM_CANV_ELEMENT_PROP_STRING { CANV_ELEMENT_PROP_NAME_OBJ = (CANV_ELEMENT_PROP_INTEGER_TOTAL+CANV_ELEMENT_PROP_DOUBLE_TOTAL), class=class="str">"cmt">// Graphical element object name CANV_ELEMENT_PROP_NAME_RES, class=class="str">"cmt">// Graphical resource name CANV_ELEMENT_PROP_TEXT, class=class="str">"cmt">// Graphical element text CANV_ELEMENT_PROP_DESCRIPTION, class=class="str">"cmt">// Graphical element description CANV_ELEMENT_PROP_TOOLTIP_TITLE, class=class="str">"cmt">// Element tooltip title CANV_ELEMENT_PROP_TOOLTIP_TEXT, class=class="str">"cmt">// Element tooltip text }; class="macro">#define CANV_ELEMENT_PROP_STRING_TOTAL(class="num">6) class=class="str">"cmt">// Total number of class="type">class="kw">string properties class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Possible sorting criteria of graphical elements on the canvas | class=class="str">"cmt">//+------------------------------------------------------------------+ 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 { class=class="str">"cmt">//--- Sort by integer properties SORT_BY_CANV_ELEMENT_ID = class="num">0, class=class="str">"cmt">// Sort by element ID SORT_BY_CANV_ELEMENT_TYPE, class=class="str">"cmt">// Sort by graphical element type class=class="str">"cmt">//---... class=class="str">"cmt">//---... 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_TOOLTIP_INITIAL_DELAY, class=class="str">"cmt">// Sort by tooltip display delay SORT_BY_CANV_ELEMENT_TOOLTIP_AUTO_POP_DELAY, class=class="str">"cmt">// Sort by tooltip display duration SORT_BY_CANV_ELEMENT_TOOLTIP_RESHOW_DELAY, class=class="str">"cmt">// Sort by one element new tooltip display delay SORT_BY_CANV_ELEMENT_TOOLTIP_SHOW_ALWAYS, class=class="str">"cmt">// Sort by a tooltip in inactive window SORT_BY_CANV_ELEMENT_TOOLTIP_ICON, class=class="str">"cmt">// Sort by icon displayed in a tooltip SORT_BY_CANV_ELEMENT_TOOLTIP_IS_BALLOON, class=class="str">"cmt">// Sort by a cloud tooltip flag SORT_BY_CANV_ELEMENT_TOOLTIP_USE_FADING, class=class="str">"cmt">// Sort by the flag of fading when showing/hiding a tooltip class=class="str">"cmt">//--- Sort by real properties class=class="str">"cmt">//--- Sort by class="type">class="kw">string properties