Delphi 7:多个监视器上的中心形状位置

Delphi 7:多个监视器上的中心形状位置,delphi,delphi-7,Delphi,Delphi 7,我有一个TForm,我将“Position”设置为poMainFormCenter 当我打开该窗体时,它将正确显示在主窗体的中心 但是,在多个屏幕(2个监视器)上,当我将应用程序放入辅助监视器时,该窗体不会显示在主窗体的中心 它仍显示在主监视器中,位于屏幕边缘 我的应用程序没有什么特别之处,我只设置了Position属性 有人知道怎么解决这个问题吗 我正在使用Delphi 7和Windows XP SP3。我在创建事件中使用此选项: C_FollowMouse :BOOLEAN=TRUE; //

我有一个TForm,我将“Position”设置为poMainFormCenter

当我打开该窗体时,它将正确显示在主窗体的中心

但是,在多个屏幕(2个监视器)上,当我将应用程序放入辅助监视器时,该窗体不会显示在主窗体的中心

它仍显示在主监视器中,位于屏幕边缘

我的应用程序没有什么特别之处,我只设置了Position属性

有人知道怎么解决这个问题吗


我正在使用Delphi 7和Windows XP SP3。

我在创建事件中使用此选项:

C_FollowMouse :BOOLEAN=TRUE; // Global Const - Follow mouse. Opens App in the monitor where the mouse is.
C_Monitor   :BYTE=0;    // Default Monitor


    Procedure   TfrmMain.ScreenPOS;
    Var  pt:tpoint;
        _lMonitor :BYTE;
    Begin
        if NOT Screen.MonitorCount > 1 then Begin
            Position := poScreenCenter;
            Exit;
        End;

        _lMonitor := C_Monitor;
        if C_FollowMouse then Begin
            _lMonitor := 0;
            getcursorpos(pt);
            if pt.X < 0 then
            _lMonitor := 1;
    End;
    Left:= Screen.Monitors[_lMonitor].Left + Round( (Screen.Monitors[_lMonitor].Width - Width ) / 2);
    Top:=Screen.Monitors[_lMonitor].Top + Round( (Screen.Monitors[_lMonitor].Height - Height ) / 2)
  End;
C_FollowMouse:BOOLEAN=TRUE;//全局常量跟踪鼠标。在鼠标所在的监视器中打开应用程序。
C_监视器:字节=0;//默认监视器
程序TfrmMain.ScreenPOS;
Var-pt:tpoint;
_l监视器:字节;
开始
如果不是Screen.MonitorCount>1,则开始
位置:=位置中心;
出口
结束;
_l监视器:=C_监视器;
如果使用鼠标,则开始
_l监视器:=0;
getcursorpos(pt);
如果pt.X<0,则
_l监视器:=1;
结束;
左:=Screen.Monitors[\u lMonitor]。左+圆形((Screen.Monitors[\u lMonitor]。Width-Width)/2);
顶部:=屏幕.监视器[\u lMonitor].顶部+圆形((屏幕.监视器[\u lMonitor].高度-高度)/2)
结束;
刚刚用两台显示器测试过。这是我所有的。
如果有更多更改,请发回更改。

我在创建事件中使用此选项:

C_FollowMouse :BOOLEAN=TRUE; // Global Const - Follow mouse. Opens App in the monitor where the mouse is.
C_Monitor   :BYTE=0;    // Default Monitor


    Procedure   TfrmMain.ScreenPOS;
    Var  pt:tpoint;
        _lMonitor :BYTE;
    Begin
        if NOT Screen.MonitorCount > 1 then Begin
            Position := poScreenCenter;
            Exit;
        End;

        _lMonitor := C_Monitor;
        if C_FollowMouse then Begin
            _lMonitor := 0;
            getcursorpos(pt);
            if pt.X < 0 then
            _lMonitor := 1;
    End;
    Left:= Screen.Monitors[_lMonitor].Left + Round( (Screen.Monitors[_lMonitor].Width - Width ) / 2);
    Top:=Screen.Monitors[_lMonitor].Top + Round( (Screen.Monitors[_lMonitor].Height - Height ) / 2)
  End;
C_FollowMouse:BOOLEAN=TRUE;//全局常量跟踪鼠标。在鼠标所在的监视器中打开应用程序。
C_监视器:字节=0;//默认监视器
程序TfrmMain.ScreenPOS;
Var-pt:tpoint;
_l监视器:字节;
开始
如果不是Screen.MonitorCount>1,则开始
位置:=位置中心;
出口
结束;
_l监视器:=C_监视器;
如果使用鼠标,则开始
_l监视器:=0;
getcursorpos(pt);
如果pt.X<0,则
_l监视器:=1;
结束;
左:=Screen.Monitors[\u lMonitor]。左+圆形((Screen.Monitors[\u lMonitor]。Width-Width)/2);
顶部:=屏幕.监视器[\u lMonitor].顶部+圆形((屏幕.监视器[\u lMonitor].高度-高度)/2)
结束;
刚刚用两台显示器测试过。这是我所有的。
如果您还有更多,请发回更改。

Jlouro的想法是正确的,除了看鼠标。屏幕。监视器[]包含每个屏幕上的信息

我有一个标准的程序,通过监视器列表,找出左上角的位置,来决定放在哪个监视器上。虽然我的代码并不集中(我只是在确保窗口完全在它出现的任何监视器中之后),但想法仍然是一样的。请注意,必须考虑窗口不显示在任何监视器上的情况,我通过将其投向第一个监视器来处理。(当保存的位置位于不再存在的监视器上时,可能会发生这种情况——要么已删除,要么正在另一台机器上运行。)

我已经有很长一段时间没有处理这个问题了,它已经很久没有给我带来任何麻烦了,所以我没有在XP/Delphi7之外的任何更新版本上测试过它

请注意,这只是为了确保窗体在一个监视器上是可见的和完整的,而没有试图将其居中

Function        PointInBox(x, y, x1, y1, x2, y2 : Integer) : Boolean;

Begin
    Result := (X >= X1) And (X <= X2) And (Y >= Y1) And (Y <= Y2);
End;

Function        Overlapping(x11, y11, x12, y12, x21, y21, x22, y22 : Integer) : Boolean;

Var
    tx1, ty1, tx2, ty2      : Integer;

Begin
    Tx1 := Max(x11, x21);
    Tx2 := Min(x12, x22);
    Ty1 := Max(y11, y21);
    Ty2 := Min(y12, y22);
    Result := (Tx1 < Tx2) And (Ty1 < Ty2);
End;

Function        GetWhere(Form : TForm) : Integer;

Var
    Loop        : Integer;
    Where       : Integer;

Begin
    Where           := -1;
    For Loop := 1 to Screen.MonitorCount do
        With Screen.Monitors[Loop - 1] do
            If PointInBox(Form.Left, Form.Top, Left, Top, Left + Width - 1, Top + Height - 1) then
                Where := Loop - 1;
    If Where = -1 then // Top left corner is wild, check for anything
        For Loop := 1 to Screen.MonitorCount do
            With Screen.Monitors[Loop - 1] do
                If Overlapping(Form.Left, Form.Top, Form.Left + Form.Width - 1, Form.Top + Form.Height - 1, Left, Top, Left + Width - 1, Top + Height - 1) then
                    Where := Loop - 1;
    Result := Where;
End;

Procedure   GetLimits(Where : Integer; var X, Y, WWidth, WHeight : Integer);

Var
    R               : TRect;

Begin
    If Where < 0 then
        Begin
            SystemParametersInfo(Spi_GetWorkArea, 0, @R, 0);
            X           := R.Left;
            Y           := R.Top;
            WWidth  := R.Right - R.Left + 1;
            WHeight := R.Bottom - R.Top + 1;
        End
    Else With Screen.Monitors[Where] do
        Begin
            X           := Left;
            Y           := Top;
            WWidth  := Width;
            WHeight := Height;
        End;
End;

Procedure   EnsureValidDisplay(Form : TForm);

Var
    Left            : Integer;
    Top         : Integer;
    Width           : Integer;
    Height      : Integer;
    Where           : WindowPlacement;

Begin
    GetLimits(GetWhere(Form), Left, Top, Width, Height);
    Where.Length    := SizeOf(Where);
    Where.Flags     := 0;
    GetWindowPlacement(Form.Handle, @Where);
    If Form.Left < Left then
        Where.rcNormalPosition.Left := Left
    Else If Form.Left + Form.Width > Left + Width then
        Where.rcNormalPosition.Left := Left + Width - Form.Width;
    If Form.Top < Top then
        Where.rcNormalPosition.Top      := Top
    Else If Form.Top + Form.Height > Top + Height then
        Where.rcNormalPosition.Top      := Top + Height - Form.Height;
    If Form.Width > Width then
        Where.rcNormalPosition.Right    := Where.rcNormalPosition.Left + Width
    Else
        Where.rcNormalPosition.Right    := Where.rcNormalPosition.Left + Form.Width;
    If Form.Height > Height then
        Where.rcNormalPosition.Bottom   := Where.rcNormalPosition.Top + Height
    Else
        Where.rcNormalPosition.Bottom   := Where.rcNormalPosition.Top + Form.Height;
    SetWindowPlacement(Form.Handle, @Where);
End;
函数点收件箱(x,y,x1,y1,x2,y2:整数):布尔值;
开始
结果:=(X>=X1)和(X=Y1)以及(Y左+宽)
其中.rcNormalPosition.Left:=Left+Width-Form.Width;
如果Form.TopTop+Height,则
其中.rcNormalPosition.Top:=顶部+高度-形状高度;
如果Form.Width>Width,则
Where.rcNormalPosition.Right:=Where.rcNormalPosition.Left+宽度
其他的
Where.rcNormalPosition.Right:=Where.rcNormalPosition.Left+Form.Width;
如果Form.Height>Height,则
Where.rcNormalPosition.Bottom:=Where.rcNormalPosition.Top+高度
其他的
Where.rcNormalPosition.Bottom:=Where.rcNormalPosition.Top+Form.Height;
SetWindowPlacement(Form.Handle,@Where);
结束;

Jlouro的想法是正确的,除了看鼠标。屏幕。监视器[]包含每个屏幕上的信息

我有一个标准的程序,它遍历监视器列表,并找出左上角的位置,以决定将其放在哪个监视器上。虽然我的代码不居中(我只是在确保窗口完全位于它出现的监视器内之后)这个想法仍然是一样的。注意,你必须考虑窗口不显示在任何监视器上的情况——我通过把它扔到第一个监视器来处理这个问题(这将在保存的位置在一个不再存在的监视器上发生——或者在另一台机器上被删除或运行)。 我已经有很长一段时间没有处理这个问题了,它已经很久没有给我带来任何麻烦了,所以我没有在XP/Delphi7之外的任何更新版本上测试过它

请注意,这只是为了确保窗体在一个监视器上是可见的和完整的,而没有试图将其居中

Function        PointInBox(x, y, x1, y1, x2, y2 : Integer) : Boolean;

Begin
    Result := (X >= X1) And (X <= X2) And (Y >= Y1) And (Y <= Y2);
End;

Function        Overlapping(x11, y11, x12, y12, x21, y21, x22, y22 : Integer) : Boolean;

Var
    tx1, ty1, tx2, ty2      : Integer;

Begin
    Tx1 := Max(x11, x21);
    Tx2 := Min(x12, x22);
    Ty1 := Max(y11, y21);
    Ty2 := Min(y12, y22);
    Result := (Tx1 < Tx2) And (Ty1 < Ty2);
End;

Function        GetWhere(Form : TForm) : Integer;

Var
    Loop        : Integer;
    Where       : Integer;

Begin
    Where           := -1;
    For Loop := 1 to Screen.MonitorCount do
        With Screen.Monitors[Loop - 1] do
            If PointInBox(Form.Left, Form.Top, Left, Top, Left + Width - 1, Top + Height - 1) then
                Where := Loop - 1;
    If Where = -1 then // Top left corner is wild, check for anything
        For Loop := 1 to Screen.MonitorCount do
            With Screen.Monitors[Loop - 1] do
                If Overlapping(Form.Left, Form.Top, Form.Left + Form.Width - 1, Form.Top + Form.Height - 1, Left, Top, Left + Width - 1, Top + Height - 1) then
                    Where := Loop - 1;
    Result := Where;
End;

Procedure   GetLimits(Where : Integer; var X, Y, WWidth, WHeight : Integer);

Var
    R               : TRect;

Begin
    If Where < 0 then
        Begin
            SystemParametersInfo(Spi_GetWorkArea, 0, @R, 0);
            X           := R.Left;
            Y           := R.Top;
            WWidth  := R.Right - R.Left + 1;
            WHeight := R.Bottom - R.Top + 1;
        End
    Else With Screen.Monitors[Where] do
        Begin
            X           := Left;
            Y           := Top;
            WWidth  := Width;
            WHeight := Height;
        End;
End;

Procedure   EnsureValidDisplay(Form : TForm);

Var
    Left            : Integer;
    Top         : Integer;
    Width           : Integer;
    Height      : Integer;
    Where           : WindowPlacement;

Begin
    GetLimits(GetWhere(Form), Left, Top, Width, Height);
    Where.Length    := SizeOf(Where);
    Where.Flags     := 0;
    GetWindowPlacement(Form.Handle, @Where);
    If Form.Left < Left then
        Where.rcNormalPosition.Left := Left
    Else If Form.Left + Form.Width > Left + Width then
        Where.rcNormalPosition.Left := Left + Width - Form.Width;
    If Form.Top < Top then
        Where.rcNormalPosition.Top      := Top
    Else If Form.Top + Form.Height > Top + Height then
        Where.rcNormalPosition.Top      := Top + Height - Form.Height;
    If Form.Width > Width then
        Where.rcNormalPosition.Right    := Where.rcNormalPosition.Left + Width
    Else
        Where.rcNormalPosition.Right    := Where.rcNormalPosition.Left + Form.Width;
    If Form.Height > Height then
        Where.rcNormalPosition.Bottom   := Where.rcNormalPosition.Top + Height
    Else
        Where.rcNormalPosition.Bottom   := Where.rcNormalPosition.Top + Form.Height;
    SetWindowPlacement(Form.Handle, @Where);
End;
函数点收件箱(x,y,x1,y1,x2,y2:整数):布尔值;
开始
结果:=(X>=X1)和(X=Y1)以及(Y左+宽)
其中.rcNormalPosition.Left:=Left+Width-Form.Width;
如果Form.TopTop+Height,则
其中.rcNormalPosition.Top:=顶部+高度-形状高度;
如果Form.Width>Width,则
Where.rcNormalPosition.Right:=Where.rcNormalPosition.Left+宽度
其他的
Where.rcNormalPosition.Right:=Where.rcNormalPosition.Left+Form.Width;
如果Form.Height>Height,则
Where.rcNor
X := (Application.MainForm.ClientWidth - Width) div 2;
Y := (Application.MainForm.ClientHeight - Height) div 2;
self.SetBounds(x,y,self.width,self.height);