// fired when a document is about to be shown on screen for various // reasons // public override int OnBeforeDocumentWindowShow( uint itemCookie, int first, IVsWindowFrame wf) { ThreadHelper.ThrowIfNotOnUIThread(); // this may be called any time after the solution is loaded since // window frames are lazily created when a tab is clicked for the // first time if (first == 0) { // only handle the first time a document is shown return(VSConstants.S_OK); } Trace( "OnBeforeDocumentWindowShow: {0}", VSDocument.DebugWindowFrameName(wf)); var d = VSDocument.DocumentFromWindowFrame(wf); if (d == null) { Error("OnBeforeDocumentWindowShow: frame has no document"); return(VSConstants.S_OK); } DocumentOpened?.Invoke(new VSDocument(d, wf)); return(VSConstants.S_OK); }
// fired when document attributes change, such as renaming, but also // dirty state, etc. // public override int OnAfterAttributeChangeEx( uint cookie, uint atts, IVsHierarchy oldHier, uint oldId, string oldPath, IVsHierarchy newHier, uint newId, string newPath) { ThreadHelper.ThrowIfNotOnUIThread(); const uint RenameBit = (uint)__VSRDTATTRIB.RDTA_MkDocument; if ((atts & RenameBit) == 0) { // don't bother with anything else than rename return(VSConstants.S_OK); } // this is fired for: // // 1) renaming a C# project // ignored because it also fires HierarchyEvents.OnPropertyChanged // // 2) renaming a file for both C++ and C# projects // this is handled here // // 3) moving a C# file // this is handled here and ignored in HierarchyEvents.OnItemAdded Trace( "OnAfterAttributeChangeEx rename: cookie={0} atts={1} " + "oldId={2} oldPath={3} newId={4} newPath={5}", cookie, atts, oldId, oldPath, newId, newPath); var d = VSDocument.DocumentFromCookie(cookie); if (d == null) { // this happens when renaming a C# project, which is handled // elsewhere, so that's fine return(VSConstants.S_OK); } DocumentRenamed?.Invoke(new VSDocument(d)); return(VSConstants.S_OK); }
// fired when an item is moved or added // public override int OnItemAdded( uint parent, uint prevSibling, uint item) { ThreadHelper.ThrowIfNotOnUIThread(); Trace( "OnItemAdded: parent={0} prevSibling={1} item={2}", parent, prevSibling, item); // it's generally impossible to differentiate between moves and // renames for either files or folders, so they're merged into one // rename event // OnItemAdded for folders and files is fired for C# projects on // move and rename, but only on move for C++ projects for move // // renaming a file or a folder for C++ projects fires // OnPropertyChanged, which is handled below if (VSTreeItem.GetIsFolder(Hierarchy, item)) { FolderRenamed?.Invoke(new VSTreeItem(Hierarchy, item)); } else { var d = VSDocument.DocumentFromItemID(Hierarchy, item); if (d == null) { // this happens when renaming C# files for whatever reason, // but it's fine because it's already handled in // OnAfterAttributeChangeEx return(VSConstants.S_OK); } DocumentRenamed?.Invoke(new VSDocument(d)); } return(VSConstants.S_OK); }