If the cursor clip rectangle is a global resource, how come I can’t change it with ClipCursor?


A customer reported that the Clip­Cursor function was not working. "The cursor clip rectangle is a shared global resource, so I should be able to change it any time I like. My app installs a global mouse hook and sets the clip cursor inside the hook function, but the change doesn't have any effect. Why can't I change the clip cursor inside a mouse hook?"

Sure, you can change the clip cursor inside a mouse hook. But remember, a shared global resource cuts both ways. Since anybody can change it, your app can change it any time it likes. But since anybody can change it, another app can also change it any time they like.

In this case, what's happening is that your hook comes in and sets the clip rectangle. And the application gets the mouse message and passes it to Def­Window­Proc, and the default behavior for focus changes is to clear the clip rectangle so that any clip rectangle set by the previous window doesn't spill over into the new focus window.

The convention for the clip rectangle is that the focus window (perhaps after some negotiation with one of its ancestors) controls the clip rectangle.

This convention is not enforced for a few reasons. First of all, you can't programmatically determine whether code is executing on behalf of any particular window. Even if you say "can be called only during the handling of a message", that doesn't prove that the code is associated with the window. The message handler might call into some other component, and that other component might decide to clip the cursor just because.

Another reason the rule isn't enforced is that the clip cursor was invented back in the day when programmers were trusted to do the right thing. The theory was that preventing people from doing sneaky things would also prevent them from doing clever things.

(Nowadays, the API design philosophy prefers to prevent people from doing sneaky things, even though it also prevents them from doing clever things, because the bad guys are sneakier than the good guys are clever.)

Comments (7)
  1. Mordachai says:

    I like to think it's because the consequences of the bad guy's sneakiness outweighs the benefits of good guys' cleverness.

  2. Anon says:

    @Steve Wolf

    I like to think it is because we've had a societal shift away from "give me liberty or give me death" to "I'll give you anything you want if you promise you'll never let anything bad happen."

  3. voo says:

    @Anon I would attribute it more to practicality. In the old days computers just weren't powerful enough to include all these new-fangled safeguards and people were happy to use systems that easily bluescreened, corrupted data and what else. Also without the internet readily available there just weren't that many sources of maliciousness around to worry about.

    The whole world has changed extremely since then and it makes perfect sense to change your priorities based on this.

  4. ulric says:

    i just want to know why anybody needs ClipCursor.

    that sudden mouse behavior just looks like a bug to the user

  5. 640k says:

    >> First of all, you can't programmatically determine whether code is executing on behalf of any particular window.

    Kernel always knows which process makes an api call, and can prevent that. This will be a future version of windows for sure. + backward compat shims.

    [You know what thread is issuing the request, but since multiple windows can live on a single thread, you don't know which window. -Raymond]
  6. 640k says:

    Kernel knows if the process/thread owns the focused window.

  7. 640k says:

    …kernel doesn't need to know which particular window it was, kernel should only prevent other threads which doesn't own the focused window to tamper with the clip region.

Comments are closed.

Skip to main content