2014-12-03 81 views
2

我有一個具有兩種形式的MDI表單應用程序。第一個有一個StringGrid,第二個窗體有很多Edit控件和幾個按鈕。從一種形式拖放到另一種形式的任何地方

我需要從網格中拖動並放在第二個窗體上,並使用第一個窗體中的StringGrid中的選定單元格的值更新一個Edit。

這很容易做,如果我事先知道哪個控件用戶將釋放鼠標左鍵,因爲我可以設置該特定控件的OnDragDrop事件。但我不想爲第二個窗體上的每個控件編寫多個OnDragDrop事件。

如何攔截一個窗體範圍的消息來攔截任何控件上的放置操作?

+1

你不需要代碼分開'OnDragOver/OnDragDrop'事件。將所有接收控件的OnDragOver/OnDragDrop事件設置爲指向一個公共處理程序。 'Sender'參數告訴你哪個控件即將接收到,而'Source'參數告訴你 - 源代碼。 – 2014-12-03 15:41:08

+0

是的,我知道,但我仍然需要手動將相同的處理程序分配給每個組件的onDragDrop事件。一個可能的解決方案可能是枚舉窗體上的所有組件,並將它們分配給每個組件...但是如果我嘗試這種方法,我會收到無效的類型轉換錯誤 – user1566931 2014-12-03 16:22:19

+0

@ user1566931枚舉控件,而不是組件 – MBo 2014-12-03 17:07:18

回答

4

坐落在OnStartDrag事件的StringGrid的定製DragObject

{ TMyDragObject } 

type 
    TMyDragObject = class(TDragControlObjectEx) 
    protected 
    DragText: String; 
    procedure Finished(Target: TObject; X, Y: Integer; Accepted: Boolean); override; 
    function GetDragCursor(Accepted: Boolean; X, Y: Integer): TCursor; override; 
    end; 

procedure TMyDragObject.Finished(Target: TObject; X, Y: Integer; Accepted: Boolean); 
begin 
    if Target is TCustomEdit then 
    TCustomEdit(Target).SelText := DragText; 
    inherited; 
end; 

function TMyDragObject.GetDragCursor(Accepted: Boolean; X, Y: Integer): TCursor; 
begin 
    if TObject(DragTarget) is TCustomEdit then 
    Result := crDrag 
    else 
    Result := inherited GetDragCursor(Accepted, X, Y); 
end; 

{ TForm1 } 

procedure TForm1.StringGrid1StartDrag(Sender: TObject; var DragObject: TDragObject); 
begin 
    DragObject := TMyDragObject.Create(StringGrid1); 
    TMyDragObject(DragObject).DragText := StringGrid1.Cells[StringGrid1.Col, 
    StringGrid1.Row]; 
end;