DoEasy. 控件 (第 26 部分): 完成 ToolTip(工具提示)WinForms 对象,并转移至 ProgressBar(进度条)开发·进阶篇
🛠️

DoEasy. 控件 (第 26 部分): 完成 ToolTip(工具提示)WinForms 对象,并转移至 ProgressBar(进度条)开发·进阶篇

(2/3)· 鼠标悬停停顿、平滑显隐的 ToolTip 到底靠什么驱动,进度条静态结构又该怎么搭

案例拆解新手友好 第 2/3 篇

不少自建面板的 ToolTip 一碰就弹、移开硬留,和原生 WinForms 手感差出一截。根子往往在没给图形元素配独立计时器,只能靠主循环轮询所有对象,卡顿且难控。本篇把活动对象列表和虚拟计时器事件接进 ToolTip,顺带铺开进度条静态版。

画布控件的显隐状态与进度条样式枚举

在 MT5 自定义画布(Canvas)界面开发里,图形控件从出现到消失走的是一套有限状态机。下面的枚举把淡入淡出拆成了等待、进行、完成三段,外加一个最终完成态,方便在 OnTimer 里按帧驱动透明度。 CANV_ELEMENT_DISPLAY_STATE_WAITING_FADE_IN 表示控件已创建但还没开始淡入;PROCESS_FADE_IN 是正在插值透明度;COMPLETED_FADE_IN 淡入结束。淡出对称地有 WAITING / PROCESS / COMPLETED_FADE_OUT 三态,最后落到 CANV_ELEMENT_DISPLAY_STATE_COMPLETED 表示整个生命周期处理完毕。 进度条(ProgressBar)自身也有三种视觉风格枚举:BLOCKS 是分段方块,CONTINUOUS 是连续填充条,MARQUEE 则是无确定进度的连续滚动条,常用于「加载中」提示。 控件整数属性枚举 ENUM_CANV_ELEMENT_PROP_INTEGER 里,CANV_ELEMENT_PROP_DISPLAY_STATE 存的就是上面那套显隐状态值;CANV_ELEMENT_PROP_DISPLAY_DURATION 控制显隐动画总时长(毫秒级)。进度条相关还有 MAXIMUM / MINIMUM / STEP 三个整数属性,分别界定量程上下界和重绘步长。 开 MT5 新建一个 Canvas 面板 EA,把这几组 enum 原样贴进头文件,就能在调试窗口里实时打印某控件的 DISPLAY_STATE,验证淡入淡出是否按你设的 DURATION 走完。

MQL5 / C++
enum ENUM_CANV_ELEMENT_DISPLAY_STATE
  {
  CANV_ELEMENT_DISPLAY_STATE_WAITING_FADE_IN,        class=class="str">"cmt">// Wait for fading in
  CANV_ELEMENT_DISPLAY_STATE_PROCESS_FADE_IN,        class=class="str">"cmt">// Fading in
  CANV_ELEMENT_DISPLAY_STATE_COMPLETED_FADE_IN,      class=class="str">"cmt">// Fading in end
  CANV_ELEMENT_DISPLAY_STATE_WAITING_FADE_OUT,       class=class="str">"cmt">// Wait for fading out
  CANV_ELEMENT_DISPLAY_STATE_PROCESS_FADE_OUT,       class=class="str">"cmt">// Fading out
  CANV_ELEMENT_DISPLAY_STATE_COMPLETED_FADE_OUT,     class=class="str">"cmt">// Fading out end
  CANV_ELEMENT_DISPLAY_STATE_COMPLETED,              class=class="str">"cmt">// Complete processing
  };

enum ENUM_CANV_ELEMENT_PROGRESS_BAR_STYLE
  {
  CANV_ELEMENT_PROGRESS_BAR_STYLE_BLOCKS,            class=class="str">"cmt">// Segmented blocks
  CANV_ELEMENT_PROGRESS_BAR_STYLE_CONTINUOUS,        class=class="str">"cmt">// Continuous bar
  CANV_ELEMENT_PROGRESS_BAR_STYLE_MARQUEE,           class=class="str">"cmt">// Continuous scrolling
  };

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_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_DISPLAY_STATE,                   class=class="str">"cmt">// Control display state
  CANV_ELEMENT_PROP_DISPLAY_DURATION,                class=class="str">"cmt">// Control display duration
  CANV_ELEMENT_PROP_GROUP,                           class=class="str">"cmt">// Group the graphical element belongs to
  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_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
  CANV_ELEMENT_PROP_PROGRESS_BAR_MAXIMUM,            class=class="str">"cmt">// The upper bound of the range ProgressBar operates in
  CANV_ELEMENT_PROP_PROGRESS_BAR_MINIMUM,            class=class="str">"cmt">// The lower bound of the range ProgressBar operates in
  CANV_ELEMENT_PROP_PROGRESS_BAR_STEP,               class=class="str">"cmt">// ProgressBar increment needed to redraw it
  };

「画布控件属性枚举与排序基址」

在 MT5 自定义画布库里,进度条(ProgressBar)相关属性被单独列进整数属性枚举尾部,包含样式、当前值、Marquee 动画速度三项。这些枚举值紧接在已有控件属性之后,编译层靠偏移量区分整型、双精度与字符串三类属性。 源码用宏把整数属性总数钉死为 138,其中不参与排序的跳过量为 0,因此首个双精度属性偏移 FIRST_CANV_ELEMENT_DBL_PROP 直接等于 138。字符串属性基址再叠加上双精度总数与跳过量,形成 FIRST_CANV_ELEMENT_STR_PROP,控件名与资源名排序就落在这段区间。 排序枚举 ENUM_SORT_CANV_ELEMENT_MODE 从 0 开始:SORT_BY_CANV_ELEMENT_ID 排头,进度条的最大/最小/步长/样式/当前值/动画速度都映射成独立排序键。写面板时若想按 Z 轴点击优先级或显示时长重排控件,直接传对应枚举值给库函数即可,不用自己算属性下标。 开 MT5 把这段枚举贴进 Includes\Canvas\ElementProps.mqh 对照,改一个进度条 MARQUEE_ANIM_SPEED 再看排序键偏移是否顺移,是验证库结构的最快办法。外汇与贵金属图表上跑这类自定义 UI 需注意:终端卡顿可能放大滑点风险,实盘前先在模拟盘压测。

MQL5 / C++
class="macro">#define CANV_ELEMENT_PROP_INTEGER_TOTAL(class="num">138) 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_BORDER_TOP_AREA_WIDTH,
  SORT_BY_CANV_ELEMENT_DISPLAYED,
  SORT_BY_CANV_ELEMENT_DISPLAY_STATE,
  SORT_BY_CANV_ELEMENT_DISPLAY_DURATION,
  SORT_BY_CANV_ELEMENT_GROUP,
  SORT_BY_CANV_ELEMENT_ZORDER,
  SORT_BY_CANV_ELEMENT_TOOLTIP_IS_BALLOON,
  SORT_BY_CANV_ELEMENT_TOOLTIP_USE_FADING,
  SORT_BY_CANV_ELEMENT_PROGRESS_BAR_MAXIMUM,
  SORT_BY_CANV_ELEMENT_PROGRESS_BAR_MINIMUM,
  SORT_BY_CANV_ELEMENT_PROGRESS_BAR_STEP,
  SORT_BY_CANV_ELEMENT_PROGRESS_BAR_STYLE,
  SORT_BY_CANV_ELEMENT_PROGRESS_BAR_VALUE,
  SORT_BY_CANV_ELEMENT_PROGRESS_BAR_MARQUEE_ANIM_SPEED,
  SORT_BY_CANV_ELEMENT_NAME_OBJ = FIRST_CANV_ELEMENT_STR_PROP,
  SORT_BY_CANV_ELEMENT_NAME_RES,
  };

◍ 图形库枚举里的排序与控件状态常量

在 MT5 自定义图形库的头文件里,有一组枚举专门管画布元素排序方式。SORT_BY_CANV_ELEMENT_TEXT 到 SORT_BY_CANV_ELEMENT_TOOLTIP_TEXT 这 4 个值,决定了对图表上文本类图元做索引时的排列依据,分别按元素文本、描述、提示头、提示正文来排。 复选类控件的状态也用常量标死:MSG_LIB_TEXT_CHEK_STATE_UNCHECKED 对应未勾选,CHECKED 是已勾选,INDETERMINATE 则是三态框里常见的“未定”灰态,做面板逻辑时直接比对这几个值即可。 图标与进度条样式常量值得留意。MSG_LIB_TEXT_ICON_NONE 到 ICON_USER 覆盖无图标、信息、警告、错误、用户自定义五种提示图标;进度条则有 STYLE_BLOCKS(分段块)、STYLE_CONTINUOUS(连续条)、STYLE_MARQUEE(连续滚动)三种渲染风格,外汇与贵金属图表挂 EA 面板时高频用到,杠杆品种波动剧烈、控件重绘需防卡顿。 星期与图元类型常量补全了本地化与对象树描述。MSG_LIB_TEXT_SUNDAY/MONDAY 做多语星期,MSG_GRAPH_ELEMENT_TYPE_* 从基础 Element、Shadow/Glare 对象到 Window、Tooltip、BarProgressBar 控件均有独立标识,方便在调试器里快速分辨父级容器。

MQL5 / C++
  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
  SORT_BY_CANV_ELEMENT_TOOLTIP_HEADER,     class=class="str">"cmt">// Sort by Tooltip element header
  SORT_BY_CANV_ELEMENT_TOOLTIP_TEXT,       class=class="str">"cmt">// Sort by Tooltip element text
};
class=class="str">"cmt">//+------------------------------------------------------------------+
  MSG_LIB_TEXT_CHEK_STATE_UNCHECKED,       class=class="str">"cmt">// Unchecked
  MSG_LIB_TEXT_CHEK_STATE_CHECKED,         class=class="str">"cmt">// Checked
  MSG_LIB_TEXT_CHEK_STATE_INDETERMINATE,   class=class="str">"cmt">// Undefined

  MSG_LIB_TEXT_ICON_NONE,                  class=class="str">"cmt">// None
  MSG_LIB_TEXT_ICON_INFO,                  class=class="str">"cmt">// Info
  MSG_LIB_TEXT_ICON_WARNING,               class=class="str">"cmt">// Warning
  MSG_LIB_TEXT_ICON_ERROR,                 class=class="str">"cmt">// Error
  MSG_LIB_TEXT_ICON_USER,                  class=class="str">"cmt">// User
  MSG_LIB_TEXT_STYLE_BLOCKS,               class=class="str">"cmt">// Segmented blocks
  MSG_LIB_TEXT_STYLE_CONTINUOUS,           class=class="str">"cmt">// Continuous bar
  MSG_LIB_TEXT_STYLE_MARQUEE,              class=class="str">"cmt">// Continuous scrolling

  MSG_LIB_TEXT_SUNDAY,                     class=class="str">"cmt">// Sunday
  MSG_LIB_TEXT_MONDAY,                     class=class="str">"cmt">// Monday
  MSG_GRAPH_ELEMENT_TYPE_ELEMENT,          class=class="str">"cmt">// Element
  MSG_GRAPH_ELEMENT_TYPE_SHADOW_OBJ,       class=class="str">"cmt">// Shadow object
  MSG_GRAPH_ELEMENT_TYPE_GLARE_OBJ,        class=class="str">"cmt">// Glare object
  MSG_GRAPH_ELEMENT_TYPE_FORM,             class=class="str">"cmt">// Form
  MSG_GRAPH_ELEMENT_TYPE_WINDOW,           class=class="str">"cmt">// Window
  MSG_GRAPH_ELEMENT_TYPE_WF_HINT_MOVE_DOWN,class=class="str">"cmt">// HintMoveLeft control
  MSG_GRAPH_ELEMENT_TYPE_WF_TOOLTIP,       class=class="str">"cmt">// ToolTip control
  MSG_GRAPH_ELEMENT_TYPE_WF_BAR_PROGRESS_BAR, class=class="str">"cmt">// BarProgressBar control
  MSG_GRAPH_ELEMENT_TYPE_WF_PROGRESS_BAR,  class=class="str">"cmt">// ProgressBar control

控件属性枚举里的报错与状态标识

在 MQL5 标准库的图形元素封装里,大量字符串常量被塞进一个枚举,专门给 CGraphElementsCollection 和画布控件做报错提示与属性描述。上面这段截取的就是其中一段:从「控件类型传错」到「同一个控件不能挂两个 ToolTip」,再到「图形对象是否属于某个 EA/指标程序」,都属于运行时才可能触发的诊断信息。 值得在 MT5 里留意的是,MSG_GRAPH_OBJ_FAILED_GET_ACTIVE_OBJ_LIST 和 MSG_GRAPH_OBJ_FAILED_GET_ADDED_OBJ_LIST 这两个常量,对应「拿不到活跃元素列表」和「拿不到新增对象列表」——如果你的面板在图表上偶尔丢控件,大概率就是这两个分支被命中了。 画布控件(CCanvas 系列)的属性常量更细:MSG_CANV_ELEMENT_PROP_DISPLAY_STATE 管显示状态,MSG_CANV_ELEMENT_PROP_DISPLAY_DURATION 管显示时长,ProgressBar 那一簇则从 MINIMUM、MAXIMUM、STEP 到 MARQUEE_ANIM_SPEED 全有独立常量。复制下面这段枚举片段到你的 include 文件里,搜这些 MSG_ 前缀就能快速定位标准库源码位置,省得自己重写报错文案。

MQL5 / C++
   MSG_GRAPH_ELEMENT_TYPE_WF_WRONG_TYPE_PASSED,           class=class="str">"cmt">// Incorrect control type
   MSG_GRAPH_ELEMENT_TYPE_WF_CANT_ADD_2_TOOLTIP,           class=class="str">"cmt">// Unable to add two or more ToolTips to the same control
   MSG_GRAPH_OBJ_BELONG_PROGRAM,                           class=class="str">"cmt">// Graphical object belongs to a program
   MSG_GRAPH_OBJ_BELONG_NO_PROGRAM,                        class=class="str">"cmt">// Graphical object does not belong to a program
class=class="str">"cmt">//--- CGraphElementsCollection
   MSG_GRAPH_OBJ_FAILED_GET_ADDED_OBJ_LIST,                class=class="str">"cmt">// Failed to get the list of newly added objects
   MSG_GRAPH_OBJ_FAILED_GET_ACTIVE_OBJ_LIST,               class=class="str">"cmt">// Failed to get the list of active elements
   MSG_GRAPH_OBJ_FAILED_GET_OBJECT_NAMES,                  class=class="str">"cmt">// Failed to get object names
   MSG_GRAPH_OBJ_FAILED_DETACH_OBJ_FROM_LIST,              class=class="str">"cmt">// Failed to remove a graphical object from the list
   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_DISPLAY_STATE,                    class=class="str">"cmt">// Control display state
   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_FORE_COLOR,                       class=class="str">"cmt">// Default text class="type">color for all control objects
   MSG_CANV_ELEMENT_PROP_TOOLTIP_IS_BALLOON,               class=class="str">"cmt">// Tooltip in the form of a "cloud"
   MSG_CANV_ELEMENT_PROP_TOOLTIP_USE_FADING,               class=class="str">"cmt">// Fade when showing/hiding a tooltip
   MSG_CANV_ELEMENT_PROP_PROGRESS_BAR_MAXIMUM,             class=class="str">"cmt">// The upper bound of the range ProgressBar operates in
   MSG_CANV_ELEMENT_PROP_PROGRESS_BAR_MINIMUM,             class=class="str">"cmt">// The lower bound of the range ProgressBar operates in
   MSG_CANV_ELEMENT_PROP_PROGRESS_BAR_STEP,                class=class="str">"cmt">// ProgressBar increment needed to redraw it
   MSG_CANV_ELEMENT_PROP_PROGRESS_BAR_STYLE,               class=class="str">"cmt">// ProgressBar style
   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
class=class="str">"cmt">//--- Real properties of graphical elements
class=class="str">"cmt">//--- String properties of graphical elements
   MSG_CANV_ELEMENT_PROP_NAME_OBJ,                         class=class="str">"cmt">// Graphical element object name
   MSG_CANV_ELEMENT_PROP_NAME_RES,                         class=class="str">"cmt">// Graphical resource name
   MSG_CANV_ELEMENT_PROP_TEXT,                             class=class="str">"cmt">// Graphical element text
   MSG_CANV_ELEMENT_PROP_DESCRIPTION,                      class=class="str">"cmt">// Graphical element description
   MSG_CANV_ELEMENT_PROP_TOOLTIP_TITLE,                    class=class="str">"cmt">// Element tooltip title
   MSG_CANV_ELEMENT_PROP_TOOLTIP_TEXT,                     class=class="str">"cmt">// Element tooltip text
   };

「GUI 资源枚举里的双语映射细节」

在 MT5 自定义控件库里,大量界面元素和状态提示都用俄英双键值数组做本地化映射,上面这段就是标准写法:前半组是复选框三态(未勾选 / 勾选 / 不确定),接着是日志与进度条样式(None、Info、Warning、Error、User 及 Blocks/Continuous/Marquee 等 7 种)。 进度条相关有两条容易忽略:BarProgressBar 和 ProgressBar 是分开声明的控件名,Tooltip 不允许给同一个控件挂两个及以上,报错串写得很直白——"Can't add two or more ToolTips to one control"。 图形对象归属也有显式区分:"The graphic object belongs to the program" 与 "does not belong to the program" 各占一条,说明集合类 CGraphElementsCollection 在增删对象时会先判归属再操作。 实际调界面时,若你发现 tooltip 不弹或进度条不刷,优先核对这几条枚举字符串是否原样传入,而不是怀疑 OnTick 逻辑——这类坑 80% 出在资源名拼错。

MQL5 / C++
{"Не установлен","Unchecked"},
{"Установлен","Checked"},
{"Неопределённый","Indeterminate"},

{"None","None"},
{"Info","Info"},
{"Warning","Warning"},
{"Error","Error"},
{"Пользовательский","User"},
{"Сегментированные блоки","Blocks"},
{"Непрерывная полоса","Continuous"},
{"Непрерывная прокрутка","Marquee"},

{"Воскресение","Sunday"},
{"Понедельник","Monday"},
{"Элемент","Element"},
{"Объект тени","Shadow object"},
{"Объект блика","Glare object"},
{"Форма","Form"},
{"Окно","Window"},
{"Элемент управления \"HintMoveDown\"","Control element \"HintMoveDown\""},
{"Элемент управления \"ToolTip\"","Control element \"ToolTip\""},
{"Элемент управления BarProgressBar","Control element \"BarProgressBar\""},
{"Элемент управления ProgressBar","Control element \"ProgressBar\""},

{"Передан не правильный тип элемента управления","Wrong control type passed"},
{"Нельзя к одному элементу управления добавить два и более ToolTip","Can&class="macro">#x27;t add two or more ToolTips to one control"},
{"Графический объект принадлежит программе","The graphic object belongs to the program"},
{"Графический объект не принадлежит программе","The graphic object does not belong to the program"},
class=class="str">"cmt">//--- CGraphElementsCollection
{"Не удалось получить список вновь добавленных объектов","Failed to get the list of newly added objects"},
{"Не удалось получить список активных элементов","Failed to get list of active elements"},
{"Не удалось получить имена объектов","Failed to get object names"},
{"Не удалось изъять графический объект из списка","Failed to detach graphic object from the list"},
{"Ширина области верхней грани","Width of the top border area"},
{"Флаг отображения не скрытого элемента управления","Flag that sets the display of a non-hidden control"},
{"Состояние отображения элемента управления","Display state of the control"},
{"Продолжительность процесса отображения элемента управления","Duration of the process of displaying the control"},
{"Флаг доступности элемента","Element Availability Flag"},
{"Цвет текста по умолчанию для всех объектов элемента управления","Default text class="type">color for all objects in the control"},
{"Подсказка в форме \"облачка\"","Tooltip as \"Balloon\""},
{"Угасание при отображении и скрытии подсказки","Tooltip uses fading"}

◍ 进度条与图元属性的本地化映射

在自定义控件库里,进度条(ProgressBar)有一组必须暴露给多语言界面的属性字段。其取值范围由上下边界决定:上限对应「Upper bound of the range in which the ProgressBar operates」,下限对应「Lower bound of the range in which the ProgressBar operates」,当前值则被约束在 Min 到 Max 之间。 重绘逻辑依赖一个增量参数——「Increment value of the ProgressBar to redraw it」,即每次值变化超过该步长才触发重绘,避免高频刷新拖慢 MT5 终端。Marquee 样式下另有独立动画速度字段,控制滚动条循环速率。 字符串类属性覆盖图元对象名、图片资源名、显示文本、描述及两套悬浮提示(标题与正文)。下面这段局部代码给出了俄英双语文案表的收尾项与集合列表类的抽取方法,可直接拷进 ListObj.mqh 对照验证。 调用 CArrayObj::Detach 拿到的指针若为空,说明索引越界或列表未初始化,这在遍历动态创建的进度条实例时容易踩坑。外汇与贵金属图表加载此类 EA 控件存在渲染冲突可能,建议在策略测试器先跑空图验证。

MQL5 / C++
  {"Верхняя граница диапазона, в котором действует ProgressBar","Upper bound of the range in which the ProgressBar operates"},
  {"Нижняя граница диапазона, в котором действует ProgressBar","Lower bound of the range in which the ProgressBar operates"},
  {"Величина приращения значения ProgressBar для его перерисовки","Increment value of the ProgressBar to redraw it"},
  {"Стиль элемента ProgressBar","Progress Bar element style"},
  {"Текущее начение элемента ProgressBar в диапазоне от Min до Max","Current value of the ProgressBar in the range from Min to Max"},
  {"Скорость анимации полосы прогресса при стиле Marquee","Marquee style progress bar animation speed"},

class=class="str">"cmt">//--- String properties of graphical elements
  {"Имя объекта-графического элемента","The name of the graphic element object"},
  {"Имя графического ресурса","Image resource name"},
  {"Текст графического элемента","Text of the graphic element"},
  {"Описание графического элемента","Description of the graphic element"},
  {"Заголовок подсказки элемента","Element tooltip header"},
  {"Текст подсказки элемента","Element tooltip title"},
  };

class CListObj : class="kw">public CArrayObj
  {
class="kw">private:
   class="type">int               m_type;
class="kw">public:
   class="type">bool              DetachElement(const class="type">int index)
     {
      CObject *obj=CArrayObj::Detach(index);
把控件行为巡检交给小布盯盘
这些诊断小布盯盘的 AIGC 已内置,打开对应品种页即可看到面板对象的计时器负载与显隐异常,你只管调逻辑。

常见问题

活动对象列表只装需要在计时器里处理的指针,循环范围大幅缩小,界面动态化和动画帧交替才跑得顺,不至于每帧扫全量对象。
可以,小布盯盘的品种页会呈现控件计时器相关诊断,帮你定位是列表漏加还是事件处理写错,省去手动打点。
本篇第 2/3 篇只建属性和外观,运行行为留到第 3 篇实现,关于进度条完整讨论见《DoEasy 控件·实战篇》。
不需要,只在需要专门处理(如动画、显隐节奏)的类里实现,其余对象走默认空处理即可。
参考库里已有计时器的一组暂停、计数器增量和 ID 参数结构,按控件响应速度需求微调,外汇贵金属面板注意高频刷新下的资源占用风险。