Fog Creek Software
Discussion Board




Welcome! and rules

Joel on Software

Changing Cursor styles in Windows Forms

I'm writing an application in C# that reads in a large amount of data from source files (why isn't really important).  Naturally, this process can take a few seconds (or minutes) to complete, with no real indication given to the user.  I decided that I should change the cursor to Cursors.WaitCursor, read my files, and then change it back to the Cursors.Default.  This works fine, as long as the application remains the active application.  Unfortunately, if another window (Internet Explorer, C# IDE, etc.) is made the active window, I get  this error: "Null Reference Exception: Object reference not set to and instance of an object."  I am pretty sure that is has to do with the fact that the active window isn't my application, but I don't know how to fix it.  I'm currently doing this:

private void FunctionBlah()
{
    AppName.ActiveForm.Cursor = Cursors.WaitCursor;
    //...

    try
    {
        //Read files
    }
    catch
    {
        //In case drive is not ready
    }
    finally
    {
        AppName.ActiveForm.BringToFront();
        AppName.ActiveForm.Cursor = Cursors.Default;
    }
}

I'm a little new to C#, so I wouldn't be surprised if it is something simple.  Any help would be appriciated.  Thanks.

Ken
Monday, March 29, 2004

From the docs:
"Form.ActiveForm Property: Gets the currently active form for this application.
Property Value: A Form that represents the currently active form, or a null reference (Nothing in Visual Basic) if there is no active form."

Therefore, adapting your code:

if( AppName.ActiveForm != null )
{
  AppName.ActiveForm.BringToFront();
  AppName.ActiveForm.Cursor = Cursors.Default;
}

Note that BringToFront works only with your stack of windows. It's bad practice to try and globally set the focus in Windows - well, because it's f###ing annoying basically.

Duncan Smart
Monday, March 29, 2004

Thanks for the reply.  After having tried it, it did what I expected it to do, which isn't exactly what I want it to do.  Atleast now the program doesn't throw an exception, but th cursor doesn't get changed back to the default one.  Aside from implementing a button to reset the cursor (easy, but not exactly pretty) or a timer to do it (not hard, but when dealing with variable lengh read times it gets hard to decide how long to wait).

Ideally I would like to bring my entire application (only one window when the cursor is changing) to the front of the Windows Z-buffer, and make it the active window.

Ken
Tuesday, March 30, 2004

"but th cursor doesn't get changed back to the default one"

Because the cursor changing code doesn't run because if the conditional. In any case the cursor-changing code should be somewhere like in the button handler code on the form - then you can do:

void myButton_Click(...)
{
  this.Cursor = Cursors.WaitCursor;
  try
  {
    copyFilesFunction();
  }
  catch(...)
  {
    //...
  }
  finally
  {
    this.BringToFront();
    this.Cursor = Cursors.Default;
  }
}

Then you don't have to worry about ActiveForm a) being null and b) being the form you intended it to be.

Duncan Smart
Tuesday, March 30, 2004

Thanks a bunch.  That did it.  Refering to the object with the "this" reference makes things happier than outright refering to the object by name.  Guess that makes sence...or atleast I think it does.  Oh well, just remindes me how much I have to learn about this language.

Thanks again.

Ken
Tuesday, March 30, 2004

*  Recent Topics

*  Fog Creek Home