当我们想知道一个字符串在屏幕上显示所占的区域大小,该怎么实现呢?
minigui提供了GetTabbedTextExtentPoint
函数用于计算一个字符串在屏幕显示的时候实际的显示区域大小.下面是GetTabbedTextExtentPoint
的函数声明(declared in minigui/gdi.h
)
MG_EXPORT int GUIAPI GetTabbedTextExtentPoint (HDC hdc,
const char* text, int len, int max_extent,
int* fit_chars, int* pos_chars, int* dx_chars, SIZE* size);
其中max_extent
用于指定显示的最大宽度,如果字符串太长超过这个长度,那么size.cx就是这个值。GetTabbedTextExtentPoint
的返回值是实际显示的字符数。
比如字符串”hello,world”,指定max_extent=40
,则函数返回值为5,代表对于40像素的宽度限制,只能显示前5个字符。返回的SIZE值为cx=40,cy=16
,代表屏幕显示宽度为40,高度为16(一行的高度)。
HDC hdc = GetDC(HWND_DESKTOP);
SIZE ls;
const char*pstr = "hello,world";
int offset = GetTabbedTextExtentPoint (hdc, "hello,world", strlen(pstr),
40, NULL, NULL, NULL, &ls);
// offset = 5, ls = {40,16}
ReleaseDC(hdc);
根据这个函数提供的功能,就可以实现计算多行文本显示区域大小(gnu c编译)。
#include <minigui/common.h>
#include <minigui/minigui.h>
#include <minigui/gdi.h>
#include <minigui/window.h>
// 计算文本显示需要的屏幕尺寸
// text 显示的文本,不可为NULL
// max_width 显示文本的最大屏幕宽度
// size 返回计算结果
// log_font 指定显示字体,为NULL使用缺省字体
// 计算成功返回值 TRUE,否则返回FALSE
BOOL compute_text_rect(const char*text,int max_width,SIZE *size,PLOGFONT log_font){
if (!size) {
return FALSE;
}
// 获取屏幕DC
HDC hdc = GetDC(HWND_DESKTOP);
PLOGFONT of = NULL;
// gnu c内置函数用于返回时释放DC
BOOL do_finally(BOOL ret)
{
if( HDC_SCREEN == hdc){
SelectFont(hdc,of);
}
ReleaseDC(hdc);
return ret;
}
if(log_font){
// 设置字体
of =SelectFont(hdc,log_font);
}
size->cx=0,size->cy=0;
// max_width 至少要大于一个字符宽度
if(!(max_width >= GetMaxFontWidth(hdc))){
return do_finally(FALSE);
}
SIZE ls;
const char *pstr = text ? text : "";
int offset = 0;
while(strlen(pstr += offset)){
// 计算一行的显示区域输出到ls,offset为实际输出了多少个字符
offset = GetTabbedTextExtentPoint (hdc, pstr, strlen(pstr),
max_width, NULL, NULL, NULL, &ls);
// 显示区域宽度为所有行的最大宽度
size->cx = MAX(size->cx,ls.cx);
// 显示区域高度累加一行的高度
size->cy += ls.cy;
// 继续处理剩下的字符
offset = MIN(offset,strlen(pstr));
}
return do_finally(TRUE);
}