Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/128.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在Windows中从鼠标挂钩设置光标位置?_C++_Windows_Winapi_Mouse Hook - Fatal编程技术网

C++ 如何在Windows中从鼠标挂钩设置光标位置?

C++ 如何在Windows中从鼠标挂钩设置光标位置?,c++,windows,winapi,mouse-hook,C++,Windows,Winapi,Mouse Hook,我正在尝试创建一个小应用程序,它将检测鼠标光标何时移动到屏幕边缘,并将其移动到相对的边缘,以创建一个连续的桌面效果,如果这样做有意义的话 下面是其他人(鼠标挂钩部分)的一些代码,我添加了SetCursorPos,现在可以将鼠标移动到固定位置。当我运行它时,SetCursorPos返回true,我认为这意味着调用成功,但鼠标不移动。我在某个地方读到过一些关于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;
}
#定义_WIN32_WINNT 0x0400
#pragma注释(lib,“user32.lib”)
#包括
#包括
HHOOK-hMouseHook;
__declspec(dllexport)LRESULT回调键盘事件(int-nCode、WPARAM-WPARAM、LPARAM-LPARAM)
{
MOUSEHOOKSTRUCT*pmousestuct=(MOUSEHOOKSTRUCT*)lParam;
if(pmousestuct!=NULL)
{
如果(pmousestuct->pt.x<-1900)
{
BOOL r=SetCursorPos(
500,
500
);
printf(“触发器%d.响应%d”,pmousestuct->pt.x,r);
}
}
返回CallNextHookEx(hMouseHook、nCode、wParam、lParam);
}
void MessageLoop()
{
消息;
while(GetMessage(&message,NULL,0,0)){
翻译消息(和消息);
DispatchMessage(&message);
}
}
DWORD WINAPI MyMouseLogger(LPVOID lpParm)
{
HINSTANCE HINSTANCE=GetModuleHandle(NULL);
如果(!hInstance)hInstance=LoadLibrary((LPCSTR)lpParm);
如果(!hInstance)返回1;
hMouseHook=SetWindowsHookEx(
你会怎么做,
(HOOKPROC)键盘事件,
hInstance,
无效的
);
MessageLoop();
解钩钩钩(hMouseHook);
返回0;
}
int main(int argc,字符**argv)
{
处理hThread;
德沃德·德沃德;
hThread=CreateThread(NULL,NULL,(LPTHREAD\u START\u例程)
MyMouseLogger,(LPVOID)argv[0],NULL,&dwThread);
if(hThread)
返回WaitForSingleObject(hThread,无限);
否则返回1;
}

看起来您需要转换坐标。 根据文档,您需要调用或
ScreenToClient
来翻译要点。我不知道哪个窗口是参考。您需要将窗口句柄作为点(作为out参数)作为参数传递。然后将更改后的点与
SetCursorPos

检查


如果需要屏幕,则需要执行
GetDC(NULL)
,并将返回的句柄传递给
ClientToScreen

,这似乎是在钩子过程中调用SetCursorPos的问题。我想这在Vista/Windows7中是明确禁止的,但我找不到任何文档来证实这一点。我稍微修改了您的代码,以便在需要移动光标时发布一条线程消息,并在消息过程中执行实际的SetCursorPos。一旦这样做了,它就可以正常工作了

在钩子程序中:

if (pMouseStruct->pt.x < -1900)
    {
        PostThreadMessage( GetCurrentThreadId(), WM_USER, 0, 0 );
        printf("Trigger %d.  Response %d", pMouseStruct->pt.x, r);
    }
(请注意,这只是一个演示,不是实际的修复。)


尽管如此,您的代码仍然存在许多严重的问题。我不认为在这里讨论所有这些内容都是合适的,但我建议您将其发布。

您的printfs是否有任何输出?您也可以尝试使用大于-1900的东西进行测试。@drescherjm它是-1900,因为我的左手显示器左侧大约有20个像素。我的printf吐出了下面的“Trigger-1917.Response 1”,等等。我认为“Response 1”表示调用没有失败,但鼠标没有移动。这可能与单独的线程有关吗?如果我在程序开始时(挂接之前)执行SetCursorPos调用,则调用成功。您的KeyboardEvent函数不是100%正确。当nCode<0时,您需要立即返回CallNextHookEx。也许这不是SetCursorPos失败的原因,但钩子函数必须根据文档工作。许多事情在异步执行时开始工作。我会尝试将用户定义的消息从KeyboardEvent发布到主应用程序线程,并在那里执行SetCursorPos。对不起,我不确定我是否理解。你指的是哪些文件?为什么我需要一扇窗户?我只是希望这是一个简单的应用程序,监测全球鼠标位置。事件方法正确接收屏幕坐标中的鼠标位置。SetCursorPos需要屏幕坐标。为什么我需要翻译?谢谢Peter,试过了,效果很好。我知道这段代码很糟糕,它本来是一个很糟糕的原型,我想稍后再做,但无法弄清楚什么SetCursorPos不起作用。再次感谢你,史蒂夫。PS不知道codereview,肯定有用!
while (GetMessage(&message,NULL,0,0)) {
    if( message.hwnd == NULL ) {
        if( message.message == WM_USER ) {
            SetWindowPos( 500, 500 );
        }
     } else {
         TranslateMessage( &message );
         DispatchMessage( &message );
     }
}