Home General

Controlling the mouse pointer

I have a script that implements some UI elements, and some button clicks perform slightly long-running tasks. I want to be able to change the mouse pointer to the wait cursor while tasks are running but UserQuery doesn't have a Cursor property. Is there a way to do it?

Comments

  • I would set cursor for the whole page (Results to Rich Text mode).

  • Under Windows you can play with application cursor. I wouldn't recommend that though.

  • Ctrl+F1 and search for progress.

  • I tried the code below but it isn't working. When the button is clicked it displays the following but the mousepointer stays as the default arrow pointer throughout. The fact that the initial state of Current is WaitCursor seems odd.

    Saved [Cursor: WaitCursor]
    Setting WaitCursor
    1
    2
    3
    4
    5
    Restoring [Cursor: WaitCursor]
    
    void Main()
    {
        var testButton = new LINQPad.Controls.Button("Test", _ =>
        {
            using (var waitCursor = new WaitCursor())
            {
                for (int i = 1; i < 5; i++)
                {
                    Console.WriteLine(i);
                    System.Threading.Thread.Sleep(1000);
                }
                Console.WriteLine(5);
            }
        });
    
        testButton.Dump();
    }
    
    public class WaitCursor : IDisposable
    {
        private System.Windows.Forms.Cursor _previousCursor;
    
        public WaitCursor()
        {
            _previousCursor = System.Windows.Forms.Cursor.Current!;
            Console.WriteLine($"Saved {_previousCursor}");
    
            Console.WriteLine("Setting WaitCursor");
            System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.WaitCursor;
        }
    
        public void Dispose()
        {
            Console.WriteLine($"Restoring {_previousCursor}");
            System.Windows.Forms.Cursor.Current = _previousCursor;
        }
    }
    
  • In real WinForms System.Threading.Thread.Sleep(1000); blocks event loop, so cursor wouldn't be changed.

  • I could be completely wrong, but I suspect the reason this does not work is because your query is run as a separate progress which does not have an application form or its own UI (or cursor), but uses some 'magic' to send the results to the application form in LinqPad.

    For example if you dump System.Windows.Forms.Application.OpenForms from your query you will see that it has no results.

    If you create your own Windows.Form in your query and add a standard windows button the WaitCursor class would work correctly.

    If I am correct then, to do want you want, you may need to ask Joe if he can add some command (like Util.SetCursor) that will allow your query to send a request to the main Linqpad UI to change it's cursor.

    P.S. When I have wanted to do something like this, I have taken a completely different approach :

    Either change the text of the button during the operation. .e.g.

    var testButton = new LINQPad.Controls.Button("Test", a =>
        {
            var oldText = a.Text;
            a.Text = "Waiting ...";
            a.Enabled = false;
    
            for (int i = 1; i < 5; i++)
            {
                Console.WriteLine(i);
                System.Threading.Thread.Sleep(1000);
            }
            Console.WriteLine(5);
    
            a.Text = oldText;
            a.Enabled = true;
        });
    
    testButton.Dump();
    

    or if I want to make it completely obviously, add a huge header at the start, e.g.

    DumpContainer banner = new DumpContainer().Dump();
    void Main()
    {
    
        var testButton = new LINQPad.Controls.Button("Test", a =>
        {
            banner.UpdateContent( Util.WithStyle("Waiting ...",  "font-size:100pt; color:blue"));
    
            for (int i = 1; i < 5; i++)
            {
                Console.WriteLine(i);
                System.Threading.Thread.Sleep(1000);
            }
            Console.WriteLine(5);
    
            banner.UpdateContent("");       
        });
    
        testButton.Dump();
    }
    
    

    (Note there does seem to be a tiny glitch with the later example where the banner shrinks but does not completely disappear)

  • Thanks for the replies. I had hoped it would be simple to do but as it isn't and the script is for my own use I'll just live with knowing that sometimes the task after button click takes longer than others.

Sign In or Register to comment.