我的 Delphi-7 应用程序显示:
Screen.DesktopWidth
Screen.DesktopHeight
Screen.Monitors[0].Width
Screen.Monitors[0].Height
并且,如果选择了第二个显示器,也:
Screen.Monitors[1].Width
Screen.Monitors[1].Height
当应用程序在我的 WinXP-Pro PC 上运行时,我转到“控制面板/显示/设置”,然后更改第二个显示器的设置(添加或删除它)。
然后,我单击“刷新”按钮以显示 4 个(或 6 个)参数的新值,但发生了意外情况:Screen.DesktopWidth 和 Screen.DesktopHeight 显示正确的新值,但其他 2 个参数的值(或者4)参数非常错误。
类似于 Screen.Monitors[0].Width = 5586935 ,而它应该是 1680 。
在 Delphi 7 中使用 TScreen 有一些特殊规则吗?
最佳答案
由于连接或断开显示器或 USB 显示设备时 TScreen 的刷新问题(错误)而来到这里。 @Dave82 的答案对我不起作用。 MonitorFromWindow 函数的结果必须返回另一个值(未知/无效值)以强制更新 TScreen 对象。
下面这个作弊可以解决问题:
确保 multimon 位于 uses 子句中:
uses
multimon;
将此添加到(表单的)界面部分
protected
procedure WMDeviceChange(var Msg: TMessage); message WM_DEVICECHANGE;
将此添加到(表单的)实现部分
function cheatMonitorFromWindow(hWnd: HWND; dwFlags: DWORD): HMONITOR; stdcall;
begin
// Does nothing, returns zero to force invalidate
Result:=0;
end;
procedure TForm1.WMDeviceChange(var Msg: TMessage);
var
iCurrDisplayCount : LongInt;
iNewDisplayCount : LongInt;
pMonitorFromWinProc : TMonitorFromWindow;
begin
iCurrDisplayCount:=Screen.MonitorCount;
// Force monitor update, fix bug in customform, won't update at display change.
// This a hack/cheat to multimon MonitorFromWindow func, it's fakes the result.
// This is required to tell customform.getMonitor() to update the TScreen object.
pMonitorFromWinProc:=MonitorFromWindow; // Backup pointer to dynamic assigned DLL func
MonitorFromWindow:=cheatMonitorFromWindow; // Assign cheat func
monitor; // call the monitor property that calls customform.getMonitor and cheatfunc
MonitorFromWindow:=pMonitorFromWinProc; // restore the original func
// ==========
iNewDisplayCount:=Screen.MonitorCount;
if( iCurrDisplayCount <> iNewDisplayCount ) then
begin
// Display count change!
end;
end;
customform 内部发生了什么(Forms.pas 中的代码)?
function TCustomForm.GetMonitor: TMonitor;
var
HM: HMonitor;
I: Integer;
begin
Result := nil;
HM := MonitorFromWindow(Handle, MONITOR_DEFAULTTONEAREST);
for I := 0 to Screen.MonitorCount - 1 do
if Screen.Monitors[I].Handle = HM then
begin
Result := Screen.Monitors[I];
Exit;
end;
//if we get here, the Monitors array has changed, so we need to clear and reinitialize it
for i := 0 to Screen.MonitorCount-1 do
TMonitor(Screen.FMonitors[i]).Free;
Screen.FMonitors.Clear;
EnumDisplayMonitors(0, nil, @EnumMonitorsProc, LongInt(Screen.FMonitors));
for I := 0 to Screen.MonitorCount - 1 do
if Screen.Monitors[I].Handle = HM then
begin
Result := Screen.Monitors[I];
Exit;
end;
end;
希望当有人正在寻找这个时它会有所帮助。当您想要检测显示设备设置更改(分辨率和方向)时,请捕获 WM_DISPLAYCHANGE 事件。
关于delphi - 在 Delphi 7 中使用 TScreen,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11167736/