Как мне определить, установлен ли пользовательский шрифт (DPI) на small, large или что-то еще?

#.net #windows #vb.net #winforms #dpi

#.net #Windows #vb.net #winforms #dpi

Вопрос:

Мне нужно выяснить, установлен ли на экране пользователя обычный шрифт 96 dpi (маленький размер), большие шрифты 120 dpi или что-то еще. Как мне это сделать в VB.NET (предпочтительно) или C #?

Комментарии:

1. Собственный способ (написанный на Delphi, но использующий только собственный Windows API): var dc: HDC; res: integer; begin dc := GetDC(0); if dc <> 0 then try res := GetDeviceCaps(dc, LOGPIXELSX); finally ReleaseDC(0, dc) end;

2. Как предлагает Андреас, вы также можете вызвать функции Windows API GetDC и GetDeviceCaps , чтобы получить эту информацию, но вам придется использовать P / Invoke, чтобы получить к ним доступ из приложения .NET, и в этом мало пользы, поскольку Graphics класс уже так хорошо обернул это в управляемый код.

3. Но в любом случае, спасибо, что заплатили налоги !!

Ответ №1:

Лучший способ — просто позволить форме автоматически изменять размер на основе текущих настроек DPI пользователя. Чтобы это сделать, просто установите для AutoScaleMode свойства значение AutoScaleMode.Dpi и включите AutoSize свойство. Вы можете сделать это либо из окна свойств в конструкторе, либо с помощью кода:

 Public Sub New()
    InitializeComponent()

    Me.AutoScaleMode = AutoScaleMode.Dpi
    Me.AutoSize = True
End Sub
  

Или, если вам нужно знать эту информацию во время рисования (например, в Paint методе обработчика событий), вы можете извлечь информацию из DpiX и DpiY свойств экземпляра Graphics класса.

 Private Sub myControl_Paint(ByVal sender As Object, ByVal e As PaintEventArgs)
    Dim dpiX As Single = e.Graphics.DpiX
    Dim dpiY As Single = e.Graphics.DpiY

    ' Do your drawing here
    ' ...
End Sub
  

Наконец, если вам нужно определить уровень DPI «на лету», вам нужно будет создать временный экземпляр Graphics класса для вашей формы и проверить DpiX и DpiY свойства, как показано выше. CreateGraphics Метод класса form делает это очень простым в выполнении; просто убедитесь, что вы заключили создание этого объекта в Using инструкцию, чтобы избежать утечек памяти. Пример кода:

 Dim dpiX As Single
Dim dpiY As Single

Using g As Graphics = myForm.CreateGraphics()
    dpiX = g.DpiX
    dpiY = g.DpiY
End Using
  

Комментарии:

1. Привет и спасибо! Но связан ли dpi с размером экрана (X / Y) или с размером шрифта (доступен только X)? Другими словами, могу ли я быть уверен, что DpiX = DpiY во всех случаях? В противном случае новый шрифт выглядел бы растянутым, не так ли?

2. @Didier: Да, обычно DpiX будет эквивалентен DpiY. Если нет, это будет выглядеть растянутым. Это будет зависеть от разрешения и выбранных пользователем настроек DPI. Настройки small по умолчанию имеют DpiX = 96 и DpiY = 96. Настройки большого размера по умолчанию имеют DpiX = 120 и DpiY = 120. Вы могли бы проверить эту страницу MSDN в приложениях с высоким разрешением. Связанная страница с практическими рекомендациями превосходна.

Ответ №2:

Взгляните на свойства DpiX и DpiY. Например:

 using (Graphics gfx = form.CreateGraphics())
{
    userDPI = (int)gfx.DpiX;
}
  

В VB:

 Using gfx As Graphics = form.CreateGraphics()
    userDPI = CInt(gfx.DpiX)
End Using