uns*_*zed 6 delphi winapi delphi-7 windows-7
编辑 - 请参阅最后更新
这适用于Delphi 7.0 Build 4.453
摘要
我需要能够从TMonitor对象(TScreen组件中的Monitors数组中的一个元素)获取Handle属性,该对象是一个HMONITOR,并将其转换为您在调用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;
Run Code Online (Sandbox Code Playgroud)
更新
感谢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;
Run Code Online (Sandbox Code Playgroud)
我认为你必须打错电话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.
Run Code Online (Sandbox Code Playgroud)
在我的机器上生成此输出:
\\.\DISPLAY1 \\.\DISPLAY2
我怀疑你的调用GetMonitorInfo
是以某种方式失败的,也许你没有检查错误的返回值.
搜索过QualityCentral后,我怀疑你已经成为旧版Delphi中已知错误的受害者:QC#3239.这是在版本10.0.2124.6661(Delphi 2006)中修复的.
您的评论证实了这一诊断.要解决此问题,您需要一个新的TMonitorInfoEx
定义.这是一个适用于你的Unicode前Delphi的:
type
TMonitorInfoEx = record
cbSize: DWORD;
rcMonitor: TRect;
rcWork: TRect;
dwFlags: DWORD;
szDevice: array[0..CCHDEVICENAME - 1] of AnsiChar;
end;
Run Code Online (Sandbox Code Playgroud)
如果你将它添加到上面的代码中(当然你声明变量之前),那么我相信它会解决你的问题.
有趣的是,即使在XE3中,这些结构也没有被正确翻译:QC#114460.不可否认,错误是相当温和的,因为它只影响PMonitorInfoExA
和TMonitorInfoExA
,但错误引起了我,试图解决这个问题中的问题!
归档时间: |
|
查看次数: |
2105 次 |
最近记录: |