views:

250

answers:

4

Using the 'standard' VCL drag and drop events OnDragOver and OnDragDrop, how can I distinguish between "Copy" and "Move" operations?

I don't seem to have a TDragType available, and the keyboard Shift state isn't passed to these events.

A: 

Not sure about Delphi specifically, but in C# you check the AllowedEffect property of your event parameter. Since they both link back to Win32 I can't imagine there is much difference.

http://msdn.microsoft.com/en-us/library/system.windows.forms.drageventargs.aspx has a good example. Hope this helps!

Kleinux
Sadly no help. The Delphi VCL doesn't use Win32 calls for it's 'internal' drag and drop, AFAIK.
Roddy
Still.. no need to downvote. I found it helpful. +1
Wouter van Nifterick
+3  A: 

The short answer is - you don't. The VCL's built-in drag-n-drop system does not distinquish between the two. You can, however, derive your own TDragObject/Ex classes to control what kind of data actually gets dragged around.

Remy Lebeau - TeamB
+6  A: 

This is not something you can determine from the events because the events make no assumptions about your application needs or capabilities.

Interpreting a particular drag/drop as having any particular semantics is the responsibility of the application itself - the OS cannot know how the application will react to the dropping of a file so can make no assumptions about what the dragging operation may imply for the user.

For many applications there will be no distinction between copy/move, there will be just drag-and-drop.

The copy/move distinction is something that Windows Explorer applies to file operations. For "vanilla" drag/drops it applies rules based on original and destination drive volumes - dragging/dropping files around on a volume is a move operation, by default. Dragging/dropping across volumes is a copy, by default.

But these are only default rules determined by the application (Windows Explorer). The user can override these default using keyboard shortcuts during dragging and (most importantly) when dropping. But these are defined and interpreted by the particular application - i.e. Windows Explorer - not the OS.

So, if you're application is a drop target for files that may be dragged from Windows Explorer, and if it makes sense for your application to discriminate between copy and move, then you may need to support the same keyboard modifiers that Windows Explorer supports. I don't believe these are modifiable (although I'd advise this be confirmed), so you could simply test the state of the Ctrl or Shift keys in your drag events:

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

GetKeyState() can be used to directly interrogate the state of a specific key at any given moment in time.

If a varying "default" behaviour is desired then you would have to apply your own tests to the source information to determine which default makes most sense (i.e. to mimic the Windows Explorer "volume boundary" default rules), or simply choose the most appropriate or intuitive default action for your application.

Deltics
+1 for GetKeyState() - but if the move vs. copy concepts aren't hard-coded into the VCL, why does the drag cursor acquire a "+" sign (indicating copy) when the control key is pressed.
Roddy
Well, the VCL doesn't set this "copy" cursor for internal, VCL originated drag/drop operations, so it probably isn't the VCL *setting* this cursor. I think it's the VCL *not* setting the cursor.i.e. Windows Explorer sets the cursor when the user presses Ctrl during a drag. If the drop target doesn't specifically override that cursor then it won't change (Notepad and PaintShop Pro also both inappropriately "keep" the copy cursor, for example). It may even be that the drop target application isn't even able to change the cursor, which could be "owned" by the drag source. I'd have to check.
Deltics
When using DragAcceptFiles() to receive files from Windows Explorer (the only way I managed to get a + "copy" drag cursor), it doesn't appear that the target application gets the opportunity to change the *drag* cursor as the Windows file drag/drop system only sends a *drop* notification. And this mechanism doesn't involve the VCL drag events anyway.Perhaps some more information about your specific implementation may help. Are you using a 3rd party drag/drop control to support file-dropping, for example?
Deltics
@Deltics - you're right. It's a 3rd party component I'm using that's setting the "+" cursor for some reason. Hey-ho...
Roddy
+3  A: 

If you want to use Drag'n'Drop between your application and other Windows applications, it's worth looking at Anders Melander's Drag and Drop Component Suite for Delphi.
The latest code being here.

François
Actually, I'm using it already ;-)
Roddy