Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/23.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 10(C+;+;)中生成全局滚动事件并禁用鼠标移动?_C++_Windows_Winapi - Fatal编程技术网

C++ 如何在Windows 10(C+;+;)中生成全局滚动事件并禁用鼠标移动?

C++ 如何在Windows 10(C+;+;)中生成全局滚动事件并禁用鼠标移动?,c++,windows,winapi,C++,Windows,Winapi,我正在写一个程序来实现触摸板上的手性滚动。我有读取原始触摸板数据的代码,我对如何实现手势有一个粗略的想法。我的问题是如何实现滚动行为。以下是我的要求: 我的程序需要能够生成滚动事件,就像默认的触摸板手势或鼠标滚轮一样。这会影响任何正在运行的程序,就像真正的鼠标或触摸板滚动一样。最好,滚动也应该是平滑的(不是大刻度) 当滚动手势生效时,应禁用正常的鼠标移动。这一点很重要,因为它将确保正在滚动的UI元素在滚动期间不会更改 其他内置触摸板手势不应受到影响 我的选择是什么? 有什么图书馆可以提供帮助吗?

我正在写一个程序来实现触摸板上的手性滚动。我有读取原始触摸板数据的代码,我对如何实现手势有一个粗略的想法。我的问题是如何实现滚动行为。以下是我的要求:

  • 我的程序需要能够生成滚动事件,就像默认的触摸板手势或鼠标滚轮一样。这会影响任何正在运行的程序,就像真正的鼠标或触摸板滚动一样。最好,滚动也应该是平滑的(不是大刻度)
  • 当滚动手势生效时,应禁用正常的鼠标移动。这一点很重要,因为它将确保正在滚动的UI元素在滚动期间不会更改
  • 其他内置触摸板手势不应受到影响
  • 我的选择是什么?
    有什么图书馆可以提供帮助吗?
    这是否需要作为某种驱动程序来实现

    我已经考虑并研究了一些可能的解决方案,但似乎没有一个是完整的:

    • 可能存在某种编程虚拟鼠标库,如果是这样的话,我可以使用它来生成滚轮事件,但我还没有找到这样的库,我不确定它是否可以实现#2
    • 我已经读了一些关于Windows钩子的内容,但是看起来它只能修改现有的鼠标事件,而这在这里是不起作用的
    • 我也读过一些关于SentInput函数的文章,但听起来它也不能实现#2,我不确定它是否能影响所有其他程序
    我认为钩子可以满足您的需要

    这里是一个快速演示

    运行代码

  • 按“L”键=>安装鼠标挂钩(开始)
  • 按鼠标左键=>开始滚动
  • 按鼠标右键=>停止滚动
  • 按“P”键=>卸载鼠标挂钩(结束)
  • 安装挂钩后,鼠标无法移动。按下鼠标左键,鼠标将自动滚动。按鼠标右键停止滚动。按P键卸载挂钩后,一切将恢复正常

    当鼠标自动滚动时,我仍然可以手动滚动鼠标滚轮

    代码示例:(代码比较粗糙,仅供参考)

    #包括
    #包括
    #包括
    使用名称空间std;
    UINT滚动鼠标(int滚动);
    void SetHook();
    LRESULT uu stdcall MouseHookCallback(int、WPARAM、LPARAM);
    HHOOK鼠标套;
    布尔标志=0;
    void fun1()
    {
    而(1)
    {
    if(GetAsyncKeyState(0x50)&0x0001)
    {
    unhookwindowshookx(鼠标钩);
    }
    }
    }
    void fun2()
    {
    而(1)
    {
    国际单项体育联合会(旗)
    {
    滚动鼠标(50);
    睡眠(100);
    }
    }
    }
    int fun3()
    {
    而(1)
    {
    if(GetAsyncKeyState(0x4C)&0x0001)
    {
    SetHook();
    味精;
    while(GetMessage(&msg,NULL,0,0))
    {
    翻译信息(&msg);
    发送消息(&msg);
    }
    返回msg.wParam;
    }       
    }   
    }
    UINT滚动鼠标(int滚动)
    {
    输入;
    点位;
    GetCursorPos(&pos);
    input.type=输入\鼠标;
    input.mi.dwFlags=鼠标事件轮;
    input.mi.time=NULL;//Windows将执行时间戳
    input.mi.mouseData=(DWORD)scroll;//正值表示控制盘已向前旋转,远离用户;负值表示控制盘已向后旋转,朝向用户。一次控制盘单击定义为wheel_DELTA,即120。
    input.mi.dx=pos.x;
    input.mi.dy=pos.y;
    input.mi.dwExtraInfo=GetMessageExtraInfo();
    返回SendInput(1,&input,sizeof(input));
    }
    LRESULT uu stdcall MouseHookCallback(int-nCode、WPARAM-WPARAM、LPARAM-LPARAM)
    {
    如果(nCode>=0)
    {
    交换机(wParam)
    {
    案例WM_MOUSEMOVE:
    {           
    返回1;
    }
    案例WM_LBUTTONDOWN:
    {
    flag=1;
    }
    打破
    案例WM_RBUTTONDOWN:
    {
    flag=0;
    }
    打破
    }
    }
    返回CallNextHookEx(鼠标指针、nCode、wParam、lParam);
    }
    void SetHook()
    {
    if(!(MouseHook=SetWindowsHookEx(WH\u MOUSE\u LL,MouseHookCallback,NULL,0)))
    {
    
    cout这个问题需要更多关注。它目前包含多个问题。它应该只关注一个问题。(因为这是堆栈溢出,它应该是关于编程的。)这里只有一个真正的问题:如何用我所描述的行为来滚动。其他问题只是介绍一些我想的上下文。问这些问题中的任何一个都会出现XY问题。我问C++如何做这个问题,所以这是一个编程问题。正是我所需要的!比我担心我可能也需要做的要容易得多。
    #include <Windows.h>
    #include <iostream>
    #include <thread>
    
    using namespace std;
    
    UINT ScrollMouse(int scroll);
    void SetHook();
    LRESULT __stdcall MouseHookCallback(int, WPARAM, LPARAM);
    
    HHOOK MouseHook;
    BOOL flag = 0;
    
    void fun1()
    {
        while (1)
        {
            if (GetAsyncKeyState(0x50) & 0x0001)
            {
                UnhookWindowsHookEx(MouseHook);
            }
        }
    }
    
    void fun2()
    {
        while (1)
        {
            if (flag)
            {
                ScrollMouse(50);
                Sleep(100);
            }
        }
    }
    
    int fun3()
    {
        while (1)
        {
            if (GetAsyncKeyState(0x4C) & 0x0001)
            {
                SetHook();
                MSG msg;
    
                while(GetMessage(&msg, NULL, 0, 0))
                {
                    TranslateMessage(&msg);
                    DispatchMessage(&msg);
                }
                return msg.wParam;
            }       
        }   
    }
    
    UINT ScrollMouse(int scroll)
    {
        INPUT input;
        POINT pos;
        GetCursorPos(&pos);
    
        input.type = INPUT_MOUSE;
        input.mi.dwFlags = MOUSEEVENTF_WHEEL;
        input.mi.time = NULL; //Windows will do the timestamp
        input.mi.mouseData = (DWORD)scroll; //A positive value indicates that the wheel was rotated forward, away from the user; a negative value indicates that the wheel was rotated backward, toward the user. One wheel click is defined as WHEEL_DELTA, which is 120.
        input.mi.dx = pos.x;
        input.mi.dy = pos.y;
        input.mi.dwExtraInfo = GetMessageExtraInfo();
    
        return SendInput(1, &input, sizeof(INPUT));
    }
    
    LRESULT __stdcall MouseHookCallback(int nCode, WPARAM wParam, LPARAM lParam)
    {
        if (nCode >= 0)
        {
            switch (wParam)
            {
            case WM_MOUSEMOVE:
            {           
                return 1;         
            }
            case WM_LBUTTONDOWN:
            {
                flag = 1;            
            }
            break;
            case WM_RBUTTONDOWN:
            {
                flag = 0;
            }
            break;
            }
        }
        return CallNextHookEx(MouseHook, nCode, wParam, lParam);
    }
    
    void SetHook()
    {
        if (!(MouseHook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookCallback, NULL, 0)))
        {
            cout << "Failed to install MouseHook hook!" << endl;
        }
    }
    
    int main()
    {
        thread t1(fun1);
        thread t2(fun2);   
        thread t3(fun3);  
        t3.join();
    
        return 0;
    }