图表更改事件

当更改图表尺寸、价格显示模式、比例或其他参数时,终端将发送无参数的 CHARTEVENT_CHART_CHANGE 事件。MQL 程序必须通过调用 ChartGet函数自行获取变更信息。

我们在 图表显示模式章节中的ChartModeMonitor.mq5示例中已经使用该事件。现在我们来看看另一个示例。

如你所知,MetaTrader 5 允许将当前图表的截屏保存为指定尺寸的文件(通过上下文菜单中的Save as Picture命令)。但这种获取截屏的方法并非适用于所有情况。具体来说,当需要包含工具提示的图像,或当输入字段类型的对象处于激活状态时(例如字段内文本被选中且文本光标可见),标准命令将无法满足需求,因为它会重新生成图表图像,而不会考虑窗口当前状态的细节特征。

获取窗口精确副本的唯一替代方法是使用终端外部的工具(例如通过 Windows 剪贴板的PrtSc键),但该方法无法保证所需的窗口尺寸。为了避免通过反复尝试或借助其他程序来选择尺寸,我们将创建一个名为 EventWindowSizer.mq5的指标,它会实时追踪用户设置的尺寸,并在注释中显示当前值。

所有操作均在OnChartEvent处理程序中完成,首先检查事件 ID 是否为 CHARTEVENT_CHART_CHANGE。窗口尺寸可通过 CHART_WIDTH_IN_PIXELSCHART_HEIGHT_IN_PIXELS 特性获取,以像素为单位。然而,它们返回的尺寸并未考虑边框,而截屏时通常需要包含边框。因此,我们将在注释中不仅显示特性值(标记为“Screen”),还会显示修正后的值(标记为“Picture”):宽度需增加 2 像素,垂直方向增加 1 像素(这是终端窗口渲染的特性)。

void OnChartEvent(const int idconst long &lparamconst double &dparamconst string &sparam)
{
   if(id == CHARTEVENT_CHART_CHANGE)
   {
      const int w = (int)ChartGetInteger(0CHART_WIDTH_IN_PIXELS);
      const int h = (int)ChartGetInteger(0CHART_HEIGHT_IN_PIXELS);
      // "Raw" sizes "as is" are displayed with the "Screen" mark,
      // correction for (-2,-1) is needed to include frames - it is displayed with the "Picture" mark,
      // correction for (-54,-22) is needed to include scales - it is displayed with "Including scales" flag.
      Comment(StringFormat("Screen: %d x %d\nPicture: %d x %d\nIncluding scales: %d x %d",
         whw + 2h + 1w + 2 + 54h + 1 + 22));
   }
}

此外,所得到的数值也未考虑时间和价格刻度。如果截屏尺寸还需要包含这些元素,则还需对它们的尺寸进行调整。遗憾的是,MQL5 API 并未提供获取这些尺寸的方法,因此我们只能通过经验确定:在标准 Windows 字体设置下,价格轴宽度为 54 像素,时间轴高度为 22 像素。这些常量可能因 Windows 版本而异,你需要编辑它们,或通过输入参数进行设置。

在图表上运行该指标后,尝试调整窗口大小,观察注释中的数值如何变化。

窗口截屏(注释中显示工具提示和当前尺寸)
窗口 s

窗口截屏(注释中显示工具提示和当前大小)