Найти позиционные координаты отображения относительно области рабочего стола

В примере, сделанном несколько лет назад для stackru, EnumDisplaySettings используется для загрузки структуры данных DEVMODE, которая имеет это определение:

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 и dmPelsHeight извлекаются в эту структуру данных. Это также работает для меня. Я также хочу найти позиционные координаты дисплея относительно области рабочего стола. Глядя на информацию в Центре разработки Windows по структуре DEVMODE, я вижу, что есть также параметр dmPosition, который является структурой POINTL. Это было исключено из определения типа DEVMODE, приведенного выше, и когда я его добавляю, dmPelsWidth и dmPelsHeight больше не получают нужную информацию.

Почему dmPosition опущен выше, и почему извлеченная информация больше не работает, когда я ее включаю?

Ссылка на пример: найти размер внешнего монитора в Excel VBA

1 ответ

Эта проблема заключается в том, что DEVMODE определение в C++ включает ( согласно 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;
    };
  };

union перекрывает два stuct параметры в той же памяти, первый относится к устройствам принтера, второй для устройств отображения. AFAIK эта техника не поддерживается в VBA

Поскольку вы пытаетесь получить данные для устройства отображения, измените Type DEVMODE определение к этому

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

Вы должны иметь возможность получить доступ к рабочему столу в dmPosition_X а также dmPosition_Y и до сих пор получить разрешение в dmPelsWidth а также dmPelsHeight

Другие вопросы по тегам