ID Number: Q79983
3.00
WINDOWS
docerr
Summary:
SYMPTOMS
An application uses the method described in the documentation for
WM_SETCURSOR in version 3.0 of the "Microsoft Windows Software
Development Kit Reference Volume 1" on pages 6-98 and 6-99 to
change the cursor for one of the child window controls in a dialog
box, and the cursor does not change.
CAUSE
A dialog procedure cannot change the value returned by DefDlgProc()
in response to WM_SETCURSOR.
RESOLUTION
Subclass the child window control in the dialog box and change the
cursor in the subclass procedure.
More Information:
In the documentation for WM_SETCURSOR, the comments section states
that when the message is not processed by a window, DefWindowProc()
sends the message to the parent window to allow it to change the
cursor. If the parent window's window procedure returns TRUE, further
processing of the message is halted and the cursor specified by the
parent window is used. This method gives the parent window control
over the cursor used in a child window.
This technique does not work when a standard dialog box attempts to
set the cursor for one of its child window controls because there is
no method to change the value returned by DefDlgProc() in response to
the WM_SETCURSOR message. DefDlgProc() is the window procedure for the
standard dialog-box class. It calls the user-defined dialog procedure.
If the dialog procedure returns FALSE to indicate that it did not
process a message, DefDlgProc() performs the default processing.
The Boolean value returned from the dialog procedure in response to
WM_SETCURSOR indicates only whether the dialog procedure has processed
the message or not. It does not specify the value that DefDlgProc()
should return in response to the message. [Note that the WM_CTLCOLOR,
WM_COMPAREITEM, WM_VKEYTOITEM, and WM_CHARTOITEM messages are treated
differently. The value returned by the dialog procedure in response to
these messages is returned by DefDlgProc().]
Because it is not possible for the dialog procedure to specify the
value returned by DefDlgProc() when it processes the WM_SETCURSOR
message, it cannot indicate that a new cursor was specified for a
child window control. DefDlgProc() always returns FALSE in response to
the WM_SETCURSOR message, regardless of how the dialog procedure
processed the message. Therefore, the control's default cursor is
always used because its parent window did not return TRUE in response
to the WM_SETCURSOR message.
One way to work around this problem is to subclass the control that
will have its cursor changed. The following code demonstrates how the
subclass procedure can process the WM_SETCURSOR message:
case WM_SETCURSOR:
SetCursor(hCursor);
return 0L; // Do not pass this message on
This technique succeeds because the control sets its own cursor and
does not pass the WM_SETCURSOR message to DefDlgProc().
Additional reference words: 3.00