SDI and MDI applications currently provide two mechanisms for opening files: the File | Open menu or double-clicking a file in the shell. However, there's a common file open mechanism that's missing: allowing users to drag files from the shell and drop them onto the application. To detect when a file is dropped onto an application's main form, the application needs to filter its Windows message queue for the message that's sent whenever one or more files are dropped. To do that, your application registers an IMessageFilter (from System.Windows.Forms) implementation and broadcasts its ability to accept dropped files by calling the DragAcceptFiles function from the shell32.dll. When the IMessageFilter implementation detects the dropped-files message, it calls the DragQueryFile function to determine how many files are being dropped; then it gets the file name of each one by again calling DragQueryFile, this time passing an index to the required file. When processing is complete, the IMessageFilter implementation must call DragFinish to release memory allocated by the system for this operation. After the set of file names is retrieved, it is passed to the client for processing. Assembling this code, although fun, isn't necessary, because you'll find a component with the book's samples at our web site (http://www.sellsbrothers.com/writing/wfbook) a component, DragAndDropFileComponent, that you can drop onto a form to provide this support.[11]
When this component is on the form, you can configure DragAndDropFileComponent's FileDropped event, as shown in Figure F.21, to detect when files are dropped onto your application so that they can be processed as the application sees fit. Figure F.21. Handling the DragAndDropFileComponent's FileDropped Event from the Properties WindowWhen DragAndDropFileComponent is hosted on a form, it fires the FileDropped event whenever one or more files are dragged from the shell onto the host form at any one time. The FileDropped event handler is passed a FileDroppedEventArgs from which you determine the files that were dropped (it could be more than one) and use this information to open it: partial class RatesOfReturnForm : Form { ... void dragAndDropFileComponent_FileDropped( object sender, FileDroppedEventArgs e) { // Process each file foreach( string filename in e.Filenames ) { // Only open files with the appropriate extension string extension = Path.GetExtension(filename); if( extension == ".ror" ) { OpenDocument(filename); } else { MessageBox.Show("Can't open files of type " + extension); } } } } Figure F.22 illustrates the drag-and-drop half of the operation, and Figure F.23 shows the consequently opened file. Figure F.22. Dragging and Dropping a File from the Shell onto an ApplicationFigure F.23. The Dropped File Is Opened
Note that for MDI applications, DragAndDropFileComponent must be dropped onto the MDI parent form, because this is the form that is exposed to the shell. However, when the component is dropped, the code to handle the FileDropped event on an MDI parent is the same as for SDI applications. |