none
How to get the state of the "Show All Files" toggle button RRS feed

  • Question

  • Hi,

    in a VS Package that I'm working on, I programmatically exclude some items from the project so they don't get included in the build. Even though they're excluded, I'd like my users to see that they are still there. I've found out that I can use DTE to activate the "Show All Files" button in the Solution Explorer by executing Project.ShowAllFiles command. The problem is, that button is a toggle button so it might be already toggled and executing the command would achieve the opposite result of what I need.

    Maybe I'm missing something obvious here, but I guess my question is... is there a way to get the state of that button before I execute my command, or any other workaround to achieve what I want?

    Thanks.

    Wednesday, March 18, 2009 10:32 PM

Answers

  • This might be a little tricky to figure out.

    That "Show All Files" button is handled by the individual project hierarchies, and some project systems may not support the command at all.

    Under the hood, each project hierarchy implements a method called IVsHierarchy.QueryStatusCommand. Periodically, the IDE invokes this method to determine how to render the button (enable, disable, hide). The way command routing works, the projects QueryStatusCommand gets invoked when that project happens to be the actively selected project in the solution explorer.

    You could try calling the project's QueryStatusCommand method to see what the state of the command is. But it may only work for the actively selected project.

    Use the EnableVSIPLogging registry trick to identify the guid:id pair for that button.

    You should be able to retrieve the actively selected project's IVsUIHierarchy interface, by calling IVsMonitorSelection.GetCurrentSelection. Use Marshal.GetObjectForIUnknown on the ppHier argument, to retrieve the IVsUIHierachy interface.

    The call IVsUIHierarchy.QueryStatusCommand, using VSITEMID_ROOT for the itemid, and initialize the OLECMD.cmdID with the commandID you retrieved with that EnableVSIPLogging trick. Upon return, the OLECMD.cmdf will contain the flags indicating the state of the command. OLECMDF_LATCHED will be present if the command is currently toggled on.

    Sincerely,
    Ed Dore
    Thursday, March 19, 2009 3:48 PM
    Moderator

All replies

  • This might be a little tricky to figure out.

    That "Show All Files" button is handled by the individual project hierarchies, and some project systems may not support the command at all.

    Under the hood, each project hierarchy implements a method called IVsHierarchy.QueryStatusCommand. Periodically, the IDE invokes this method to determine how to render the button (enable, disable, hide). The way command routing works, the projects QueryStatusCommand gets invoked when that project happens to be the actively selected project in the solution explorer.

    You could try calling the project's QueryStatusCommand method to see what the state of the command is. But it may only work for the actively selected project.

    Use the EnableVSIPLogging registry trick to identify the guid:id pair for that button.

    You should be able to retrieve the actively selected project's IVsUIHierarchy interface, by calling IVsMonitorSelection.GetCurrentSelection. Use Marshal.GetObjectForIUnknown on the ppHier argument, to retrieve the IVsUIHierachy interface.

    The call IVsUIHierarchy.QueryStatusCommand, using VSITEMID_ROOT for the itemid, and initialize the OLECMD.cmdID with the commandID you retrieved with that EnableVSIPLogging trick. Upon return, the OLECMD.cmdf will contain the flags indicating the state of the command. OLECMDF_LATCHED will be present if the command is currently toggled on.

    Sincerely,
    Ed Dore
    Thursday, March 19, 2009 3:48 PM
    Moderator
  • Alright, I think I got it working. Thank you!

    I got some sample code in case anyone's interested, I hope it's ok if I paste it here. In my case, the following would be placed in a method inside a custom tool window. It's pretty raw but may be enough to put someone interested in something similar on the right track:

    Microsoft.VisualStudio.Shell.Interop.IVsMonitorSelection ms =  
        GetService(typeof(Microsoft.VisualStudio.Shell.Interop.IVsMonitorSelection))  
        as Microsoft.VisualStudio.Shell.Interop.IVsMonitorSelection;  
     
    IntPtr ppHier;  
    uint pitemid;  
    Microsoft.VisualStudio.Shell.Interop.IVsMultiItemSelect ppMIS;  
    IntPtr ppSC;  
    ms.GetCurrentSelection(out ppHier, out pitemid, out ppMIS, out ppSC);  
    if (ppHier == IntPtr.Zero)  
    {  
        // a project is not selected in the solution explorer  
        MessageBox.Show("A project is not selected");  
        return;  
    }  
     
    object obj = System.Runtime.InteropServices.Marshal.GetObjectForIUnknown(ppHier);  
    Microsoft.VisualStudio.Shell.Interop.IVsUIHierarchy hierarchy =  
        obj as Microsoft.VisualStudio.Shell.Interop.IVsUIHierarchy;  
     
    Microsoft.VisualStudio.OLE.Interop.OLECMD cmd =  
        new Microsoft.VisualStudio.OLE.Interop.OLECMD();  
    cmd.cmdID = 600;  
    Microsoft.VisualStudio.OLE.Interop.OLECMD[] cmdArray = { cmd };  
    Guid cmdGuid = new Guid("{1496A755-94DE-11D0-8C3F-00C04FC2AAE2}");  
     
    hierarchy.QueryStatusCommand(  
        Microsoft.VisualStudio.VSConstants.VSITEMID_ROOT, // uint itemid  
        ref cmdGuid, // ref Guid pguidCmdGroup  
        600, // uint cCmds  
        cmdArray, // Microsoft.VisualStudio.OLE.Interop.OLECMD[] prgCmds  
        new IntPtr() // IntPtr pCmdText  
    );  
     
    // test the result  
    uint resultFlag = cmdArray[0].cmdf;  
    uint toggledFlag = (uint)Microsoft.VisualStudio.OLE.Interop.OLECMDF.OLECMDF_LATCHED;  
     
    if ((resultFlag & toggledFlag) == toggledFlag)  
    {  
        MessageBox.Show("The toggle button is on");  
    }  
    else 
    {  
        MessageBox.Show("The toggle button is off");  

    Again, thanks.
    Thursday, March 19, 2009 6:51 PM