Note that there are some explanatory texts on larger screens.

plurals
  1. PONeed to resolve HMONITOR --> deviceName (or deviceName --> HMONITOR) in windows
    text
    copied!<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="nofollow">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="nofollow">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="nofollow">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>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload