使用SetWindowPos API函數移動視窗後,還需修改Delphi的屬性值,以備下次使用,否則就會出問題(不是API不起作用,而是使用了錯誤的座標值)

來源:互聯網
上載者:User

標籤:

單獨改變座標的代碼如下,可不斷左移:

procedure TForm1.Button1Click(Sender: TObject);begin  SetWindowPos(panel1.Handle, 0, panel1.Left-10, panel1.Top, panel1.Width, panel1.Height, SWP_NOZORDER + SWP_NOACTIVATE);end;

照理每次改變座標,都會調用SetBounds,都會調用SetWindowPos函數,可是一旦我屏蔽UpdateBounds函數,控制項從第二次開始,就沒有效果了:

procedure TForm1.Button1Click(Sender: TObject);begin  panel1.Left:=panel1.Left-10;end;

這是為什麼呢?原因是,在使用API達到相應的目的之後,必須修改Delphi的屬性值,以備下次使用。否則Delphi下次還是按照原來的left值再減去10,這樣看上去就沒有被移動。所以關鍵是UpdateBounds裡的代碼:

procedure TWinControl.UpdateBounds;var  ParentHandle: HWnd;  Rect: TRect;  WindowPlacement: TWindowPlacement;begin  GetWindowRect(FHandle, Rect); // API,取得客戶區,注意第二個參數是指標,但Delphi裡直接使用  // important 如果具有子視窗風格,就要根據父控制項在螢幕上的位置重新顯示  if GetWindowLong(FHandle, GWL_STYLE) and WS_CHILD <> 0 then  begin    ParentHandle := GetWindowLong(FHandle, GWL_HWNDPARENT); // API,fixme 還可以這樣簡單取得父控制項控制代碼?就這一處    if ParentHandle <> 0 then    begin      Windows.ScreenToClient(ParentHandle, Rect.TopLeft); // API      Windows.ScreenToClient(ParentHandle, Rect.BottomRight);    end;  end;  // important 使用API取得實際效果後,也要改變Delphi的屬性值,否則屬性值還是保持上一次的值,這樣下一次看起來就無法移動了  // 錯誤:顯示完以後,根據windows內部資訊更新Win控制項的屬性  // important 如果這裡exit,那麼只有第一次的時候座標可以移動,後面都無法移動了。說到底都是通過這裡起作用的  FLeft := Rect.Left;  FTop := Rect.Top;  FWidth := Rect.Right - Rect.Left;  FHeight := Rect.Bottom - Rect.Top;  // 更新座標和長寬後,要重新鉚接  // fixme 難道不用對齊嗎,別處好多地方也都是這樣  UpdateAnchorRules;end;

的最後幾句。這樣就達到了修改值的目的。

--------------------------------------------------------------------

另一種辦法改變Windows視窗的座標(親測):

procedure TForm1.Button2Click(Sender: TObject);var  WindowPlacement: TWindowPlacement; // Windows結構類型,包含最大化已最小化的視窗位置等6項內容begin  WindowPlacement.Length := SizeOf(WindowPlacement);  GetWindowPlacement(Panel1.Handle, @WindowPlacement);  // API,取得結構體指標,包括7項內容  // 更改視窗的位置資訊  WindowPlacement.rcNormalPosition := Panel1.BoundsRect;  WindowPlacement.rcNormalPosition.Left := WindowPlacement.rcNormalPosition.Left - 10;  WindowPlacement.rcNormalPosition.Right := WindowPlacement.rcNormalPosition.Right - 10;  SetWindowPlacement(Panel1.Handle, @WindowPlacement);end;

 

使用SetWindowPos API函數移動視窗後,還需修改Delphi的屬性值,以備下次使用,否則就會出問題(不是API不起作用,而是使用了錯誤的座標值)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.