首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> Delphi

Delphi 停靠技術完整指南:DockSite/DragKind、事件流程、頁簽合併、工具列浮動與進階屬性總覽

     編輯:Delphi

核心屬性:兩行啟用基本停靠

角色基類關鍵屬性值
被停靠端 (容器)TWinControlDockSiteTrue
停靠端 (客戶端)TControlDragKinddkDock
DragModedmAutomatic (自動拖曳)

標準佈局:IDE 風格停靠面板

  • 主視窗邊緣放置 TPanel (如 LeftDockPanel):Align=alLeft、Width=0、DockSite=True
  • 旁邊放 TSplitter (如 LeftSplitter):Align=alLeft,可調整面板寬度
  • 可停靠表單:DragKind=dkDock、DragMode=dmAutomatic

六大核心事件流程

事件觸發時機關鍵參數主要用途
OnDockOver客戶端掠過容器Source: TDragDockObject; X,Y; State; var Accept控制**預覽矩形**位置、決定是否接受
OnDockDrop客戶端釋放於容器Source; X,Y設定容器最終尺寸、完成停靠佈局
OnGetSiteInfo客戶端移動中 (高頻)DockClient; var InfluenceRect; MousePos; var CanDock查詢是否可停靠、影響區域
OnStartDock客戶端開始拖曳var DragObject自訂拖曳物件、初始化
OnEndDock客戶端結束拖曳 (無論成功)Target; X,Y清理、狀態重置
OnUnDock客戶端從容器拖出 (浮動)Client; NewTarget; var Allow控制是否允許浮動、恢復容器狀態

關鍵事件實作範例

OnDockOver:設定預覽區域


procedure TMainForm.LeftDockPanelDockOver(Sender: TObject; Source: TDragDockObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
var ARect: TRect;
begin
  Accept := Source.Control is TDockableForm;
  if Accept then begin
    ARect.TopLeft := LeftDockPanel.ClientToScreen(Point(0,0));
    ARect.BottomRight := LeftDockPanel.ClientToScreen(Point(ClientWidth div 3, LeftDockPanel.Height));
    Source.DockRect := ARect; // 虛線預覽區域
  end;
end;

OnDockDrop:確定最終佈局


procedure TMainForm.LeftDockPanelDockDrop(Sender: TObject; Source: TDragDockObject; X, Y: Integer);
begin
  LeftDockPanel.Width := ClientWidth div 3;
  LeftSplitter.Left := LeftDockPanel.Width + LeftSplitter.Width;
end;

OnUnDock / FormClose:恢復容器


procedure TDockableForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  MainForm.LeftDockPanel.Width := 0; // 隱藏面板
  Action := caHide; // 隱藏而非釋放
end;

進階:表單間相互停靠 (頁簽/並排)

捕獲 CM_DOCKCLIENT 訊息


private
  procedure CMDockClient(var Msg: TCMDockClient); message CM_DOCKCLIENT;

procedure TDockableForm.CMDockClient(var Msg: TCMDockClient);
var Host: TForm;
begin
  if Msg.DockSource.Control is TDockableForm then begin
    Host := TTiledHost.Create(Application); // 宿主視窗
    Host.BoundsRect := Self.BoundsRect;
    Self.ManualDock(Host, nil, alNone);
    Self.DockSite := False; // 變為客戶端
    Msg.DockSource.Control.ManualDock(Host, nil, alNone);
    TDockableForm(Msg.DockSource.Control).DockSite := False;
    Host.Visible := True;
  end;
end;
  • ManualDock(NewDockSite, DropControl, ControlSide):安全程式化停靠
  • 宿主視窗 TTiledHost 需 DockSite=True

頁簽式合併 (TPageControl 宿主)


procedure TDockableForm.CMDockClient(var Msg: TCMDockClient);
var Host: TTabHost; // 含 PageControl1 (Align=alClient, DockSite=True)
begin
  if Msg.DockSource.Control is TDockableForm then begin
    Host := TTabHost.Create(Application);
    Host.BoundsRect := Self.BoundsRect;
    Self.ManualDock(Host.PageControl1, nil, alClient);
    Msg.DockSource.Control.ManualDock(Host.PageControl1, nil, alClient);
    Host.Visible := True;
  end;
end;

TPageControl 內建處理 CM_DOCKCLIENT/CM_DOCKNOTIFICATION/CM_UNDOCKCLIENT,自動建立分頁。

工具列浮動宿主

  • TControlBar/TCoolBar:DockSite=True
  • TToolBar:DragKind=dkDock、DragMode=dmAutomatic
  • FloatingDockSiteClass:指定浮動時的宿主視窗類別 (設計時設定,運行時自動建立)

進階屬性與方法速查

分類成員說明
尺寸記憶TBDockHeight停靠時高度
LRDockWidth停靠時寬度
UnDockHeight浮動時高度
UnDockWidth浮動時寬度
關係查詢HostDockSite所在容器實例
FloatingDockSiteClass浮動宿主類別
Floating是否浮動狀態
容器管理DockClientCount已停靠客戶端數
DockClients[Index]客戶端列表
DockManager / UseDockManager停靠管理器 (TDockTree ActiveX)
方法ManualFloat程式化浮動
ReplaceDockedControl替換已停靠控件
DoAddDockClient / DockDrop / DockOver / DoDockOver / DoUnDock內部虛擬方法,可覆寫擴充

核心訊息

  • CM_DOCKCLIENT:停靠請求 (含 TCMDockClient 結構)
  • CM_DOCKNOTIFICATION:停靠完成通知
  • CM_UNDOCKCLIENT:取消停靠通知

官方範例參考

Delphi\Demos\Docking\ 目錄包含完整示範專案。

總結

Delphi 停靠架構極度成熟:DockSite + DragKind = 基礎;六大事件 = 精細控制;CM_DOCKCLIENT + ManualDock = 表單間自由組合;TPageControl = 內建頁簽宿主;ToolBar/CoolBar = 工具列停靠標準。掌握此體系,可輕鬆構建媲美 IDE 的專業級可停靠介面。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved