资源
在MQL4程序中使用图形和声音
MQL4中的程序允许处理声音和图形文件:
PlaySound() // 播放声音文件;
ObjectCreate() // 允许使用图形对象OBJ_BITMAP和OBJ_BITMAP_LABEL创建用户界面。
PlaySound()
调用示例:
//+-------------调用标准OrderSend()并播放声音 -----------------+
void OrderSendWithAudio()
{
double 用价= Ask;
//--- 下1手买单
int ticket= OrderSend(Symbol(),OP_BUY,1,price,3,0,0,"My order",16384,0,clrGreen);
if(ticket<0)
{
Print("发送买单出现错误失败 ,错码号 #",GetLastError());
//---如果错误, 从timeout.wav中播放声音
PlaySound("timeout.wav");
}
else {
Print("订单安置成功");
//--- 如果成功, 从Ok.wavL中播放声音
PlaySound("Ok.wav");
}
}
这个例子展示了如何播放来自文件“Ok”wav”和“timeout。wav’的声音,包含在标准终端包中。这些文件位于文件夹terminal_directory\ sound中。这里的terminal_directory是一个文件夹,MetaTrader 4客户端就是从这个文件夹开始启动的。通过mql4程序可以找到终端目录的位置,方法如下:
//--- -文件夹,其中存储终端数据
string terminal_path = TerminalInfoString(terminal_path);
您不仅可以使用文件夹terminal_directory\ sound中的声音文件,还可以使用位于terminal_data_directory\MQL4中的任何子文件夹中的声音文件。您可以通过终端菜单“File”->“Open Data Folder”或使用程序方法找到终端数据目录的位置:
//---文件夹,其中存储终端数据
string 电脑端路径= TerminalInfoString(TERMINAL_PATH);
例如,如果演示。wav声音文件位于terminal_data_directory\MQL4\Files中,然后调用PlaySound()应该是这样写的:
/ / ---播放演示。wav来自文件夹terminal_directory_data\MQL4\Files
PlaySound("\Files\Demo.wav");
请注意,在注释中,文件的路径是使用反斜杠“\”编写的,在函数中使用双反斜杠“\”。
在指定路径时,始终只使用双反斜杠作为分隔符,因为在处理程序源代码中的常量字符串和字符常量时,单个反斜杠是编译器的控制符号。
调用PlaySound()函数,参数为空:
//---调用PlaySound()的空参数会停止播放
PlaySound(NULL);
ObjectCreate()
在这个个EA的示例,使用了ObjectCreate()函数创建一个图形标签(OBJ_BITMAP_LABEL)。
string 标签名= "currency_label"; // OBJ_BITMAP_LABEL 物件的标签名
string 欧元= "\Images\euro.bmp"; // erminal_data_directory\MQL4\Images\euro.bmp 的所在路径
string 美元= "\Images\dollar.bmp"; // terminal_data_directory\MQL4\Images\dollar.bmp的所在路径
//+---------------------------初始化-------------------------+
int OnInit()
{
//--- 创建一个OBJ_BITMAP_LABEL按钮,(如果它还没有被创建)
if(ObjectFind(0,标签名)<0)
{
//--- 尝试创建OBJ_BITMAP_LABEL物件
bool 己创建= ObjectCreate(0,标签名,OBJ_BITMAP_LABEL,0,0,0);
if(created)
{
//--- 连接按钮在图表左上角
ObjectSetInteger(0,l标签名,OBJPROP_CORNER,CORNER_RIGHT_UPPER);
//--- now set up the object properties
ObjectSetInteger(0,标签名,OBJPROP_XDISTANCE,100);
ObjectSetInteger(0,l标签名,OBJPROP_YDISTANCE,50);
//---刷新最后错码为0 (0表示无错)
ResetLastError();
//---下载一个图片以提示按钮现在状况为"已通过"
bool 设置成功= ObjectSetString(0,标签名,OBJPROP_BMPFILE,0,euro);
//--- 测试结果
if(!设置成功) {
PrintFormat("从%s下载图片失败. 错码 %d",euro,GetLastError());
}
ResetLastError();
//---下载一个图片以提示按钮现在状况为"未通过"
设置成功= ObjectSetString(0,标签名,OBJPROP_BMPFILE,1,dollar);
if(!设置成功) {
PrintFormat("从%s下载图片失败. 错码 %d",dollar,GetLastError());
}
//--- 发送一个命令给图表 刷新出一个按钮,使其在一个tick上
ChartRedraw(0);
}
else{
//---物件未成功创建的通知
PrintFormat("创建 OBJ_BITMAP_LABEL.物件出错,错码 %d",GetLastError());
}
}
//--- 初始化成功
return(INIT_SUCCEEDED);
}
//+---------------------卸载函数--------------------------------+
void OnDeinit(const int reason)
{
//--- 从图表卸载物件
ObjectDelete(0,标签名);
}
本例中:
在OnInit()函数中,创建和设置名为currency_label的图形对象。图形文件的路径设置在全局变量欧元和美元中,分隔符使用了双重反作用力:
string euro ="\Images\euro.bmp"; // 文件路径为 terminal_dara_directory\MQL4\Images\euro.bmp
string dollar ="\Images\dollar.bmp"; // 文件路径为 terminal_dara_directory\MQL4\Images\dollar.bmp
带有图形界面的按钮的大小会自动调整为图片的大小。通过鼠标左键单击OBJ_BITMAP_LABEL物件 (必须在属性中选中“禁用选择”"Disable selection"选项)来更改图像。OBJ_BITMAP物件是用同样的方式创建的——它用于创建具必要的图像背景。
OBJPROP_BMPFILE属性值可以动态更改,该属性负责物件OBJ_BITMAP和OBJ_BITMAP_LABEL的外观。这允许为mql4程序创建各种交互式用户界面。
image.png
在编译mql4程序时,将资源包含到可执行文件中
mql4程序可能需要以图像和声音文件的形式提供大量不同的可下载资源。为了避免在MQL4中移动可执行文件时需要传输所有这些文件,应该使用编译器的指令:
.#resource path_to_resource_file
.#resource告诉电脑资源在指定的路径 path_to_resource_file 应该包含在可执行EX5文件中. 因此,所有必需的图像和声音都可以直接定位在EX4文件中, 这样如果你想在不同的终端上运行程序 , 就不需要分别传输其中使用的文件 。任何EX4文件都可以包含资源,任何EX4程序都可以使用其他EX4程序的资源。
格式为BMP和WAV的文件在包含到EX4文件之前会自动压缩。这表示除了在MQL4中创建完整的程序之外,使用资源还可以在使用图形和声音时减少所需文件的总大小,这与MQL4程序编写的通常方式不同。
资源文件大小不能超过16 Mb。
由编译器搜索指定的资源
使用命令#resource“,如:
.#resource "<path_to_resource_file>"
常量字符串的长度不能超过63个字符。
作为资源包含的文件和文件夹名称 必须是英文的。
编译器按以下顺序在指定的路径上搜索资源
如果反斜杠“\”分隔符(写为“\”)放在路径的开头,它会搜索相对于目录terminal_data_directory\MQL4\的资源,如果没有反斜杠,它会搜索相对于源文件的位置的资源,在源文件中,资源被写入。
资源路径不能包含子字符串。\ \ "和":\ \”。
资源包含的例子:
//---正确的资源规范
.#resource "\Images\euro.bmp" // euro.bmp位于terminal_data_directory\MQL4\Images
.#resource "picture.bmp" // picture.bmp 位于与源文件相同的目录中
.#resource "Resource\map.bmp" // resource 位于source_file_directory\Resource\map.bmp
//--- 规格不正确的资源
.#resource ":picture_2.bmp" // 必须不能包含 ":"
.#resource "..\picture_3.bmp" // 必须不能包含 ".."
.#resource "\Files\Images\Folder_First\My_panel\Labels\too_long_path.bmp" // 超过63个符号
利用资源
资源名称
在使用#resource指令声明资源之后,它可以用于程序的任何部分。资源的名称是其在行首没有反斜杠的路径,这将设置到资源的路径。要在代码中使用您自己的资源,应该在资源名之前添加特殊的“::”符号。
例子:
//---资源规范示例及其注释中的名称
.#resource "\Images\euro.bmp" // 资源名 - Images\euro.bmp
.#resource "picture.bmp" // 资源名- picture.bmp
.#resource "Resource\map.bmp" // 资源名 - Resource\map.bmp
.#resource "\Files\Pictures\good.bmp" // 资源名 - Files\Pictures\good.bmp
.#resource "\Files\Demo.wav"; // 资源名 - Files\Demo.wav"
.#resource "\Sounds\thrill.wav"; // 资源名 - Sounds\thrill.wav"
...
//---资源的利用
ObjectSetString(0,bitmap_name,OBJPROP_BMPFILE,0,"::Images\euro.bmp");
...
ObjectSetString(0,my_bitmap,OBJPROP_BMPFILE,0,"::picture.bmp");
...
set=ObjectSetString(0,bitmap_label,OBJPROP_BMPFILE,1,"::Files\Pictures\good.bmp");
...
PlaySound("::Files\Demo.wav");
...
PlaySound("::Sounds\thrill.wav");
应该注意的是,当将图像从资源设置为OBJ_BITMAP和OBJ_BITMAP_LABEL物件时,OBJPROP_BMPFILE属性的值不能手动修改。例如,为了创建OBJ_BITMAP_LABEL,我们使用资源euro。bmp和dollar.bmp。
.#resource "\Images\euro.bmp"; // euro.bmp 位于 terminal_data_directory\MQL4\Images
.#resource "\Images\dollar.bmp"; // dollar.bmp 位于terminal_data_directory\MQL4\Images
当查看这个物件的属性时,我们会看到属性位图文件(On)和位图文件(Off)都变暗了,无法手动更改:
使用其他mql4程序的资源
使用资源还有另一个好处——在任何MQL4程序中,都可以使用另一个EX4文件的资源。因此,一个EX4文件中的资源可以在许多其他mql4程序中使用。
为了使用来自另一个文件的资源名,应该将其指定为::。例如,假设Draw_Triangles_Script。mq5脚本包含一个资源到一个图像在the file triangle.bmp:
.#resource "\Files\triangle.bmp"
然后它的名字(用于脚本本身)看起来就像 "Files\triangle.bmp"。为了使用它,“::”应该添加到资源名中
//--- 使用脚本中的资源
ObjectSetString(0,my_bitmap_name,OBJPROP_BMPFILE,0,"::Files\triangle.bmp");
为了从另一个程序中使用相同的资源,例如从专家顾问中,我们需要向资源名添加到EX4文件的路径(相对于terminal_data_directory\MQL4\以及脚本的EX4文件的名称——Draw_Triangles_Script.ex4)。假设脚本位于标准文件夹terminal_data_directory\MQL4\Scripts\ Scripts中,那么调用应该这样写:
//---使用EA中脚本中的资源
ObjectSetString(0,my_bitmap_name,OBJPROP_BMPFILE,0,"\Scripts\Draw_Triangles_Script.ex4::Files\triangle.bmp");
如果从另一个EX4调用资源时没有指定到可执行文件的路径,则在包含调用资源的程序的同一个文件夹中搜索可执行文件。这意味着如果一个EA从Draw_Triangles_Script调用一个资源。ex4没有指定路径,如下:
//---在EA中调用脚本资源,而不指定路径
ObjectSetString(0,my_bitmap_name,OBJPROP_BMPFILE,0,"Draw_Triangles_Script.ex4::Files\triangle.bmp");
然后在文件夹terminal_data_directory\MQL4\Experts\ \专家\ \中搜索文件,如果Expert Advisor位于terminal_data_directory\MQL4\Experts\ \上。
使用作为资源包含的自定义指标
MQL4应用程序的操作可能需要一个或多个自定义指标。所有这些都可以包含在可执行的MQL5程序的代码中。将指标包含在资源中可以简化应用程序的分布。
下面是包含和使用SampleIndicator的例子。ex4自定义指标位于terminal_data_folder\MQL4\指标中
//+------------------------------------------------------------------+
//| SampleEA.mq4 |
//| Copyright 2013, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
.#resource "\Indicators\SampleIndicator.ex4"
.#property strict
//+----------------------初始化-----------------------------+
int OnInit()
{
//--- 获取自定义指标值
double value= iCustom(_Symbol,_Period,"::Indicators\SampleIndicator.ex4",0,0);
PrintFormat("Indicator: iCustom value=%f",value);
//--- ...
return(INIT_SUCCEEDED);
}
当OnInit()函数中的自定义指示器创建一个或多个自身副本时,需要特别考虑这种情况。请记住,资源应该按照以下方式指定:< path_EX4_file_name>::。
例如,if SampleIndicator。样品包括ex4指示剂。ex4 Expert Advisor作为资源,在自定义指示器的初始化函数中调用iCustom()时指定的路径如下所示:“\Expert \SampleEA.ex4::Indicators\SampleIndicator.ex4”。显式设置此路径时,SampleIndicator。ex4定制指示器严格连接到SampleEA。丧失独立工作的能力。
可以使用GetRelativeProgramPath()函数接收到自己的路径。其用法示例如下:
//+------------------------------------------------------------------+
//| SampleIndicator.mq4 |
//| Copyright 2013, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
.#property indicator_separate_window
//+--------------------------初始化-----------------------+
int OnInit()
{
//---提供链接到自身的错误方式
//--- string path= "\Experts\SampleEA.ex4::Indicators\SampleIndicator.ex4";
//---接收链接的正确方式
string path= GetRelativeProgramPath();
//--- 获得指标值
double value= iCustom(_Symbol,_Period,path,0,0);
PrintFormat("Path=%s, iCustom value=%f",path,value);
//---
return(INIT_SUCCEEDED);
}
///....
//+--------------------获得相关程序路径------------------------+
string GetRelativeProgramPath()
{
int pos2;
//--- 获得应用程序的完全路径
string path=MQLInfoString(MQL_PROGRAM_PATH);
//---查找“\MQL4\”子字符串的位置
int pos =StringFind(path,"\MQL4\");
//---子字符串未找到-错误
if(pos<0)
return(NULL);
//---跳过“\ MQL4”目录
pos+=5;
//---跳过额外的“\”符号
while(StringGetCharacter(path,pos+1)=='\')
pos++;
//---如果这是一个资源,则返回相对于MQL5目录的路径
if(StringFind(path,"::",pos)>=0)
return(StringSubstr(path,pos));
//---为第一个MQL4子目录查找分隔符(例如,MQL4\指标)
//---如果没有找到,返回相对于MQL4目录的路径
if((pos2=StringFind(path,"\",pos+1))<0)
return(StringSubstr(path,pos));
//---返回相对于子目录的路径(例如,MQL4\指标)
return(StringSubstr(path,pos2+1));
}
//+------------------自定义指标迭代函数----------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const int begin,
const double& price[])
{
//---为下一次调用返回prev_computed值
return(rates_total);
}
网友评论