利用MQL5创建您自己的图形面板(基础篇)
◍ 用MQL5搭一个自己的图形面板
在 MT5 里做自定义图形界面,不一定非得依赖第三方 EA 面板。MQL5 自带的 CAppDialog 和 CChartObject 体系,足够让你把按钮、输入框、状态标签直接画在图表上,而不是塞进独立的窗口。
官方示例最早发布于 2013 年 11 月 6 日,至今在终端里仍可编译运行;该帖历史浏览量约 7968 次、评论 35 条,说明这类基础面板需求长期存在。外汇与贵金属杠杆高、滑点随机,任何面板都只是辅助观察工具,信号决策仍需人工复核。
一个最小可行思路是:继承 CAppDialog 创建主面板类,在 OnInit 里 Create 控件,在 OnChartEvent 里捕获 CHARTEVENT_OBJECT_CLICK 做按钮响应。先跑通‘点按钮改标签文字’这一步,再谈复杂逻辑。
「用标准库类搭自定义面板到底多轻」
MQL5 标准库里有一组新类,专门给 MQL5 程序做独立控件对话框和显示面板用。它们的底层是事件驱动模型,所有组件都挂在终端自带的图表对象和事件系统上,不依赖外部 GUI 框架。 这类封装能直接落在这几种场景:图表子窗口里的显示面板、EA 交易的控制面板、以及完全自定义的显示控制台。 本文这一篇只演示其中一种——在独立图表子窗口里建一个自己的显示面板。你会发现基于标准库类,这件事的代码量比从零画对象小得多,开 MT5 拖一份标准库进来就能跑。
开箱即用的标准库控件清单
MT5 标准库把界面开发拆成了两层:简单控件和复杂控件,都封装在 Include\Controls 目录下,直接 #include 就能用,不用自己从零画窗体。 简单层有 7 个基础件:按钮(Button.mqh)和图按钮(BmpButton.mqh)负责鼠标交互,编辑框(Edit.mqh)做文本输入输出且能切只读,标签(Label.mqh)和面板(Panel.mqh)做辅助显示与分组,图像(Picture.mqh)纯装饰。 复杂层是在简单件上拼出来的:列表(List.mqh)用矩形+图按钮+编辑组合;下拉框(ComboBox.mqh)叠了编辑+图按钮+列表;SpinEdit.mqh 做枚举步进;RadioButton/RadioGroup 管单选,CheckBox/CheckGroup 管多选;Dialog.mqh 则是完整对话框骨架。 做 EA 面板时,先确认要交互的字段类型,再去对应 mqh 里抄类声明,能省掉 80% 的自定义重绘代码。外汇与贵金属界面开发同样面临平台断线、点差跳变等高风险,控件只解决交互不解决盈亏。
◍ 徒手搭一个无缓冲区的图表面板
在 MT5 里说的“显示面板”,指的是不占用任何绘图缓冲区、只在独立子窗口里用图表对象(OBJ_LABEL、OBJ_RECTANGLE 之类)呈现信息的自定义显示层。它不画 K 线也不画指标线,只负责把数值、文本、颜色状态直接贴到窗口上,适合做盯盘速读。 要落地这么一个面板,工程上最少需要两个文件:一个是包含文件(头文件),里面封装好面板类的描述与绘制逻辑;另一个是指标源码文件,作为挂载入口。两者分开,能让面板逻辑在多个指标间复用。 用 MQL5 向导可以一键生成这两类文件的模板,不用从零写框架。实操路径:在 MQL5\Indicators 下建一个独立文件夹(例如 MyIndicators),再在里面开一个子文件夹 MyPanel 放头文件。文件夹建法终端“帮助”里写了,照着点就行,这里不重复。 建完目录结构后,你打开 MT5 导航器应该能立刻看到空壳指标可被编译,这一步验证的是路径与文件归属有没有错——编译通过且子窗口能加载,面板骨架就算立住了。
「在 MT5 里建一个空对话框类」
在导航器窗口里定位到工作文件夹,右键选「New File」,向导里挑「New Class」一路 Next,填完类描述对话框点 Finish,MT5 会自动吐出一份头文件骨架。 生成的 CPanelDialog 直接继承标准库的 CAppDialog,目前构造函数和析构函数都是空壳,还没挂任何控件。真正让它能编译通过的,是文件末尾那行 #include <Controls\Dialog.mqh>,把基础对话框类拉了进来。 这套流程跑通后,指标里就能 #include 这个 mqh 并声明 CPanelDialog 对象,后续往里塞按钮、标签才有容器可用。外汇与贵金属交易自带高杠杆风险,自动化面板只是辅助观察,别当成下单依据。
class=class="str">"cmt">//+------------------------------------------------------------------ class=class="str">"cmt">//| PanelDialog.mqh | class=class="str">"cmt">//| Copyright class="num">2011, MetaQuotes Software Corp. | class=class="str">"cmt">//| [MQL5官方文档] | class=class="str">"cmt">//+------------------------------------------------------------------ class="macro">#class="kw">property copyright "Copyright class="num">2011, MetaQuotes Software Corp." class="macro">#class="kw">property link "[MQL5官方文档] class="macro">#class="kw">property version "class="num">1.00" class=class="str">"cmt">//+------------------------------------------------------------------ class=class="str">"cmt">//| | class=class="str">"cmt">//+------------------------------------------------------------------ class CPanelDialog : class="kw">public CAppDialog { class="kw">private: class="kw">public: CPanelDialog(); ~CPanelDialog(); }; class=class="str">"cmt">//+------------------------------------------------------------------ class=class="str">"cmt">//| | class=class="str">"cmt">//+------------------------------------------------------------------ CPanelDialog::CPanelDialog() { } class=class="str">"cmt">//+------------------------------------------------------------------ class=class="str">"cmt">//| | class=class="str">"cmt">//+------------------------------------------------------------------ CPanelDialog::~CPanelDialog() { } class=class="str">"cmt">//+------------------------------------------------------------------ class=class="str">"cmt">//+------------------------------------------------------------------ class=class="str">"cmt">//| PanelDialog.mqh | class=class="str">"cmt">//| Copyright class="num">2011, MetaQuotes Software Corp. | class=class="str">"cmt">//| [MQL5官方文档] | class=class="str">"cmt">//+------------------------------------------------------------------ class="macro">#include <Controls\Dialog.mqh> class=class="str">"cmt">//+------------------------------------------------------------------ class=class="str">"cmt">//| CPanelDialog类 |
对话框骨架先留空构造函数
把面板主体从 CAppDialog 继承出来,类名叫 CPanelDialog,这一步只是把 MT5 自定义程序面板的容器定义好,还没往里塞任何控件。 构造函数和析构函数目前都是空实现,意味着面板被创建和销毁时暂不执行额外逻辑。后面要挂按钮、图表对象或接小布信号,都得在这两个函数里补初始化与释放代码。 开 MT5 新建 EA 或指标工程,把这段类声明贴进文件,编译能通过就说明继承链没写错;空构造不会报错,但面板出来是块白板。
class=class="str">"cmt">//| 函数:主要应用程序对话框 | class=class="str">"cmt">//+------------------------------------------------------------------ class CPanelDialog : class="kw">public CAppDialog { class="kw">private: class="kw">public: CPanelDialog(class="type">void); ~CPanelDialog(class="type">void); }; class=class="str">"cmt">//+------------------------------------------------------------------ class=class="str">"cmt">//| 构造函数 | class=class="str">"cmt">//+------------------------------------------------------------------ CPanelDialog::CPanelDialog(class="type">void) { } class=class="str">"cmt">//+------------------------------------------------------------------ class=class="str">"cmt">//| 析构函数 | class=class="str">"cmt">//+------------------------------------------------------------------ CPanelDialog::~CPanelDialog(class="type">void) { } class=class="str">"cmt">//+------------------------------------------------------------------