管理对象的按下状态

对于按钮 (OBJ_BUTTON) 和带图像的面板 (OBJ_BITMAP_LABEL) 等对象,终端支持一种特殊特性,可直观地将对象在正常(释放)状态与按下状态之间进行双向切换。预留常量 OBJPROP_STATE 便是用于这种情况。该特性为布尔类型:当值为 true时,对象被视为处于按下状态;当值为 false 时则被视为处于释放状态(默认)。

对于 OBJ_BUTTON,终端将自行绘制三维边框效果;而对于 OBJ_BITMAP_LABEL,程序员必须指定两张图像(作为文件或 资源),以提供合适的外观展示。由于该特性在技术上只是一个切换开关,因此除了用于“按下”和“释放”效果外,也很容易将其用于其他用途。例如,借助合适的图像,你可以实现一个标志(选项)功能。

将在下一节中讨论如何在对象中使用图像。

在交互式 MQL 程序中,对象状态通常会随用户操作(特别是鼠标点击)而改变。我们将在 事件一章中讨论这种可能性。

现在让我们在静态模式下,通过简单按钮来测试该特性。ObjectButtons.mq5脚本会在图表上创建两个按钮:一个处于按下状态,另一个处于释放状态。

单个按钮的设置工作由 SetupButton函数完成,该函数通过参数指定按钮的名称、文本、坐标、大小和状态。

#include "ObjectPrefix.mqh"
   
void SetupButton(const string button,
   const int xconst int y,
   const int dxconst int dy,
   const bool state = false)
{
   const string name = ObjNamePrefix + button;
   ObjectCreate(0nameOBJ_BUTTON000);
   // position and size
   ObjectSetInteger(0nameOBJPROP_XDISTANCEx);
   ObjectSetInteger(0nameOBJPROP_YDISTANCEy);
   ObjectSetInteger(0nameOBJPROP_XSIZEdx);
   ObjectSetInteger(0nameOBJPROP_YSIZEdy);
   // label on the button
   ObjectSetString(0nameOBJPROP_TEXTbutton);
   
   // pressed (true) / released (false)
   ObjectSetInteger(0nameOBJPROP_STATEstate);
}

然后在 OnStart函数中调用该函数两次。

void OnStart()
{
   SetupButton("Pressed"10010010020true);
   SetupButton("Normal"10015010020);
}

以下是脚本运行后,两个按钮在图表上的预期显示效果示意图:

按下和释放状态的 OBJ_BUTTON 按钮

按下和释放状态的 OBJ_BUTTON 按钮

有趣的是,你可以用鼠标点击任意一个按钮,按钮将改变其状态。不过,我们尚未探讨如何拦截相关状态变更通知。

需特别注意,只有当对象特性中选中Disable selection选项时,才会执行这种自动状态切换,而通过编程创建的所有对象默认均满足此条件。需注意,必要时可通过显式设置 OBJPROP_SELECTABLE 特性为true启用此选择功能。我们在先前的一些示例中已使用过该特性。

要移除不再需要的按钮,请使用 ObjectCleanup1.mq5脚本。