2009-08-18 39 views
4

使用'標準'VCL拖放事件OnDragOver和OnDragDrop,我怎麼能區分「複製」和「移動」操作?檢查複製與移動德爾福拖放

我似乎沒有TDragType可用,並且鍵盤Shift狀態不傳遞給這些事件。

回答

8

這不是您可以從事件中確定的事情,因爲事件不會對您的應用程序需求或功能做出假設。

將特定的拖放解釋爲具有任何特定的語義是應用程序本身的責任 - 操作系統無法知道應用程序將如何對文件的丟棄作出反應,因此不能假定拖動操作可能意味着什麼爲用戶。

對於很多應用程序來說,複製/移動之間沒有區別,只會拖放。

複製/移動的區別是Windows資源管理器適用於文件操作。對於「vanilla」拖/放,它應用基於原始和目標驅動器卷的規則 - 默認情況下在捲上拖放文件是移動操作。跨越拖/放卷是副本,默認情況下。

但這些只是由應用程序(Windows資源管理器)確定的默認規則。用戶可以在拖動過程中使用鍵盤快捷方式覆蓋這些默認設置,最重要的是在放置時使用鍵盤快捷鍵。但這些是由特定應用程序定義和解釋的,即Windows資源管理器 - 不是操作系統。

所以,如果你的應用是用於文件放置目標可以從Windows資源管理器拖動,如果是有意義的,你的應用程序複製和移動之間進行區分,那麼你可能需要支持相同鍵盤修飾符Windows資源管理器支持。我不相信這是可以修改的(雖然我建議這個有待確認),所以你可以簡單地測試了Ctrl鍵的狀態或在您拖動事件Shift鍵:

Ctrl   = COPY 
Shift  = MOVE 
Ctrl + Shift = MAKE SHORTCUT (if this is applicable to your application) 

GetKeyState()可以用來直接在任何特定時刻詢問特定密鑰的狀態。

如果改變「默認」的行爲需要,那麼你就必須運用自己的測試的源信息來確定哪些默認最有意義(即模仿Windows資源管理器「卷邊界」默認規則),或者爲您的應用程序選擇最合適或直觀的默認操作。

+0

用於GetKeyState()的+1 - 但是如果移動與複製概念沒有硬編碼到VCL中,爲什麼當按下控制鍵時拖動光標會獲得「+」號(表示複製)。 – Roddy 2009-08-19 08:48:17

+0

那麼,VCL不會爲內部的VCL初始拖放操作設置這個「複製」光標,所以它可能不是VCL *設置*這個光標。我認爲這是VCL *不*設置光標。 即當用戶在拖動過程中按下Ctrl時,Windows資源管理器設置光標。如果放置目標不特別覆蓋該光標,則不會改變(例如,記事本和PaintShop Pro也不適當地「保留」複製光標)。甚至可能是放置目標應用程序甚至無法更改光標,這可能由拖動源「擁有」。我必須檢查。 – Deltics 2009-08-19 10:42:29

+0

當使用DragAcceptFiles()從Windows資源管理器接收文件(我設法獲得+「複製」拖動光標的唯一方法)時,目標應用程序沒有機會將* drag *光標更改爲Windows文件拖放系統僅發送* drop *通知。無論如何,這種機制並不涉及VCL拖動事件。 也許有關您的具體實施的更多信息可能會有所幫助。例如,您是否使用第三方拖放控件來支持文件丟棄? – Deltics 2009-08-19 10:55:44

0

不確定關於Delphi的具體情況,但在C#中,您檢查了EventEvent參數的AllowedEffect屬性。既然它們都鏈接回Win32,我無法想象它們有什麼不同。

http://msdn.microsoft.com/en-us/library/system.windows.forms.drageventargs.aspx有一個很好的例子。希望這可以幫助!

+0

可悲的是沒有幫助。 Delphi VCL不使用Win32調用進行「內部」拖放操作,AFAIK。 – Roddy 2009-08-18 20:57:37

+0

仍然..不需要downvote。我發現它很有幫助。 +1 – 2009-08-19 19:20:04

4

簡短的回答是 - 你不知道。 VCL的內置拖放系統並不區分這兩者。但是,您可以派生自己的TDragObject/Ex類來控制實際被拖動的數據類型。

4

如果你想在應用程序和其他Windows應用程序之間使用Drag'n'Drop,那麼值得看看Anders Melander的Drag and Drop Component Suite for Delphi
最新的代碼是here

+1

其實,我已經使用它了;-) – Roddy 2009-08-19 10:05:17