У меня есть следующий код в проекте VisualStudio по умолчанию. Он передает DT_CALCRECT в DrawTextW, чтобы вычислить прямоугольник для рисования некоторого текста, затем он использует этот прямоугольник для рисования текста. Чтобы проверить это самостоятельно просто вставить этот код в проект в VisualStudio по умолчанию:DrawText с DT_CALCRECT и DT_RIGHT не работает
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, будет правильным размером для рисования текста (в реальном коде прямоугольник также используется для позиционирования окружающих элементов управления, поэтому просто расширение его волей-неволей действительно помогают). Я также ожидал бы, что текст будет правильно выровнен (т. Е. Напротив текста, выровненного слева), а не беспорядок, как показано на втором скриншоте выше. При правильном выравнивание по правому краю, я имею в виду, как показано на этом скриншоте WordPad:
Http: //i63.tinypic.com/qqya1u.png (. Пожалуйста, удалите пространство по этой ссылке, чтобы заставить его работать)
Что не так с этим кодом? Почему DT_CALCRECT с DT_RIGHT не дает ожидаемых результатов? Или, если это так, почему второй вызов DrawTextW не выводит его правильно?
Возможно ли, что есть пробелы в конце каждой строки на выровненном справа тексте, и поэтому ширина прямоугольника смещена? – VuVirt
Я не уверен, что вы подразумеваете под смещением. В обоих случаях это один и тот же текст. Это тот же код работает в обоих случаях. Единственное различие между двумя скриншотами заключается в том, что используется DT_RIGHT и другой DT_LEFT. Тем не менее DrawText рисует правую выровненную. – Alice
Нет, это не тот же текст. Левый выровненный на первом снимке экрана имеет дополнительный текст 123456. Я не уверен, что понимаю, какова ваша фактическая проблема. Можете ли вы объяснить, поскольку это не очевидно из скриншотов? – VuVirt