2013-03-07 139 views
1

我有一個組合框有兩個選項,兩個選項都觸發窗體大小調整。我的想法是隱藏並顯示基於選擇的其他控件。更改窗體大小後的窗體

當我更改窗體寬度時,大小會根據需要進行更改,但窗體現在不再位於屏幕的中心。我可以在改變窗體寬度的同時來回移動窗體的XY位置嗎?

procedure TReportFrm.SpecialFilesComboBoxChange(Sender: TObject); 
begin 
    if(SpecialFilesComboBox.ItemIndex = 0) then begin 
    //No special files 
    Width := 412; 
    Height := 423; 
    ... 
    end 
    else begin 
    //Yes special files 
    Width := 893; 
    Height := 423; 
    ... 
    end; 
end; 
+0

PS我可以'if'語句後沒有簡單的調用了這一點,我會得到一個訪問衝突:'BugReportFrm.Position := poMainFormCenter;' – ikathegreat 2013-03-07 06:31:22

+1

是BugReportFrm分配的?您的代碼顯示TReportFrm。只是不要使用實例:Position:= poMainFormCenter; – bummi 2013-03-07 06:38:54

+0

只需根據需要設置「頂部」和「左側」即可。從Monitor.WorkAreaRect – 2013-03-07 06:41:06

回答

5

一個非常簡單的ReCenter功能可能是這樣的:

procedure TReportFrm.ReCenter; 
var 
    LRect: TRect; 
    X, Y: Integer; 
begin 
    LRect := Screen.WorkAreaRect; 
    X := LRect.Left + (LRect.Right - LRect.Left - Width) div 2; 
    Y := LRect.Top + (LRect.Bottom - LRect.Top - Height) div 2; 
    SetBounds(X, Y, Width, Height); 
end; 

procedure TReportFrm.SpecialFilesComboBoxChange(Sender: TObject); 
begin 
    if(SpecialFilesComboBox.ItemIndex = 0) then begin 
    //No special files 
    Width := 412; 
    Height := 423; 
    ... 
    end 
    else begin 
    //Yes special files 
    Width := 893; 
    Height := 423; 
    ... 
    end; 
    ReCenter; 
end; 

IT中心的窗口到屏幕的工作區,你可能希望將其中心到其他的參考,在這種情況下,它是由給你確定有意義的矩形。

+0

完美計算。最好/最直接的delphi解決方案我已經在一段時間了,謝謝。 – ikathegreat 2013-03-07 07:04:09

+4

這個數學在這裏是錯誤的。只有在工作區域頂部和左側均爲零的情況下才能工作。工作區域的中心是(左+右)div 2.你的減號是錯誤的。該代碼也否認了多監視器系統的存在。 – 2013-03-07 07:34:26

+0

@大衛哦,我的...我不確定屏幕是否可以有不同的左/頂比0,0,但我更新了我的答案。如上所述,它將表格置於屏幕Workarea中,並且很大程度上展示瞭如何在答案中獲取表單監視器的WorkArea。我不同意你提出的(左+右)div 2解決方案,你確定嗎?我手頭沒有其他顯示器可供測試。 – jachguate 2013-03-07 08:16:46

5

多顯示器系統現在很常見。放置在屏幕的中心可能會將表格分散到多個顯示器上。這是不可取的。

所以我中心形式的監視器上:

R := Form.Monitor.WorkAreaRect; 
Form.Left := (R.Left+R.Right-Form.Width) div 2; 
Form.Top := (R.Top+R.Bottom-Form.Height) div 2; 

由於@bummi指出的那樣,你可以這樣寫:

Form.Position := poScreenCenter; 

這幾乎可以作爲你的願望。我將把這個表格放在屏幕上。但是,它總是選擇默認監視器。因此,使用該代碼可能會導致您的表單被移到不同的顯示器上,我認爲這絕對不可取。

而是迫使形式中心,你可以決定,而不是在所有側面擴大或縮小它:

procedure TReportFrm.SpecialFilesComboBoxChange(Sender: TObject); 
var 
    NewLeft, NewTop, NewWidth, NewHeight: Integer; 
begin 
    if(SpecialFilesComboBox.ItemIndex = 0) then begin 
    //No special files 
    NewWidth := 412; 
    NewHeight := 423; 
    ... 
    end 
    else begin 
    //Yes special files 
    NewWidth := 893; 
    NewHeight := 423; 
    ... 
    end; 

    NewLeft := Left + (Width-NewWidth) div 2; 
    NewTop := Top + (Top-NewHeight) div 2; 
    NewBoundsRect := Rect(NewLeft, NewTop, NewLeft+NewWidth, NewTop+NewHeight); 
    BoundsRect := NewBoundsRect; 
end; 

如果你想獲得真正可愛的你會調整邊界RECT從而使新大小和定位的形式沒有離開顯示器的邊緣。

procedure MakeAppearOnScreen(var Rect: TRect); 
const 
    Padding = 24; 
var 
    Monitor: HMonitor; 
    MonInfo: TMonitorInfo; 
    Excess, Width, Height: Integer; 
begin 
    Monitor := MonitorFromPoint(Point((Rect.Left+Rect.Right) div 2, (Rect.Top+Rect.Bottom) div 2), MONITOR_DEFAULTTONEAREST); 
    if Monitor=0 then begin 
    exit; 
    end; 
    MonInfo.cbSize := SizeOf(MonInfo); 
    if not GetMonitorInfo(Monitor, @MonInfo) then begin 
    exit; 
    end; 
    Width := Rect.Right-Rect.Left; 
    Height := Rect.Bottom-Rect.Top; 

    Excess := Rect.Right+Padding-MonInfo.rcWork.Right; 
    if Excess>0 then begin 
    dec(Rect.Left, Excess); 
    end; 
    Excess := Rect.Bottom+Padding-MonInfo.rcWork.Bottom; 
    if Excess>0 then begin 
    dec(Rect.Top, Excess); 
    end; 
    Excess := MonInfo.rcWork.Left+Padding-Rect.Left; 
    if Excess>0 then begin 
    inc(Rect.Left, Excess); 
    end; 
    Excess := MonInfo.rcWork.Top+Padding-Rect.Top; 
    if Excess>0 then begin 
    inc(Rect.Top, Excess); 
    end; 
    Rect.Right := Rect.Left+Width; 
    Rect.Bottom := Rect.Top+Height; 
end; 

接着前面的代碼示例將改變這樣的:

NewBoundsRect := Rect(NewLeft, NewTop, NewLeft+NewWidth, NewTop+NewHeight); 
MakeAppearOnScreen(NewBoundsRect); 
BoundsRect := NewBoundsRect; 
+0

至於位置將按照不同的設置所需的工作,我沒有看到重新補充的需要。 – bummi 2013-03-07 07:49:46

+1

@bummi位置僅適用於我認爲的表單的初始顯示。 – 2013-03-07 08:00:57

+0

我無法談論D7之前的版本,但是這會起作用:procedure TForm1.Button1Click(Sender:TObject); 開始 位置:= poScreenCenter; 結束; – bummi 2013-03-07 09:17:38

相關問題