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

C++Builder 拖放功能實現:DockSite/DragKind/DragMode 與手動拖放事件

     編輯:VC 教學

兩種拖放模式

  • Docking (停駐/合併):控件脫離原父容器,成為另一容器子控件(如工具列拖曳停駐)。
  • Drag & Drop (拖曳放置):資料/視覺元素從來源拖曳到目標,觸發資料傳輸或動作(如檔案複製、列表項移動)。

一、Docking 停駐:三屬性搞定工具列自由拖曳

容器 (接受停駐):


CoolBar1->DockSite = true;  // 接受 dkDock 型別拖曳

可停駐控件 (工具列):


ToolBar1->DragKind = dkDock;      // 停駐模式
ToolBar1->DragMode = dmAutomatic; // 自動啟動 (無需 OnDragOver 手寫)

其他 ToolBar 同理設定。編譯執行即可像 IDE 工具列一樣自由拖曳停駐。

二、手動 Drag & Drop:核心事件與流程

關鍵事件

事件觸發時機關鍵參數用途
OnDragOver拖曳物件進入/移動於控件上方Source, X, Y, State, Accept設定 Accept = true 允許放置,可根據 Source 類型決定
OnDragDrop使用者在控件上釋放滑鼠Source, X, Y執行實際資料傳輸/動作
OnEndDrag拖曳結束 (無論是否放置)Target, X, Y來源控件清理/回饋
OnStartDragdmManual 模式下開始拖曳DragObject自訂拖曳影像/資料物件

基本範例:ListBox 項目拖曳到另一 ListBox


// 來源 ListBox1: DragMode = dmAutomatic
// 目標 ListBox2: DragMode = dmAutomatic

void __fastcall TForm1::ListBox2DragOver(TObject* Sender, TObject* Source, int X, int Y, TDragState State, bool& Accept) {
    Accept = (Source == ListBox1);  // 只接受來自 ListBox1
}

void __fastcall TForm1::ListBox2DragDrop(TObject* Sender, TObject* Source, int X, int Y) {
    if (Source == ListBox1) {
        int idx = ListBox1->ItemIndex;
        if (idx >= 0) {
            ListBox2->Items->Add(ListBox1->Items->Strings[idx]);
            ListBox1->Items->Delete(idx);  // 移動語義;複製則不刪除
        }
    }
}

進階:自訂拖曳影像 (dmManual + OnStartDrag)


void __fastcall TForm1::TreeView1StartDrag(TObject* Sender, TDragObject*& DragObject) {
    // 建立自訂拖曳物件,可攜帶資料、自訂游標
    DragObject = new TDragControlObjectEx(TreeView1);
    // 或 TDragDockObjectEx 用於 Docking
}

三、檔案/外部資料拖入應用程式

  • 表單/控件 DragMode = dmAutomatic。
  • OnDragOver 檢查 Source 為 TDragFileObject (C++Builder 封裝) 或處理 WM_DROPFILES。
  • 更簡單:DragAcceptFiles(Handle, TRUE) + 處理 WM_DROPFILES 取得檔案列表 (DragQueryFile)。

常見問題與解決

現代替代:VCL 樣式 / FireMonkey / 自訂拖放管理器

  • VCL 原生拖放功能基礎但足夠大多數場景。
  • 複雜需求(多選、跨表單、動畫影像、觸控支援)可封裝 IDropTarget/IDropSource COM 介面實現完整 OLE 拖放。
  • FireMonkey (FMX) 提供跨平台 OnDragEnter/Leave/Over/Drop/End 事件體系。

總結

C++Builder 拖放分為 **Docking (三屬性自動化)** 與 **手動 Drag&Drop (四大事件核心)**。工具列停駐用前者,資料傳輸/排序用後者。掌握 OnDragOver.Accept、OnDragDrop 資料移動、DragMode 選擇,即可覆蓋 90% 場景。複雜跨應用拖放請轉向 OLE Drag&Drop COM 介面。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
問題原因解決
拖曳不啟動DragMode = dmManual 但未呼叫 BeginDrag設 dmAutomatic 或 OnMouseDown 呼叫 BeginDrag
目標不接受OnDragOver 未設 Accept=true正確判斷 Source 類型並設 Accept
拖曳游標錯誤未處理 OnDragOver State 參數根據 dsDragEnter/Leave/Move 更新游標
Docking 後無法拖出容器 DockSite=true 但子控件 DragKind≠dkDock子控件 DragKind=dkDock, DragMode=dmAutomatic