【发布时间】:2023-03-26 16:51:01
【问题描述】:
我在一个默认的 VisualStudio 项目中有以下代码。它将 DT_CALCRECT 传递给 DrawTextW 以计算矩形以绘制一些文本,然后使用该矩形来绘制文本。要自己测试,只需将此代码粘贴到默认 VisualStudio 项目中:
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
{
wchar_t txt[] = L"abcdef abcdef abcdef abcdef abcdef abcdef abcdef abcdef abcdef abcdef abcdef abcdef abcdef abcdef abcdef\r\nabc\r\n123456";
BOOL useDT_RIGHT = TRUE; // <<< ** SWITCH THIS BETWEEN TRUE AND FALSE **
wchar_t buf1[100] = {0};
wchar_t buf2[100] = {0};
RECT r1 = {0, 0, 192, 1000};
RECT r2 = {r1.right + 10, r1.top, r1.right + 400, r1.top + 100};
int ret1, ret2;
FillRect(hdc, &r1, (HBRUSH)GetStockObject(GRAY_BRUSH));
ret1 = DrawTextW(hdc, txt, -1, &r1,
DT_CALCRECT |
DT_WORDBREAK |
(useDT_RIGHT == FALSE ? DT_LEFT : DT_RIGHT)
);
if(ret1 == 0) MessageBoxW(NULL, L"ret1 == 0", NULL, MB_OK);
wsprintfW(buf1, L"useDT_RIGHT = %i\r\nDT_CALCRECT returned %i %i %i %i\r\nret1 = %i\r\n", useDT_RIGHT, r1.left, r1.top, r1.right, r1.bottom, ret1);
ret2 = DrawTextW(hdc, txt, -1, &r1,
DT_WORDBREAK |
(useDT_RIGHT == FALSE ? DT_LEFT : DT_RIGHT)
);
if(ret2 == 0) MessageBoxW(NULL, L"ret2 == 0", NULL, MB_OK);
wsprintfW(buf2, L"%sret2 = %i", buf1, ret2);
DrawTextW(hdc, buf2, -1, &r2, DT_LEFT);
}
EndPaint(hWnd, &ps);
break;
代码中,如果useDT_RIGHT设置为FALSE,文字左对齐,DT_CALCRECT返回正确的矩形,如下图:
http://i64.tinypic.com/2ptw2dk.png
如果useDT_RIGHT设置为TRUE,文本右对齐但DT_CALCRECT返回一个不正确的矩形,如下图:
http://i68.tinypic.com/nwx9co.png
或者更确切地说,它可能返回了一个正确的矩形,而随后实际绘制文本的调用是错误地绘制它,这是不可能的。
DT_CALCRECT 的文档说“如果有多行文本,DrawText 使用 lpRect 参数指向的矩形的宽度并扩展矩形的底部以绑定最后一行文本。如果最大的单词是比矩形更宽,宽度被扩大。如果文本小于矩形宽度,宽度被缩小。"
我期望的是 DrawTextW 返回的矩形将是绘制文本的正确大小(在实际代码中,矩形也用于定位周围的控件,所以只是随意扩展它不会真的帮助)。我还希望文本正确右对齐(即与左对齐文本相反),而不是上面第二个屏幕截图所示的混乱。我的意思是正确右对齐,如写字板的屏幕截图所示:
http: //i63.tinypic.com/qqya1u.png (请删除此链接中的空格以使其正常工作。)
这段代码有什么问题?为什么带有 DT_RIGHT 的 DT_CALCRECT 不能产生预期的结果?或者,如果是,为什么对 DrawTextW 的第二次调用没有正确绘制它?
【问题讨论】:
-
是否有可能是右对齐文本的每一行末尾都有空格,这就是矩形宽度偏移的原因?
-
我不确定你所说的偏移是什么意思。在这两种情况下都是相同的文本。在这两种情况下运行的是相同的代码。两个屏幕截图之间的唯一区别是一个使用 DT_RIGHT,另一个使用 DT_LEFT。然而 DrawText 正在绘制右对齐的错位。
-
不,这不是同一个文本。第一个屏幕截图中左对齐的有一个额外的 123456 文本。我不确定我是否了解您的实际问题。您能解释一下,因为从屏幕截图中看不出来吗?
-
你也可以试试 DT_EDITCONTROL 看看是否有什么不同。
-
我刚试过 DT_EDITCONTROL 但没有任何区别。它是相同的文本。在第二个屏幕截图中,DrawText 无法绘制 123456。如果将代码粘贴到默认的 VS 项目中,您可以自己查看。我的实际问题如上所述。 DrawText 在传递该文本 DT_CALCRECT 和 DT_LEFT 时返回一个矩形,该矩形可用于第二次调用 DrawText 以实际绘制文本。如果你做同样的事情,只将 DT_LEFT 更改为 DT_RIGHT,矩形要么太小,要么第二次调用 DrawText 绘制的文本被破坏。