如何在Windows中从鼠标挂钩设置光标位置?
How can I set cursor position from mouse hook in Windows?
我正在尝试创建一个小应用程序,它将检测当鼠标光标移动到屏幕的边缘,并将其移动到相反的边缘,以创建一个连续的桌面效果,如果这是有意义的。
下面是其他人的一些代码(鼠标钩子部分),我通过添加SetCursorPos来将鼠标移动到一个固定的位置。当我运行它时,SetCursorPos返回true,我假设这意味着调用成功了,但是鼠标没有移动。我在某个地方读到一些关于后来的Windows版本的安全约束阻止了类似的事情,这是有道理的,但来源不清楚这是多么真实。有人知道为什么这行不通吗?
谢谢,代码如下:
#define _WIN32_WINNT 0x0400
#pragma comment( lib, "user32.lib" )
#include <windows.h>
#include <stdio.h>
HHOOK hMouseHook;
__declspec(dllexport) LRESULT CALLBACK KeyboardEvent (int nCode, WPARAM wParam, LPARAM lParam)
{
MOUSEHOOKSTRUCT * pMouseStruct = (MOUSEHOOKSTRUCT *)lParam;
if (pMouseStruct != NULL)
{
if (pMouseStruct->pt.x < -1900)
{
BOOL r = SetCursorPos(
500,
500
);
printf("Trigger %d. Response %d", pMouseStruct->pt.x, r);
}
}
return CallNextHookEx(hMouseHook, nCode, wParam, lParam);
}
void MessageLoop()
{
MSG message;
while (GetMessage(&message,NULL,0,0)) {
TranslateMessage( &message );
DispatchMessage( &message );
}
}
DWORD WINAPI MyMouseLogger(LPVOID lpParm)
{
HINSTANCE hInstance = GetModuleHandle(NULL);
if (!hInstance) hInstance = LoadLibrary((LPCSTR) lpParm);
if (!hInstance) return 1;
hMouseHook = SetWindowsHookEx (
WH_MOUSE_LL,
(HOOKPROC) KeyboardEvent,
hInstance,
NULL
);
MessageLoop();
UnhookWindowsHookEx(hMouseHook);
return 0;
}
int main(int argc, char** argv)
{
HANDLE hThread;
DWORD dwThread;
hThread = CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)
MyMouseLogger, (LPVOID) argv[0], NULL, &dwThread);
if (hThread)
return WaitForSingleObject(hThread,INFINITE);
else return 1;
}
这似乎是在钩子子程中调用SetCursorPos的问题。我猜这在Vista/Windows 7中是明确禁止的,但我找不到任何文档来证实这一点。我稍微修改了代码,以便在想要移动光标时发布线程消息,并在消息过程中执行实际的SetCursorPos。一旦完成,它就可以正常工作了。
钩子子程:
if (pMouseStruct->pt.x < -1900)
{
PostThreadMessage( GetCurrentThreadId(), WM_USER, 0, 0 );
printf("Trigger %d. Response %d", pMouseStruct->pt.x, r);
}
在你的消息循环中:
while (GetMessage(&message,NULL,0,0)) {
if( message.hwnd == NULL ) {
if( message.message == WM_USER ) {
SetWindowPos( 500, 500 );
}
} else {
TranslateMessage( &message );
DispatchMessage( &message );
}
}
(注意这只是一个演示,不是一个实际的修复。)
也就是说,您的代码存在许多严重的问题。我认为不适合在这里一一介绍,但我建议你把它发布在https://codereview.stackexchange.com/.
看起来您需要转换坐标。根据文档,您需要调用ClientToScreen
或ScreenToClient
来翻译点。我不知道哪个窗口是参考。您需要将该窗口句柄作为点(作为输出参数)作为参数传递。然后用SetCursorPos
检查示例
如果您想要屏幕您需要执行GetDC(NULL)
并将返回的句柄传递给ClientToScreen
相关文章:
- C++ - 重置字符串流不会重置获取位置或清除标志吗?
- 如何在QML中设置鼠标光标位置
- 当光标位置在编辑控件 MFC 中更改时是否有通知代码?
- 将光标位置存储在类对象中(ncurses c++)
- 在系统设置光标位置之前获取和设置光标位置?
- 在重新居中之前获取游戏中的光标位置
- 尝试在自定义 QT 创建器文本编辑器中创建查找和替换循环.我似乎无法设置光标位置
- 如何在应用程序窗口中设置光标位置?(C )
- 如何在Qwidget上获取当前的鼠标光标位置
- 如何在 c++ 控制台应用程序中控制光标位置
- 如何使用 Gtkmm 获取光标位置
- C++如何获取当前光标位置
- SFML 碰撞检测,C++ -> 重置玩家位置
- 在Embarcadero Tools API中的光标位置插入文本
- 光标位置 在控制台上需要有关此代码的帮助
- 在记事本++插件中获取当前光标位置
- 在Qt中如何处理相对于光标位置的光标形状
- 在linux终端中获取光标位置和终端大小
- 如何从最后一个光标位置读取文件
- 信号编辑文本已更改为可编辑的QComboBox设置光标位置在设置编辑文本之后的末尾