Getting Files from the Windows Shell
When you select one or more files in any Explorer window, the names of the files are packed in an array of strings and passed along during the drag-and-drop operation. Suppose you have an MDI application and set the AllowDrop
property of your main window to true. What happens when you drop one or more files selected from the shell onto that window? The drag-and-drop infrastructure fires the DragDrop
event to the object that is the target of the drop: your form.
|Implementing drag-and-drop from within a TextBox control is more complicated than with other controls. This is mostly due to the fact that the TextBox control handles the MouseDown; event on its own.|
More precisely, you need to handle a couple of events: DragOver
. The former is useful to check the type of data being dragged and determines whether that data is of any interest to you. The latter finalizes the operation accepting the file names as effective input of the application. Listing 1
shows a possible implementation. Both events store arguments using an instance of the DragEventArgs
class. The class counts the properties listed in Table 3.
Table 3: These are the properties of the DragEventArgs class.
Returns which operations the source allows on the target. You can accept all of them or only a subset.
Data associated with this event. Data is exposed as an object that implements the IDataObject interface.
Gets and sets the operations that the target can accept.
Returns the state of the Shift, Ctrl, and Alt keys, as well as the state of the mouse buttons.
Screen X-coordinate of the mouse.
Screen Y-coordinate of the mouse.
Of particular interest is the property Data
. It is a member of type IDataObject, an interface that gathers the methods to get and set data to drag and drop. The interface lists four methods: GetData
, and SetData
Any data coming to you through a drag-and-drop operation is normally available in multiple formats. The GetFormats
method returns an array of strings with the names of the supported formats. You can check them all using the following code:
For Each fmt As String In e.Data.GetFormats()
' Output format name and type
Debug.WriteLine(fmt + " (" + _
e.Data.GetData(fmt).ToString() + ")")
The .NET Framework groups the most commonly used data formats in the DataFormats
enum type. The GetData
method extracts and returns the data of the specified format and GetDataPresent
indicates whether data is available in a given format. Finally, you use SetData
to add data in a given format to the container being moved across controls.
When the Windows shell initiates the drag-and-drop operation, data is moved in six different formats: an array of shell IDs, the DragContext
structure, the InShellDragLoop
structure, the FileName
, the FileNameW
, and the FileDrop
. The first three types are memory streams; the latter three are arrays of strings. The first three types are supported for backward compatibility toward Win16 and Win32 applications. FileName
, and FileDrop
are formats specifically designed for .NET applications. Of these, only FileDrop
is significant in the vast majority of situations.
It is interesting to illustrate the difference between FileDrop
and the other two formats. First and foremost, only the FileDrop
format guarantees that, in case of multiple selections, all the file names are reported. FileName
return a one-element array, the currently focused shell item. In addition, FileName
returns the MS-DOS name of the file in the old 8+3 format; FileNameW
returns the long file name. For example, you can get the focused item using the following code:
Dim s() As String
s = CType(e.Data.GetData("FileNameW"), String())
Dim fileName As String = s(0)