예제 #1
0
        public static string GetSourceProjectPath(Microsoft.VisualStudio.OLE.Interop.IDataObject dataObject)
        {
            string    projectPath = null;
            FORMATETC fmtetc      = CreateFormatEtc(CF_VSPROJECTCLIPDESCRIPTOR);

            if (QueryGetData(dataObject, ref fmtetc) == VSConstants.S_OK)
            {
                STGMEDIUM stgmedium = DragDropHelper.GetData(dataObject, ref fmtetc);
                if (stgmedium.tymed == (uint)TYMED.TYMED_HGLOBAL)
                {
                    // We are releasing the cloned hglobal here.
                    IntPtr dropInfoHandle = stgmedium.unionmember;
                    if (dropInfoHandle != IntPtr.Zero)
                    {
                        try
                        {
                            string path = GetData(dropInfoHandle);

                            // Clone the path that we can release our memory.
                            if (!String.IsNullOrEmpty(path))
                            {
                                projectPath = String.Copy(path);
                            }
                        }
                        finally
                        {
                            Marshal.FreeHGlobal(dropInfoHandle);
                        }
                    }
                }
            }

            return(projectPath);
        }
예제 #2
0
        /// <summary>
        /// Empties all the data structures added to the clipboard and flushes the clipboard.
        /// </summary>
        private void CleanAndFlushClipboard()
        {
            IOleDataObject oleDataObject = null;

            ErrorHandler.ThrowOnFailure(UnsafeNativeMethods.OleGetClipboard(out oleDataObject));
            if (oleDataObject == null)
            {
                return;
            }


            string sourceProjectPath = DragDropHelper.GetSourceProjectPath(oleDataObject);

            if (!String.IsNullOrEmpty(sourceProjectPath) && NativeMethods.IsSamePath(sourceProjectPath, this.GetMkDocument()))
            {
                UnsafeNativeMethods.OleFlushClipboard();
                int clipboardOpened = 0;
                try
                {
                    clipboardOpened = UnsafeNativeMethods.OpenClipboard(IntPtr.Zero);
                    UnsafeNativeMethods.EmptyClipboard();
                }
                finally
                {
                    if (clipboardOpened == 1)
                    {
                        UnsafeNativeMethods.CloseClipboard();
                    }
                }
            }
        }
예제 #3
0
 public static void QueryGetData(Microsoft.VisualStudio.OLE.Interop.IDataObject pDataObject, ref FORMATETC fmtetc)
 {
     FORMATETC[] af = new FORMATETC[1];
     af[0] = fmtetc;
     pDataObject.QueryGetData(af);
     fmtetc = af[0];
 }
예제 #4
0
        /// <summary>
        /// Handle the Cut operation to the clipboard
        /// </summary>
        protected internal override int CutToClipboard()
        {
            int returnValue = (int)OleConstants.OLECMDERR_E_NOTSUPPORTED;

            try
            {
                this.RegisterClipboardNotifications(true);

                // Create our data object and change the selection to show item(s) being cut
                IOleDataObject dataObject = this.PackageSelectionDataObject(true);
                if (dataObject != null)
                {
                    this.SourceDraggedOrCutOrCopied = true;

                    // Add our cut item(s) to the clipboard
                    ErrorHandler.ThrowOnFailure(UnsafeNativeMethods.OleSetClipboard(dataObject));

                    // Inform VS (UiHierarchyWindow) of the cut
                    IVsUIHierWinClipboardHelper clipboardHelper = (IVsUIHierWinClipboardHelper)GetService(typeof(SVsUIHierWinClipboardHelper));
                    if (clipboardHelper == null)
                    {
                        return(VSConstants.E_FAIL);
                    }

                    returnValue = ErrorHandler.ThrowOnFailure(clipboardHelper.Cut(dataObject));
                }
            }
            catch (COMException e)
            {
                Trace.WriteLine("Exception : " + e.Message);
                returnValue = e.ErrorCode;
            }

            return(returnValue);
        }
예제 #5
0
        /// <summary>
        /// Determines if the paste command should be allowed.
        /// </summary>
        /// <returns></returns>
        protected internal override bool AllowPasteCommand()
        {
            IOleDataObject dataObject = null;

            try
            {
                ErrorHandler.ThrowOnFailure(UnsafeNativeMethods.OleGetClipboard(out dataObject));
                if (dataObject == null)
                {
                    return(false);
                }

                // First see if this is a set of storage based items
                FORMATETC format = DragDropHelper.CreateFormatEtc((ushort)DragDropHelper.CF_VSSTGPROJECTITEMS);
                if (dataObject.QueryGetData(new FORMATETC[] { format }) == VSConstants.S_OK)
                {
                    return(true);
                }
                // Try reference based items
                format = DragDropHelper.CreateFormatEtc((ushort)DragDropHelper.CF_VSREFPROJECTITEMS);
                if (dataObject.QueryGetData(new FORMATETC[] { format }) == VSConstants.S_OK)
                {
                    return(true);
                }
                // Try windows explorer files format
                format = DragDropHelper.CreateFormatEtc((ushort)NativeMethods.CF_HDROP);
                return(dataObject.QueryGetData(new FORMATETC[] { format }) == VSConstants.S_OK);
            }
            // We catch External exceptions since it might be that it is not our data on the clipboard.
            catch (ExternalException e)
            {
                Trace.WriteLine("Exception :" + e.Message);
                return(false);
            }
        }
예제 #6
0
        /// <summary>
        /// Get the dropdatatype from the dataobject
        /// </summary>
        /// <param name="pDataObject">The dataobject to be analysed for its format</param>
        /// <returns>dropdatatype or none if dataobject does not contain known format</returns>
        internal static DropDataType QueryDropDataType(IOleDataObject pDataObject)
        {
            if (pDataObject == null)
            {
                return(DropDataType.None);
            }

            // known formats include File Drops (as from WindowsExplorer),
            // VSProject Reference Items and VSProject Storage Items.
            FORMATETC fmt = DragDropHelper.CreateFormatEtc(NativeMethods.CF_HDROP);

            if (DragDropHelper.QueryGetData(pDataObject, ref fmt) == VSConstants.S_OK)
            {
                return(DropDataType.Shell);
            }

            fmt.cfFormat = DragDropHelper.CF_VSREFPROJECTITEMS;
            if (DragDropHelper.QueryGetData(pDataObject, ref fmt) == VSConstants.S_OK)
            {
                // Data is from a Ref-based project.
                return(DropDataType.VsRef);
            }

            fmt.cfFormat = DragDropHelper.CF_VSSTGPROJECTITEMS;
            if (DragDropHelper.QueryGetData(pDataObject, ref fmt) == VSConstants.S_OK)
            {
                return(DropDataType.VsStg);
            }

            return(DropDataType.None);
        }
예제 #7
0
        public static int QueryGetData(Microsoft.VisualStudio.OLE.Interop.IDataObject pDataObject, ref FORMATETC fmtetc)
        {
            ThreadHelper.ThrowIfNotOnUIThread();
            int returnValue = VSConstants.E_FAIL;

            FORMATETC[] af = new FORMATETC[1];
            af[0] = fmtetc;
            try
            {
                int result = ErrorHandler.ThrowOnFailure(pDataObject.QueryGetData(af));
                if (result == VSConstants.S_OK)
                {
                    fmtetc      = af[0];
                    returnValue = VSConstants.S_OK;
                }
            }
            catch (COMException e)
            {
                // do not display exception. We see this also when trying to ask for a Clipboard operation
                // when the actual change was a drag/drop
                returnValue = e.ErrorCode;
            }

            return(returnValue);
        }
예제 #8
0
        public static int QueryGetData(Microsoft.VisualStudio.OLE.Interop.IDataObject dataObject, ref FORMATETC fmtetc)
        {
            if (dataObject == null)
            {
                throw new ArgumentNullException("dataObject");
            }

            int returnValue = VSConstants.E_FAIL;

            FORMATETC[] af = new FORMATETC[1];
            af[0] = fmtetc;
            try
            {
                int result = ErrorHandler.ThrowOnFailure(dataObject.QueryGetData(af));
                if (result == VSConstants.S_OK)
                {
                    fmtetc      = af[0];
                    returnValue = VSConstants.S_OK;
                }
            }
            catch (COMException e)
            {
                Trace.WriteLine("COMException : " + e.Message);
                returnValue = e.ErrorCode;
            }

            return(returnValue);
        }
        /// <summary>
        /// Determines whether the Toolbox user supports the referenced data object.
        /// </summary>
        /// <param name="pDO">Data object to be supported.</param>
        /// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code.</returns>
        int IVsToolboxUser.IsSupported(IOleDataObject pDO)
        {
            // Create a OleDataObject from the input interface.
            new OleDataObject(pDO);

            // In all the other cases return S_FALSE
            return(VSConstants.S_FALSE);
        }
예제 #10
0
        /// <summary>
        ///  After a drop or paste, will use the dwEffects
        ///  to determine whether we need to clean up the source nodes or not. If
        ///  justCleanup is set, it only does the cleanup work.
        /// </summary>
        internal void CleanupSelectionDataObject(bool dropped, bool cut, bool moved, bool justCleanup)
        {
            if (this.ItemsDraggedOrCutOrCopied == null || this.ItemsDraggedOrCutOrCopied.Count == 0)
            {
                return;
            }

            try
            {
                IVsUIHierarchyWindow w = UIHierarchyUtilities.GetUIHierarchyWindow(this.site, HierarchyNode.SolutionExplorer);
                foreach (HierarchyNode node in this.ItemsDraggedOrCutOrCopied)
                {
                    if ((moved && (cut || dropped) && !justCleanup))
                    {
                        // do not close it if the doc is dirty or we do not own it
                        bool isDirty, isOpen, isOpenedByUs;
                        uint docCookie;
                        IVsPersistDocData ppIVsPersistDocData;
                        DocumentManager   manager = node.GetDocumentManager();

                        if (manager != null)
                        {
                            manager.GetDocInfo(out isOpen, out isDirty, out isOpenedByUs, out docCookie, out ppIVsPersistDocData);
                            if (isDirty || (isOpen && !isOpenedByUs))
                            {
                                continue;
                            }

                            // close it if opened
                            if (isOpen)
                            {
                                manager.Close(__FRAMECLOSE.FRAMECLOSE_NoSave);
                            }
                        }

                        node.Remove(true);
                    }
                    else if (w != null)
                    {
                        ErrorHandler.ThrowOnFailure(w.ExpandItem((IVsUIHierarchy)this, node.ID, EXPANDFLAGS.EXPF_UnCutHighlightItem));
                    }
                }
            }
            finally
            {
                // Now delete the memory allocated by the packaging of datasources.
                // If we just did a cut, or we are told to cleanup, then we need to free the data object. Otherwise, we leave it
                // alone so that you can continue to paste the data in new locations.
                if (moved || cut || justCleanup)
                {
                    this.ItemsDraggedOrCutOrCopied.Clear();
                    this.CleanAndFlushClipboard();
                }

                this.dataObject   = null;
                this.dropDataType = DropDataType.None;
            }
        }
예제 #11
0
        public static int QueryGetData(Microsoft.VisualStudio.OLE.Interop.IDataObject pDataObject, ref FORMATETC fmtetc)
        {
            FORMATETC[] af = new FORMATETC[1];
            af[0] = fmtetc;
            int hr = pDataObject.QueryGetData(af);

            fmtetc = af[0];
            return(hr);
        }
예제 #12
0
 public static STGMEDIUM GetData(Microsoft.VisualStudio.OLE.Interop.IDataObject pDataObject, ref FORMATETC fmtetc)
 {
     FORMATETC[] af = new FORMATETC[1];
     af[0] = fmtetc;
     STGMEDIUM[] sm = new STGMEDIUM[1];
     pDataObject.GetData(af, sm);
     fmtetc = af[0];
     return(sm[0]);
 }
예제 #13
0
 internal Ole2BclDataObject(OleInterop.IDataObject oleData)
 {
     if (null == oleData)
     {
         throw new ArgumentNullException("Microsoft.VisualStudio.OLE.Interop.IDataObject");
     }
     this.oleData = oleData;
     //this.bclData = oleData as BclComTypes.IDataObject;
     this.bclData = null;
 }
예제 #14
0
 internal Ole2BclDataObject(BclComTypes.IDataObject bclData)
 {
     if (null == bclData)
     {
         throw new ArgumentNullException("System.Runtime.InteropServices.ComTypes.IDataObject");
     }
     //this.oleData = bclData as OleInterop.IDataObject;
     this.oleData = null;
     this.bclData = bclData;
 }
예제 #15
0
        /// <summary>
        /// Handle the Paste operation to a targetNode
        /// </summary>
        protected internal override int PasteFromClipboard(HierarchyNode targetNode)
        {
            int returnValue = (int)OleConstants.OLECMDERR_E_NOTSUPPORTED;

            //Get the clipboardhelper service and use it after processing dataobject
            IVsUIHierWinClipboardHelper clipboardHelper = (IVsUIHierWinClipboardHelper)GetService(typeof(SVsUIHierWinClipboardHelper));

            if (clipboardHelper == null)
            {
                return(VSConstants.E_FAIL);
            }

            try
            {
                //Get dataobject from clipboard
                IOleDataObject dataObject = null;
                ErrorHandler.ThrowOnFailure(UnsafeNativeMethods.OleGetClipboard(out dataObject));
                if (dataObject == null)
                {
                    return(VSConstants.E_UNEXPECTED);
                }

                DropEffect   dropEffect   = DropEffect.None;
                DropDataType dropDataType = DropDataType.None;
                try
                {
                    dropDataType = this.ProcessSelectionDataObject(dataObject, targetNode.GetDragTargetHandlerNode());
                    dropEffect   = this.QueryDropEffect(dropDataType, 0);
                }
                catch (ExternalException e)
                {
                    Trace.WriteLine("Exception : " + e.Message);

                    // If it is a drop from windows and we get any kind of error ignore it. This
                    // prevents bogus messages from the shell from being displayed
                    if (dropDataType != DropDataType.Shell)
                    {
                        throw e;
                    }
                }
                finally
                {
                    // Inform VS (UiHierarchyWindow) of the paste
                    returnValue = clipboardHelper.Paste(dataObject, (uint)dropEffect);
                }
            }
            catch (COMException e)
            {
                Trace.WriteLine("Exception : " + e.Message);

                returnValue = e.ErrorCode;
            }

            return(returnValue);
        }
예제 #16
0
        /// <summary>
        /// Process dataobject from Drag/Drop/Cut/Copy/Paste operation
        /// </summary>
        /// <remarks>The targetNode is set if the method is called from a drop operation, otherwise it is null</remarks>
        ///
        internal DropDataType ProcessSelectionDataObject(IOleDataObject dataObject, HierarchyNode targetNode)
        {
            DropDataType dropDataType    = DropDataType.None;
            bool         isWindowsFormat = false;

            // Try to get it as a directory based project.
            List <string> filesDropped = DragDropHelper.GetDroppedFiles(DragDropHelper.CF_VSSTGPROJECTITEMS, dataObject, out dropDataType);

            if (filesDropped.Count == 0)
            {
                filesDropped = DragDropHelper.GetDroppedFiles(DragDropHelper.CF_VSREFPROJECTITEMS, dataObject, out dropDataType);
            }
            if (filesDropped.Count == 0)
            {
                filesDropped    = DragDropHelper.GetDroppedFiles(NativeMethods.CF_HDROP, dataObject, out dropDataType);
                isWindowsFormat = (filesDropped.Count > 0);
            }

            if (dropDataType != DropDataType.None && filesDropped.Count > 0)
            {
                string[] filesDroppedAsArray = filesDropped.ToArray();

                string sourceProjectPath = DragDropHelper.GetSourceProjectPath(dataObject);

                HierarchyNode node = (targetNode == null) ? this : targetNode;

                // For directory based projects the content of the clipboard is a double-NULL terminated list of Projref strings.
                if (isWindowsFormat)
                {
                    // This is the code path when source is windows explorer
                    VSADDRESULT[] vsaddresults = new VSADDRESULT[1];
                    vsaddresults[0] = VSADDRESULT.ADDRESULT_Failure;
                    int addResult = AddItem(node.ID, VSADDITEMOPERATION.VSADDITEMOP_OPENFILE, null, (uint)filesDropped.Count, filesDropped.ToArray(), IntPtr.Zero, vsaddresults);
                    if (addResult != VSConstants.S_OK && addResult != VSConstants.S_FALSE && addResult != (int)OleConstants.OLECMDERR_E_CANCELED &&
                        vsaddresults[0] != VSADDRESULT.ADDRESULT_Success)
                    {
                        ErrorHandler.ThrowOnFailure(addResult);
                    }
                    return(dropDataType);
                }
                else
                {
                    if (AddFilesFromProjectReferences(node, filesDroppedAsArray))
                    {
                        return(dropDataType);
                    }
                }
            }

            // If we reached this point then the drop data must be set to None.
            // Otherwise the OnPaste will be called with a valid DropData and that would actually delete the item.
            return(DropDataType.None);
        }
        /// <summary>
        /// Called as soon as the mouse drags an item over a new hierarchy or hierarchy window
        /// </summary>
        /// <param name="pDataObject">reference to interface IDataObject of the item being dragged</param>
        /// <param name="grfKeyState">Current state of the keyboard and the mouse modifier keys. See docs for a list of possible values</param>
        /// <param name="itemid">Item identifier for the item currently being dragged</param>
        /// <param name="pdwEffect">On entry, a pointer to the current DropEffect. On return, must contain the new valid DropEffect</param>
        /// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code.</returns>
        public override int DragEnter(IOleDataObject pDataObject, uint grfKeyState, uint itemid, ref uint pdwEffect)
        {
            pdwEffect = (uint)DropEffect.None;

            this.dropDataType = QueryDropDataType(pDataObject);
            if (this.dropDataType != DropDataType.None)
            {
                pdwEffect = (uint)this.QueryDropEffect(this.dropDataType, grfKeyState);
            }

            return VSConstants.S_OK;
        }
예제 #18
0
        /// <summary>
        /// Called when one or more items are dropped into the target hierarchy or hierarchy window when the mouse button is released.
        /// </summary>
        /// <param name="pDataObject">Reference to the IDataObject interface on the item being dragged. This data object contains the data being transferred in the drag-and-drop operation.
        /// If the drop occurs, then this data object (item) is incorporated into the target hierarchy or hierarchy window.</param>
        /// <param name="grfKeyState">Current state of the keyboard and the mouse modifier keys. See <seealso cref="IVsHierarchyDropDataTarget"/></param>
        /// <param name="itemid">Item identifier of the drop data target over which the item is being dragged</param>
        /// <param name="pdwEffect">Visual effects associated with the drag-and drop-operation, such as a cursor, bitmap, and so on.
        /// The value of dwEffects passed to the source object via the OnDropNotify method is the value of pdwEffects returned by the Drop method</param>
        /// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code. </returns>
        public override int Drop(IOleDataObject pDataObject, uint grfKeyState, uint itemid, ref uint pdwEffect)
        {
            if (pDataObject == null)
            {
                return(VSConstants.E_INVALIDARG);
            }

            pdwEffect = (uint)DropEffect.None;

            // Get the node that is being dragged over and ask it which node should handle this call
            HierarchyNode targetNode = NodeFromItemId(itemid);

            if (targetNode != null)
            {
                targetNode = targetNode.GetDragTargetHandlerNode();
            }
            else
            {
                // There is no target node. The drop can not be completed.
                return(VSConstants.S_FALSE);
            }

            int returnValue;

            try
            {
                DropDataType dropDataType = DropDataType.None;
                dropDataType = ProcessSelectionDataObject(pDataObject, targetNode);
                pdwEffect    = (uint)this.QueryDropEffect(dropDataType, grfKeyState);

                // If it is a drop from windows and we get any kind of error we return S_FALSE and dropeffect none. This
                // prevents bogus messages from the shell from being displayed
                returnValue = (dropDataType != DropDataType.Shell) ? VSConstants.E_FAIL : VSConstants.S_OK;
            }
            catch (System.IO.FileNotFoundException e)
            {
                Trace.WriteLine("Exception : " + e.Message);

                if (!Utilities.IsInAutomationFunction(this.Site))
                {
                    string          message       = e.Message;
                    string          title         = string.Empty;
                    OLEMSGICON      icon          = OLEMSGICON.OLEMSGICON_CRITICAL;
                    OLEMSGBUTTON    buttons       = OLEMSGBUTTON.OLEMSGBUTTON_OK;
                    OLEMSGDEFBUTTON defaultButton = OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST;
                    VsShellUtilities.ShowMessageBox(this.Site, title, message, icon, buttons, defaultButton);
                }

                returnValue = VSConstants.E_FAIL;
            }

            return(returnValue);
        }
        public static int QueryGetData(Microsoft.VisualStudio.OLE.Interop.IDataObject pDataObject, ref FORMATETC fmtetc)
        {
            FORMATETC[] af = new FORMATETC[1];
            af[0] = fmtetc;
            int result = pDataObject.QueryGetData(af);

            if (result == VSConstants.S_OK)
            {
                fmtetc = af[0];
                return(VSConstants.S_OK);
            }
            return(result);
        }
예제 #20
0
        public static STGMEDIUM GetData(Microsoft.VisualStudio.OLE.Interop.IDataObject dataObject, ref FORMATETC fmtetc)
        {
            if (dataObject == null)
            {
                throw new ArgumentNullException("dataObject");
            }

            FORMATETC[] af = new FORMATETC[1];
            af[0] = fmtetc;
            STGMEDIUM[] sm = new STGMEDIUM[1];
            dataObject.GetData(af, sm);
            fmtetc = af[0];
            return(sm[0]);
        }
        /// <summary>
        /// Determines whether the Toolbox user supports the referenced data object.
        /// </summary>
        /// <param name="pDO">Data object to be supported.</param>
        /// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code.</returns>
        int IVsToolboxUser.IsSupported(IOleDataObject pDO)
        {
            // Create a OleDataObject from the input interface.
            OleDataObject oleData = new OleDataObject(pDO);

            // Check if the data object is of type MyToolboxData.
            if (oleData.GetDataPresent(typeof(ToolboxItemData)))
            {
                return(VSConstants.S_OK);
            }

            // In all the other cases return S_FALSE
            return(VSConstants.S_FALSE);
        }
예제 #22
0
        /// <summary>
        /// Sends notification that an item in the Toolbox is selected through a click, or by pressing ENTER.
        /// </summary>
        /// <param name="pDO">Data object that is selected.</param>
        /// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code.</returns>
        int IVsToolboxUser.ItemPicked(IOleDataObject pDO)
        {
            // Create a OleDataObject from the input interface.
            OleDataObject oleData = new OleDataObject(pDO);

            // Check if the picked item is the one we added to the toolbox.
            if (oleData.GetDataPresent(typeof(Toolbox_TestItem1)))
            {
                Debug.WriteLine("MyToolboxItemData selected from the toolbox");
                Toolbox_TestItem1 myData = (Toolbox_TestItem1)oleData.GetData(typeof(Toolbox_TestItem1));
                //editorControl.Text += myData.Content;
            }
            return(VSConstants.S_OK);
        }
        /// <summary>
        /// Called as soon as the mouse drags an item over a new hierarchy or hierarchy window
        /// </summary>
        /// <param name="pDataObject">reference to interface IDataObject of the item being dragged</param>
        /// <param name="grfKeyState">Current state of the keyboard and the mouse modifier keys. See docs for a list of possible values</param>
        /// <param name="itemid">Item identifier for the item currently being dragged</param>
        /// <param name="pdwEffect">On entry, a pointer to the current DropEffect. On return, must contain the new valid DropEffect</param>
        /// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code.</returns>
        public int DragEnter(IOleDataObject pDataObject, uint grfKeyState, uint itemid, ref uint pdwEffect) {
            pdwEffect = (uint)DropEffect.None;

            var item = NodeFromItemId(itemid);

            if (item.GetDragTargetHandlerNode().CanAddFiles) {
                _dropType = QueryDropDataType(pDataObject);
                if (_dropType != DropDataType.None) {
                    pdwEffect = (uint)QueryDropEffect(grfKeyState);
                }
            }

            return VSConstants.S_OK;
        }
예제 #24
0
        /// <summary>
        /// Called as soon as the mouse drags an item over a new hierarchy or hierarchy window
        /// </summary>
        /// <param name="pDataObject">reference to interface IDataObject of the item being dragged</param>
        /// <param name="grfKeyState">Current state of the keyboard and the mouse modifier keys. See docs for a list of possible values</param>
        /// <param name="itemid">Item identifier for the item currently being dragged</param>
        /// <param name="pdwEffect">On entry, a pointer to the current DropEffect. On return, must contain the new valid DropEffect</param>
        /// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code.</returns>
        public override int DragEnter(IOleDataObject pDataObject, uint grfKeyState, uint itemid, ref uint pdwEffect)
        {
            pdwEffect = (uint)DropEffect.None;

            if (this.SourceDraggedOrCutOrCopied)
            {
                return(VSConstants.S_OK);
            }

            this.dropDataType = QueryDropDataType(pDataObject);
            if (this.dropDataType != DropDataType.None)
            {
                pdwEffect = (uint)this.QueryDropEffect(this.dropDataType, grfKeyState);
            }

            return(VSConstants.S_OK);
        }
예제 #25
0
        /// <summary>
        /// Retrives data from a VS format.
        /// </summary>
        public static List <string> GetDroppedFiles(ushort format, Microsoft.VisualStudio.OLE.Interop.IDataObject dataObject, out DropDataType ddt)
        {
            ddt = DropDataType.None;
            List <string> droppedFiles = new List <string>();

            ThreadHelper.ThrowIfNotOnUIThread();

            // try HDROP
            FORMATETC fmtetc = CreateFormatEtc(format);

            if (QueryGetData(dataObject, ref fmtetc) == VSConstants.S_OK)
            {
                STGMEDIUM stgmedium = DragDropHelper.GetData(dataObject, ref fmtetc);
                if (stgmedium.tymed == (uint)TYMED.TYMED_HGLOBAL)
                {
                    // We are releasing the cloned hglobal here.
                    IntPtr dropInfoHandle = stgmedium.unionmember;
                    if (dropInfoHandle != IntPtr.Zero)
                    {
                        ddt = DropDataType.Shell;
                        try
                        {
                            uint numFiles = UnsafeNativeMethods.DragQueryFile(dropInfoHandle, 0xFFFFFFFF, null, 0);

                            // We are a directory based project thus a projref string is placed on the clipboard.
                            // We assign the maximum length of a projref string.
                            // The format of a projref is : <Proj Guid>|<project rel path>|<file path>
                            uint   lenght  = (uint)Guid.Empty.ToString().Length + 2 * NativeMethods.MAX_PATH + 2;
                            char[] moniker = new char[lenght + 1];
                            for (uint fileIndex = 0; fileIndex < numFiles; fileIndex++)
                            {
                                uint   queryFileLength = UnsafeNativeMethods.DragQueryFile(dropInfoHandle, fileIndex, moniker, lenght);
                                string filename        = new String(moniker, 0, (int)queryFileLength);
                                droppedFiles.Add(filename);
                            }
                        }
                        finally
                        {
                            Marshal.FreeHGlobal(dropInfoHandle);
                        }
                    }
                }
            }

            return(droppedFiles);
        }
예제 #26
0
        public override int DragOver(uint grfKeyState, uint itemid, ref uint pdwEffect)
        {
            if (this.dataObject == null)
            {
                this.dataObject = PackageSelectionDataObject(false);
            }
            this.dropDataType = QueryDropDataType(this.dataObject);
            if (this.dropDataType != DropDataType.None)
            {
                pdwEffect = (uint)QueryDropEffect(dropDataType, grfKeyState);
            }
            //We should also analyze if the node being dragged over can accept the drop
            if (!CanTargetNodeAcceptDrop(itemid))
            {
                pdwEffect = (uint)DropEffect.None;
            }

            return(VSConstants.S_OK);
        }
예제 #27
0
        /// <summary>
        /// Implements <see cref="IVsToolboxUser.IsSupported"/>
        /// </summary>
        protected int IsSupported(OLE.IDataObject pDO)
        {
            IDataObject data = pDO as IDataObject;

            if (data == null)
            {
                data = new DataObject(pDO);
            }
            IToolboxService toolboxService;

            if (null != (toolboxService = ToolboxService))
            {
                if (toolboxService.IsSupported(data, ToolboxFilterManager.ToolboxFilters))
                {
                    return(VSConstants.S_OK);
                }
            }
            return(VSConstants.E_FAIL);
        }
예제 #28
0
        /// <summary>
        /// Called as soon as the mouse drags an item over a new hierarchy or hierarchy window
        /// </summary>
        /// <param name="pDataObject">reference to interface IDataObject of the item being dragged</param>
        /// <param name="grfKeyState">Current state of the keyboard and the mouse modifier keys. See docs for a list of possible values</param>
        /// <param name="itemid">Item identifier for the item currently bbeing dragged</param>
        /// <param name="pdwEffect">On entry, a pointer to the current DropEffect. On return, must contain the
        /// new valid DropEffect</param>
        /// <returns>S_OK if the method succeeds</returns>
        public override int DragEnter(IOleDataObject pDataObject, uint grfKeyState, uint itemid, ref uint pdwEffect)
        {
            pdwEffect = (uint)DropEffect.None;
            if (this.SourceDraggedOrCutOrCopied)
            {
                return VSConstants.S_OK;
            }
            else
            {
                this.dataObject = (IOleDataObject)pDataObject;
            }

            this.dropDataType = QueryDropDataType(pDataObject);
            if (this.dropDataType != DropDataType.None)
            {
                pdwEffect = (uint)QueryDropEffect(this.dropDataType, grfKeyState);
            }
            return VSConstants.S_OK;
        }
예제 #29
0
        /// <summary>
        /// Called as soon as the mouse drags an item over a new hierarchy or hierarchy window
        /// </summary>
        /// <param name="pDataObject">reference to interface IDataObject of the item being dragged</param>
        /// <param name="grfKeyState">Current state of the keyboard and the mouse modifier keys. See docs for a list of possible values</param>
        /// <param name="itemid">Item identifier for the item currently being dragged</param>
        /// <param name="pdwEffect">On entry, a pointer to the current DropEffect. On return, must contain the new valid DropEffect</param>
        /// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code.</returns>
        public override int DragEnter(IOleDataObject pDataObject, uint grfKeyState, uint itemid, ref uint pdwEffect)
        {
            pdwEffect = (uint)DropEffect.None;

            // changed from MPFProj:
            // http://mpfproj10.codeplex.com/WorkItem/View.aspx?WorkItemId=8145
            /*
            if(this.SourceDraggedOrCutOrCopied)
            {
                return VSConstants.S_OK;
            }*/

            this.dropDataType = QueryDropDataType(pDataObject);
            if (this.dropDataType != DropDataType.None)
            {
                pdwEffect = (uint)this.QueryDropEffect(this.dropDataType, grfKeyState);
            }

            return VSConstants.S_OK;
        }
예제 #30
0
        public static string GetSourceProjectPath(Microsoft.VisualStudio.OLE.Interop.IDataObject dataObject)
        {
            string    projectPath = null;
            FORMATETC fmtetc      = CreateFormatEtc(CF_VSPROJECTCLIPDESCRIPTOR);

            if (QueryGetData(dataObject, ref fmtetc) == VSConstants.S_OK)
            {
                STGMEDIUM stgmedium = DragDropHelper.GetData(dataObject, ref fmtetc);
                if (stgmedium.tymed == (uint)TYMED.TYMED_HGLOBAL && stgmedium.unionmember != IntPtr.Zero)
                {
                    // We are releasing the cloned hglobal here.
                    using (SafeGlobalAllocHandle dropInfoHandle = new SafeGlobalAllocHandle(stgmedium.unionmember, true))
                    {
                        projectPath = GetData(dropInfoHandle);
                    }
                }
            }

            return(projectPath);
        }
예제 #31
0
        /// <summary>
        /// Returns information about one or more of the items being dragged
        /// </summary>
        /// <param name="pdwOKEffects">Pointer to a DWORD value describing the effects displayed while the item is being dragged,
        /// such as cursor icons that change during the drag-and-drop operation.
        /// For example, if the item is dragged over an invalid target point
        /// (such as the item's original location), the cursor icon changes to a circle with a line through it.
        /// Similarly, if the item is dragged over a valid target point, the cursor icon changes to a file or folder.</param>
        /// <param name="ppDataObject">Pointer to the IDataObject interface on the item being dragged.
        /// This data object contains the data being transferred in the drag-and-drop operation.
        /// If the drop occurs, then this data object (item) is incorporated into the target hierarchy or hierarchy window.</param>
        /// <param name="ppDropSource">Pointer to the IDropSource interface of the item being dragged.</param>
        /// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code.</returns>
        public override int GetDropInfo(out uint pdwOKEffects, out IOleDataObject ppDataObject, out IDropSource ppDropSource)
        {
            //init out params
            pdwOKEffects = (uint)DropEffect.None;
            ppDataObject = null;
            ppDropSource = null;

            IOleDataObject dataObject = PackageSelectionDataObject(false);

            if (dataObject == null)
            {
                return(VSConstants.E_NOTIMPL);
            }

            this.SourceDraggedOrCutOrCopied = true;

            pdwOKEffects = (uint)(DropEffect.Move | DropEffect.Copy);

            ppDataObject = dataObject;
            return(VSConstants.S_OK);
        }
예제 #32
0
        public static int QueryGetData(Microsoft.VisualStudio.OLE.Interop.IDataObject pDataObject, ref FORMATETC fmtetc)
        {
            int returnValue = VSConstants.E_FAIL;

            FORMATETC[] af = new FORMATETC[1];
            af[0] = fmtetc;
            try
            {
                int result = ErrorHandler.ThrowOnFailure(pDataObject.QueryGetData(af));
                if (result == VSConstants.S_OK)
                {
                    fmtetc      = af[0];
                    returnValue = VSConstants.S_OK;
                }
            }
            catch (COMException e)
            {
                XSharpProjectPackage.Instance.DisplayException(e);
                returnValue = e.ErrorCode;
            }

            return(returnValue);
        }
        /// <summary>
        /// Process dataobject from Drag/Drop/Cut/Copy/Paste operation
        /// </summary>
        /// <remarks>The targetNode is set if the method is called from a drop operation, otherwise it is null</remarks>
        internal DropDataType ProcessSelectionDataObject(IOleDataObject dataObject, HierarchyNode targetNode)
        {
            DropDataType dropDataType = DropDataType.None;
            bool isWindowsFormat = false;

            // Try to get it as a directory based project.
            List<string> filesDropped = DragDropHelper.GetDroppedFiles(DragDropHelper.CF_VSSTGPROJECTITEMS, dataObject, out dropDataType);
            if (filesDropped.Count == 0)
            {
                filesDropped = DragDropHelper.GetDroppedFiles(DragDropHelper.CF_VSREFPROJECTITEMS, dataObject, out dropDataType);
            }
            if (filesDropped.Count == 0)
            {
                filesDropped = DragDropHelper.GetDroppedFiles(NativeMethods.CF_HDROP, dataObject, out dropDataType);
                isWindowsFormat = (filesDropped.Count > 0);
            }

            if (dropDataType != DropDataType.None && filesDropped.Count > 0)
            {
                string[] filesDroppedAsArray = filesDropped.ToArray();

                HierarchyNode node = (targetNode == null) ? this : targetNode;

                // For directory based projects the content of the clipboard is a double-NULL terminated list of Projref strings.
                if (isWindowsFormat)
                {
                    // This is the code path when source is windows explorer
                    VSADDRESULT[] vsaddresults = new VSADDRESULT[1];
                    vsaddresults[0] = VSADDRESULT.ADDRESULT_Failure;
                    int addResult = AddItem(node.ID, VSADDITEMOPERATION.VSADDITEMOP_OPENFILE, null, (uint)filesDropped.Count, filesDroppedAsArray, IntPtr.Zero, vsaddresults);
                    if (addResult != VSConstants.S_OK && addResult != VSConstants.S_FALSE && addResult != (int)OleConstants.OLECMDERR_E_CANCELED
                        && vsaddresults[0] != VSADDRESULT.ADDRESULT_Success)
                    {
                        ErrorHandler.ThrowOnFailure(addResult);
                    }
                    
                    return dropDataType;
                }
                else
                {
                    if (AddFilesFromProjectReferences(node, filesDroppedAsArray))
                    {
                        return dropDataType;
                    }
                }
            }

            // If we reached this point then the drop data must be set to None.
            // Otherwise the OnPaste will be called with a valid DropData and that would actually delete the item.
            return DropDataType.None;
        }
예제 #34
0
        /// <summary>
        /// The item picked.
        /// </summary>
        /// <param name="pDO">
        /// The p do.
        /// </param>
        /// <returns>
        /// The <see cref="int"/>.
        /// </returns>
        public int ItemPicked(IDataObject pDO)
        {
            // Create a OleDataObject from the input interface.
            var oleData = new OleDataObject(pDO);

            // Check if the picked item is the one we can paste.
            if (oleData.GetDataPresent(DataFormats.UnicodeText))
            {
                object o = null;
                this.EditorControl.TextSelection.Paste(ref o, 0);
            }

            return VSConstants.S_OK;
        }
예제 #35
0
        /// <summary>
        /// Handle the Cut operation to the clipboard
        /// </summary>
        protected internal override int CutToClipboard()
        {
            int returnValue = (int)OleConstants.OLECMDERR_E_NOTSUPPORTED;
            try
            {
                this.RegisterClipboardNotifications(true);

                // Create our data object and change the selection to show item(s) being cut
                this.dataObject = this.PackageSelectionDataObject(true);
                if (this.dataObject != null)
                {
                    this.SourceDraggedOrCutOrCopied = true;

                    // Add our cut item(s) to the clipboard
                    ErrorHandler.ThrowOnFailure(UnsafeNativeMethods.OleSetClipboard(dataObject));

                    // Inform VS (UiHierarchyWindow) of the cut
                    IVsUIHierWinClipboardHelper clipboardHelper = (IVsUIHierWinClipboardHelper)GetService(typeof(SVsUIHierWinClipboardHelper));
                    if (clipboardHelper == null)
                    {
                        return VSConstants.E_FAIL;
                    }
                    returnValue = ErrorHandler.ThrowOnFailure(clipboardHelper.Cut(dataObject));
                }
            }
            catch (COMException e)
            {
                Trace.WriteLine("Exception : " + e.Message);
                returnValue = e.ErrorCode;
            }

            return returnValue;
        }
예제 #36
0
        public override int DragOver(uint grfKeyState, uint itemid, ref uint pdwEffect)
        {
            if (this.dataObject == null)
            {
                this.dataObject = PackageSelectionDataObject(false);
            }
            this.dropDataType = QueryDropDataType(this.dataObject);
            if (this.dropDataType != DropDataType.None)
            {
                pdwEffect = (uint)QueryDropEffect(dropDataType, grfKeyState);
            }
            //We should also analyze if the node being dragged over can accept the drop
            if (!CanTargetNodeAcceptDrop(itemid))
                pdwEffect = (uint)DropEffect.None;

            return VSConstants.S_OK;
        }
예제 #37
0
        /// <summary>
        /// Returns a dataobject from selected nodes
        /// </summary>
        /// <param name="cutHighlightItems">boolean that defines if the selected items must be cut</param>
        /// <returns>data object for selected items</returns>
        internal virtual DataObject PackageSelectionDataObject(bool cutHighlightItems)
        {
            this.CleanupSelectionDataObject(false, false, false);
            StringBuilder sb = new StringBuilder();

            DataObject dataObject = null;

            try
            {
                IList<HierarchyNode> selectedNodes = this.GetSelectedNodes();
                if (selectedNodes != null)
                {
                    this.InstantiateItemsDraggedOrCutOrCopiedList();

                    StringBuilder selectionContent = null;

                    // If there is a selection package the data
                    if (selectedNodes.Count > 1)
                    {
                        foreach (HierarchyNode node in selectedNodes)
                        {
                            selectionContent = node.PrepareSelectedNodesForClipBoard();
                            if (selectionContent != null)
                            {
                                sb.Append(selectionContent);
                            }
                        }
                    }
                    else if (selectedNodes.Count == 1)
                    {
                        HierarchyNode selectedNode = selectedNodes[0];
                        selectionContent = selectedNode.PrepareSelectedNodesForClipBoard();
                        if (selectionContent != null)
                        {
                            sb.Append(selectionContent);
                        }
                    }
                }

                // Add the project items first.
                IntPtr ptrToItems = this.PackageSelectionData(sb, false);
                if (ptrToItems == IntPtr.Zero)
                {
                    return null;
                }

                FORMATETC fmt = DragDropHelper.CreateFormatEtc(DragDropHelper.CF_VSSTGPROJECTITEMS);
                dataObject = new DataObject();
                dataObject.SetData(fmt, ptrToItems);

                // Now add the project path that sourced data. We just write the project file path.
                IntPtr ptrToProjectPath = this.PackageSelectionData(new StringBuilder(this.GetMkDocument()), true);

                if (ptrToProjectPath != IntPtr.Zero)
                {
                    dataObject.SetData(DragDropHelper.CreateFormatEtc(DragDropHelper.CF_VSPROJECTCLIPDESCRIPTOR), ptrToProjectPath);
                }

                if (cutHighlightItems)
                {
                    bool first = true;
                    IVsUIHierarchyWindow w = UIHierarchyUtilities.GetUIHierarchyWindow(this.site, HierarchyNode.SolutionExplorer);

                    foreach (HierarchyNode node in this.ItemsDraggedOrCutOrCopied)
                    {
                        ErrorHandler.ThrowOnFailure(w.ExpandItem((IVsUIHierarchy)this, node.ID, first ? EXPANDFLAGS.EXPF_CutHighlightItem : EXPANDFLAGS.EXPF_AddCutHighlightItem));
                        first = false;
                    }
                }
            }
            catch (COMException e)
            {
                Trace.WriteLine("Exception : " + e.Message);

                dataObject = null;
            }

            return dataObject;
        }
예제 #38
0
        /// <summary>
        /// Allows the drag source to prompt to save unsaved items being dropped.
        /// Notifies the source hierarchy that information dragged from it is about to be dropped on a target.
        /// This method is called immediately after the mouse button is released on a drop.
        /// </summary>
        /// <param name="o">Reference to the IDataObject interface on the item being dragged.
        /// This data object contains the data being transferred in the drag-and-drop operation.
        /// If the drop occurs, then this data object (item) is incorporated into the hierarchy window of the new hierarchy.</param>
        /// <param name="dwEffect">Current state of the keyboard and the mouse modifier keys.</param>
        /// <param name="fCancelDrop">If true, then the drop is cancelled by the source hierarchy. If false, then the drop can continue.</param>
        /// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code. </returns>
        public override int OnBeforeDropNotify(IOleDataObject o, uint dwEffect, out int fCancelDrop)
        {
            // If there is nothing to be dropped just return that drop should be cancelled.
            if (this.ItemsDraggedOrCutOrCopied == null)
            {
                fCancelDrop = 1;
                return(VSConstants.S_OK);
            }

            fCancelDrop = 0;
            bool dirty = false;

            foreach (HierarchyNode node in this.ItemsDraggedOrCutOrCopied)
            {
                bool isDirty, isOpen, isOpenedByUs;
                uint docCookie;
                IVsPersistDocData ppIVsPersistDocData;
                DocumentManager   manager = node.GetDocumentManager();
                if (manager != null)
                {
                    manager.GetDocInfo(out isOpen, out isDirty, out isOpenedByUs, out docCookie, out ppIVsPersistDocData);
                    if (isDirty && isOpenedByUs)
                    {
                        dirty = true;
                        break;
                    }
                }
            }

            // if there are no dirty docs we are ok to proceed
            if (!dirty)
            {
                return(VSConstants.S_OK);
            }

            // Prompt to save if there are dirty docs
            string          message       = SR.GetString(SR.SaveModifiedDocuments, CultureInfo.CurrentUICulture);
            string          title         = string.Empty;
            OLEMSGICON      icon          = OLEMSGICON.OLEMSGICON_WARNING;
            OLEMSGBUTTON    buttons       = OLEMSGBUTTON.OLEMSGBUTTON_YESNOCANCEL;
            OLEMSGDEFBUTTON defaultButton = OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST;
            int             result        = VsShellUtilities.ShowMessageBox(Site, title, message, icon, buttons, defaultButton);

            switch (result)
            {
            case NativeMethods.IDYES:
                break;

            case NativeMethods.IDNO:
                return(VSConstants.S_OK);

            case NativeMethods.IDCANCEL: goto default;

            default:
                fCancelDrop = 1;
                return(VSConstants.S_OK);
            }

            // Save all dirty documents
            foreach (HierarchyNode node in this.ItemsDraggedOrCutOrCopied)
            {
                DocumentManager manager = node.GetDocumentManager();
                if (manager != null)
                {
                    manager.Save(true);
                }
            }

            return(VSConstants.S_OK);
        }
        /// <summary>
        /// Called as soon as the mouse drags an item over a new hierarchy or hierarchy window
        /// </summary>
        /// <param name="dataObject">reference to interface IDataObject of the item being dragged</param>
        /// <param name="keyState">Current state of the keyboard and the mouse modifier keys. See docs for a list of possible values</param>
        /// <param name="itemId">Item identifier for the item currently being dragged</param>
        /// <param name="effect">On entry, a pointer to the current DropEffect. On return, must contain the new valid DropEffect</param>
        /// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code.</returns>
        public override int DragEnter(IOleDataObject dataObject, uint keyState, uint itemId, ref DropEffects effect)
        {
            effect = DropEffects.None;

            if(this.SourceDraggedOrCutOrCopied)
            {
                return VSConstants.S_OK;
            }

            this._dropDataType = QueryDropDataType(dataObject);
            if(this._dropDataType != DropDataType.None)
            {
                effect = this.QueryDropEffect(this._dropDataType, keyState);
            }

            return VSConstants.S_OK;
        }
        /// <summary>
        /// Process dataobject from Drag/Drop/Cut/Copy/Paste operation
        /// 
        /// drop indicates if it is a drag/drop or a cut/copy/paste.
        /// </summary>
        /// <remarks>The targetNode is set if the method is called from a drop operation, otherwise it is null</remarks>
        internal DropDataType ProcessSelectionDataObject(IOleDataObject dataObject, HierarchyNode targetNode, bool drop, DropEffect dropEffect) {
            Utilities.ArgumentNotNull("targetNode", targetNode);

            DropDataType dropDataType = DropDataType.None;
            bool isWindowsFormat = false;

            // Try to get it as a directory based project.
            List<string> filesDropped = DragDropHelper.GetDroppedFiles(DragDropHelper.CF_VSSTGPROJECTITEMS, dataObject, out dropDataType);
            if (filesDropped.Count == 0) {
                filesDropped = DragDropHelper.GetDroppedFiles(DragDropHelper.CF_VSREFPROJECTITEMS, dataObject, out dropDataType);
            }
            if (filesDropped.Count == 0) {
                filesDropped = DragDropHelper.GetDroppedFiles(NativeMethods.CF_HDROP, dataObject, out dropDataType);
                isWindowsFormat = (filesDropped.Count > 0);
            }

            if (dropDataType != DropDataType.None && filesDropped.Count > 0) {
                string[] filesDroppedAsArray = filesDropped.ToArray();

                HierarchyNode node = targetNode;

                // For directory based projects the content of the clipboard is a double-NULL terminated list of Projref strings.
                if (isWindowsFormat) {
                    DropFilesOrFolders(filesDroppedAsArray, node);

                    return dropDataType;
                } else {
                    if (AddFilesFromProjectReferences(node, filesDroppedAsArray, drop, dropEffect)) {
                        return dropDataType;
                    }
                }
            }

            // If we reached this point then the drop data must be set to None.
            // Otherwise the OnPaste will be called with a valid DropData and that would actually delete the item.
            return DropDataType.None;
        }
        /// <summary>
        /// Returns information about one or more of the items being dragged
        /// </summary>
        /// <param name="effects">Pointer to a DWORD value describing the effects displayed while the item is being dragged, 
        /// such as cursor icons that change during the drag-and-drop operation. 
        /// For example, if the item is dragged over an invalid target point 
        /// (such as the item's original location), the cursor icon changes to a circle with a line through it. 
        /// Similarly, if the item is dragged over a valid target point, the cursor icon changes to a file or folder.</param>
        /// <param name="dataObject">Pointer to the IDataObject interface on the item being dragged. 
        /// This data object contains the data being transferred in the drag-and-drop operation. 
        /// If the drop occurs, then this data object (item) is incorporated into the target hierarchy or hierarchy window.</param>
        /// <param name="dropSource">Pointer to the IDropSource interface of the item being dragged.</param>
        /// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code.</returns>
        public override int GetDropInfo(out DropEffects effects, out IOleDataObject dataObject, out IDropSource dropSource)
        {
            //init out params
            effects = (uint)DropEffects.None;
            dataObject = null;
            dropSource = null;

            IOleDataObject selectionDataObject = PackageSelectionDataObject(false);
            if(selectionDataObject == null)
            {
                return VSConstants.E_NOTIMPL;
            }

            this.SourceDraggedOrCutOrCopied = true;

            effects = DropEffects.Move | DropEffects.Copy;

            dataObject = selectionDataObject;
            return VSConstants.S_OK;
        }
예제 #42
0
        /// <summary>
        /// The is supported.
        /// </summary>
        /// <param name="pDO">
        /// The p do.
        /// </param>
        /// <returns>
        /// The <see cref="int"/>.
        /// </returns>
        public int IsSupported(IDataObject pDO)
        {
            // Create a OleDataObject from the input interface.
            var oleData = new OleDataObject(pDO);

            // && EditorControl.RichTextBoxControl.CanPaste(DataFormats.GetFormat(DataFormats.UnicodeText))
            // Check if the data object is of type UnicodeText.
            if (oleData.GetDataPresent(DataFormats.UnicodeText))
            {
                return VSConstants.S_OK;
            }

            // In all the other cases return S_FALSE
            return VSConstants.S_FALSE;
        }
예제 #43
0
        /// <summary>
        ///  After a drop or paste, will use the dwEffects 
        ///  to determine whether we need to clean up the source nodes or not. If
        ///  justCleanup is set, it only does the cleanup work.
        /// </summary>
        internal void CleanupSelectionDataObject(bool dropped, bool cut, bool moved, bool justCleanup)
        {
            if (this.ItemsDraggedOrCutOrCopied == null || this.ItemsDraggedOrCutOrCopied.Count == 0)
            {
                return;
            }

            try
            {
                IVsUIHierarchyWindow w = UIHierarchyUtilities.GetUIHierarchyWindow(this.site, HierarchyNode.SolutionExplorer);
                foreach (HierarchyNode node in this.ItemsDraggedOrCutOrCopied)
                {
                    if ((moved && (cut || dropped) && !justCleanup))
                    {
                        // do not close it if the doc is dirty or we do not own it
                        bool isDirty, isOpen, isOpenedByUs;
                        uint docCookie;
                        IVsPersistDocData ppIVsPersistDocData;
                        DocumentManager manager = node.GetDocumentManager();

                        if (manager != null)
                        {
                            manager.GetDocInfo(out isOpen, out isDirty, out isOpenedByUs, out docCookie, out ppIVsPersistDocData);
                            if (isDirty || (isOpen && !isOpenedByUs))
                            {
                                continue;
                            }

                            // close it if opened
                            if (isOpen)
                            {
                                manager.Close(__FRAMECLOSE.FRAMECLOSE_NoSave);
                            }
                        }

                        node.Remove(true);
                    }
                    else if (w != null)
                    {
                        ErrorHandler.ThrowOnFailure(w.ExpandItem((IVsUIHierarchy)this, node.ID, EXPANDFLAGS.EXPF_UnCutHighlightItem));
                    }
                }
            }
            finally
            {

                // Now delete the memory allocated by the packaging of datasources.
                // If we just did a cut, or we are told to cleanup, then we need to free the data object. Otherwise, we leave it
                // alone so that you can continue to paste the data in new locations.
                if (moved || cut || justCleanup)
                {
                    this.ItemsDraggedOrCutOrCopied.Clear();
                    this.CleanAndFlushClipboard();
                }

                this.dataObject = null;
                this.dropDataType = DropDataType.None;
            }
        }
        /// <summary>
        /// Returns information about one or more of the items being dragged
        /// </summary>
        /// <param name="pdwOKEffects">Pointer to a DWORD value describing the effects displayed while the item is being dragged, 
        /// such as cursor icons that change during the drag-and-drop operation. 
        /// For example, if the item is dragged over an invalid target point 
        /// (such as the item's original location), the cursor icon changes to a circle with a line through it. 
        /// Similarly, if the item is dragged over a valid target point, the cursor icon changes to a file or folder.</param>
        /// <param name="ppDataObject">Pointer to the IDataObject interface on the item being dragged. 
        /// This data object contains the data being transferred in the drag-and-drop operation. 
        /// If the drop occurs, then this data object (item) is incorporated into the target hierarchy or hierarchy window.</param>
        /// <param name="ppDropSource">Pointer to the IDropSource interface of the item being dragged.</param>
        /// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code.</returns>
        public override int GetDropInfo(out uint pdwOKEffects, out IOleDataObject ppDataObject, out IDropSource ppDropSource)
        {
            //init out params
            pdwOKEffects = (uint)DropEffect.None;
            ppDataObject = null;
            ppDropSource = null;

            IOleDataObject dataObject = PackageSelectionDataObject(false);
            if (dataObject == null)
            {
                return VSConstants.E_NOTIMPL;
            }

            this.SourceDraggedOrCutOrCopied = true;
            this.SourceDragged = true;

            pdwOKEffects = (uint)(DropEffect.Move | DropEffect.Copy);

            ppDataObject = dataObject;
            return VSConstants.S_OK;
        }
        /// <summary>
        /// Get the dropdatatype from the dataobject
        /// </summary>
        /// <param name="pDataObject">The dataobject to be analysed for its format</param>
        /// <returns>dropdatatype or none if dataobject does not contain known format</returns>
        internal static DropDataType QueryDropDataType(IOleDataObject pDataObject)
        {
            if (pDataObject == null)
            {
                return DropDataType.None;
            }
            
            // known formats include File Drops (as from WindowsExplorer),
            // VSProject Reference Items and VSProject Storage Items.
            FORMATETC fmt = DragDropHelper.CreateFormatEtc(NativeMethods.CF_HDROP);

            if (DragDropHelper.QueryGetData(pDataObject, ref fmt) == VSConstants.S_OK)
            {
                return DropDataType.Shell;
            }

            fmt.cfFormat = DragDropHelper.CF_VSREFPROJECTITEMS;
            if (DragDropHelper.QueryGetData(pDataObject, ref fmt) == VSConstants.S_OK)
            {
                // Data is from a Ref-based project.
                return DropDataType.VsRef;
            }

            fmt.cfFormat = DragDropHelper.CF_VSSTGPROJECTITEMS;
            if (DragDropHelper.QueryGetData(pDataObject, ref fmt) == VSConstants.S_OK)
            {
                return DropDataType.VsStg;
            }

            return DropDataType.None;
        }
예제 #46
0
        /// <summary>
        /// Determines whether the Toolbox user supports the referenced data object.
        /// </summary>
        /// <param name="pDO">Data object to be supported.</param>
        /// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code.</returns>
        int IVsToolboxUser.IsSupported(IOleDataObject pDO)
        {
            // Create a OleDataObject from the input interface.
            OleDataObject oleData = new OleDataObject(pDO);

            // Check if the data object is of type MyToolboxData.
            if (oleData.GetDataPresent(typeof(ToolboxItemData)))
                return VSConstants.S_OK;

            // In all the other cases return S_FALSE
            return VSConstants.S_FALSE;
        }
예제 #47
0
        /// <summary>
        /// Sends notification that an item in the Toolbox is selected through a click, or by pressing ENTER.
        /// </summary>
        /// <param name="pDO">Data object that is selected.</param>
        /// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code.</returns>
        int IVsToolboxUser.ItemPicked(IOleDataObject pDO)
        {
            // Create a OleDataObject from the input interface.
            OleDataObject oleData = new OleDataObject(pDO);

            // Check if the picked item is the one we added to the toolbox.
            if (oleData.GetDataPresent(typeof(ToolboxItemData)))
            {
                Debug.WriteLine("MyToolboxItemData selected from the toolbox");
                ToolboxItemData myData = (ToolboxItemData)oleData.GetData(typeof(ToolboxItemData));
                editorControl.Text += myData.Content;
            }
            return VSConstants.S_OK;
        }
예제 #48
0
 internal Ole2BclDataObject(BclComTypes.IDataObject bclData)
 {
     if (null == bclData)
         throw new ArgumentNullException("System.Runtime.InteropServices.ComTypes.IDataObject");
     //this.oleData = bclData as OleInterop.IDataObject;
     this.oleData = null;
     this.bclData = bclData;
 }
        /// <summary>
        /// Called when one or more items are dropped into the target hierarchy or hierarchy window when the mouse button is released.
        /// </summary>
        /// <param name="pDataObject">Reference to the IDataObject interface on the item being dragged. This data object contains the data being transferred in the drag-and-drop operation. 
        /// If the drop occurs, then this data object (item) is incorporated into the target hierarchy or hierarchy window.</param>
        /// <param name="grfKeyState">Current state of the keyboard and the mouse modifier keys. See <seealso cref="IVsHierarchyDropDataTarget"/></param>
        /// <param name="itemid">Item identifier of the drop data target over which the item is being dragged</param>
        /// <param name="pdwEffect">Visual effects associated with the drag-and drop-operation, such as a cursor, bitmap, and so on. 
        /// The value of dwEffects passed to the source object via the OnDropNotify method is the value of pdwEffects returned by the Drop method</param>
        /// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code. </returns>
        public override int Drop(IOleDataObject pDataObject, uint grfKeyState, uint itemid, ref uint pdwEffect)
        {
            if (pDataObject == null)
            {
                return VSConstants.E_INVALIDARG;
            }

            pdwEffect = (uint)DropEffect.None;

            // Get the node that is being dragged over and ask it which node should handle this call
            HierarchyNode targetNode = NodeFromItemId(itemid);
            if (targetNode != null)
            {
                targetNode = targetNode.GetDragTargetHandlerNode();
            }
            else
            {
                // There is no target node. The drop can not be completed.
                return VSConstants.S_FALSE;
            }

            int returnValue;
            try
            {
                this.isInPasteOrDrop = true;
                DropDataType dropDataType = DropDataType.None;
                dropDataType = ProcessSelectionDataObject(pDataObject, targetNode, grfKeyState);
                pdwEffect = (uint)this.QueryDropEffect(dropDataType, grfKeyState);

                // If it is a drop from windows and we get any kind of error we return S_FALSE and dropeffect none. This
                // prevents bogus messages from the shell from being displayed
                returnValue = (dropDataType != DropDataType.Shell) ? VSConstants.E_FAIL : VSConstants.S_OK;
            }
            catch (System.IO.FileNotFoundException e)
            {
                Trace.WriteLine("Exception : " + e.Message);

                if (!Utilities.IsInAutomationFunction(this.Site))
                {
                    string message = e.Message;
                    string title = string.Empty;
                    OLEMSGICON icon = OLEMSGICON.OLEMSGICON_CRITICAL;
                    OLEMSGBUTTON buttons = OLEMSGBUTTON.OLEMSGBUTTON_OK;
                    OLEMSGDEFBUTTON defaultButton = OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST;
                    VsShellUtilities.ShowMessageBox(this.Site, title, message, icon, buttons, defaultButton);
                }

                returnValue = VSConstants.E_FAIL;
            }
            finally
            {
                this.isInPasteOrDrop = false;
                this.dropAsCopy = false;
            }

            return returnValue;
        }
예제 #50
0
 internal Ole2BclDataObject(OleInterop.IDataObject oleData)
 {
     if (null == oleData)
         throw new ArgumentNullException("Microsoft.VisualStudio.OLE.Interop.IDataObject");
     this.oleData = oleData;
     //this.bclData = oleData as BclComTypes.IDataObject;
     this.bclData = null;
 }
        /// <summary>
        /// Allows the drag source to prompt to save unsaved items being dropped. 
        /// Notifies the source hierarchy that information dragged from it is about to be dropped on a target. 
        /// This method is called immediately after the mouse button is released on a drop. 
        /// </summary>
        /// <param name="o">Reference to the IDataObject interface on the item being dragged. 
        /// This data object contains the data being transferred in the drag-and-drop operation. 
        /// If the drop occurs, then this data object (item) is incorporated into the hierarchy window of the new hierarchy.</param>
        /// <param name="dwEffect">Current state of the keyboard and the mouse modifier keys.</param>
        /// <param name="fCancelDrop">If true, then the drop is cancelled by the source hierarchy. If false, then the drop can continue.</param>
        /// <returns>If the method succeeds, it returns S_OK. If it fails, it returns an error code. </returns>
        public override int OnBeforeDropNotify(IOleDataObject o, uint dwEffect, out int fCancelDrop)
        {
            // If there is nothing to be dropped just return that drop should be cancelled.
            if (this.ItemsDraggedOrCutOrCopied == null)
            {
                fCancelDrop = 1;
                return VSConstants.S_OK;
            }
            
            fCancelDrop = 0;
            bool dirty = false;
            foreach (HierarchyNode node in this.ItemsDraggedOrCutOrCopied)
            {
                bool isDirty, isOpen, isOpenedByUs;
                uint docCookie;
                IVsPersistDocData ppIVsPersistDocData;
                DocumentManager manager = node.GetDocumentManager();
                if (manager != null)
                {
                    manager.GetDocInfo(out isOpen, out isDirty, out isOpenedByUs, out docCookie, out ppIVsPersistDocData);
                    if (isDirty && isOpenedByUs)
                    {
                        dirty = true;
                        break;
                    }
                }
            }

            // if there are no dirty docs we are ok to proceed
            if (!dirty)
            {
                return VSConstants.S_OK;
            }

            // Prompt to save if there are dirty docs
            string message = SR.GetString(SR.SaveModifiedDocuments, CultureInfo.CurrentUICulture);
            string title = string.Empty;
            OLEMSGICON icon = OLEMSGICON.OLEMSGICON_WARNING;
            OLEMSGBUTTON buttons = OLEMSGBUTTON.OLEMSGBUTTON_YESNOCANCEL;
            OLEMSGDEFBUTTON defaultButton = OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST;
            int result = VsShellUtilities.ShowMessageBox(Site, title, message, icon, buttons, defaultButton);
            switch (result)
            {
                case NativeMethods.IDYES:
                    break;

                case NativeMethods.IDNO:
                    return VSConstants.S_OK;

                case NativeMethods.IDCANCEL: goto default;

                default:
                    fCancelDrop = 1;
                    return VSConstants.S_OK;
            }

            // Save all dirty documents
            foreach (HierarchyNode node in this.ItemsDraggedOrCutOrCopied)
            {
                DocumentManager manager = node.GetDocumentManager();
                if (manager != null)
                {
                    manager.Save(true);
                }
            }

            return VSConstants.S_OK;
        }
예제 #52
0
        public static bool AttemptVsFormat(HierarchyNode activeNode, ushort cfFormat, Microsoft.VisualStudio.OLE.Interop.IDataObject pDataObject, uint grfKeyState, out DropDataType pddt)
        {
            pddt = DropDataType.None;
            FORMATETC fmtetc = new FORMATETC();

            fmtetc.cfFormat = cfFormat;
            fmtetc.ptd      = IntPtr.Zero;
            fmtetc.dwAspect = (uint)DVASPECT.DVASPECT_CONTENT;
            fmtetc.lindex   = -1;
            fmtetc.tymed    = (uint)TYMED.TYMED_HGLOBAL;

            bool hasData = false;

            try
            {
                QueryGetData(pDataObject, ref fmtetc);
                hasData = true;
            }
            catch
            {
            }

            if (hasData)
            {
                try
                {
                    STGMEDIUM stgmedium = GetData(pDataObject, ref fmtetc);
                    if (stgmedium.tymed == (uint)TYMED.TYMED_HGLOBAL)
                    {
                        IntPtr hDropInfo = stgmedium.unionmember;
                        if (hDropInfo != IntPtr.Zero)
                        {
                            pddt = DropDataType.VsRef;
                            try
                            {
                                activeNode.AddFiles(UtilGetFilesFromPROJITEMDrop(hDropInfo));
                            }
                            finally
                            {
                                Marshal.FreeHGlobal(hDropInfo);
                            }
                            return(true);
                        }
                    }
                }
                catch (Exception e)
                {
                    Trace.WriteLine("Exception:" + e.Message);
                }
                catch
                {
                    Trace.WriteLine("Exception");
                }
            }
            return(false);
        }
        /// <summary>
        /// Process dataobject from Drag/Drop/Cut/Copy/Paste operation
        /// </summary>
        /// <remarks>The targetNode is set if the method is called from a drop operation, otherwise it is null</remarks>
        internal DropDataType ProcessSelectionDataObject(IOleDataObject dataObject, HierarchyNode targetNode, uint grfKeyState)
        {
            DropDataType dropDataType = DropDataType.None;
            bool isWindowsFormat = false;

            // Try to get it as a directory based project.
            List<string> filesDropped = DragDropHelper.GetDroppedFiles(DragDropHelper.CF_VSSTGPROJECTITEMS, dataObject, out dropDataType);
            if (filesDropped.Count == 0)
            {
                filesDropped = DragDropHelper.GetDroppedFiles(DragDropHelper.CF_VSREFPROJECTITEMS, dataObject, out dropDataType);
            }
            if (filesDropped.Count == 0)
            {
                filesDropped = DragDropHelper.GetDroppedFiles(NativeMethods.CF_HDROP, dataObject, out dropDataType);
                isWindowsFormat = (filesDropped.Count > 0);
            }

            dropItems.Clear();

            if (dropDataType != DropDataType.None && filesDropped.Count > 0)
            {
                bool saveAllowDuplicateLinks = this.AllowDuplicateLinks;
                try
                {
                    DropEffect dropEffect = this.QueryDropEffect(dropDataType, grfKeyState);
                    this.dropAsCopy = dropEffect == DropEffect.Copy;
                    if (dropEffect == DropEffect.Move && this.SourceDraggedOrCutOrCopied)
                    {
                        // Temporarily allow duplicate links to enable cut-paste or drag-move of links within the project.
                        // This won't happen when the source is another project because this.SourceDraggedOrCutOrCopied won't get set.
                        this.AllowDuplicateLinks = true;
                    }

                    string[] filesDroppedAsArray = filesDropped.ToArray();

                    HierarchyNode node = (targetNode == null) ? this : targetNode;

                    // For directory based projects the content of the clipboard is a double-NULL terminated list of Projref strings.
                    if (isWindowsFormat)
                    {
                        // This is the code path when source is windows explorer
                        VSADDRESULT[] vsaddresults = new VSADDRESULT[1];
                        vsaddresults[0] = VSADDRESULT.ADDRESULT_Failure;
                        int addResult = AddItem(node.ID, VSADDITEMOPERATION.VSADDITEMOP_OPENFILE, null, (uint)filesDropped.Count, filesDroppedAsArray, IntPtr.Zero, vsaddresults);
                        if (addResult != VSConstants.S_OK && addResult != VSConstants.S_FALSE && addResult != (int)OleConstants.OLECMDERR_E_CANCELED
                            && vsaddresults[0] != VSADDRESULT.ADDRESULT_Success)
                        {
                            ErrorHandler.ThrowOnFailure(addResult);
                        }

                        return dropDataType;
                    }
                    else
                    {
                        if (AddFilesFromProjectReferences(node, filesDroppedAsArray, (uint)dropEffect))
                        {
                            return dropDataType;
                        }
                    }
                }
                finally
                {
                    this.AllowDuplicateLinks = saveAllowDuplicateLinks;
                }
            }

            this.dataWasCut = false;

            // If we reached this point then the drop data must be set to None.
            // Otherwise the OnPaste will be called with a valid DropData and that would actually delete the item.
            return DropDataType.None;
        }
예제 #54
0
 /// <summary>
 /// The get selection data object.
 /// </summary>
 /// <param name="ppIDataObject">
 /// The pp i data object.
 /// </param>
 /// <returns>
 /// The <see cref="int"/>.
 /// </returns>
 int IVsTextView.GetSelectionDataObject(out IDataObject ppIDataObject)
 {
     ppIDataObject = null;
     return VSConstants.E_NOTIMPL;
 }