In my earlier discussion of the fact that changing a class property affects all windows of that class, commenters LittleHelper and Norman Diamond wanted to know "Why is the cursor associated with class and not a window?"
This is another one of those questions that start off with an invalid
assumption.
The cursor is not associated with a class.
The cursor is not associated with a window.
The cursor is associated with an input state.
(Initially, each thread has its own input state,
but functions like
AttachThreadInput
can cause threads to share their input states.)
As we saw when we explored
the process by which the cursor gets set,
the cursor-setting process is initiated by the
WM_
message,
which is percolated up and down the window hierarchy
until somebody calls
SetCursor
and returns TRUE
to say "Okay, I set the cursor. You can stop searching now."
And that cursor remains in effect until
somebody else in the same thread group calls
SetCursor
.
It so happens that the DefWindowProc
function,
when asked to set a cursor, will use the window's class cursor.
But that's just the default in the absence of any customization
to the contrary.
If you want to customize the cursor when it is over a particular window,
then use the customization; don't go changing the default.
If you change the default, then you affect what happens to all
the other windows of the class.
Just handle the WM_
message to establish
your "per-window cursor".
(And you can be even more specific than just per-window.
For example, you might decide to show a hand cursor if the user
is over a hyperlink but an arrow cursor otherwise.)
Many of the fields in the WNDCLASS
structure are
merely defaults which are applied to windows of the class.
You can still override them on a per-window basis.
Field | How to override |
---|---|
lpfnWndProc |
SetWindowLongPtr(GWLP_ |
hIcon |
SendMessage(WM_ |
hCursor |
Handle the WM_ message |
hbrBackground |
Handle the WM_ message |
lpszMenuName |
SetMenu() |
(This is the same table I wrote up some time ago, but the original table didn't have an entry for the window procedure, so this table is slightly more complete.