title: Need to resolve HMONITOR --> deviceName (or deviceName --> HMONITOR) in windows
body: <p><strong>EDIT</strong> - See Update at end </p>
  
  <p>This is for Delphi 7.0 Build 4.453</p>
  
  <p><strong>Summary</strong></p>
  
  <p>I need to be able to take the Handle property from a TMonitor object (an element in the Monitors array in the TScreen component) which is a HMONITOR, and turn it into the string you would use in calls to <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd162611%28v=vs.85%29.aspx" rel="noreferrer">EnumDisplaySettings</a> as the lpszDeviceName parameter.</p>
  
  <p>(my end goal is to get a list of device settings from a given HMONITOR value, by passing the resolved lpszDeviceName into calls to EnumDisplaySettings).</p>
  
  <p><strong>Detailed Information</strong></p>
  
  <p>As mentioned above, the Screen.Monitors[x].Handle property is of type HMONITOR and is normally used to pass into the <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd144901%28v=vs.85%29.aspx" rel="noreferrer">GetMonitorInfo</a> function, which returns, geometry information, but no lpszDeviceName. (note: there is a <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/dd145066%28v=vs.85%29.aspx" rel="noreferrer">TMonitorInfoEx</a> structure that has a szDevice field, but it does not seem to get filled in on my system, even though i am setting the cbSize field to the appropriate size).</p>
  
  <p><strong>Alternatively</strong>, if i can use a szDeviceName to get the equivalent HMONITOR value, i could plug it into the following function, which would use it in a comparison (I have inserted a call to fictitious function called <strong>hMonitorFromDeviceName</strong> in the code below) to indicate how it would be used. </p>
  
  <pre><code>function GetMonitorDeviceName(hmon : HMONITOR) : string;
  var
    DispDev : TDisplayDevice;
    deviceName : string;
    nDeviceIndex : integer;
  begin
    Result := '';
  
    FillChar(DispDev, sizeof(DispDev),0);
    DispDev.cb := sizeof(DispDev);
  
    nDeviceIndex := 0;
    while (EnumDisplayDevices(nil, nDeviceIndex, DispDev, 0)) do
    begin
  
       if ( hMonitorFromDeviceName(DispDev.DeviceString) = hmon ) then
       begin
          Result := StrPas(DispDev.DeviceString);
          exit;
       end;
  
       inc(nDeviceIndex);
  
    end;
  end;
  </code></pre>
  
  <p><strong>Update</strong></p>
  
  <p>Thanks to David Heffernan, I have tested his solution, and here is a sample function to get the monitor name from a given handle:</p>
  
  <pre><code>function GetMonitorName(hmon : HMONITOR) : string;
  type
    TMonitorInfoEx = record
      cbSize: DWORD;
      rcMonitor: TRect;
      rcWork: TRect;
      dwFlags: DWORD;
      szDevice: array[0..CCHDEVICENAME - 1] of AnsiChar;
  end;
  var
    DispDev : TDisplayDevice;
    deviceName : string;
     monInfo : TMonitorInfoEx;
  begin
    Result := '';
  
    monInfo.cbSize := sizeof(monInfo);
    if GetMonitorInfo(hmon,@monInfo) then
    begin
  
      DispDev.cb := sizeof(DispDev);
       EnumDisplayDevices(@monInfo.szDevice, 0, DispDev, 0);
       Result := StrPas(DispDev.DeviceString);
  
    end;
  end;
  </code></pre>