Find Positional Coordinates of Display Relative to Desktop Area

313 Views Asked by At

In an example from several years ago on stackoverflow, EnumDisplaySettings is used to load data structure DEVMODE that has this definition:

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

dmPelsWidth and dmPelsHeight are retrieved into this data structure. This also works for me. I also want to find positional coordinates of the display relative to the desktop area. Looking at the information in Windows Dev Center on the DEVMODE structure, I see there is also a dmPosition parameter that is a POINTL structure. This has been left out of the DEVMODE type definition above and when I add it, dmPelsWidth and dmPelsHeight no longer retrieve the right info.

Why was dmPosition omitted above, and why is the retrieved info no longer working when I include it?

Link to the example: find size of external monitor in excel vba

1

There are 1 best solutions below

1
On

This issue is that DEVMODE definition in C++ includes (according to Microsoft)

  union {
    struct {
      short dmOrientation;
      short dmPaperSize;
      short dmPaperLength;
      short dmPaperWidth;
      short dmScale;
      short dmCopies;
      short dmDefaultSource;
      short dmPrintQuality;
    };
    struct {
      POINTL dmPosition;
      DWORD  dmDisplayOrientation;
      DWORD  dmDisplayFixedOutput;
    };
  };

the union overlays the two stuct options on the same memory, the first relavent to printer devices, the second to display devices. AFAIK this technique is not supported in VBA

Since you are trying to get data for a display device, change the Type DEVMODE definition to this

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
    dmPosition_X As Long
    dmPosition_Y As Long
    dmDisplayOrientation As Long
    dmDisplayFixedOutput As Long

  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

You should be able to access desktop position in dmPosition_X and dmPosition_Y and still get resolution in dmPelsWidth and dmPelsHeight