使用 #resource 指令描述资源
要在编译后的程序版本中包含资源文件,请在源代码中使用 #resource 指令。根据文件类型的不同,该指令有不同的形式。无论如何,该指令都包含 #resource 关键字,后面跟一个常量字符串。
#resource "path_file_name" |
#resource 命令指示编译器在生成的可执行程序中包含一个文件(二进制格式 ex5),该文件具有指定的名称和可选位置(编译时)。路径是可选项:如果字符串中只包含文件名,则会在编译后的源代码旁边的目录中搜索到。如果字符串中包含路径,则适用以下规则。
编译器会按以下顺序在指定路径下查找资源:
- 如果路径前有反斜杠 '\\'(必须是双斜杠,因为单反斜杠是控制字符;特别是,'\' 用于换行符 '\r'、'\n' 和制表符 '\t'),则从终端数据目录内的 MQL5 文件夹开始搜索资源。
- 如果没有反斜杠,则相对于注册该资源的源文件的位置搜索资源。
请注意,在包含资源路径的常量字符串中,必须使用双反斜杠作为分隔符。与文件系统中的路径不同,这里不支持正向单斜杠。
例如:
#resource "\\Images\\euro.bmp" // euro.bmp is in /MQL5/Images/
|
如果资源在 mqh 头文件中声明了相对路径,则该路径将被视为相对于该 mqh 文件,而不是相对于正在编译的程序的 mq5 文件。
资源路径中不允许使用子字符串 "..\\" 和 ":\\"。
例如,使用一些指令,你可以将所有必要的图片和声音直接放入 ex5 文件中。这样,在另一个终端运行这样的程序时,就不需要单独传输它们了。我们将在接下来的各节中讨论从 MQL5 中访问资源的编程方法。
常量字符串 "path_file_name" 长度不得超过 63 个字符。资源文件大小不能超过 128 Mb。资源文件在纳入可执行文件中之前会自动压缩。
资源由 #resource 指令声明后,可在程序的任何部分使用。资源名称将变为指令中指定的常量字符串,开头不加斜线(如果有),字符串内容前应加上资源的特殊符号(两个冒号,"::")。
下面我们将举例说明资源,并在注释中列出其名称。
#resource "\\Images\\euro.bmp" // resource name - ::Images\\euro.bmp
|
在后续的 MQL 代码中,可以按如下方式引用这些资源(在此,我们只知道 ObjectSetString 和 PlaySound 函数,但还有其他选项,如 ResourceReadImage,将在后续各节中介绍)。
ObjectSetString(0, bitmap_name, OBJPROP_BMPFILE, 0, "::Images\\euro.bmp");
|
需要注意的是,将资源中的图像设置为 OBJ_BITMAP 和 OBJ_BITMAP_LABEL 对象时,不能手动更改 OBJPROP_BMPFILE 属性的值(在对象的属性对话框中)。
请注意,默认情况下,PlaySound 函数会相对于终端数据目录下的 Sounds 文件夹(或其子文件夹)设置 wav 文件。同时,如果资源(包括声音资源)在路径中带有斜线,则会在 MQL5 目录中搜索。因此,在上面的示例中,"\\Sounds\\thrill.wav" 字符串指的是 MQL5/Sounds/thrill.wav 文件,而不是相对于数据目录的 Sounds/thrill.wav(确实有一个包含标准终端声音的 Sounds 目录)。
上面讨论的 #resource 指令的简单语法只允许描述图像资源(BMP 格式)和声音资源(WAV 格式)。试图将不同类型的文件描述为资源时,会出现“未知资源类型”错误。
经过 #resource 指令处理后,文件实际上已嵌入可执行二进制程序,并可通过资源名称访问。此外,还应注意此类资源的一个特殊属性,即它们可以从其他程序中公开获取(下一节将详细介绍)。
MQL5 还支持在程序中嵌入文件的另一种方式:以 资源变量一节中显示了相关示例。此方法使用 #resource 指令的扩展语法,不仅可以连接 BMP 或 WAV 文件,还可以连接其他文件,例如文本或结构体数组。
我们将在后面几节分析连接资源的实际例子。