【问题标题】:How to simulate mouse cursor movement in C++如何在 C++ 中模拟鼠标光标移动
【发布时间】:2018-07-25 00:58:57
【问题描述】:

我正在利用业余时间创建一个程序,并尝试模拟鼠标光标的移动。

我正在努力做到这一点,以便当我启动我的程序时,它会将我的光标从 [x,y] 移动到 [0,0](这是我屏幕的左上角)。

在没有传送的情况下有没有办法做到这一点?

这是我目前的鼠标光标移动程序:

POINT p;
GetCursorPos( &p );
double mouseX = p.x;
double mouseY = p.y;
SetCursorPos(0, 0);

有什么方法可以实际看到我的鼠标被移动而不是立即传送到 [0,0]?

【问题讨论】:

    标签: c++ c winapi


    【解决方案1】:

    您需要一次一点一点地逐步移动鼠标。例如,考虑以下伪代码函数:

    def moveMouse (endX, endY, stepCount, stepDelay):
        GetCurrentPosTo(startX, startY);
        for step = 1 to stepCount
            currX = startX + (endX - startX) * step / stepCount
            currY = startY + (endY - startY) * step / stepCount
            SetCurrentPosFrom(currX, currY)
            DelayFor(stepDelay)
        endfor
    enddef
    

    这会将当前位置(在循环内)计算为从(startX, startY)(endX, endY) 的旅程的一部分,并根据您希望采取的步数进行调整。

    因此,使用 100 的 stepCount 和 10 毫秒的 stepDelay,鼠标光标将在一秒钟内平滑移动。

    可能有其他种可能性,例如以特定速度移动光标而不是花费特定时间,或者指定最小速度和最大时间以结合两种方法.

    我将把它作为一个额外的练习。可以说它会涉及到 same 方法,每次移动一点光标,而不是立即将其位置设置为最终值。

    【讨论】:

    • 你先生是天才哈哈。现在我想弄清楚如何让它螺旋上升到一个点。我调整了你的代码,将鼠标拉回屏幕中心......非常顺利;)现在一些螺旋
    【解决方案2】:

    这是我从网络上收集的小混合物!

    它以Archimedean spiral 从屏幕中心向外旋转鼠标,并且相当流畅。你也可以在循环中弄乱数学,特别是 `cos()` 和 `sin()` 函数来让它做不同的动作。仅用于教育目的。

    享受:)

    #include <Windows.h>
    #include <iostream>
    
    void moveMouse(int x, int y){
    
        int count = 800;
        int movex, movey;
        float angle = 0.0f;
    
        // set mouse at center screen
        SetCursorPos(x/2, y/2); 
    
        // begin spiral! :)
        for(int i = 0; i <= count; i++){
            angle = .3 * i;
            movex = (angle * cos(angle) * 2) + x/2;
            movey = (angle * sin(angle) * 2) + y/2;
            SetCursorPos(movex, movey);
            Sleep(1);
        }
    
    }
    
    int main(){
        int Height = GetSystemMetrics(SM_CYSCREEN);
        int Width = GetSystemMetrics(SM_CXSCREEN);
        moveMouse(Width,Height);
        return 0;
    }
    

    【讨论】:

      【解决方案3】:

      您将不得不多次调用 SetCursorPos,坐标首先接近您的点,然后逐渐接近 (0,0)。如果没有一些故意的延迟,无论如何它似乎会立即发生,所以请记住这一点。

      【讨论】:

        【解决方案4】:

        试试我用来调试输入的这段代码。我把它放在每帧运行的地方。获取鼠标位置,设置鼠标位置。您的鼠标不应该移动,否则数学错误..

        {
            POINT       pos;
            GetCursorPos(&pos);
        
            INPUT input[1];
            memset(&input, 0, sizeof(input));
        
            int left    = GetSystemMetrics(SM_XVIRTUALSCREEN);
            int top     = GetSystemMetrics(SM_YVIRTUALSCREEN);
            int width   = GetSystemMetrics(SM_CXVIRTUALSCREEN);
            int heigth  = GetSystemMetrics(SM_CYVIRTUALSCREEN);
        
            // 0x1000 because 0 to 0xffff is not 65535, its 65536.
            // we add 0.5f to the location to put us in the center of the pixel. to avoid rounding errors.  Take it out and your mouse will move up and to the left.
            POINT Desired;
            Desired.x = ((float)(pos.x - left ) + 0.5f) * (float) (0x10000) / (float) (width);
            Desired.y = ((float)(pos.y - top) + 0.5f) * (float) (0x10000) / (float) (heigth);
        
            // move to new location
            input[0].type           = INPUT_MOUSE;
            input[0].mi.dx          = Desired.x;
            input[0].mi.dy          = Desired.y;
            input[0].mi.mouseData   = 0;
            input[0].mi.dwFlags     = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE_NOCOALESCE | MOUSEEVENTF_MOVE | MOUSEEVENTF_VIRTUALDESK;
            input[0].mi.time        = 0;
        
            SendInput(1, &input[0], sizeof(INPUT));
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-12-24
          • 2011-11-21
          • 1970-01-01
          相关资源
          最近更新 更多