find size of external monitor in excel vba

2019-05-18 21:20发布

问题:

To find the size of the monitor, I've been using:

Declare Function GetSystemMetrics32 Lib "user32" Alias "GetSystemMetrics" (ByVal Index As Long) As Long

and then:

Function getMonitorSize()
  monitorHeight = GetSystemMetrics32(1)
  monitorWidth = GetSystemMetrics32(0)
End Function

This works fine for the main monitor, but how do I find the size of an external monitor?

回答1:

EnumDisplayDevices tells you something about a monitor with a certain index. You can increment the index from 0 to whatever, until the function returns 0, which means there's no monitor with that index.

Then you call EnumDisplaySettings to figure the size.

Private Const ENUM_CURRENT_SETTINGS As Long = -1
Private Const DISPLAY_DEVICE_ATTACHED_TO_DESKTOP As Long = &H1
Private Const CCHDEVICENAME As Long = 32
Private Const CCHFORMNAME As Long = 32

Private Type DISPLAY_DEVICE
  cb As Long
  DeviceName As String * CCHDEVICENAME
  DeviceString As String * 128
  StateFlags As Long
  DeviceID As String * 128
  DeviceKey As String * 128
End Type

Private Type DEVMODE
  dmDeviceName As String * CCHDEVICENAME
  dmSpecVersion As Integer
  dmDriverVersion As Integer
  dmSize As Integer
  dmDriverExtra As Integer
  dmFields As Long
  dmOrientation As Integer
  dmPaperSize As Integer
  dmPaperLength As Integer
  dmPaperWidth As Integer
  dmScale As Integer
  dmCopies As Integer
  dmDefaultSource As Integer
  dmPrintQuality As Integer
  dmColor As Integer
  dmDuplex As Integer
  dmYResolution As Integer
  dmTTOption As Integer
  dmCollate As Integer
  dmFormName As String * CCHFORMNAME
  dmLogPixels As Integer
  dmBitsPerPel As Long
  dmPelsWidth As Long
  dmPelsHeight As Long
  dmDisplayFlags As Long
  dmDisplayFrequency As Long
End Type

Private Declare Function EnumDisplayDevices Lib "user32.dll" Alias "EnumDisplayDevicesA" (ByVal lpDevice As String, ByVal iDevNum As Long, ByRef lpDisplayDevice As DISPLAY_DEVICE, ByVal dwFlags As Long) As Long
Private Declare Function EnumDisplaySettings Lib "user32.dll" Alias "EnumDisplaySettingsA" (ByVal lpszDeviceName As String, ByVal iModeNum As Long, ByRef lpDevMode As DEVMODE) As Long

Dim indAdapter As Long, indDisplay As Long
Dim ddAdapters As DISPLAY_DEVICE, ddDisplays As DISPLAY_DEVICE
ddAdapters.cb = Len(ddAdapters):  ddDisplays.cb = Len(ddDisplays)

indAdapter = 0
Do Until EnumDisplayDevices(vbNullString, indAdapter, ddAdapters, 0) = 0

  If (ddAdapters.StateFlags And DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) = DISPLAY_DEVICE_ATTACHED_TO_DESKTOP Then

      Dim NullCharPos As Long
      NullCharPos = InStr(ddAdapters.DeviceName, vbNullChar)

      Dim CurDeviceName As String

      If NullCharPos > 0 Then
        CurDeviceName = Left$(ddAdapters.DeviceName, NullCharPos - 1)
      Else
        CurDeviceName = ddAdapters.DeviceName
      End If

      Dim dmode As DEVMODE
      dmode.dmSize = Len(dmode)

      EnumDisplaySettings CurDeviceName, ENUM_CURRENT_SETTINGS, dmode

      MsgBox "Width: " & dmode.dmPelsWidth
      MsgBox "Height: " & dmode.dmPelsHeight

  End If

  indAdapter = indAdapter + 1
Loop