2012-04-04 26 views
7

如果(在Delphi)我做ManualFloat不使用指定的矩形

Panel1.ManualFloat(Rect(500,500,600,600)); 

面板在指定的矩形位置不浮動,而是在某種Windows默認的位置。如何讓面板(或其他控件)在指定位置浮動。但它似乎有正確的形狀。是否有一些其他屬性需要設置才能正常工作?

編輯:只是爲了說清楚。我期望上面的代碼使面板成爲一個100x100正方形,相對於屏幕的左上角(500x500),而不是。形狀是正確的,但位置不正確。如果隨後的控件浮動,它們將在屏幕上級聯。

EDIT2:這似乎並不在德爾福7個問題,但通過XE2是德爾福2007年(甚至更早)

+0

固定代碼當與'ManualFloat','矩形(500,500,600,600)用於'是500個像素和向下從屏幕的左上方,總是。 (它基本上是「Windows默認位置」類型區域,因爲'ManualFloat'使用屏幕座標而不是窗口座標。)您是否期望它位於客戶端座標中(取決於您的窗體位置)? – 2012-04-04 02:24:43

+0

@KenWhite,謝謝Ken,但不會發生什麼情況。面板是一個100x100平方米,如預期的那樣,但不在位置(500,500)相對於左上角有一個屏幕 – Alister 2012-04-04 03:33:04

+0

@KenWhite,請嘗試自己的代碼並親自看看...... – 2012-04-04 20:22:54

回答

5

不要再看:它是VCL中的一個bug。

ManualFloat創建一個浮動窗口,並設置在其TControl.CreateFloatingDockSite(Bounds: TRect)TopLeft值和後來設置其ClientWidth

這是一個錯誤,因爲這樣做會強制WindowHandle創建(它沒有一個手柄還)在

function TCustomForm.GetClientRect: TRect; 
begin 
    if IsIconic(Handle) then // <=== 

並調用該窗口的默認定位(級聯腳本非常重要...)重置TopLeft

的修復將是TControl.CreateFloatingDockSite(Bounds: TRect)

設定 TopLeft屬性之前設置 ClientWidth

更新:在Controls.pas

function TControl.CreateFloatingDockSite(Bounds: TRect): TWinControl; 
begin 
    Result := nil; 
    if (FloatingDockSiteClass <> nil) and 
    (FloatingDockSiteClass <> TWinControlClass(ClassType)) then 
    begin 
    Result := FloatingDockSiteClass.Create(Application); 
    with Bounds do 
    begin 
     // Setting Client area can create the window handle and reset Top and Left 
     Result.ClientWidth := Right - Left; 
     Result.ClientHeight := Bottom - Top; 
     // It is now safe to position the window where asked 
     Result.Top := Top; 
     Result.Left := Left; 
    end; 
    end; 
end; 
+0

但默認浮動停靠站點類「Forms.TCustomDockForm」具有'BorderStyle = bsSizeToolWin'並且不是標誌性的。這就是爲什麼我問OP是否爲該面板分配了自己的FloatingDockSiteClass。 – NGLN 2012-04-04 19:52:10

+0

@NGLN。 BorderStyle或iconic是無關緊要的。在創建窗口句柄之前設置頂部和左側是一種可靠的方式來丟失它們......只需像OP一樣嘗試一個簡單的例子:一個窗體,一個面板,一個帶有代碼的按鈕,用於設置面板浮動並查看.. 。 – 2012-04-04 20:21:09

+0

設置或獲取'ClientRect'不會重新創建窗口。不,我沒看見:我已經嘗試了我的答案以及OP的代碼中的所有示例,並且它們的工作方式與VCL的內容_(在D7中)相同_。 – NGLN 2012-04-04 22:23:38

1

喜歡the functionTRect參數的名稱 - ScreenPos - 樣的說它已經,座標在屏幕單位,而不是父母的座標。

如果你想面板留在同一個地方,它是,翻譯相對於屏幕座標:

with Panel1.ClientToScreen(Point(0, 0)) do 
    Panel1.ManualFloat(Bounds(X, Y, 100, 100)); 

或者,包括面板的邊框:

if Panel1.HasParent then 
    with Panel1.Parent.ClientToScreen(Panel1.BoundsRect.TopLeft) do 
     Panel1.ManualFloat(Bounds(X, Y, 100, 100)); 

或者,翻譯成相對於父母的特定座標,使用:

if Panel1.HasParent then 
    with Panel1.Parent.ClientOrigin do 
     Panel1.ManualFloat(Bounds(X + 500, Y + 500, 100, 100)); 
+0

是的,我知道屏幕座標所需的翻譯。問題是ManualFloat忽略X和Y(使用上面的變量)。與Forms完美合作,但無法使用面板進行操作。寬度和高度是正確的。如果我將X和Y設置爲0,我希望面板出現在屏幕的左上角,但它不是我卡住的地方。 – Alister 2012-04-04 03:31:16

+0

你使用自己的'FloatingDockSiteClass'嗎?否則我無法解釋爲什麼這不起作用。 – NGLN 2012-04-04 03:46:18

+0

@NGLN *「否則我無法解釋爲什麼這不起作用。」*,嘗試他的代碼,並參見.. – 2012-04-04 20:24:07