在对象上定义锚点

某些类型的对象允许选择锚点。属于此范畴的对象类型包括与报价关联的文本标签 (OBJ_TEXT) 和位图图像 (OBJ_BITMAP),以及按屏幕坐标定位的标题 (OBJ_LABEL) 和带图像的面板 (OBJ_BITMAP_LABEL)。

要读取和设置锚点,可使用带有 OBJPROP_ANCHOR 特性的 ObjectGetIntegerObjectSetInteger

所有锚点选择选项均包含在 ENUM_ANCHOR_POINT 枚举中。

标识符

锚点位置

ANCHOR_LEFT_UPPER

左上角

ANCHOR_LEFT

左侧居中

ANCHOR_LEFT_LOWER

左下角

ANCHOR_LOWER

底部居中

ANCHOR_RIGHT_LOWER

右下角

ANCHOR_RIGHT

右侧居中

ANCHOR_RIGHT_UPPER

右上角

ANCHOR_UPPER

顶部居中

ANCHOR_CENTER

对象正中心

这些锚点在下图中清晰可见,图中的图表应用了多个标签对象。

具有不同锚点的 OBJ_LABEL 文本对象

具有不同锚点的 OBJ_LABEL 文本对象

上方的四个标签组具有相同的坐标对 (X,Y),但由于锚定到对象的不同角落,它们位于该点的不同侧面。第二组四个文本标签的情况类似,但它们锚定到对象不同侧面的中点。最后,底部单独显示的标题锚定在其中心位置,因此该点位于对象内部。

按钮 (OBJ_BUTTON)、矩形面板 (OBJ_RECTANGLE_LABEL)、输入字段 (OBJ_EDIT) 和图表对象 (OBJ_CHART) 的锚点固定在左上角 (ANCHOR_LEFT_UPPER)。

单价格标记组中的某些图形对象(OBJ_ARROW、OBJ_ARROW_THUMB_UP、OBJ_ARROW_THUMB_DOWN、OBJ_ARROW_UP、OBJ_ARROW_DOWN、OBJ_ARROW_STOP 和 OBJ_ARROW_CHECK)具有两种坐标锚定方式,这些方式由另一个枚举类型 ENUM_ARROW_ANCH OR 的标识符指定。

标识符

锚点位置

ANCHOR_TOP

顶部居中

ANCHOR_BOTTOM

底部居中

该组其余对象具有预定义锚点:买入箭头 (OBJ_ARROW_BUY) 和卖出箭头 (OBJ_ARROW_SELL) 分别位于上边缘和下边缘的中间位置,而价格标签(OBJ_ARROW_RIGHT_PRICE 和 OBJ_ARROW_LEFT_PRICE)则分别位于左侧和右侧。

与上一节的 ObjectCornerLabel.mq5脚本类似,我们将创建ObjectAnchorLabel.mq5 脚本。在新版本中,除移动标注外,我们还将随机更改其中的锚点。

与之前一样,窗口锚定角点仍将由用户在脚本启动时选择。

input ENUM_BASE_CORNER Corner = CORNER_LEFT_UPPER;

我们将在图表上以注释形式显示该角点的名称。

void OnStart()
{
   Comment(EnumToString(Corner));
   ...

在无限循环中,将在选定时间生成 9 种可能的锚点值之一。

   ENUM_ANCHOR_POINT anchor = 0;
   for( ;!IsStopped(); ++pass)
   {
      if(pass % 50 == 0)
      {
        ...
         anchor = (ENUM_ANCHOR_POINT)(rand() * 9 / 32768);
         ObjectSetInteger(0nameOBJPROP_ANCHORanchor);
      }
      ...

锚点名称将与当前坐标一并成为标签的文本内容。

      ObjectSetString(0nameOBJPROP_TEXTEnumToString(anchor)
         + "[" + (string)x + "," + (string)y + "]");

其余代码片段基本保持不变。

编译并运行脚本后,请注意标注如何根据所选锚点相对于当前坐标 (x, y) 改变位置。

目前,我们已能控制锚点,并可防止其本身超出窗口范围。但对象具有一定尺寸,因此可能出现标注大部分内容被被截断的情况。在未来学习相关特性后,我们将解决此问题(请参阅 确定对象宽度和高度章节中的 ObjectSizeLabel.mq5示例)。