我想知道如何通过Windows获得真正的鼠标位移。
例如,我可以保存前一个鼠标位置的位置,并请求新位置,并从前一个位置减去后一个位置。但这不会给我真正的鼠标移位。
想象一下,前一个光标位置是屏幕分辨率的最大x坐标,用户将鼠标移到右侧。还有办法捕获真正的鼠标移位吗?
由于
答案 0 :(得分:2)
尽管可能实际读取传感器数据(在所有鼠标本身仅报告移动而不是位置之后),我不知道如何做到这一点。我认为在非常低级别的窗口中,位移信息会转换为屏幕上的光标位置,从那时起,您将始终受到屏幕分辨率的限制。
无论你想做什么,鼠标光标是否仍然可见?
不久前,我编写了一个WPF数字编辑框控件,模仿了这些控件在Expression Blend中的工作方式。您可以从编辑框本身拖动鼠标,它将更改值。我遇到了与您发现的完全相同的问题,我的解决方案是隐藏鼠标光标,检测每个刻度上的位移并将光标重置到屏幕中心。然后,当用户放开按钮停止拖动时,我会将光标放回到拖动前我找到的位置。这非常好,Expression Blend在隐藏光标时也表现得这样。
答案 1 :(得分:1)
据我所知,DirectX有自己的API与外围设备进行交互,建议游戏开发人员使用。您应该调查一下 - 例如DirectX 8 and the Mouse,您可以找到更详细的文档on MSDN。
答案 2 :(得分:0)
这种位移? :http://en.wikipedia.org/wiki/Differential_calculus
尝试俯仰/偏航:How could simply calling Pitch() and Yaw() cause the camera to eventually Roll()?
FPS风格:http://cboard.cprogramming.com/game-programming/94944-mouse-input-aiming-fps-style-using-glut.html
并且:Jittering when moving mouse
伪代码:
int mouseX, mouseY;
int oldMouseX, oldMouseY;
while(game_is_Running)
{
oldMouseX = mouseX;
oldMouseY = mouseY;
mouseX = get_new_mouse_from_windows_X();
mouseY = get_new_mouse_from_windows_Y();
if ((mouseX - oldMouseX) > 0)
{
// mouse moved to the right
}
else if ((mouseX - oldMouseX) < 0)
{
// mouse moved to the left
}
if ((mouseY - oldMouseY) < 0)
{
// mouse moved down
}
else if ((mouseY - oldMouseY) > 0)
{
// mouse moved up
}
}
答案 3 :(得分:0)
这种常见方法(在游戏中):
游戏的每一帧,获取鼠标的位置,然后使用操作系统功能将鼠标重新放在窗口中间。对于除第一帧以外的每个帧,这应该为您提供准确的位移信息。关键是每帧重新定位鼠标,使其永远不会到达屏幕的阻挡外边界。
编辑:Woops,没有意识到DXM已经说过这个。答案 4 :(得分:0)
最可靠的方法是使用窗口挂钩。这是一个使用C(++)
的极简主义样本LRESULT CALLBACK LowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lParam){
MSLLHOOKSTRUCT* hookStruct = (MSLLHOOKSTRUCT*)lParam;
int ScreenWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);
int ScreenHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
int x = hookStruct->pt.x * ScreenWidth / 65536);
int y = hookStruct->pt.y * ScreenHeight / 65536);
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
HHOOK LowLevelMouseProcHook = NULL;
void hook_window_procedure()
{
if (LowLevelMouseProcHook == NULL)
LowLevelMouseProcHook = SetWindowsHookEx(WH_MOUSE_LL, (HOOKPROC)LowLevelMouseProc, (HINSTANCE)NULL, NULL);
}
void unhook_window_procedure()
{
if (LowLevelMouseProcHook != NULL)
UnhookWindowsHookEx(LowLevelMouseProcHook);
}
你可以勾住调用hook_window_procedure();
的鼠标,并通过调用unhook_window_procedure();
取消挂钩
只要鼠标移动,您就会收到void LowLevelMouseProc(...)
的来电。 lParam
包含指向MSLLHOOKSTRUCT
的指针,您可以在其结构中找到所有需要的鼠标信息。这里最有趣的是POINT pt;
,它在相对屏幕坐标中,假设屏幕的1/65536。通过乘以int ScreenWidth
或int ScreenHeight
并除以65536
如果您难以被屏幕边框夹住,可以在每次调用时将鼠标设置回窗口中心。这在老游戏中经常出现。如果您不想仅使用Windows API,我会尝试使用直接输入。
另一种方法是直接在WindowProc中评估WM_INPUT
。这直接从人机接口设备(HID)堆栈读取数据,并且其中应包含原始鼠标数据。以下是MS-Documentation
答案 5 :(得分:-1)
使用Windows API无法跟踪物理鼠标位移。但是,DirectInput提供了跟踪它的功能。你也可以使用Windows API来“伪造”它,使用SO用户DXM答案中的巧妙小技巧