using System; using System.IO; using System.ComponentModel; using System.ComponentModel.Design; using System.Collections; using System.Diagnostics; using System.Drawing; using System.Windows.Forms; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; using Microsoft.Win32; // Registry using System.Runtime.InteropServices; using System.Reflection; using System.Text; namespace DragAndDropFileControlLibrary { [DefaultEventAttribute("FileDropped")] public partial class DragAndDropFileComponent : Component, ISupportInitialize, IMessageFilter { [DllImport("shell32.dll")] static extern long DragAcceptFiles(IntPtr hwnd, Boolean accept); [DllImport("shell32.dll")] static extern int DragQueryFile(IntPtr hdrop, int iFile, StringBuilder fileName, int fileSize); [DllImport("shell32.dll")] static extern void DragFinish(IntPtr hdrop); const int WM_DROPFILES = 563; private Form host; public DragAndDropFileComponent() { } public DragAndDropFileComponent(IContainer container) : this() { // Integrate with container if( container != null ) container.Add(this); } #region ISupportInitialize Members public void BeginInit() { } public void EndInit() { // Filter file drop associated messages Application.AddMessageFilter(this); DragAcceptFiles(this.host.Handle, true); } #endregion // From Ian Griffiths (thanks, Ian!) [Browsable(false)] public Form HostingForm { get { if( (host == null) && this.DesignMode ) { // See if we're being hosted in VS.NET (or something similar) IDesignerHost designer = this.GetService(typeof(IDesignerHost)) as IDesignerHost; if( designer != null ) host = designer.RootComponent as Form; } return host; } set { // Cache the hosting form host = value; } } [Category("Action")] [Description("Occurs when a file is dropped onto the host form.")] public event FileDroppedEventHandler FileDropped; public bool PreFilterMessage(ref Message m) { if( m.Msg == WM_DROPFILES ) { // This code handles multiple dropped files. int filecount = DragQueryFile(m.WParam, -1, null, 0); // Extract files if( filecount > 0 ) { string[] filenames = new string[filecount]; for( int i = 0; i < filecount; i++ ) { StringBuilder sb = new StringBuilder(256); DragQueryFile(m.WParam, i, sb, 256); filenames[i] = sb.ToString(); } // Process files HandleDroppedFiles(filenames); } // Release system allocated memory DragFinish(m.WParam); return true; } return false; } public void HandleDroppedFiles(string[] filenames) { FileDroppedEventArgs e = new FileDroppedEventArgs(filenames); OnFileDropped(e); } protected virtual void OnFileDropped(FileDroppedEventArgs e) { if( FileDropped != null ) { FileDropped(this, e); } } } }