我在默认的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的文档说&#34;如果有多行文本,DrawText使用lpRect参数指向的矩形的宽度,并扩展矩形的底边以绑定最后一行文本。如果最大的单词比矩形宽,则扩展宽度。如果文本小于矩形的宽度,则宽度会减小。&#34;
我所期望的是DrawTextW返回的矩形是正确的大小来绘制文本(在实际代码中,矩形也用于定位周围的控件,所以只需扩展它就可以赢得&#39;真的有帮助)。我还希望文本正确对齐(即与左对齐文本相反),而不是如上面第二个屏幕截图所示的混乱。通过正确对齐,我的意思是如wordpad的截图所示:
HTTP: //i63.tinypic.com/qqya1u.png (请从此链接中删除空格以使其正常工作。)
这段代码有什么问题?为什么带有DT_RIGHT的DT_CALCRECT不能产生预期的结果?或者,如果是,为什么第二次调用DrawTextW没有正确绘制它?
答案 0 :(得分:1)
这种行为似乎是一个错误或设计。也许DT_WORDBREAK会删除空格,这就是使用DT_RIGHT时产生更窄矩形的原因。无论如何,当使用DT_CALCRECT与DT_LEFT或DT_RIGHT时,这是一种使DrawText的行为方式相同的方法,您可以测试此代码(检查以FIX开头的注释):
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 = FALSE; // 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);
// FIX: The following two lines make DrawText with DT_CALCRECT behave the same way for DT_LEFT and DT_RIGHT
r1.right = 192;
r1.bottom = ret1;
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;