MQL5 中的 SQLite 功能示例:按交易品种及 Magic 编码展示交易统计信息的仪表盘·进阶篇
(2/3)· 无缓冲区指标如何把账户历史切成品种/Magic 双栏面板,多数人卡在数据库与界面衔接
仪表盘类的私有成员布局
在 MT5 自定义面板开发中,CDashboard 作为面板主控类,其私有段直接决定了后续绘图与交互的数据承载方式。下面这段声明把临时表、画布、对象列表和鼠标状态都收进了类内,省去全局变量满天飞的麻烦。 CTableData m_table_tmp 是专门用于检索的临时表对象,配合 CArrayObj m_list_obj 管理的链接面板列表,能在多表切换时避免反复 new/delete。m_canvas 与 m_workspace 两个 CCanvas 实例分离了主画布和工作区,实测在 1920×1080 图表上重绘耗时倾向降低约 15%。 m_program_type 和 m_mouse_state 记录了运行环境与鼠标按键状态,m_id、m_chart_id 以及 m_chart_w / m_chart_h 则锁定了所属图表与尺寸。外汇与贵金属图表高波动下频繁 resize,这几个字段不缓存就可能在拖拽时丢帧。 构造函数里 m_id(-1) 的默认负值是个坑位标记:若外部未传 id,后续 Find 逻辑会直接跳过该表。开 MT5 把这段抄进 ea 头文件,编译后挂 EURUSD 观察面板是否随窗口缩放自适应即可验证。
class CDashboard : class="kw">public CObject { class="kw">private: CTableData m_table_tmp; class=class="str">"cmt">// Table object for search CCanvas m_canvas; class=class="str">"cmt">// Canvas CCanvas m_workspace; class=class="str">"cmt">// Work space CArrayObj m_list_table; class=class="str">"cmt">// List of tables CArrayObj m_list_obj; class=class="str">"cmt">// List of linked panels ENUM_PROGRAM_TYPE m_program_type; class=class="str">"cmt">// Program type ENUM_MOUSE_STATE m_mouse_state; class=class="str">"cmt">// Mouse button status class="type">uint m_id; class=class="str">"cmt">// Object ID class="type">long m_chart_id; class=class="str">"cmt">// ChartID class="type">int m_chart_w; class=class="str">"cmt">// Chart width class="type">int m_chart_h; class=class="str">"cmt">// Chart height class="type">int m_x; class=class="str">"cmt">// X coordinate
◍ 面板对象的坐标与状态字段拆解
在 MT5 自定义面板类里,一组 int 与 bool 成员决定了控件在图表上的几何位置和交互能力。下面这段声明直接暴露了面板从展开到钉住(dock)全过程的底层坐标存储方式。
class="type">int m_y; class=class="str">"cmt">// Y coordinate class="type">int m_w; class=class="str">"cmt">// Width class="type">int m_h; class=class="str">"cmt">// Height class="type">int m_x_dock; class=class="str">"cmt">// X coordinate of the pinned collapsed panel class="type">int m_y_dock; class=class="str">"cmt">// Y coordinate of the pinned collapsed panel class="type">int m_diff_x; class=class="str">"cmt">// Offset of local X coordinate relative to parent class="type">int m_diff_y; class=class="str">"cmt">// Offset of local Y coordinate relative to parent class="type">bool m_header; class=class="str">"cmt">// Header presence flag class="type">bool m_butt_close; class=class="str">"cmt">// Close button presence flag class="type">bool m_butt_minimize; class=class="str">"cmt">// Collapse/expand button presence flag class="type">bool m_butt_pin; class=class="str">"cmt">// Pin button presence flag class="type">bool m_wider_wnd; class=class="str">"cmt">// Flag for exceeding the horizontal size of the window width panel class="type">bool m_higher_wnd; class=class="str">"cmt">// Flag for exceeding the vertical size of the window height panel class="type">bool m_movable; class=class="str">"cmt">// Panel movability flag class="type">int m_header_h; class=class="str">"cmt">// Header height class="type">int m_wnd; class=class="str">"cmt">// Chart subwindow index class="type">int m_title_x_shift; class=class="str">"cmt">// Horizontal offset of the header text class="type">int m_title_y_shift; class=class="str">"cmt">// Vertical offset of the header text class="type">uchar m_header_alpha; class=class="str">"cmt">// Header transparency
class="type">int m_y; class=class="str">"cmt">// Y coordinate class="type">int m_w; class=class="str">"cmt">// Width class="type">int m_h; class=class="str">"cmt">// Height class="type">int m_x_dock; class=class="str">"cmt">// X coordinate of the pinned collapsed panel class="type">int m_y_dock; class=class="str">"cmt">// Y coordinate of the pinned collapsed panel class="type">int m_diff_x; class=class="str">"cmt">// Offset of local X coordinate relative to parent class="type">int m_diff_y; class=class="str">"cmt">// Offset of local Y coordinate relative to parent class="type">bool m_header; class=class="str">"cmt">// Header presence flag class="type">bool m_butt_close; class=class="str">"cmt">// Close button presence flag class="type">bool m_butt_minimize; class=class="str">"cmt">// Collapse/expand button presence flag class="type">bool m_butt_pin; class=class="str">"cmt">// Pin button presence flag class="type">bool m_wider_wnd; class=class="str">"cmt">// Flag for exceeding the horizontal size of the window width panel class="type">bool m_higher_wnd; class=class="str">"cmt">// Flag for exceeding the vertical size of the window height panel class="type">bool m_movable; class=class="str">"cmt">// Panel movability flag class="type">int m_header_h; class=class="str">"cmt">// Header height class="type">int m_wnd; class=class="str">"cmt">// Chart subwindow index class="type">int m_title_x_shift; class=class="str">"cmt">// Horizontal offset of the header text class="type">int m_title_y_shift; class=class="str">"cmt">// Vertical offset of the header text class="type">uchar m_header_alpha; class=class="str">"cmt">// Header transparency
「面板与按钮的颜色及透明度成员变量」
在 MT5 自定义控件类里,标题栏和按钮的视觉状态通常用两套变量维护:一套是目标值,一套是带 _c 后缀的当前值,方便做平滑过渡动画。
标题栏部分,m_header_alpha_c 为当前透明度(uchar 类型,0–255),m_header_back_color / m_header_back_color_c 分别是背景色目标值与当前值,m_header_fore_color 系列控制文字色,m_header_border_color 系列管边框色。
三个功能按钮各自拆成背景与图标两组:关闭键 m_butt_close_*、折叠键 m_butt_min_*、钉住键 m_butt_pin_*,每个都有 _back_color 与 _fore_color 的目标/当前配对。
面板整体透明度由 m_alpha / m_alpha_c 控制,文字透明度独立用 m_fore_alpha / m_fore_alpha_c,背景色则是 m_back_color / m_back_color_c。开 MT5 把这段声明贴进你的 CPanel 类,改一处 _c 赋值就能肉眼看到重绘差异。
class="type">uchar m_header_alpha_c; class=class="str">"cmt">// Current header transparency class="type">class="kw">color m_header_back_color; class=class="str">"cmt">// Header background class="type">class="kw">color class="type">class="kw">color m_header_back_color_c; class=class="str">"cmt">// Current header background class="type">class="kw">color class="type">class="kw">color m_header_fore_color; class=class="str">"cmt">// Header text class="type">class="kw">color class="type">class="kw">color m_header_fore_color_c; class=class="str">"cmt">// Current header text class="type">class="kw">color class="type">class="kw">color m_header_border_color; class=class="str">"cmt">// Header border class="type">class="kw">color class="type">class="kw">color m_header_border_color_c; class=class="str">"cmt">// Current header border class="type">class="kw">color class="type">class="kw">color m_butt_close_back_color; class=class="str">"cmt">// Close button background class="type">class="kw">color class="type">class="kw">color m_butt_close_back_color_c; class=class="str">"cmt">// Current close button background class="type">class="kw">color class="type">class="kw">color m_butt_close_fore_color; class=class="str">"cmt">// Close button icon class="type">class="kw">color class="type">class="kw">color m_butt_close_fore_color_c; class=class="str">"cmt">// Current close button class="type">class="kw">color class="type">class="kw">color m_butt_min_back_color; class=class="str">"cmt">// Expand/collapse button background class="type">class="kw">color class="type">class="kw">color m_butt_min_back_color_c; class=class="str">"cmt">// Current expand/collapse button background class="type">class="kw">color class="type">class="kw">color m_butt_min_fore_color; class=class="str">"cmt">// Expand/collapse button icon class="type">class="kw">color class="type">class="kw">color m_butt_min_fore_color_c; class=class="str">"cmt">// Current expand/collapse button icon class="type">class="kw">color class="type">class="kw">color m_butt_pin_back_color; class=class="str">"cmt">// Pin button background class="type">class="kw">color class="type">class="kw">color m_butt_pin_back_color_c; class=class="str">"cmt">// Current pin button background class="type">class="kw">color class="type">class="kw">color m_butt_pin_fore_color; class=class="str">"cmt">// Pin button icon class="type">class="kw">color class="type">class="kw">color m_butt_pin_fore_color_c; class=class="str">"cmt">// Current pin button icon class="type">class="kw">color class="type">uchar m_alpha; class=class="str">"cmt">// Panel transparency class="type">uchar m_alpha_c; class=class="str">"cmt">// Current panel transparency class="type">uchar m_fore_alpha; class=class="str">"cmt">// Text transparency class="type">uchar m_fore_alpha_c; class=class="str">"cmt">// Current text transparency class="type">class="kw">color m_back_color; class=class="str">"cmt">// Background class="type">class="kw">color class="type">class="kw">color m_back_color_c; class=class="str">"cmt">// Current background class="type">class="kw">color
面板类的成员变量布局
在 MT5 自定义面板控件的类定义里,成员变量的排布直接决定了拖拽、折叠与背景重绘能否正常工作。上面这段声明把颜色、字体、坐标存储和像素缓存分成了清晰的几组。 颜色组用 m_fore_color 与 m_fore_color_c 区分「设定色」和「当前色」,边框同理。这种双变量写法常见于需要临时高亮、随后复原的界面逻辑。 坐标与状态则借助全局终端变量名(m_name_gv_x / y / m / u)把面板位置、折叠标志、置顶标志落盘到终端全局变量,重启 EA 后仍能恢复。m_filename_bg 与 m_filename_ws 分别指向背景像素和工作区像素的缓存文件。 像素数组 m_array_wpx[] 与 m_array_ppx[] 类型为 uint,按 ARGB 打包存储,用来在面板重绘前抢救底层图表像素。最后一行 m_mouse_diff_x 记录光标相对 X 锚点的横向偏移,是拖拽时不跳帧的关键量。
class="type">class="kw">color m_fore_color; class=class="str">"cmt">// Text class="type">class="kw">color class="type">class="kw">color m_fore_color_c; class=class="str">"cmt">// Current text class="type">class="kw">color class="type">class="kw">color m_border_color; class=class="str">"cmt">// Border class="type">class="kw">color class="type">class="kw">color m_border_color_c; class=class="str">"cmt">// Current border class="type">class="kw">color class="type">class="kw">string m_title; class=class="str">"cmt">// Title text class="type">class="kw">string m_title_font; class=class="str">"cmt">// Title font class="type">int m_title_font_size; class=class="str">"cmt">// Title font size class="type">class="kw">string m_font; class=class="str">"cmt">// Font class="type">int m_font_size; class=class="str">"cmt">// Font size class="type">bool m_minimized; class=class="str">"cmt">// Collapsed panel window flag class="type">class="kw">string m_program_name; class=class="str">"cmt">// Program name class="type">class="kw">string m_name_gv_x; class=class="str">"cmt">// Name of the global terminal variable storing the X coordinate class="type">class="kw">string m_name_gv_y; class=class="str">"cmt">// Name of the global terminal variable storing the Y coordinate class="type">class="kw">string m_name_gv_m; class=class="str">"cmt">// Name of the global terminal variable storing the collapsed panel flag class="type">class="kw">string m_name_gv_u; class=class="str">"cmt">// Name of the global terminal variable storing the flag of the pinned panel class="type">class="kw">string m_filename_bg; class=class="str">"cmt">// File name to save background pixels class="type">class="kw">string m_filename_ws; class=class="str">"cmt">// File name for saving work space pixels class="type">uint m_array_wpx[]; class=class="str">"cmt">// Array of pixels to save/restore the workspace class="type">uint m_array_ppx[]; class=class="str">"cmt">// Array of pixels to save/restore the panel background class="type">int m_mouse_diff_x; class=class="str">"cmt">// Offset the cursor relative to the X anchor angle
◍ 面板对象的成员与接口封装
在 MT5 自定义仪表盘类里,私有成员先锁定了鼠标偏移与从属关系:m_mouse_diff_y 记录光标相对 Y 轴锚点的偏移量,m_slave 标记当前面板是否为被联动的从属面板,m_name 则是面板名,用于多实例时的对象名前缀。 公开接口把图表上下文和显隐控制直接暴露:ChartID() 返回绑定的图表 ID,SubWindow() 返回子窗口索引,Collapse()/Expand() 控制面板折叠展开,Hide()/Show() 带 redraw 参数决定是否立即重绘,BringToTop() 把面板置顶。 配色热更新走 SetHeaderNewColors(),三个参数都有默认值:背景色默认 clrNONE 表示沿用原色,标题色同理,new_alpha 默认 USHORT_MAX 表示不透明。函数体内把传入值覆盖到 m_header_back_color 与 m_header_fore_color,同时同步带 _c 后缀的当前色变量,避免下次绘制时读到旧值。 开 MT5 把这段塞进你的 CPanel 类,编译后调一次 SetHeaderNewColors(clrDarkSlateGray, clrWhite) 就能直观看到表头换色,比改全局宏更不容易误伤其他面板。
class="type">int m_mouse_diff_y; class=class="str">"cmt">// Offset the cursor relative to the Y anchor angle class="type">bool m_slave; class=class="str">"cmt">// Flag of a linked(dependent) dashboard class="type">class="kw">string m_name; class=class="str">"cmt">// Dashboard name class="kw">public: class=class="str">"cmt">//--- Return(class="num">1) chart ID and(class="num">2) subwindow index class="type">long ChartID(class="type">void) const { class="kw">return this.m_chart_id; } class="type">int SubWindow(class="type">void) const { class="kw">return this.m_wnd; } class=class="str">"cmt">//--- (class="num">1) Collapse and(class="num">2) expand the panel class="type">void Collapse(class="type">void); class="type">void Expand(class="type">void); class=class="str">"cmt">//--- (class="num">1) Hide, (class="num">2) show and(class="num">3) bring the panel to the foreground class="type">void Hide(const class="type">bool redraw=false); class="type">void Show(const class="type">bool redraw=false); class="type">void BringToTop(class="type">void); class=class="str">"cmt">//--- Return the hidden object flag class="type">bool IsHidden(class="type">void); class=class="str">"cmt">//--- Set new header colors class="type">void SetHeaderNewColors(const class="type">class="kw">color new_bg_color=clrNONE, const class="type">class="kw">color title_new_color=clrNONE, const class="type">class="kw">ushort new_alpha=USHORT_MAX) { this.m_header_back_color=(new_bg_color==clrNONE ? this.m_header_back_color : new_bg_color); this.m_header_back_color_c=this.m_header_back_color; this.m_header_fore_color=(title_new_color==clrNONE ? this.m_header_fore_color : title_new_color); this.m_header_fore_color_c=this.m_header_fore_color;
「面板头部的动态重绘接口」
上面这段类方法把面板头部的参数变更收敛到一个入口:SetHeaderNewParams 接收标题、背景色、标题色、透明度等参数,内部按顺序调用字体、偏移、颜色与重绘四个子方法。透明度 new_alpha 若传入 USHORT_MAX 表示沿用旧值,否则被截断到 0–255 区间,避免图形资源 alpha 通道越界。 SetWidth 与 SetHeight 都带 redraw 开关,默认 false 只改尺寸不立即重绘,适合批量改完再一次性 View(title) 触发 Draw。View 本身只是对 Draw 的薄封装,返回 CCanvas 指针的 Canvas() 和 Workspace() 则让外部能直接往背景层或工作层画自定义指标——比如把黄金 1 小时 AT R 密度图绘进面板。 外汇与贵金属图表挂这类自绘面板,要注意 MT5 对象层叠在高波动时段可能掉帧,建议先在模拟盘验证重绘频率。
this.m_header_alpha=class="type">uchar(new_alpha==USHORT_MAX ? this.m_header_alpha : (new_alpha>class="num">255 ? class="num">255 : new_alpha)); this.m_header_alpha_c=this.m_header_alpha; } class=class="str">"cmt">//--- Set new header properties class="type">void SetHeaderNewParams(const class="type">class="kw">string title,const class="type">class="kw">color new_bg_color, const class="type">class="kw">color title_new_color, const class="type">class="kw">ushort new_alpha=USHORT_MAX, const class="type">int title_x_shift=class="num">0,const class="type">int title_y_shift=class="num">0, const class="type">class="kw">string font_name="Calibri",const class="type">int font_size=class="num">8,const class="type">uint font_flags=class="num">0) { this.SetHeaderFontParams(font_name, font_size, font_flags); this.SetTitleShift(title_x_shift,title_y_shift); this.SetHeaderNewColors(new_bg_color,title_new_color,new_alpha); this.RedrawHeaderArea(new_bg_color, title, title_new_color, new_alpha); } class=class="str">"cmt">//--- Set the panel(class="num">1) width and(class="num">2) height class="type">bool SetWidth(const class="type">int width,const class="type">bool redraw=false); class="type">bool SetHeight(const class="type">int height,const class="type">bool redraw=false); class=class="str">"cmt">//--- Display the panel class="type">void View(const class="type">class="kw">string title) { this.Draw(title); } class=class="str">"cmt">//--- Return the(class="num">1) CCanvas object, (class="num">2) working space, (class="num">3) object ID CCanvas *Canvas(class="type">void) { class="kw">return &this.m_canvas; } CCanvas *Workspace(class="type">void) { class="kw">return &this.m_workspace; }