ClipCursor成功,但实际上什么也没做

时间:2012-08-18 01:56:41

标签: winapi

我正在写一个非常简单的程序来将鼠标剪辑到指定的窗口。它从系统托盘运行,没有可见窗口。因为同一个窗口会有多个实例,所以它使用EnumWindows()遍历每个顶级窗口并将其hwnd与GetForegroundWindow()进行比较。如果为true,则运行标准ClipCursor()代码。 ClipCursor()返回TRUE,并且我声称RECT设置的GetClipCursor()与传递给RECT的{​​{1}}完全相同。然而,光标可以自由移动到屏幕上的任何位置。

我已经检查过ClipCursor()中的值是窗口的确切值,我已经在发布模式下编译了程序并使用管理员权限运行它,但仍然没有。以下代码正是在我们找到RECT的{​​{1}}之后运行的代码:

HWND

我已经删除了很多检查,因为它们变得很烦人(我使用的是GetForegroundWindow()),但是这个代码肯定会在它应该运行的时候运行。光标没有被修剪,我无法理解为什么。

2 个答案:

答案 0 :(得分:5)

由于光标是共享资源,因此任何调用ClipCursor来解除光标的人都会覆盖您剪辑它的尝试。并且许多操作会自动解开光标(例如任何焦点更改)。对于更改光标剪辑的背景窗口,它被认为是不好的形式。

答案 1 :(得分:4)

好吧,我花了几天的时间才发现尽管Cursor资源具有共享特性,但是如果一个进程在某些情况下剪切光标我还不完全知道(也许这个过程必须是前台应用程序?或类似的东西...我不太确定。)然后操作系统自动将光标释放回完全剪辑模式(或任何你称之为)。

无论如何,修复是做一个低级鼠标钩并从那里调用clipcursor。这里有一些概念代码的快速证明(测试和工作,虽然我删除了无关的东西,如创建一个窗口或设置系统托盘等):

// Some variables we'll use
bool clipped = false;   // Do we need to clip the mouse?
RECT rc;                // The clip rect
HHOOK hMouseHook;       // Low level mouse hook

// Low level mouse hook callback function
__declspec(dllexport) LRESULT CALLBACK MouseEvent(int nCode, WPARAM wParam, LPARAM lParam)
{
    // This part should be rewritten to make it not be a CPU-hog
    // But works as a proof of concept
    if ( clipped )
        ClipCursor(&rc);

    return CallNextHookEx(hMouseHook, nCode, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
    // .... Blah blah blah ....

    // Low level mouse hook
    hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, (HOOKPROC)MouseEvent, hInstance, 0);

    // Only included to show that you set the hook before this,
    // And unhook after this.
    while(GetMessage(&msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    // Unhook the mouse
    UnhookWindowsHookEx(hMouseHook);

    return msg.wParam;
}