我有以下代码来检查显示表单的屏幕的DPI。它对于常规(无模式)窗口可以正常工作,但是如果对话框以模态显示,则返回显示主窗口的屏幕的DPI。明显的错误是通过调用Process.GetCurrentProcess()。MainWindowHandle引起的,它似乎返回了主窗口的进程ID(因为模态窗口可能在调用窗口的进程下运行)。不幸的是,当必须在模式对话框中检测到DPI时,这会导致布局问题;当将DPI从一个监视器拖到另一个监视器时,会重新排列元素。
如何获取显示模式对话框的窗口的DPI?
谢谢!
-Pete
通话格式:
Dim factor As Single = GetDpiWindowMonitor(Me) / 96.0
被调用的代码:
'Get DPI of monitor containing this window by GetDpiForMonitor.
Public Function GetDpiWindowMonitor(ByVal curForm As Form) As Single
'Get handle to this window.
Process.GetCurrentProcess().Refresh()
Dim handleWindow As Integer = Process.GetCurrentProcess().MainWindowHandle
' ^^^ This seems to return the handle of the main window, not the dialog
'Get handle to monitor.
Dim handleMonitor As Integer = W32.MonitorFromWindow(handleWindow, W32.MONITOR_DEFAULTTONEAREST)
'Get DPI.
Dim curDPI As Integer = GetDpiSpecifiedMonitor(curForm, handleMonitor)
Return curDPI
End Function
'Get DPI of a specified monitor by GetDpiForMonitor.
Public Function GetDpiSpecifiedMonitor(ByVal curForm As Form,
ByVal handleMonitor As Integer) As Single
'Check if GetDpiForMonitor function is available.
If Not IsEightOneOrNewer() Then
If curForm.CurrentAutoScaleDimensions.Width = 0 Then
If FrmRegisteredTo.CurrentAutoScaleDimensions.Width > 0 Then
Return FrmRegisteredTo.CurrentAutoScaleDimensions.Width
Else
Return 96
End If
Else
Return curForm.CurrentAutoScaleDimensions.Width
End If
End If
'Get DPI.
Dim dpiX As UInteger
Dim dpiY As UInteger
Dim result As Integer = W32.GetDpiForMonitor(handleMonitor, W32.Monitor_DPI_Type.MDT_Default, dpiX, dpiY)
If (result <> 0) Then 'If not S_OK (= 0)
Throw New Exception("Failed to get DPI of monitor containing this window.")
End If
Return Convert.ToSingle(dpiX)
End Function