• C++模拟鼠标键盘操作


    1、简介

    通过C++可以模拟鼠标点击和键盘输入的操作,进而可以实现一些比较有趣的功能。

    2、GetAsyncKeyState

    GetAsyncKeyState函数适用于鼠标按钮。但是,它会检查物理鼠标按钮的状态,而不是物理按钮映射到的逻辑鼠标按钮。例如,调用GetAsyncKeyState (VK_LBUTTON) 始终返回物理鼠标左键的状态,无论它是映射到逻辑鼠标左键还是逻辑鼠标右键。

    • 确定在调用函数时某个键是向上还是向下,以及在上一次调用GetAsyncKeyState之后是否按下了该键。
    • 您可以使用虚拟键代码常量VK_SHIFT、VK_CONTROL和VK_MENU作为 vKey参数的值。这给出了 SHIFT、CTRL 或 ALT 键的状态,而不区分左右。

    2.1 函数声明

    • 函数声明如下:
    SHORT GetAsyncKeyState(
      [in] int vKey
    );
    
    • 1
    • 2
    • 3

    2.2 宏定义

    #define KEY_DOWN(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x8000) ? 1:0)
    
    • 1
    #define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
    #define KEYUP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)
    
    • 1
    • 2
    while(TRUE){
    		printf("鼠标左键是否按下:");
    		if(KEY_DOWN(VK_LBUTTON))printf("是");
    		else printf("否");
    		printf("\n");
    		
    		printf("鼠标右键是否按下:");
    		if(KEY_DOWN(VK_RBUTTON))printf("是");
    		else printf("否");
    		printf("\n");
    		
    		printf("鼠标滚轮键是否按下:");
    		if(KEY_DOWN(VK_MBUTTON))printf("是");
    		else printf("否");
    		printf("\n");
    		
    		Sleep(10);
    		system("cls");
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    2.3 代码示例

    while (GetMessage(&msg, nullptr, 0, 0))
    {
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    
        switch (msg.message)
        {
        case WM_KEYDOWN:
            if ((GetAsyncKeyState(VK_ESCAPE) & 0x01) && bRunning)
            {
                Stop();
            }
            break;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    3. GetKeyState

    检索指定虚拟键的状态。状态指定按键是向上、向下还是切换(开、关——每次按下键时交替)。

    • 一个虚拟钥匙。如果所需的虚拟键是字母或数字(A 到 Z、a 到 z 或 0 到 9), 则 nVirtKey必须设置为该字符的 ASCII 值。对于其他键,它必须是虚拟键码。

    • 返回值指定指定虚拟键的状态,如下:
      如果高位为1,则key为down;否则,它就起来了。
      如果低位为 1,则键被切换。某个键(例如 CAPS LOCK 键)在打开时会被切换。如果低位为 0,则该键处于关闭状态且未切换。切换键时键盘上的切换键指示灯(如果有)将亮起,当键未切换时将熄灭。

    • 应用程序调用GetKeyState以响应键盘输入消息。此函数在生成输入消息时检索键的状态。要检索所有虚拟键的状态信息,请使用GetKeyboardState函数。
      要检索单个键的状态信息,请使用GetKeyState函数。无论是否已从消息队列中检索到相应的键盘消息,要检索单个键的当前状态,请使用GetAsyncKeyState函数。

    注意:::GetKeyState()只能在键盘消息处理程序中使用,因为它只有在线程从消息队列中读取键盘消息时才会报告被查询键的状态,如果需要在键盘消息处理程序以外查询按键状态,则需要使用::GetAsyncKeyState()来代替。

    3.1 函数声明

    SHORT GetKeyState(
      [in] int nVirtKey
    );
    
    • 1
    • 2
    • 3

    3.2 宏定义

    #define KEY_ISPRESSED_CTRL   (0x8000 & GetKeyState(VK_CONTROL)) != 0
    #define KEY_ISPRESSED_SHIFT  (0x8000 & GetKeyState(VK_SHIFT)) != 0
    #define KEY_ISPRESSED_ALT    (0x8000 & GetKeyState(VK_MENU)) != 0
    #define KEY_ISPRESSED(Key)   (GetKeyState(Key) & 0x8000) != 0
    
    • 1
    • 2
    • 3
    • 4
    • 判断按键是否被按下
    #define  IsKeyPressed(nVirtKey)   ((GetKeyState(nVirtKey) & (1<<(sizeof(SHORT)*8-1))) != 0)
    
    • 1
    • 判断按键切换状态(指示灯状态)
    #define IsKeyToggled(nVirtKey)  ((GetKeyState(nVirtKey) & 1) != 0)
    
    • 1

    4、mouse_event

    mouse_event函数合成鼠标运动和按钮点击。

    ::GetCursorPos,获取当前鼠标的位置;
    ::SetCursorPos,移动鼠标到某一位置;
    mouse_event,鼠标动作,单击等。
    mouse_even只能够发送前台消息,即仅对当前激活的窗体有效。它最好配合SetCursorPos(x,y)函数一起使用。

    4.1 函数声明

    void mouse_event(
      [in] DWORD     dwFlags,
      [in] DWORD     dx,
      [in] DWORD     dy,
      [in] DWORD     dwData,
      [in] ULONG_PTR dwExtraInfo
    );
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    4.2 代码示例

    POINT lpPoint;
    GetCursorPos(&lpPoint);
    SetCursorPos(lpPoint.x, lpPoint.y);
    mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
    mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    ::SetCursorPos(10,10);
    mouse_event(MOUSEEVENTF_LEFTDOWN|MOUSEEVENTF_LEFTUP,0,0,0,0);是在当前位置单击一次
    
    • 1
    • 2
    class MOUSE
    {
    private:
        //坐标变量
        POINT point;
    public:
        //移动类函数
        void    Move(int x,int y);
        void    RelativeMove(int cx,int cy);
        void    SavePos();
        void    RestorePos();
        //锁定启用类
        void    Lock();
        void    Unlock();
        //动作类
        void    LBClick();
        void    LBDbClick();
        void    LBDown();
        void    LBUp();
        void    RBClick();
        void    RBDbClick();
        void    RBDown();
        void    RBUp();
        void    MBClick();
        void    MBDbClick();
        void    MBDown();
        void    MBUp();
        void    MBRoll(int ch);
    };
    
    //移动鼠标到绝对位置(X坐标,Y坐标)
    void MOUSE::Move(int x,int y)
    {
        this->point.x=x;
        this->point.y=y;
        ::SetCursorPos(x,y);
    }
    
    //移动鼠标到相对位置(X位移,Y位移)
    void MOUSE::RelativeMove(int cx,int cy)
    {
        ::GetCursorPos(&this->point);
        this->point.x+=cx;
        this->point.y+=cy;
        ::SetCursorPos(this->point.x,this->point.y);
    }
    
    //保存当前位置()
    void MOUSE::SavePos()
    {
        ::GetCursorPos(&this->point);
    }
    
    //恢复鼠标位置()
    void MOUSE::RestorePos()
    {
        ::SetCursorPos(this->point.x,this->point.y);
    }
    
    //锁定鼠标()
    void MOUSE::Lock()
    {
        POINT    pt;
        RECT    rt;
    
        ::GetCursorPos(&pt);
        rt.left=rt.right=pt.x;
        rt.top=rt.bottom=pt.y;
        rt.right++;
        rt.bottom++;
        ::ClipCursor(&rt);
    }
    
    //解锁鼠标()
    void MOUSE::Unlock()
    {
        ::ClipCursor(NULL);
    }
    
    //左键单击()
    void MOUSE::LBClick()
    {
        this->SavePos();
        ::mouse_event(MOUSEEVENTF_LEFTDOWN|MOUSEEVENTF_LEFTUP,this->point.x,this->point.y,0,0);
    }
    
    //左键双击()
    void MOUSE::LBDbClick()
    {
        this->SavePos();
        ::mouse_event(MOUSEEVENTF_LEFTDOWN|MOUSEEVENTF_LEFTUP,this->point.x,this->point.y,0,0);
        ::mouse_event(MOUSEEVENTF_LEFTDOWN|MOUSEEVENTF_LEFTUP,this->point.x,this->point.y,0,0);
    }
    
    //左键按下()
    void MOUSE::LBDown()
    {
        this->SavePos();
        ::mouse_event(MOUSEEVENTF_LEFTDOWN,this->point.x,this->point.y,0,0);
    }
    
    //左键抬起()
    void MOUSE::LBUp()
    {
        this->SavePos();
        ::mouse_event(MOUSEEVENTF_LEFTUP,this->point.x,this->point.y,0,0);
    }
    
    //右键单击()
    void MOUSE::RBClick()
    {
        this->SavePos();
        ::mouse_event(MOUSEEVENTF_RIGHTDOWN|MOUSEEVENTF_RIGHTUP,this->point.x,this->point.y,0,0);
    }
    
    //右键双击()
    void MOUSE::RBDbClick()
    {
        this->SavePos();
        ::mouse_event(MOUSEEVENTF_RIGHTDOWN|MOUSEEVENTF_RIGHTUP,this->point.x,this->point.y,0,0);
        ::mouse_event(MOUSEEVENTF_RIGHTDOWN|MOUSEEVENTF_RIGHTUP,this->point.x,this->point.y,0,0);
    }
    
    //右键按下()
    void MOUSE::RBDown()
    {
        this->SavePos();
        ::mouse_event(MOUSEEVENTF_RIGHTDOWN,this->point.x,this->point.y,0,0);
    }
    
    //右键抬起()
    void MOUSE::RBUp()
    {
        this->SavePos();
        ::mouse_event(MOUSEEVENTF_RIGHTUP,this->point.x,this->point.y,0,0);
    }
    
    //中键单击()
    void MOUSE::MBClick()
    {
        this->SavePos();
        ::mouse_event(MOUSEEVENTF_MIDDLEDOWN|MOUSEEVENTF_MIDDLEUP,this->point.x,this->point.y,0,0);
    }
    
    //中键双击()
    void MOUSE::MBDbClick()
    {
        this->SavePos();
        ::mouse_event(MOUSEEVENTF_MIDDLEDOWN|MOUSEEVENTF_MIDDLEUP,this->point.x,this->point.y,0,0);
        ::mouse_event(MOUSEEVENTF_MIDDLEDOWN|MOUSEEVENTF_MIDDLEUP,this->point.x,this->point.y,0,0);
    }
    
    //中键按下()
    void MOUSE::MBDown()
    {
        this->SavePos();
        ::mouse_event(MOUSEEVENTF_MIDDLEDOWN,this->point.x,this->point.y,0,0);
    }
    
    //中键抬起()
    void MOUSE::MBUp()
    {
        this->SavePos();
        ::mouse_event(MOUSEEVENTF_MIDDLEUP,this->point.x,this->point.y,0,0);
    }
    
    //中键滚动(滚动位移)
    void MOUSE::MBRoll(int ch)
    {
        this->SavePos();
        ::mouse_event(MOUSEEVENTF_WHEEL,this->point.x,this->point.y,ch,0);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173

    5、keybd_event

    合成击键。系统可以使用这样的合成击键来生成WM_KEYUP或WM_KEYDOWN消息。键盘驱动程序的中断处理程序调用keybd_event函数。

    注意:此功能已被取代。请改用SendInput。

    应用程序可以模拟按下 PRINTSCRN 键以获得屏幕快照并将其保存到剪贴板。为此,调用keybd_event并将 bVk参数设置为VK_SNAPSHOT。

    5.1 函数声明

    void keybd_event(
      [in] BYTE      bVk,
      [in] BYTE      bScan,
      [in] DWORD     dwFlags,
      [in] ULONG_PTR dwExtraInfo
    );
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    5.2 代码示例

    以下示例程序通过使用带有VK_NUMLOCK虚拟键的keybd_event来切换 NUM LOCK 灯。它采用一个布尔值,指示灯应该关闭 ( FALSE ) 还是打开 ( TRUE )。相同的技术可用于 CAPS LOCK 键 ( VK_CAPITAL ) 和 SCROLL LOCK 键 ( VK_SCROLL )。

    #include 
    
       void SetNumLock( BOOL bState )
       {
          BYTE keyState[256];
    
          GetKeyboardState((LPBYTE)&keyState);
          if( (bState && !(keyState[VK_NUMLOCK] & 1)) ||
              (!bState && (keyState[VK_NUMLOCK] & 1)) )
          {
          // Simulate a key press
             keybd_event( VK_NUMLOCK,
                          0x45,
                          KEYEVENTF_EXTENDEDKEY | 0,
                          0 );
    
          // Simulate a key release
             keybd_event( VK_NUMLOCK,
                          0x45,
                          KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP,
                          0);
          }
       }
    
       void main()
       {
          SetNumLock( TRUE );
       }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    class KEYBOARD
    {
    public:
        void    PressStr(char *str);
        void    PressKey(BYTE bVk);
        void    KeyDown(BYTE bVk);
        void    KeyUp(BYTE bVk);
    };
    
    //按键(虚拟键值)
    void KEYBOARD::PressKey(BYTE bVk)
    {
        ::keybd_event(bVk,0,0,0);
        ::keybd_event(bVk,0,KEYEVENTF_KEYUP,0);
    }
    
    //按下(虚拟键值)
    void KEYBOARD::KeyDown(BYTE bVk)
    {
        ::keybd_event(bVk,0,0,0);
    }
    
    //抬起(虚拟键值)
    void KEYBOARD::KeyUp(BYTE bVk)
    {
        ::keybd_event(bVk,0,KEYEVENTF_KEYUP,0);
    }
    
    //发送字符串(字符串)
    void KEYBOARD::PressStr(char *str)
    {
        for (unsigned i=0;i
        {
            if (str[i]>0x60 && str[i]<0x7B)
                this->PressKey(str[i]-0x20);
            else
                this->PressKey(str[i]);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    6、SendInput

    6.1 函数声明

    合成击键、鼠标动作和按钮点击。

    SendInput函数将 INPUT 结构中的事件串行插入到键盘或鼠标输入流中。这些事件不会与用户(使用键盘或鼠标)或通过调用keybd_event、mouse_event或对SendInput的其他调用插入的其他键盘或鼠标输入事件穿插。

    此功能不会重置键盘的当前状态。调用该函数时已按下的任何键都可能会干扰该函数生成的事件。为避免此问题,请使用GetAsyncKeyState函数检查键盘的状态并根据需要进行更正。

    UINT SendInput(
      [in] UINT    cInputs,
      [in] LPINPUT pInputs,
      [in] int     cbSize
    );
    
    • 1
    • 2
    • 3
    • 4
    • 5

    6.2 代码示例

    //**********************************************************************
    //
    // Sends Win + D to toggle to the desktop
    //
    //**********************************************************************
    void ShowDesktop()
    {
        OutputString(L"Sending 'Win-D'\r\n");
        INPUT inputs[4] = {};
        ZeroMemory(inputs, sizeof(inputs));
    
        inputs[0].type = INPUT_KEYBOARD;
        inputs[0].ki.wVk = VK_LWIN;
       
        inputs[1].type = INPUT_KEYBOARD;
        inputs[1].ki.wVk = VK_D;
    
        inputs[2].type = INPUT_KEYBOARD;
        inputs[2].ki.wVk = VK_D;
        inputs[2].ki.dwFlags = KEYEVENTF_KEYUP;
    
        inputs[3].type = INPUT_KEYBOARD;
        inputs[3].ki.wVk = VK_LWIN;
        inputs[3].ki.dwFlags = KEYEVENTF_KEYUP;
    
        UINT uSent = SendInput(ARRAYSIZE(inputs), inputs, sizeof(INPUT));
        if (uSent != ARRAYSIZE(inputs))
        {
            OutputString(L"SendInput failed: 0x%x\n", HRESULT_FROM_WIN32(GetLastError()));
        } 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    //鼠标移动到指定位置  
    void MouseMove(int x, int y)
    {  
        double fScreenWidth = ::GetSystemMetrics(SM_CXSCREEN) - 1;//获取屏幕分辨率宽度  
        double fScreenHeight = ::GetSystemMetrics(SM_CYSCREEN) - 1;//获取屏幕分辨率高度  
        double fx = x*(65535.0f / fScreenWidth);  
        double fy = y*(65535.0f / fScreenHeight);  
        INPUT  Input = { 0 };  
        Input.type = INPUT_MOUSE;  
        Input.mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE;  
        Input.mi.dx = fx;  
        Input.mi.dy = fy;  
        SendInput(1, &Input, sizeof(INPUT));  
    }  
    
    //鼠标左键按下  
    void MouseLeftDown()  
    {  
        INPUT  Input = { 0 };  
        Input.type = INPUT_MOUSE;  
        Input.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;  
        SendInput(1, &Input, sizeof(INPUT));  
    }  
    
    //鼠标左键放开  
    void MouseLeftUp()
    {  
        INPUT  Input = { 0 };  
        Input.type = INPUT_MOUSE;  
        Input.mi.dwFlags = MOUSEEVENTF_LEFTUP;  
        SendInput(1, &Input, sizeof(INPUT));  
          
    }  
    
    //鼠标右键按下
    void MouseRightDown()  
    {  
        INPUT  Input = { 0 };  
        Input.type = INPUT_MOUSE;  
        Input.mi.dwFlags = MOUSEEVENTF_RIGHTDOWN;  
        SendInput(1, &Input, sizeof(INPUT));  
    }  
    
    //鼠标右键放开    
    void MouseRightUp()
    {  
        INPUT  Input = { 0 };  
        Input.type = INPUT_MOUSE;  
        Input.mi.dwFlags = MOUSEEVENTF_RIGHTUP;  
        SendInput(1, &Input, sizeof(INPUT));  
    }  
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    7、SendMessage/PostMessage

    当用户在键盘上键入时,具有键盘焦点的窗口的窗口过程接收击键消息。击键消息是WM_KEYDOWN、WM_KEYUP、WM_SYSKEYDOWN和WM_SYSKEYUP。典型的窗口过程会忽略除WM_KEYDOWN之外的所有击键消息。当用户按下某个键时,系统会发布WM_KEYDOWN消息。

    当窗口过程收到WM_KEYDOWN消息时,它应该检查伴随消息的虚拟键代码以确定如何处理击键。虚拟键代码在消息的wParam参数中。通常,应用程序只处理由非字符键生成的击键,包括功能键、光标移动键和特殊用途键,如 INS、DEL、HOME 和 END。

    这种方法不需要窗体在前端,甚至最小化也可以使用,但是此方法并不是在所有场合有效,特别是对于不响应鼠标消息的程序更是如此。在这种情况下,可以尝试使用mouse_event函数。

    7.1 函数声明

    将指定的消息发送到一个或多个窗口。SendMessage函数调用指定窗口的窗口过程,并且在窗口过程处理完消息后才返回。

    要发送消息并立即返回,请使用SendMessageCallback或SendNotifyMessage函数。要将消息发布到线程的消息队列并立即返回,请使用PostMessage或PostThreadMessage函数。

    LRESULT SendMessage(
      [in] HWND   hWnd,
      [in] UINT   Msg,
      [in] WPARAM wParam,
      [in] LPARAM lParam
    );
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在与创建指定窗口的线程关联的消息队列中放置(发布)一条消息,并在不等待线程处理消息的情况下返回。要在与线程关联的消息队列中发布消息,请使用PostThreadMessage函数。

    BOOL PostMessageA(
      [in, optional] HWND   hWnd,
      [in]           UINT   Msg,
      [in]           WPARAM wParam,
      [in]           LPARAM lParam
    );
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    7.2 代码示例

    ::SetCursorPos(x,y);
    if(IsMineIn(x, y)==TRUE){
        /*::mouse_event(MOUSEEVENTF_RIGHTDOWN,x,y,0,0);
        ::mouse_event(MOUSEEVENTF_RIGHTUP,x,y,0,0);  */
        pWnd->SendMessage(WM_RBUTTONDOWN,0,(y<<16)|x);
        pWnd->SendMessage(WM_RBUTTONUP,0,(y<<16)|x);
    }else{
        /*::mouse_event(MOUSEEVENTF_LEFTDOWN,x,y,0,0);
        ::mouse_event(MOUSEEVENTF_LEFTUP,x,y,0,0);*/            
        pWnd->SendMessage(WM_LBUTTONDOWN,0,(y<<16)|x);
        pWnd->SendMessage(WM_LBUTTONUP,0,(y<<16)|x);
    }               
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    8、辅助工具

    8.1 spy++.exe

    https://docs.microsoft.com/zh-cn/visualstudio/debugger/introducing-spy-increment?view=vs-2022

    Spy++ 有两个版本。 第一个版本,名为 Spy++ (spyxx.exe),用于显示发送到在 32 位进程中运行的窗口的消息。 例如,在 32 位进程中运行的 Visual Studio。 因此,可以使用 Spy++ 来显示发送到“解决方案资源管理器” 中的消息。 由于 Visual Studio 中大多数生成的默认配置都是在 32 位进程中运行的,因此如果已安装所需组件,则第一个版本的 Spy++ 就是在 Visual Studio 中的“工具”菜单上可用的那一个。

    第二个版本,名为 Spy++(64 位)(spyxx_amd64.exe),用于显示发送到在 64 位进程中运行的窗口的消息。 例如,在 64 位操作系统上,记事本在 64 位进程中运行。 因此,可以使用 Spy++(64 位)来显示发送到记事本的消息。 Spy++ (64 位)通常位于…\Visual Studio 安装文件夹\Common7\Tools\spyxx_amd64.exe。
    在这里插入图片描述

    8.2 Inspect.exe

    https://docs.microsoft.com/zh-cn/windows/win32/winauto/inspect-objects
    检查 (Inspect.exe) 是基于Windows的工具,可用于选择任何 UI 元素并查看元素的辅助功能数据。 可以查看 Microsoft UI 自动化 属性和控制模式,以及 Microsoft Active Accessibility (MSAA) 属性。 通过检查,还可以测试UI 自动化树中自动化元素的导航结构,以及 Microsoft Active Accessibility 层次结构中的可访问对象。
    在这里插入图片描述

    结语

    如果您觉得该方法或代码有一点点用处,可以给作者点个赞,或打赏杯咖啡;╮( ̄▽ ̄)╭
    如果您感觉方法或代码不咋地//(ㄒoㄒ)//,就在评论处留言,作者继续改进;o_O???
    如果您需要相关功能的代码定制化开发,可以留言私信作者;(✿◡‿◡)
    感谢各位大佬童鞋们的支持!( ´ ▽´ )ノ ( ´ ▽´)っ!!!

  • 相关阅读:
    java计算机毕业设计考勤系统设计MyBatis+系统+LW文档+源码+调试部署
    并发编程——java中的锁
    open cv快速入门系列---数字图像基础
    vs2019使用问题记录
    两性养生网站源码 生活类减肥网站源码 健康网模板源码 支持QQ登录和百度主动推送
    手机网络连接性能API接口:查询手机网络连接性能状态
    提高 K8S 容器运行时的可观察性最佳方法之一
    Nuxt3 的生命周期和钩子函数(一)
    强烈推荐:2024 年12款 Visual Studio 亲测、好用、优秀的工具,AI插件等
    2021 CSP J2入门组 CSP-S2提高组 第2轮 视频与题解
  • 原文地址:https://blog.csdn.net/hhy321/article/details/126075812