Winapi 在win32中绘制鼠标光标

Winapi 在win32中绘制鼠标光标,winapi,cursor,mouse,gdi,Winapi,Cursor,Mouse,Gdi,GDI的新手 我试图在Win32窗体中模拟鼠标光标。在我的每一个鼠标上 hCursor = LoadCursor(NULL, IDC_ARROW); ////Get device context hDeviceContext = GetDC(hwnd); hDCMem = CreateCompatibleDC(hDeviceContext); hBitmap = CreateCompatibleBitmap(hDCMem, 50, 50); hbmOld = SelectObject(hDCMe

GDI的新手

我试图在Win32窗体中模拟鼠标光标。在我的每一个鼠标上

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);
但我没有看到任何东西被画出来。但是,如果我直接使用to DC:

    DrawIcon(hDeviceContext , x, y, hCursor);

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

不要在
WM\u MOUSEMOVE
中绘制,这就是
WM\u 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;
注意:我不确定你说的“模拟鼠标光标”是什么意思,但可能有更好的方法来做你可能想做的事情。请检查函数和。

以了解其价值:

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

它还将允许您的“鼠标指针”挂在窗口的“边缘”上-例如,当鼠标指向最右下角的像素时,常规鼠标指针的尾部和箭头将位于框架和其后面的其他窗口上,而您不能仅通过绘制自己窗口的客户端区域来实现这一点

--


话虽如此,我不确定在这里“假装”鼠标位置是正确的做法,尽管这很可能会让你站起来跑步。另一种方法是让鼠标正常运行,但对于需要更高分辨率的应用程序,可以使用另一个API来公开更精确的值。除了常用的鼠标/键盘消息和API之外,windows还有各种技术和API(例如)用于获取输入信息、定义额外的输入设备,我认为还可以将额外的信息与消息关联起来,其中一种技术在这里可能更合适。重新问你的问题可能是值得的,但要把重点放在更高层次上,而不是光标绘制上。

奇怪的是,为什么你要尝试模拟光标,而不是让Windows为你绘制光标?我正在开发一个实验应用程序,我使用的是高清鼠标。我想将鼠标设置为高报告dpi,比如5000,但屏幕上的响应与400 dpi的普通鼠标相同。有趣的是,我添加了一个可能值得考虑的替代方法。重新绘制整个客户端区域可能效率低下;最好在每次绘制光标矩形时记住它,并在鼠标移动时使新旧矩形无效。在生成WM_画图之前,还可以获取多条WM_MOUSEMOVE消息,因此为了响应,您可能还需要在其中添加一个UpdateWindow()。@JonathanPotter,谢谢,您的观点都是正确的。我已经编辑了我的答案。DrawIcon与将光标移动到设备上下文缓冲区并使用BitBlt绘制到屏幕之间有什么区别?@dave,我不能说微软的DrawIconEx,但是
DrawIconEx
的Wine实现在内部使用了
StretchBlt
:我目前使用的正是原始输入。原始输入报告的鼠标移动与设备驱动程序看到的完全相同。但问题是,使用高分辨率鼠标时,屏幕上的光标将快速移动到边缘,几乎无法指向。因此,本质上我想在保持5000dpi物理空间分辨率的同时,对屏幕上光标的移动进行“下采样”(到普通400dpi鼠标的移动)。另一个选项是编写鼠标驱动程序进行下采样。更容易的事情似乎是在应用程序中以较低的分辨率模拟光标。关于快速指针问题-然后在鼠标控制面板中更改指针速度如何,它会变得足够慢吗?这样你就有了可用的指针速度(Windows下采样),但仍然可以通过应用程序的原始输入获得高分辨率的采样。这很有效。我以前确实尝试过这个选项,但上次没有成功——问题是在特定于鼠标的驱动程序(即logitech)中设置速度选项。事实证明,您需要使用windows本机驱动程序为原始输入设置鼠标速度,以接收未过滤的输入。