locked
How to change the cursor icon from the DTE object RRS feed

  • Question

  • From a DTE object, how do you access and change the mouse cursor?
    Thanks,
    -Melody

            public void ShowIDE() 
            { 
                //create the IDE 
                EnvDTE.DTE dte; 
                IDTEProvider dteProvider = (IDTEProvider)new VSTADTEProviderClass(); 
                dte = (EnvDTE.DTE)dteProvider.GetDTE("ShapeAppCSharp", 0); 
     
                //show the IDE 
                this.dte.MainWindow.Visible = true
     
                //HELP- change the cursor to a wait icon 
     
                //do stuff like open or create a project 
     
                //HELP- change the cursor to a pointer icon 
            } 


    Melody @ Summsoft
    Tuesday, December 9, 2008 3:52 PM

Answers

All replies

  • This is not specific to VS but to .NET, you can use:


    using System.Windows.Forms;


    System.Windows.Forms.Cursor previousCursor;

    previousCursor = System.Windows.Forms.Cursor.Current;
    System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.WaitCursor;

    // do stuff

    System.Windows.Forms.Cursor.Current = previousCursor;



    MZ-Tools: Productivity add-ins for Visual Studio: http://www.mztools.com. My blog about VS extensibility: http://msmvps.com/blogs/carlosq/
    • Proposed as answer by FengChen Wednesday, December 10, 2008 1:13 AM
    Tuesday, December 9, 2008 4:02 PM
  • Carlos,
    Thanks for the quick reply.  It makes sense to change the overall cursor from the host instead of changing the cursor only for the IDE, but I cannot get the cursor to change with this code (I have seen this in many other examples).  I tried a simplified version- a form with two buttons, one to change it to the WaitCursor, one to change it to the DefaultCursor.  The cursor never changes from the default, although the property Cursor.Current indicates the WaitCursor is in use.

    Any suggestions?

    Thanks,
    -Melody

    namespace WindowsFormsApplication1 
     
        using System.Windows.Forms; 
     
        public partial class Form1 : Form 
        { 
            public Form1() 
            { 
                InitializeComponent(); 
            } 
     
            private void button1_Click(object sender, EventArgs e) 
            { 
                Cursor.Current = Cursors.WaitCursor; 
                MessageBox.Show(Cursor.Current.ToString());             
            } 
     
            private void button2_Click(object sender, EventArgs e) 
            { 
                System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.Default; 
                MessageBox.Show(Cursor.Current.ToString()); 
            } 
     
     
        } 





    Melody @ Summsoft
    Wednesday, December 10, 2008 4:13 PM
  • Carlos,
    Sorry, I need to correct my earlier post.  The code does work for some cases, such as the simple sample I posted, but it only changes the cursor over the window in the simple sample- not over other windows or for my host.

    When I add methods to my main form to change the cursor and call it from my supporting class it does not change the cursor over my main form or over the IDE. 

    Is there a way to directly access the cursor from the IDE instead of the host?

    Thanks,
    -Melody

        using System.Windows.Forms; 
     
        internal partial class ShapeAppForm : Form 
        { 
            public void ChangeCurser(bool wait) 
            { 
                if (wait) 
                { 
                    System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.WaitCursor; 
                } 
                else 
                { 
                    System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.Default; 
                } 
            } 
        } 
     
        internal sealed class VstaDesignTimeIntegration : MarshalByRefObject, IExternalDebugHost 
        { 
            public void ShowIDE() 
            { 
                //create the IDE 
                EnvDTE.DTE dte; 
                IDTEProvider dteProvider = (IDTEProvider)new VSTADTEProviderClass(); 
                dte = (EnvDTE.DTE)dteProvider.GetDTE("ShapeAppCSharp", 0); 
     
                //show the IDE 
                this.dte.MainWindow.Visible = true
     
                //HELP- change the cursor to a wait icon over the IDE 
                this.application.ApplicationForm.ChangeCurser(true); 
     
                //do stuff like open or create a project 
     
                //HELP- change the cursor to a pointer icon over the IDE 
                this.application.ApplicationForm.ChangeCurser(false); 
            } 
     


    Melody @ Summsoft
    Wednesday, December 10, 2008 9:13 PM
  • Cursors are a bit tricky. See:

    http://stackoverflow.com/questions/302663/cursorcurrent-vs-thiscursor-in-net-c

    and:

    http://msdn.microsoft.com/en-us/library/system.windows.forms.cursor.current.aspx

    And beware of DoEvents:

    http://msdn.microsoft.com/en-us/library/system.windows.forms.cursor.current(VS.71).aspx

    And beware of Visual Studio:

    BUG: ProjectItem.Open() changes the mouse cursor in Visual Studio .NET.

    MZ-Tools: Productivity add-ins for Visual Studio: http://www.mztools.com. My blog about VS extensibility: http://msmvps.com/blogs/carlosq/
    Thursday, December 11, 2008 9:31 AM
  • I didn't read the links that Carlos posted so this might be pointed out but you need to make sure you are on the GUI thread when you call this from another class.  ChangeCurser() should check InvokeRequired and then call BeginInvoke() to a delegate if that returns true.

    Not sure if that will fix your problem or not but it is a good practice to include that code.
    Thursday, December 11, 2008 12:03 PM
  • Thanks guys!
    This looks trickier than I expected it to be.  The window that I need to change the cursor over, the IDE, is on it's own thread and requires some threading flags in the host to be set, like CheckForIllegalCrossThreadCalls=false.  This also results in using the InvokeRequired and BeginInvoke calls Darren mentioned to be used by the host for host GUI changes.  I was hopping their was a way to deal with the cursor through the EnvDTE.DTE object instead of getting involved with threading.

    Thanks,
    -Melody

    Melody @ Summsoft
    Thursday, December 11, 2008 2:55 PM
  • Hi Melody,

    To the best of my knowledge, there is no automation support for changing up the cursor on/for the various windows in the IDE. I'm kind of curious though as to why you'd want to do that in the first place. For the most part, the IDE is a pretty standard piece of Win32 code (with various toolwindows and designers that are managed). But changing up the icons over the various windows could lead to some confusion.

    If you are adding your own toolwindows, designers/editors to the shell, it's entirely feasible to register the window with a custom cursor, but to do so from an addin or external process seems a bit questionable.

    Just trying to get a feel for what exactly you're looking to do here.

    Sincerely,
    Ed Dore
    Tuesday, December 16, 2008 6:52 AM
  • Ed,
    Thanks for the answer.  This question originated on our forum for VSTA support (Summsoft.com).  Once the host application launches the IDE, the host has some processes to do during which the IDE should be in "wait mode".  Ideally this should be done through the cursor, currently a status bar is being used. 

    Thanks,
    -Melody

    Melody @ Summsoft
    Tuesday, December 16, 2008 2:30 PM