编辑-参见末尾更新
这是用于Delphi 7.0 Build 4.453
摘要
我需要能够从属于HMONITOR的TMonitor对象(TScreen组件的Monitors数组中的元素)中获取Handle属性,并将其转换为在EnumDisplaySettings调用中用作lpszDeviceName参数的字符串。
(我的最终目标是通过将解析的lpszDeviceName传递给对EnumDisplaySettings的调用,从给定的HMONITOR值获取设备设置的列表)。
详细信息
如上所述,Screen.Monitors [x] .Handle属性的类型为HMONITOR,通常用于传递给GetMonitorInfo函数,该函数返回几何信息,但不返回lpszDeviceName。 (注意:有一个TMonitorInfoEx结构,它具有szDevice字段,但是即使我将cbSize字段设置为适当的大小,它也似乎并没有在我的系统上填充)。
或者,,如果我可以使用szDeviceName获取等效的HMONITOR值,则可以将其插入以下函数中,以便在比较中使用它(我在下面的代码中插入了一个名为 hMonitorFromDeviceName的虚函数的调用)表示如何使用。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;
更新
感谢David Heffernan,我测试了他的解决方案,下面是一个示例函数,该函数从给定的句柄获取监视器名称: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;
最佳答案
我认为您一定是错误地调用了GetMonitorInfo
。这段代码:
{$APPTYPE CONSOLE}
uses
SysUtils, MultiMon, Windows, Forms;
var
i: Integer;
MonitorInfo: TMonitorInfoEx;
begin
MonitorInfo.cbSize := SizeOf(MonitorInfo);
for i := 0 to Screen.MonitorCount-1 do
begin
if not GetMonitorInfo(Screen.Monitors[i].Handle, @MonitorInfo) then
RaiseLastOSError;
Writeln(MonitorInfo.szDevice);
end;
Readln;
end.
在我的机器上产生以下输出:
\\.\DISPLAY1 \\.\DISPLAY2
I suspect that your call to GetMonitorInfo
is failing in some way and perhaps you are not checking the return value for errors.
Having searched QualityCentral I suspect you have fallen victim to a known bug in older versions of Delphi: QC#3239. This is reported fixed in version 10.0.2124.6661 which is Delphi 2006.
Your comments confirm this diagnosis. To fix the problem you'll need a new TMonitorInfoEx
definition. Here's one that will work on your pre-Unicode Delphi:
type
TMonitorInfoEx = record
cbSize: DWORD;
rcMonitor: TRect;
rcWork: TRect;
dwFlags: DWORD;
szDevice: array[0..CCHDEVICENAME - 1] of AnsiChar;
end;
如果将其添加到上面的代码中(当然,在声明变量之前),那么我相信它将解决您的问题。
另外,即使在XE3中,这些结构也没有正确翻译:QC#114460。可以肯定,该错误是相当良性的,因为它仅影响
PMonitorInfoExA
和TMonitorInfoExA
,但是在尝试解决此问题中的问题时,该错误将我吸引了出来!关于delphi - 需要在Windows中解析HMONITOR-> deviceName(或deviceName-> HMONITOR),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15746286/