예제 #1
0
 private void tv1_HandleDestroyed(object sender, EventArgs e)
 {
     //Debug.WriteLine("in handle destroyed")
     if (this.AllowDrop)
     {
         int res;
         res = ShellDll.RevokeDragDrop(tv1.Handle);
         if (res != 0)
         {
             Debug.WriteLine("RevokeDragDrop returned " + res);
         }
         //Else
         //    Debug.WriteLine("HandleDestroyed with allowdrop false")
     }
 }
예제 #2
0
        public ExpTree()
        {
            //This call is required by the Windows Form Designer.
            InitializeComponent();

            //Add any initialization after the InitializeComponent() call


            //setting the imagelist here allows many good things to happen, but
            // also one bad thing -- the "tooltip" like display of selectednode.text
            // is made invisible.  This remains a problem to be solved.
            SystemImageListManager.SetTreeViewImageList(tv1, false);

            StartUpDirectoryChanged += new ExpTreeLib.ExpTree.StartUpDirectoryChangedEventHandler(OnStartUpDirectoryChanged);

            OnStartUpDirectoryChanged(m_StartUpDirectory);

            if (tv1.IsHandleCreated)
            {
                if (this.AllowDrop)
                {
                    if (Application.OleRequired() == System.Threading.ApartmentState.STA)
                    {
                        DragDropHandler              = new TVDragWrapper(tv1);
                        DragDropHandler.ShDragEnter += new ExpTreeLib.TVDragWrapper.ShDragEnterEventHandler(DragWrapper_ShDragEnter);
                        DragDropHandler.ShDragLeave += new ExpTreeLib.TVDragWrapper.ShDragLeaveEventHandler(DragWrapper_ShDragLeave);
                        DragDropHandler.ShDragOver  += new ExpTreeLib.TVDragWrapper.ShDragOverEventHandler(DragWrapper_ShDragOver);
                        DragDropHandler.ShDragDrop  += new ExpTreeLib.TVDragWrapper.ShDragDropEventHandler(DragWrapper_ShDragDrop);
                        int res;
                        res = ShellDll.RegisterDragDrop(tv1.Handle, DragDropHandler);
                        if (!(res == 0) || (res == -2147221247))
                        {
                            Marshal.ThrowExceptionForHR(res);
                            throw (new Exception("Failed to Register DragDrop for " + this.Name));
                        }
                    }
                    else
                    {
                        throw (new ThreadStateException("ThreadMustBeSTA"));
                    }
                }
            }
        }
예제 #3
0
        ///<Summary>Given an IDataObject from some non-net source, Build the
        /// m_DragList ArrayList.
        /// Also ensure that the IDataObject has "Shell IDList Array" formatted data
        /// If not, build it in m_StreamCIDA, if so, copy to m_StreamCIDA
        ///If dealing with all FileSystem Items,
        /// </Summary>
        private void ProcessCOMIDataObject(ShellDll.IDataObject IDO)
        {
            //Don't even look for an ArrayList. If there, we don't know how to access
            //Therefore, we need either a "FileDrop" or a "Shell IDList Array" to
            //extract the info for m_DragList and to ensure that the IDataObject
            //actually has a "Shell IDList Array"

            int HR;             //general use response variable

            ShellDll.FORMATETC fmtEtc;
            ShellDll.STGMEDIUM stg;
            //ensure m_StreamCIDA is nothing  - will test for this later
            m_StreamCIDA = null;
            //First check for "Shell IDList Array" -- preferred in this case (and most others)
            int cf = ShellDll.RegisterClipboardFormat("Shell IDList Array");

            if (cf != 0)
            {
                fmtEtc.cfFormat    = (ShellDll.CF)cf;
                fmtEtc.lindex      = -1;
                fmtEtc.dwAspect    = ShellDll.DVASPECT.CONTENT;
                fmtEtc.ptd         = IntPtr.Zero;
                fmtEtc.Tymd        = ShellDll.TYMED.HGLOBAL;
                stg.hGlobal        = IntPtr.Zero;
                stg.pUnkForRelease = IntPtr.Zero;
                stg.tymed          = (int)ShellDll.TYMED.HGLOBAL;
                HR = IDO.GetData(ref fmtEtc, ref stg);
                if (HR == 0)
                {
                    IntPtr cidaptr = Marshal.ReadIntPtr(stg.hGlobal);
                    m_StreamCIDA = MakeStreamFromCIDA(cidaptr);
                    MakeDragListFromCIDA();
                    ShellDll.ReleaseStgMedium(ref stg); //done with this
                }
                else
                {
                    try
                    {
                        Marshal.ThrowExceptionForHR(HR);
                    }
                    catch (Exception)
                    {
                    }
                }
            }

            //Check for "FileDrop" (CF.HDROP) if we have to
            if (m_Draglist.Count < 1)             //skip this if already have list
            {
                fmtEtc.cfFormat    = ShellDll.CF.HDROP;
                fmtEtc.lindex      = -1;
                fmtEtc.dwAspect    = ShellDll.DVASPECT.CONTENT;
                fmtEtc.ptd         = IntPtr.Zero;
                fmtEtc.Tymd        = ShellDll.TYMED.HGLOBAL;
                stg.hGlobal        = IntPtr.Zero;
                stg.pUnkForRelease = IntPtr.Zero;
                stg.tymed          = 0;
                HR = IDO.GetData(ref fmtEtc, ref stg);
                if (HR == 0)                 //we have an HDROP and stg.hGlobal points to the info
                {
                    IntPtr pHdrop  = Marshal.ReadIntPtr(stg.hGlobal);
                    int    nrItems = ShellDll.DragQueryFile(pHdrop, -1, null, 0);
                    int    i;
                    for (i = 0; i <= nrItems - 1; i++)
                    {
                        int           plen = ShellDll.DragQueryFile(pHdrop, i, null, 0);
                        StringBuilder SB   = new StringBuilder(plen + 1);
                        int           flen = ShellDll.DragQueryFile(pHdrop, i, SB, plen + 1);
                        Debug.WriteLine("Fetched from HDROP: " + SB.ToString());
                        try                         //if GetCShitem returns Nothing(it's failure marker) then catch it
                        {
                            m_Draglist.Add(ExpTreeLib.CShItem.GetCShItem(SB.ToString()));
                        }
                        catch (Exception ex)                         // in this case, just skip it
                        {
                            Debug.WriteLine("Error: CMyDataObject.ProcessComIDataObject - Adding via HDROP" + "\r\n" + "\t" + ex.Message);
                        }
                    }
                    ShellDll.ReleaseStgMedium(ref stg);                     //done with this stg
                    //Else
                    //    Marshal.ThrowExceptionForHR(HR)
                }
            }
            //Have done what we can to get m_DragList -- exit on failure
            if (m_Draglist.Count < 1)   //Can't do any more -- Quit
            {
                return;                 //leaving m_IsValid as False
            }

            //May not have Shell IDList Array in IDataObject.  If not, give it one
            if (m_StreamCIDA == null)             //IDO does not yet have "Shell IDList Array" Data
            {
                m_StreamCIDA = MakeShellIDArray(m_Draglist);
                if (m_StreamCIDA == null)
                {
                    return;                     //failed to make it
                }
                //Now put the CIDA into the original IDataObject
                fmtEtc.cfFormat = (ShellDll.CF)cf;                 //registered at routine entry
                fmtEtc.lindex   = -1;
                fmtEtc.dwAspect = ShellDll.DVASPECT.CONTENT;
                fmtEtc.ptd      = IntPtr.Zero;
                fmtEtc.Tymd     = ShellDll.TYMED.HGLOBAL;
                //note the hGlobal item in stg is a pointer to a pointer->Data
                IntPtr m_hg = Marshal.AllocHGlobal(Convert.ToInt32(m_StreamCIDA.Length));
                Marshal.Copy(m_StreamCIDA.ToArray(), 0, m_hg, (int)m_StreamCIDA.Length);
                IntPtr hg = Marshal.AllocHGlobal(IntPtr.Size);
                Marshal.WriteIntPtr(hg, 0, m_hg);
                stg.tymed          = (int)ShellDll.TYMED.HGLOBAL;
                stg.hGlobal        = hg;
                stg.pUnkForRelease = IntPtr.Zero;

                HR = IDO.SetData(ref fmtEtc, ref stg, true);                 //callee responsible for releasing stg
                if (HR == 0)
                {
                    m_IsValid = true;
                }
                else                 //failed -- we have to release stg  -- and leave m_IsValid as False
                {
                    ShellDll.ReleaseStgMedium(ref stg);
                    return;                     //m_isvalid stays False
                }
            }
            m_IsValid = true;             //already had a Shell IDList Array, so all is OK
        }
예제 #4
0
        ///<Summary>Given an IDataObject from some non-net source, Build the
        /// m_DragList ArrayList.
        /// Also ensure that the IDataObject has "Shell IDList Array" formatted data
        /// If not, build it in m_StreamCIDA, if so, copy to m_StreamCIDA
        ///If dealing with all FileSystem Items,
        /// </Summary>
        private void ProcessCOMIDataObject(ShellDll.IDataObject IDO)
        {
            //Don't even look for an ArrayList. If there, we don't know how to access
            //Therefore, we need either a "FileDrop" or a "Shell IDList Array" to
            //extract the info for m_DragList and to ensure that the IDataObject
            //actually has a "Shell IDList Array"

            int HR; //general use response variable
            ShellDll.FORMATETC fmtEtc;
            ShellDll.STGMEDIUM stg;
            //ensure m_StreamCIDA is nothing  - will test for this later
            m_StreamCIDA = null;
            //First check for "Shell IDList Array" -- preferred in this case (and most others)
            int cf = ShellDll.RegisterClipboardFormat("Shell IDList Array");
            if (cf != 0)
            {
                fmtEtc.cfFormat = (ShellDll.CF)cf;
                fmtEtc.lindex = - 1;
                fmtEtc.dwAspect = ShellDll.DVASPECT.CONTENT;
                fmtEtc.ptd = IntPtr.Zero;
                fmtEtc.Tymd = ShellDll.TYMED.HGLOBAL;
                stg.hGlobal = IntPtr.Zero;
                stg.pUnkForRelease = IntPtr.Zero;
                stg.tymed = (int)ShellDll.TYMED.HGLOBAL;
                HR = IDO.GetData(ref fmtEtc, ref stg);
                if (HR == 0)
                {
                    IntPtr cidaptr = Marshal.ReadIntPtr(stg.hGlobal);
                    m_StreamCIDA = MakeStreamFromCIDA(cidaptr);
                    MakeDragListFromCIDA();
                    ShellDll.ReleaseStgMedium(ref stg); //done with this
                }
                else
                {
                    try
                    {
                        Marshal.ThrowExceptionForHR(HR);
                    }
                    catch (Exception)
                    {
                    }
                }
            }

            //Check for "FileDrop" (CF.HDROP) if we have to
            if (m_Draglist.Count < 1) //skip this if already have list
            {
                fmtEtc.cfFormat = ShellDll.CF.HDROP;
                fmtEtc.lindex = - 1;
                fmtEtc.dwAspect = ShellDll.DVASPECT.CONTENT;
                fmtEtc.ptd = IntPtr.Zero;
                fmtEtc.Tymd = ShellDll.TYMED.HGLOBAL;
                stg.hGlobal = IntPtr.Zero;
                stg.pUnkForRelease = IntPtr.Zero;
                stg.tymed = 0;
                HR = IDO.GetData(ref fmtEtc, ref stg);
                if (HR == 0) //we have an HDROP and stg.hGlobal points to the info
                {
                    IntPtr pHdrop = Marshal.ReadIntPtr(stg.hGlobal);
                    int nrItems = ShellDll.DragQueryFile(pHdrop, -1, null, 0);
                    int i;
                    for (i = 0; i <= nrItems - 1; i++)
                    {
                        int plen = ShellDll.DragQueryFile(pHdrop, i, null, 0);
                        StringBuilder SB = new StringBuilder(plen + 1);
                        int flen = ShellDll.DragQueryFile(pHdrop, i, SB, plen + 1);
                        Debug.WriteLine("Fetched from HDROP: " + SB.ToString());
                        try //if GetCShitem returns Nothing(it's failure marker) then catch it
                        {
                            m_Draglist.Add(ExpTreeLib.CShItem.GetCShItem(SB.ToString()));
                        }
                        catch (Exception ex) // in this case, just skip it
                        {
                            Debug.WriteLine("Error: CMyDataObject.ProcessComIDataObject - Adding via HDROP" + "\r\n" + "\t" + ex.Message);
                        }
                    }
                    ShellDll.ReleaseStgMedium(ref stg); //done with this stg
                    //Else
                    //    Marshal.ThrowExceptionForHR(HR)
                }
            }
            //Have done what we can to get m_DragList -- exit on failure
            if (m_Draglist.Count < 1) //Can't do any more -- Quit
            {
                return; //leaving m_IsValid as False
            }

            //May not have Shell IDList Array in IDataObject.  If not, give it one
            if (m_StreamCIDA == null) //IDO does not yet have "Shell IDList Array" Data
            {
                m_StreamCIDA = MakeShellIDArray(m_Draglist);
                if (m_StreamCIDA == null)
                {
                    return; //failed to make it
                }
                //Now put the CIDA into the original IDataObject
                fmtEtc.cfFormat = (ShellDll.CF)cf; //registered at routine entry
                fmtEtc.lindex = - 1;
                fmtEtc.dwAspect = ShellDll.DVASPECT.CONTENT;
                fmtEtc.ptd = IntPtr.Zero;
                fmtEtc.Tymd = ShellDll.TYMED.HGLOBAL;
                //note the hGlobal item in stg is a pointer to a pointer->Data
                IntPtr m_hg = Marshal.AllocHGlobal(Convert.ToInt32(m_StreamCIDA.Length));
                Marshal.Copy(m_StreamCIDA.ToArray(), 0, m_hg, (int)m_StreamCIDA.Length);
                IntPtr hg = Marshal.AllocHGlobal(IntPtr.Size);
                Marshal.WriteIntPtr(hg, 0, m_hg);
                stg.tymed = (int)ShellDll.TYMED.HGLOBAL;
                stg.hGlobal = hg;
                stg.pUnkForRelease = IntPtr.Zero;

                HR = IDO.SetData(ref fmtEtc, ref stg, true); //callee responsible for releasing stg
                if (HR == 0)
                {
                    m_IsValid = true;
                }
                else //failed -- we have to release stg  -- and leave m_IsValid as False
                {
                    ShellDll.ReleaseStgMedium(ref stg);
                    return; //m_isvalid stays False
                }
            }
            m_IsValid = true; //already had a Shell IDList Array, so all is OK
        }