#property copyright "Copyright 2025, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property version "1.00"
#define COORD_X 200
#define COORD_Y 100
#define OBJ_NAME "TestTextGetSizeBitmapLabel"
#define RES_NAME "TestTextGetSizeResource"
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 准备三行文本以输出到图表
string text1="This is the first line of text";
string text2="The second line also contains text";
string text3="Each word in each line has its own size";
string text_array1[]; // 用于从字符串1中取得单词集的数组
string text_array2[]; // 用于从字符串2中取得单词集的数组
string text_array3[]; // 用于从字符串3中取得单词集的数组
//--- 填充三个单词数组
if(!SplitTextIntoWords(text1, text_array1) || !SplitTextIntoWords(text2, text_array2) || !SplitTextIntoWords(text3, text_array3))
return;
//--- 当前图表 ID
long chart_id= ChartID();
//--- 声明图形资源的参数
uint rc_width =(int)ChartGetInteger(chart_id, CHART_WIDTH_IN_PIXELS);
uint rc_height=(int)ChartGetInteger(chart_id, CHART_HEIGHT_IN_PIXELS);
uint rc_data[];
uint rc_size=rc_width*rc_height;
//--- 创建用于文本输出的图形资源
if(!CreateResource(chart_id, rc_data, rc_width, rc_height))
return;
//--- 通过宽度和高度获取空格字符的大小
int space_w=0, space_h=0;
if(!TextGetSize(" ", space_w, space_h))
{
PrintFormat("%s: TextGetSize() failed. Error code %d",__FUNCTION__, GetLastError());
return;
}
//--- 将字符串之间的垂直缩进增加2,并在图表上绘制三个数组中的文本
space_h+=2;
TextArrayToChart(1, text_array1, COORD_X, COORD_Y+space_h*0, space_w, rc_data, rc_width, rc_height);
TextArrayToChart(2, text_array2, COORD_X, COORD_Y+space_h*1, space_w, rc_data, rc_width, rc_height);
TextArrayToChart(3, text_array3, COORD_X, COORD_Y+space_h*2, space_w, rc_data, rc_width, rc_height);
//--- 显示完所有文本后,更新资源数据
Update(RES_NAME, rc_data, rc_width, rc_height, true);
//--- 等待五秒钟,然后释放资源并删除图形对象
Sleep(5000);
ResourceFree(RES_NAME);
ObjectDelete(chart_id, OBJ_NAME);
/*
脚本执行后,图表上显示了三串文本
每个字符串中的每个单独单词与前一个单词相距一定距离显示,
等于使用TextGetSize()函数获得的前一个单词的文本宽度;
日志将包含每个字符串的所有单词及其大小:
Text array 1:
[0] word: "This", width=29, height=18
[1] word: "is", width=12, height=18
[2] word: "the", width=21, height=18
[3] word: "first", width=25, height=18
[4] word: "line", width=24, height=18
[5] word: "of", width=13, height=18
[6] word: "text", width=24, height=18
Text array 2:
[0] word: "The", width=26, height=18
[1] word: "second", width=51, height=18
[2] word: "line", width=24, height=18
[3] word: "also", width=29, height=18
[4] word: "contains", width=58, height=18
[5] word: "text", width=24, height=18
Text array 3:
[0] word: "Each", width=36, height=18
[1] word: "word", width=34, height=18
[2] word: "in", width=12, height=18
[3] word: "each", width=34, height=18
[4] word: "line", width=24, height=18
[5] word: "has", width=25, height=18
[6] word: "its", width=16, height=18
[7] word: "own", width=28, height=18
[8] word: "size", width=28, height=18
*/
}
//+----------------------------------------------------------------------------+
//| 使用空格分隔符(“”)将字符串拆分为单词数组 |
//+----------------------------------------------------------------------------+
bool SplitTextIntoWords(const string text, string &array[])
{
ResetLastError();
if(StringSplit(text, StringGetCharacter(" ", 0), array)<0)
{
PrintFormat("%s: StringSplit() failed. Error code %d",__FUNCTION__, GetLastError());
return(false);
}
return(true);
}
//+------------------------------------------------------------------+
//| 在图表上显示数组中的文本 |
//+------------------------------------------------------------------+
void TextArrayToChart(int array_num, string &array[], const int text_x, const int text_y, int space_w, uint &pixel_data[], const uint res_width, const uint res_height)
{
int width=0, height=0; // 文本宽度和高度
int x=text_x; // 输出文本的X坐标
//--- 打印一个包含已处理单词数组名称的标题
Print("Text array ", array_num,":");
//--- 按单词数组循环
int total=(int)array.Size();
for(int i=0; i<total; i++)
{
//--- 获取下一个单词并将其发送到图表中(我们在资源像素数组中绘制它)
string word=array[i];
TextOut(word, x, text_y, ANCHOR_LEFT_UPPER, pixel_data, res_width, res_height, ColorToARGB(clrDodgerBlue), COLOR_FORMAT_ARGB_NORMALIZE);
//--- 获取当前单词的文本大小
ResetLastError();
if(!TextGetSize(word, width, height))
{
PrintFormat("%s: TextGetSize(\"%s\") failed. Error code %d",__FUNCTION__, word, GetLastError());
continue;
}
//--- 打印日志中的文本数据 ― 单词、单词的宽度和高度,
//--- 然后将下一个单词的X坐标增加(单词宽度)+(空格宽度)
PrintFormat("[%d] word: \"%s\", width=%d, height=%d",i, word, width, height);
x+=width+space_w;
}
}
//+------------------------------------------------------------------+
//| 为整个图表创建图形资源 |
//+------------------------------------------------------------------+
bool CreateResource(const long chart_id, uint &pixel_data[], const uint width, const uint height)
{
//--- 设置像素数组的大小
ResetLastError();
uint size=width*height;
if(ArrayResize(pixel_data, size)!=size)
{
PrintFormat("%s: ArrayResize() failed. Error code %d",__FUNCTION__, GetLastError());
return(false);
}
//--- 用透明颜色填充像素数组,并基于它创建图形资源
ArrayInitialize(pixel_data, 0x00FFFFFF);
if(!ResourceCreate(RES_NAME, pixel_data, width, height, 0, 0, 0, COLOR_FORMAT_ARGB_NORMALIZE))
{
PrintFormat("%s: ResourceCreate() failed. Error code %d",__FUNCTION__, GetLastError());
return(false);
}
//--- 在图表左上角的坐标处创建图形标签对象
if(!ObjectCreate(0, OBJ_NAME, OBJ_BITMAP_LABEL, 0, 0, 0))
{
PrintFormat("%s: ObjectCreate() failed. Error code %d",__FUNCTION__, GetLastError());
return(false);
}
//--- 将创建的位图对象的宽度和高度设置为等于图形资源的宽度和高。
//--- 将对象锚点设置为其中心。
if(!ObjectSetInteger(chart_id, OBJ_NAME, OBJPROP_XSIZE, width))
{
PrintFormat("%s: ObjectSetInteger() failed. Error code %d",__FUNCTION__, GetLastError());
return(false);
}
if(!ObjectSetInteger(chart_id, OBJ_NAME, OBJPROP_YSIZE, height))
{
PrintFormat("%s: ObjectSetInteger() failed. Error code %d",__FUNCTION__, GetLastError());
return(false);
}
//--- 将之前为位图对象创建的图形资源指定为图像文件
//--- 在这种情况下,为了指示所使用的图形资源的名称,我们需要在其名称前添加“::”
if(!ObjectSetString(chart_id, OBJ_NAME, OBJPROP_BMPFILE, "::"+RES_NAME))
{
PrintFormat("%s: ObjectSetString() failed. Error code %d",__FUNCTION__, GetLastError());
return(false);
}
//--- 一切正常
return(true);
}
//+------------------------------------------------------------------+
//| 更新图形资源数据 |
//+------------------------------------------------------------------+
void Update(const string res_name, const uint &pixel_data[], const uint width, const uint height, const bool redraw)
{
//--- 如果传递零个维度,则离开
if(width==0 || height==0)
return;
//--- 更新资源数据并重新绘制图表
if(ResourceCreate(res_name, pixel_data, width, height, 0, 0, 0, COLOR_FORMAT_ARGB_NORMALIZE) && redraw)
ChartRedraw();
}
|