У меня возникли проблемы с некоторыми из моих владельцев, нарисованными списками на мониторах с высоким разрешением DPI в Windows 10 в диалоговом окне. Текст отрублен внизу. Мы видели проблему в Windows 7 и смогли ее исправить. Это не обязательно высокий DPI, но когда пользователь устанавливает другое масштабирование текста. Я решил проблему, поэтому я подумал (!), Используя CClientDC (обертка вокруг GetDC()) и вызывая GetTextMetrics(), чтобы определить высоту текста. Раньше наши значки всегда были выше нашего текста, поэтому это не проблема. С более крупными мониторами DPI мы видели, как некоторые клиенты сообщали о проблемах при масштабировании текста.Различия между GetDC() и BeginPaint()?
Теперь мы получаем новые отчеты под Windows 10. Первая проблема хорошо под Windows 7, но Windows 7 только масштабируется до 100, 125 и 150 процентов. Windows 10 (и, возможно, 8? - но без отчетов клиентов) позволяет определять масштабирование пользователя.
Итак, я несколько раз обнаружил проблему ... Я знал, что такое высота шрифта, когда я вызывал GetTextMetrics() во время WM_MEASUREITEM. Я пошел и добавил код для отладки того, что GetTextMetrics() было во время моего WM_DRAWITEM. Ну, они были разные - 20 пикселей в высоту во время WM_MEASUREITEM и 25 пикселей в высоту во время WM_DRAWITEM. Очевидно, что это проблема. Я хочу, чтобы GetTextMetrics() имел одинаковые результаты в обоих местах.
Я думал, что единственная реальная разница, о которой я мог думать, заключалась в том, что во время WM_MEASUREITEM я вызываю GetDC() через конструктор CClientDC, а во время WM_DRAWITEM я использую уже построенный HDC (который, вероятно, был из возврата GetPaint() внутри GDI32.dll или другой DLL системы).
Я думал, что, может быть, BeginPaint() делает что-то, как выбрать окна HFONT в HDC ...
Итак, в моем WM_MEASUREITEM после получения DC, я выбираю шрифт ListBox в HDC, и то я вызываю GetTextMetrics(). И вот, числа теперь совпадают в WM_MEASUREITEM и WM_DRAWITEM.
Однако, я не знаю, удался ли мне просто. На данный момент это всего лишь догадки.
Does BeginPaint() выбирает шрифт окна в DC, тогда как GetDC() не работает? Использует ли обработчик по умолчанию WM_PAINT для владельца, нарисованный LISTBOX или COMBOBOX, что-то вроде выбора шрифта окна в краску DC?
BOOL DpiAwareMeasureGraphItem(LPMEASUREITEMSTRUCT lpM, CWnd* pWnd)
{
int iItemHeight = INTERG_BITMAP_HEIGHT + 4;
if (pWnd)
{
CClientDC dc(pWnd);
if (dc.GetSafeHdc())
{
CFont* pOldFont = dc.SelectObject(pWnd->GetFont()); // seems to fix it on Windows 10, but is it luck?
TEXTMETRIC tm;
memset(&tm, 0, sizeof(tm));
dc.GetTextMetrics(&tm);
LONG tmHeight = tm.tmHeight + 4; //pad
iItemHeight = max(iItemHeight, tmHeight);
dc.SelectObject(pOldFont);
}
}
lpM->itemHeight = iItemHeight;
return (TRUE);
}
Windows 7, даже Vista, позволяет определять размер шрифта, заданного пользователем –
Спасибо. Я пошел в настройки, чтобы «доказать, что вы ошибаетесь», потому что я никогда его не видел. Затем я посмотрел на левую панель и увидел обстановку, которую я никогда раньше не видел. –