Winapi 在win32中绘制鼠标光标
GDI的新手 我试图在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
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本机驱动程序为原始输入设置鼠标速度,以接收未过滤的输入。