4

我正在尝试在 Win32 表单中模拟鼠标光标。在WM_MOUSEMOVE我拥有的每一个

hCursor = LoadCursor(NULL, IDC_ARROW);
////Get device context
hDeviceContext = GetDC(hwnd);
hDCMem = CreateCompatibleDC(hDeviceContext);
hBitmap = CreateCompatibleBitmap(hDCMem, 50, 50);
hbmOld = SelectObject(hDCMem, hBitmap);
DrawIcon(hDCMem, x, y, hCursor);
SelectObject(hDCMem, hbmOld);

但我没有看到任何被绘制的东西。但是,如果我直接在 DC 上画图:

DrawIcon(hDeviceContext, x, y, hCursor);

我确实看到了光标,但是当我移动光标时它不会擦除图像,留下一条长尾巴。

4

2 回答 2

5

不画画WM_MOUSEMOVEWM_PAINT就是为了这个。基本上,您需要处理三个消息:

    case WM_CREATE:
        hCursor = LoadCursor(NULL, IDC_ARROW);
        cWidth  = GetSystemMetrics(SM_CXCURSOR); // saving the cursor dimensions
        cHeight = GetSystemMetrics(SM_CYCURSOR);
    break;

    case WM_MOUSEMOVE:
        rcOld = rcNew;
        rcNew.left   = GET_X_LPARAM(lParam);     // saving the mouse coordinates
        rcNew.top    = GET_Y_LPARAM(lParam);
        rcNew.right  = rcNew.left + cWidth;
        rcNew.bottom = rcNew.top + cHeight;
        InvalidateRect(hwnd, &rcOld, TRUE);      // asking to redraw the rectangles
        InvalidateRect(hwnd, &rcNew, TRUE);
        UpdateWindow(hwnd);
    break;

    case WM_PAINT:
        hDC = BeginPaint(hwnd, &ps);
        DrawIcon(hDC, rcNew.left, rcNew.top, hCursor);
        EndPaint(hwnd, &ps);
    break;

注意:我不确定“模拟鼠标光标”是什么意思,但可能有更好的方法来做你可能想要的事情。请检查功能SetCursor()SetWindowLongPtr() with GCL_HCURSOR

于 2012-08-24T15:56:26.557 回答
3

物有所值:

另一种可能值得研究的方法是使用 WS_EX_TOPMOST| WS_EX_LAYERED窗口,您可以根据需要四处移动,并让 Windows 为您处理绘图/透明度。这样做的好处是它根本不会干扰绘图主窗口,即使主窗口有子控件或类似的控件也可以工作。

它还将允许您的“鼠标指针”“悬停在窗口的边缘” - 例如。当鼠标定位到最右下角像素时,普通鼠标指针的尾部和箭头将在框架和它后面的其他窗口上方,而您不能仅通过绘制自己的窗口客户区来做到这一点.

--

话虽如此,我不确定在这里“伪造”鼠标位置是否正确,尽管它很可能会让您启动并运行。另一种方法是让鼠标正常运行,但对于需要更高分辨率的应用程序,有另一个 API 可以公开更精确的值。除了通常的鼠标/键盘消息和 API 之外,Windows 还具有各种技术和 API(例如Raw Input)用于获取输入信息、定义附加输入设备,并且我认为还将附加信息与消息相关联,其中一种技术可能是这里比较合适。重新提出您的问题可能是值得的,但要关注更高级别的问题,而不是光标绘图。

于 2012-08-26T07:40:36.853 回答