private IList <VSITEMSELECTION> GetSelectedNodes() { // Retrieve shell interface in order to get current selection IVsMonitorSelection monitorSelection = package.GetServiceEx <IVsMonitorSelection>() as IVsMonitorSelection; Debug.Assert(monitorSelection != null, "Could not get the IVsMonitorSelection object from the services exposed by this project"); if (monitorSelection == null) { throw new InvalidOperationException(); } List <VSITEMSELECTION> selectedNodes = new List <VSITEMSELECTION>(); IntPtr hierarchyPtr = IntPtr.Zero; IntPtr selectionContainer = IntPtr.Zero; try { // Get the current project hierarchy, project item, and selection container for the current selection // If the selection spans multiple hierachies, hierarchyPtr is Zero uint itemid; IVsMultiItemSelect multiItemSelect = null; ErrorHandler.ThrowOnFailure(monitorSelection.GetCurrentSelection(out hierarchyPtr, out itemid, out multiItemSelect, out selectionContainer)); if (itemid != VSConstants.VSITEMID_SELECTION) { // We only care if there are nodes selected in the tree if (itemid != VSConstants.VSITEMID_NIL) { if (hierarchyPtr == IntPtr.Zero) { // Solution is selected VSITEMSELECTION vsItemSelection; vsItemSelection.pHier = null; vsItemSelection.itemid = itemid; selectedNodes.Add(vsItemSelection); } else { IVsHierarchy hierarchy = (IVsHierarchy)Marshal.GetObjectForIUnknown(hierarchyPtr); // Single item selection VSITEMSELECTION vsItemSelection; vsItemSelection.pHier = hierarchy; vsItemSelection.itemid = itemid; selectedNodes.Add(vsItemSelection); } } } else { if (multiItemSelect != null) { // This is a multiple item selection. //Get number of items selected and also determine if the items are located in more than one hierarchy uint numberOfSelectedItems; int isSingleHierarchyInt; ErrorHandler.ThrowOnFailure(multiItemSelect.GetSelectionInfo(out numberOfSelectedItems, out isSingleHierarchyInt)); bool isSingleHierarchy = (isSingleHierarchyInt != 0); // Now loop all selected items and add them to the list Debug.Assert(numberOfSelectedItems > 0, "Bad number of selected itemd"); if (numberOfSelectedItems > 0) { VSITEMSELECTION[] vsItemSelections = new VSITEMSELECTION[numberOfSelectedItems]; ErrorHandler.ThrowOnFailure(multiItemSelect.GetSelectedItems(0, numberOfSelectedItems, vsItemSelections)); foreach (VSITEMSELECTION vsItemSelection in vsItemSelections) { selectedNodes.Add(vsItemSelection); } } } } } finally { if (hierarchyPtr != IntPtr.Zero) { Marshal.Release(hierarchyPtr); } if (selectionContainer != IntPtr.Zero) { Marshal.Release(selectionContainer); } } return(selectedNodes); }
/// <summary> /// Gets all of the currently selected items. /// </summary> /// <returns></returns> private IEnumerable <VSITEMSELECTION> GetSelectedItems() { IVsMonitorSelection monitorSelection = _package.GetService(typeof(IVsMonitorSelection)) as IVsMonitorSelection; IntPtr hierarchyPtr = IntPtr.Zero; IntPtr selectionContainer = IntPtr.Zero; try { uint selectionItemId; IVsMultiItemSelect multiItemSelect = null; ErrorHandler.ThrowOnFailure(monitorSelection.GetCurrentSelection(out hierarchyPtr, out selectionItemId, out multiItemSelect, out selectionContainer)); if (selectionItemId != VSConstants.VSITEMID_NIL && hierarchyPtr != IntPtr.Zero) { IVsHierarchy hierarchy = Marshal.GetObjectForIUnknown(hierarchyPtr) as IVsHierarchy; if (selectionItemId != VSConstants.VSITEMID_SELECTION) { // This is a single selection. Compare hirarchy with our hierarchy and get node from itemid if (Utilities.IsSameComObject(this, hierarchy)) { yield return(new VSITEMSELECTION() { itemid = selectionItemId, pHier = hierarchy }); } } else if (multiItemSelect != null) { // This is a multiple item selection. // Get number of items selected and also determine if the items are located in more than one hierarchy uint numberOfSelectedItems; int isSingleHierarchyInt; ErrorHandler.ThrowOnFailure(multiItemSelect.GetSelectionInfo(out numberOfSelectedItems, out isSingleHierarchyInt)); bool isSingleHierarchy = (isSingleHierarchyInt != 0); // Now loop all selected items and add to the list only those that are selected within this hierarchy if (!isSingleHierarchy || (isSingleHierarchy && Utilities.IsSameComObject(this, hierarchy))) { Debug.Assert(numberOfSelectedItems > 0, "Bad number of selected itemd"); VSITEMSELECTION[] vsItemSelections = new VSITEMSELECTION[numberOfSelectedItems]; uint flags = (isSingleHierarchy) ? (uint)__VSGSIFLAGS.GSI_fOmitHierPtrs : 0; ErrorHandler.ThrowOnFailure(multiItemSelect.GetSelectedItems(flags, numberOfSelectedItems, vsItemSelections)); foreach (VSITEMSELECTION vsItemSelection in vsItemSelections) { yield return(new VSITEMSELECTION() { itemid = vsItemSelection.itemid, pHier = hierarchy }); } } } } } finally { if (hierarchyPtr != IntPtr.Zero) { Marshal.Release(hierarchyPtr); } if (selectionContainer != IntPtr.Zero) { Marshal.Release(selectionContainer); } } }
/// <summary> /// Returns a list of valid shader files from the current file selection /// </summary> /// <param name="shaderFileNames">List to be filled with all valid shader files from the current selection</param> /// <returns>True if at least one shader has been selected</returns> public bool GetSelectedShaderFiles(List <ShaderFile> shaderFiles) { IVsHierarchy hierarchy = null; uint itemid = VSConstants.VSITEMID_NIL; int hr = VSConstants.S_OK; var monitorSelection = Package.GetGlobalService(typeof(SVsShellMonitorSelection)) as IVsMonitorSelection; var solution = Package.GetGlobalService(typeof(SVsSolution)) as IVsSolution; if (monitorSelection == null || solution == null) { return(false); } IVsMultiItemSelect multiItemSelect = null; IntPtr hierarchyPtr = IntPtr.Zero; IntPtr selectionContainerPtr = IntPtr.Zero; try { hr = monitorSelection.GetCurrentSelection(out hierarchyPtr, out itemid, out multiItemSelect, out selectionContainerPtr); if (ErrorHandler.Failed(hr) || hierarchyPtr == IntPtr.Zero || itemid == VSConstants.VSITEMID_NIL) { return(false); } hierarchy = Marshal.GetObjectForIUnknown(hierarchyPtr) as IVsHierarchy; if (hierarchy == null) { return(false); } List <uint> itemids = new List <uint>(); if (multiItemSelect == null) { ReadItemHierarchy(itemid, hierarchy, itemids); } else { // todo: Read hierarchy for multi selects uint itemCount = 0; int fSingleHierarchy = 0; hr = multiItemSelect.GetSelectionInfo(out itemCount, out fSingleHierarchy); VSITEMSELECTION[] items = new VSITEMSELECTION[itemCount]; hr = multiItemSelect.GetSelectedItems(0, itemCount, items); foreach (var item in items) { itemids.Add(item.itemid); } } foreach (var id in itemids) { string filepath = null; ((IVsProject)hierarchy).GetMkDocument(id, out filepath); if (filepath != null && Utils.IsShaderFile(filepath)) { var transformFileInfo = new FileInfo(filepath); shaderFiles.Add(new ShaderFile(id, hierarchy, filepath)); } } // todo: hierarchy node if (itemid == VSConstants.VSITEMID_ROOT) { return(false); } Guid guidProjectID = Guid.Empty; if (ErrorHandler.Failed(solution.GetGuidOfProject(hierarchy, out guidProjectID))) { return(false); } return(shaderFiles.Count > 0); } finally { if (selectionContainerPtr != IntPtr.Zero) { Marshal.Release(selectionContainerPtr); } if (hierarchyPtr != IntPtr.Zero) { Marshal.Release(hierarchyPtr); } } }
/// <summary> /// Builds a list of nodes currently selected in the solution explorer /// </summary> /// <returns></returns> public List <ItemNode> GetSelectedNodes() { var selected_nodes = new List <ItemNode>(); IntPtr hierarchyPtr = IntPtr.Zero; IntPtr selectionContainer = IntPtr.Zero; try { // Get the current project hierarchy, project item, and selection container for the current selection // If the selection spans multiple hierachies, hierarchyPtr is Zero uint itemid; IVsMultiItemSelect multiItemSelect = null; ErrorHandler.ThrowOnFailure(GlobalServices.selectionMonitor.GetCurrentSelection(out hierarchyPtr, out itemid, out multiItemSelect, out selectionContainer)); // We only care if there are one ore more nodes selected in the tree if (itemid != VSConstants.VSITEMID_NIL && hierarchyPtr != IntPtr.Zero) { IVsHierarchy hierarchy = Marshal.GetObjectForIUnknown(hierarchyPtr) as IVsHierarchy; if (itemid != VSConstants.VSITEMID_SELECTION) { // This is a single selection. Compare hirarchy with our hierarchy and get node from itemid ItemNode node; if (GlobalServices.IsSameComObject(Project, hierarchy) && itemMap.TryGetValue(itemid, out node)) { selected_nodes.Add(node); } } else if (multiItemSelect != null) { // This is a multiple item selection. //Get number of items selected and also determine if the items are located in more than one hierarchy uint numberOfSelectedItems; int isSingleHierarchyInt; ErrorHandler.ThrowOnFailure(multiItemSelect.GetSelectionInfo(out numberOfSelectedItems, out isSingleHierarchyInt)); bool isSingleHierarchy = (isSingleHierarchyInt != 0); // Now loop all selected items and add to the list only those that are selected within this hierarchy if (!isSingleHierarchy || (isSingleHierarchy && GlobalServices.IsSameComObject(Project, hierarchy))) { Debug.Assert(numberOfSelectedItems > 0, "Bad number of selected items"); VSITEMSELECTION[] vsItemSelections = new VSITEMSELECTION[numberOfSelectedItems]; uint flags = (isSingleHierarchy) ? (uint)__VSGSIFLAGS.GSI_fOmitHierPtrs : 0; ErrorHandler.ThrowOnFailure(multiItemSelect.GetSelectedItems(flags, numberOfSelectedItems, vsItemSelections)); foreach (VSITEMSELECTION vsItemSelection in vsItemSelections) { if (isSingleHierarchy || GlobalServices.IsSameComObject(Project, vsItemSelection.pHier)) { ItemNode node; if (itemMap.TryGetValue(vsItemSelection.itemid, out node)) { selected_nodes.Add(node); } } } } } } } finally { if (hierarchyPtr != IntPtr.Zero) { Marshal.Release(hierarchyPtr); } if (selectionContainer != IntPtr.Zero) { Marshal.Release(selectionContainer); } } return(selected_nodes); }
private static uint GetSelectedItemsCount(IVsMultiItemSelect multiSelect) { uint selectedItemsCount; int isSingleHierarchy; ErrorHandler.ThrowOnFailure(multiSelect.GetSelectionInfo(out selectedItemsCount, out isSingleHierarchy)); return selectedItemsCount; }
public static IVsHierarchy GetSelectedHierarchy(this IVsMonitorSelection monitorSelection, IUIThread uiThread) { var hierarchyPtr = IntPtr.Zero; var selectionContainer = IntPtr.Zero; return(uiThread.Invoke(() => { try { // Get the current project hierarchy, project item, and selection container for the current selection // If the selection spans multiple hierarchies, hierarchyPtr is Zero. // So fast path is for non-zero result (most common case of single active project/item). uint itemid; IVsMultiItemSelect multiItemSelect = null; ErrorHandler.ThrowOnFailure(monitorSelection.GetCurrentSelection(out hierarchyPtr, out itemid, out multiItemSelect, out selectionContainer)); // There may be no selection at all. if (itemid == VSConstants.VSITEMID_NIL) { return null; } if (itemid == VSConstants.VSITEMID_ROOT) { // The root selection could be the solution itself, so no project is active. if (hierarchyPtr == IntPtr.Zero) { return null; } else { return (IVsHierarchy)Marshal.GetTypedObjectForIUnknown(hierarchyPtr, typeof(IVsHierarchy)); } } // We may have a single item selection, so we can safely pick its owning project/hierarchy. if (itemid != VSConstants.VSITEMID_SELECTION) { return (IVsHierarchy)Marshal.GetTypedObjectForIUnknown(hierarchyPtr, typeof(IVsHierarchy)); } // Otherwise, this is a multiple item selection within the same hierarchy, // we select he hierarchy. uint numberOfSelectedItems; int isSingleHierarchyInt; ErrorHandler.ThrowOnFailure(multiItemSelect.GetSelectionInfo(out numberOfSelectedItems, out isSingleHierarchyInt)); var isSingleHierarchy = (isSingleHierarchyInt != 0); if (isSingleHierarchy) { return (IVsHierarchy)Marshal.GetTypedObjectForIUnknown(hierarchyPtr, typeof(IVsHierarchy)); } return null; } finally { if (hierarchyPtr != IntPtr.Zero) { Marshal.Release(hierarchyPtr); } if (selectionContainer != IntPtr.Zero) { Marshal.Release(selectionContainer); } } })); }
public static IEnumerable <Tuple <IVsHierarchy, uint> > GetSelection(this IVsMonitorSelection monitorSelection, IUIThread uiThread, IVsHierarchy solution) { var hierarchyPtr = IntPtr.Zero; var selectionContainer = IntPtr.Zero; return(uiThread.Invoke(() => { try { // Get the current project hierarchy, project item, and selection container for the current selection // If the selection spans multiple hierarchies, hierarchyPtr is Zero uint itemid; IVsMultiItemSelect multiItemSelect = null; ErrorHandler.ThrowOnFailure(monitorSelection.GetCurrentSelection(out hierarchyPtr, out itemid, out multiItemSelect, out selectionContainer)); if (itemid == VSConstants.VSITEMID_NIL) { return Enumerable.Empty <Tuple <IVsHierarchy, uint> >(); } if (itemid == VSConstants.VSITEMID_ROOT) { if (hierarchyPtr == IntPtr.Zero) { return new[] { Tuple.Create(solution, VSConstants.VSITEMID_ROOT) } } ; else { return new[] { Tuple.Create( (IVsHierarchy)Marshal.GetTypedObjectForIUnknown(hierarchyPtr, typeof(IVsHierarchy)), VSConstants.VSITEMID_ROOT) } }; } if (itemid != VSConstants.VSITEMID_SELECTION) { return new[] { Tuple.Create( (IVsHierarchy)Marshal.GetTypedObjectForIUnknown(hierarchyPtr, typeof(IVsHierarchy)), itemid) } } ; // This is a multiple item selection. uint numberOfSelectedItems; int isSingleHierarchyInt; ErrorHandler.ThrowOnFailure(multiItemSelect.GetSelectionInfo(out numberOfSelectedItems, out isSingleHierarchyInt)); var isSingleHierarchy = (isSingleHierarchyInt != 0); var vsItemSelections = new VSITEMSELECTION[numberOfSelectedItems]; var flags = (isSingleHierarchy) ? (uint)__VSGSIFLAGS.GSI_fOmitHierPtrs : 0; ErrorHandler.ThrowOnFailure(multiItemSelect.GetSelectedItems(flags, numberOfSelectedItems, vsItemSelections)); return vsItemSelections.Where(sel => sel.pHier != null) // NOTE: we can return lazy results here, since // the GetSelectedItems has already returned in the UI thread // the array of results. We're just delaying the creation of the tuples // in case they aren't all needed. .Select(sel => Tuple.Create(sel.pHier, sel.itemid)); } finally { if (hierarchyPtr != IntPtr.Zero) { Marshal.Release(hierarchyPtr); } if (selectionContainer != IntPtr.Zero) { Marshal.Release(selectionContainer); } } })); }