Microsoft knowledgebase article Q131991 describes three techniques to change the mouse cursor in an MFC application. One method involves overriding CWnd::PreCreateWindow() to register your own window class that has the mouse pointer you want. This method works well if you want to use that mouse pointer all the time.
To dynamically change the mouse pointer, the article suggests overriding CWnd:: OnSetCursor. This works but, unfortunately, causes an annoying flicker as MFC sets its own mouse pointer and then your code sets it back again.
If you have an application that needs to change between several pointers and you don't want any flicker, here's a technique that worked well for me. The first step is to override PreCreateWindow as the Microsoft article suggests. However, instead of specifying our own mouse pointer here, specify a NULL pointer. This prevents Windows or MFC from doing anything at all with the mouse pointer.
BOOL CMyView::PreCreateWindow(CREATESTRUCT& cs)
{
// Create our own class which has no cursor
// so that we can change it as needed
if (cs.lpszClass == NULL)
cs.lpszClass = AfxRegisterWndClass(CS_DBLCLKS);
return CScrollView::PreCreateWindow(cs);
}
Because the window class does not have any prespecified mouse pointer, we effectively eliminate the flicker. (Note that this example also creates a window class with no background brush, which you'll need to paint the background yourself. To specify a background brush, just pass it as the third argument to AfxRegisterWndClass.)
No flicker is nice, but now we've got no mouse pointer either! Never fear. An easy solution is to set the pointer in the OnMouseMove handler. This works out to be a convenient place to set the pointer if you need to change it based on where the mouse is within your window.
void CMyView::OnMouseMove(UINT nFlags, CPoint point)
{
// Set cursor to indicate current operation
if (m_nOperation == OPERATION_1)
::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_CROSS));
else if (m_nOperation == OPERATION_2)
::SetCursor(AfxGetApp()->LoadStandardCursor( ??? ));
else // Normal pointer
::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
}
It's a little extra work, but if your application calls for different mouse pointers without flicker, here's a way to get the job done.