Date: 3 April 1997
Author: Christopher Kohlhoff
Cursors provide a simple and effective method of providing feedback to the user on the status of your application. Here are presented to ways of using cursors.
Sometimes you will want to associate a particular cursor with a control. That is, whenever the mouse moves over the control, the cursor is changed to what you have set. An example of this (automatically done by the system in this case) is when you get an I-beam cursor over an edit control. OWL Provides the following method:
bool TWindow::SetCursor(TModule* module, TResId resId);
For example, if you wanted to change the cursor of a window to an I-beam, you would write:
window->SetCursor(0, IDC_IBEAM);
Often, when your application is performing an operation that may take some time it is a good idea to change the cursor to indicate waiting. This lets the user know that the application is working and that they will not be able (temporarily) to work with it. You could set the cursor as above at the beginning and end of the operation, but using C++ you can implement it much more nicely.
Consider the following class. Note that the SetCursor used below is not the same as that above, but since TWaitCursor is not derived from TWindow there is no scoping issue.
class TWaitCursor
{
public:
TWaitCursor(TModule* module = 0, TResId resId = IDC_WAIT)
: OldCursor(0)
{
HCURSOR cursor = LoadCursor(module ? (HINSTANCE) *module : 0, resId);
if (cursor) OldCursor = SetCursor(cursor);
}
~TWaitCursor()
{
if (OldCursor) SetCursor(OldCursor);
}
private:
HCURSOR OldCursor;
};
We use the class like this:
void SomeFunction()
{
TWaitCursor waitCursor;
// Some long running operation...
}
The cursor is changed as soon as the TWaitCursor object is created, and is restored to its previous state when the object is destroyed (when it goes out of scope). The advantage of this method is that we let the compiler take care of ensuring the cursor is restored - no matter how many returns there are in the function, and it is even exception-safe!