2016-10-31 2 views
0

У меня есть приложение Windows, которое я хочу хорошо смотреть на мониторах с высоким разрешением DPI. Приложение использует DEFAULT_GUI_FONT во многих местах, и созданный таким образом шрифт неправильно масштабируется.Использование DEFAULT_GUI_FONT в приложении с высоким разрешением DPI

Есть ли простой способ устранить эту проблему при не слишком большой боли?

+1

[Остановить использование DEFAULT_GUI_FONT.] (Https://blogs.msdn.microsoft.com/oldnewthing/20050707-00/?p=35013) Вам не повезло с любым шрифтом растрового изображения; Прости. – andlabs

+0

@andlabs, DEFAULT_GUI_FONT использует Tahoma в качестве шрифта по умолчанию, который является векторным. И когда я использую один монитор и устанавливаю DPI-Awareness для своего приложения, при изменении DPI на мониторе с помощью настроек разрешения Windows шрифт, полученный с DEFAULT_GUI_FONT, меняет его размер. – deserg

+0

Это неправда. Это растровый шрифт. https://blogs.msdn.microsoft.com/oldnewthing/20050707-00/?p=35013 Действительно, бросьте это уже. –

ответ

2

Вам необходимо получить NONCLIENTMETRICS от SystemParametersInfo (SPI_GETNONCLIENTMETRICS,), а затем использовать его данные LOGFONT, для создания собственного шрифта. или вы можете запросить у SystemParametersInfo() и использовать его

+0

Это как можно ближе к правильному ответу, как мы когда-либо действительно получим. Я лично лично использую 'lfMessageFont'; Я не уверен, есть ли лучший вариант. Просто сделайте это один раз в инициализации программы и используйте глобальную переменную для дескриптора. Если код усеян вызовами 'GetStockObject (DEFAULT_GUI_FONT)' и простая find-replace не поможет, вы можете сделать что-то вроде '#define GetStockObject (x) ((x) == DEFAULT_GUI_FONT? HMessageFont: (GetStockObject) (x)) 'или что-то в этом роде:/Зависит от того, как написан код. (Конечно, это означает, что вы также не вызываете 'DeleteObject()'.) – andlabs

0

Рекомендуемые шрифты для разных целей могут быть получены из структуры NONCLIENTMETRICS.

Для автоматического DPI-масштабируемых шрифтов (Windows 10 1607+, должны быть за монитор DPI-Aware):

// Your window's handle 
HWND window; 

// Get the DPI for which your window should scale to 
UINT dpi = GetDpiForWindow(window); 

// Obtain the recommended fonts, which are already correctly scaled for the current DPI 
NONCLIENTMETRICSW non_client_metrics; 

if (!SystemParametersInfoForDpi(SPI_GETNONCLIENTMETRICS, sizeof(non_client_metrics), &non_client_metrics, 0, dpi) 
{ 
    // Error handling 
} 

// Create an appropriate font(s) 
HFONT message_font = CreateFontIndirectW(&non_client_metrics.lfMessageFont); 

if (!message_font) 
{ 
    // Error handling 
} 

Для более старых версий Windows, вы можете использовать систему шириной DPI и масштабировать шрифт вручную (Windows 7+, должна быть система DPI-Aware):

// Your window's handle 
HWND window; 

// Obtain the recommended fonts, which are already correctly scaled for the current DPI 
NONCLIENTMETRICSW non_client_metrics; 

if (!SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(non_client_metrics), &non_client_metrics, 0) 
{ 
    // Error handling 
} 

// Get the system-wide DPI 
HDC hdc = GetDC(nullptr); 

if (!hdc) 
{ 
    // Error handling 
} 

UINT dpi = GetDeviceCaps(hdc, LOGPIXELSY); 

ReleaseDC(nullptr, hdc); 

// Scale the font(s) 
constexpr UINT font_size = 12; 

non_client_metrics.lfMessageFont.lfHeight = -((font_size * dpi)/72); 

// Create the appropriate font(s) 
HFONT message_font = CreateFontIndirectW(&non_client_metrics.lfMessageFont); 

if (!message_font) 
{ 
    // Error handling 
} 

NONCLIENTMETRICS также имеет много других шрифтов в нем. Обязательно выберите правильный вариант для своей цели.

Вы должны установить уровень осведомленности DPI в своем application manifest, как описано here для лучшей совместимости.