在Delphi 7中使用TScreen [英] Using TScreen in Delphi 7

查看:18
本文介绍了在Delphi 7中使用TScreen的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的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)参数的值非常错误。

Like Screen.Monters[0].Width=5586935,但应为1680。

在Delphi 7中使用TScreen有什么特殊规则吗?

推荐答案

因为连接或断开显示器或usb显示设备时TScreen的刷新问题(BUG)而来到这里。@Dave82的答案对我不起作用。函数Monitor的结果必须返回另一个值(未知/无效值)才能强制更新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;

在自定义表单(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 7中使用TScreen的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆