I have the following code to check for the DPI of a screen where a form is being displayed. It works correctly for regular (modeless) windows, but returns the DPI of the screen where the main window is displayed if the dialog is displayed modally. The apparent fault is with the call Process.GetCurrentProcess().MainWindowHandle, which seems to return the process ID of the main window (since presumably, the modal window runs under the calling window's process). Unfortunately, this causes layout issues when the DPI must be detected in the modal dialog and elements rearranged when it's dragged from one monitor to another.
How do I get the DPI of the window the modal dialog is being displayed on?
Thanks!
-Pete
Calling format:
Dim factor As Single = GetDpiWindowMonitor(Me) / 96.0
Code being called:
'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