新手到GDI。
我正在尝试在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);
我确实看到了光标但是当我移动光标时它不会擦除图像,留下一条长尾巴。
答案 0 :(得分:5)
不要在WM_MOUSEMOVE
中画画,这就是WM_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
。
答案 1 :(得分:3)
为了它的价值:
另一种可能值得关注的方法是使用您根据需要移动的WS_EX_TOPMOST | WS_EX_LAYERED窗口,让Windows为您处理绘图/透明度。这样做的好处是它不会干扰绘图主窗口,即使主窗口有子控件或类似窗口,它也能正常工作。
它还允许你的“鼠标指针”“悬挂在窗口的边缘” - 例如。当鼠标定位到指向极右下方的像素时,常规鼠标指针的尾部和箭头将位于框架及其后面的其他窗口上,而您只能通过绘制自己窗口的客户区域来实现此目的
-
话虽如此,我不确定'伪造'鼠标位置是正确的做法,尽管它可能会让你起作用。另一种方法是让鼠标正常运行,但对于需要更高分辨率的应用程序,请使用另一个API来公开更精确的值。除了通常的鼠标/键盘消息和API,Windows还有各种技术和API(例如Raw Input)用于获取输入信息,定义其他输入设备,我认为还将其他信息与消息相关联,其中一个这里的技术可能更合适。重新提出问题可能是值得的,但要关注更高级别的问题,而不是光标图。