【小沐学C++】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
);

2.2 宏定义

#define KEY_DOWN(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x8000) ? 1:0)
#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEYUP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)
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");
	}

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;
    }
}

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
);

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
  • 判断按键是否被按下
#define  IsKeyPressed(nVirtKey)   ((GetKeyState(nVirtKey) & (1<<(sizeof(SHORT)*8-1))) != 0)
  • 判断按键切换状态(指示灯状态)
#define IsKeyToggled(nVirtKey)  ((GetKeyState(nVirtKey) & 1) != 0)

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
);

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);
::SetCursorPos(10,10);
mouse_event(MOUSEEVENTF_LEFTDOWN|MOUSEEVENTF_LEFTUP,0,0,0,0);是在当前位置单击一次
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);
}

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
);

5.2 代码示例

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

#include <windows.h>

   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 );
   }
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]);
    }
}

6、SendInput

6.1 函数声明

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

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

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

UINT SendInput(
  [in] UINT    cInputs,
  [in] LPINPUT pInputs,
  [in] int     cbSize
);

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()));
    } 
}
//鼠标移动到指定位置  
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));  
}  

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
);

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

BOOL PostMessageA(
  [in, optional] HWND   hWnd,
  [in]           UINT   Msg,
  [in]           WPARAM wParam,
  [in]           LPARAM lParam
);

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);
}               

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 层次结构中的可访问对象。
在这里插入图片描述

8.3 键盘键值列表

/* Virtual Keys, Standard Set*/
VK_LBUTTON     0x01
VK_RBUTTON     0x02
VK_CANCEL      0x03
VK_MBUTTON     0x04

#define VK_LBUTTON        0x01    //鼠标左键
#define VK_RBUTTON        0x02    //鼠标右键
#define VK_CANCEL         0x03    //Ctrl + Break
#define VK_MBUTTON        0x04    //鼠标中键/* NOT contiguous with L & RBUTTON */
#define VK_BACK           0x08   //Backspace 键
#define VK_TAB            0x09   //Tab 键
#define VK_CLEAR          0x0C
#define VK_RETURN         0x0D   //回车键
#define VK_SHIFT          0x10
#define VK_CONTROL        0x11
#define VK_MENU           0x12   //Alt 键
#define VK_PAUSE          0x13
#define VK_CAPITAL        0x14   //Caps Lock 键
#define VK_KANA           0x15
#define VK_HANGEUL        0x15 /* old name - should be here for compatibility */
#define VK_HANGUL         0x15
#define VK_JUNJA          0x17
#define VK_FINAL          0x18
#define VK_HANJA          0x19
#define VK_KANJI          0x19
#define VK_ESCAPE         0x1B   //Esc 键
#define VK_CONVERT        0x1C
#define VK_NONCONVERT     0x1D
#define VK_ACCEPT         0x1E
#define VK_MODECHANGE     0x1F
#define VK_SPACE          0x20   //空格
#define VK_PRIOR          0x21   //Page Up 键
#define VK_NEXT           0x22   //Page Down 键
#define VK_END            0x23   //End 键
#define VK_HOME           0x24   //Home 键
#define VK_LEFT           0x25  /*方向键*/
#define VK_UP             0x26
#define VK_RIGHT          0x27
#define VK_DOWN           0x28
#define VK_SELECT         0x29
#define VK_PRINT          0x2A
#define VK_EXECUTE        0x2B
#define VK_SNAPSHOT       0x2C   //Print Screen 键
#define VK_INSERT         0x2D  //Insert键
#define VK_DELETE         0x2E  //Delete键
#define VK_HELP           0x2F
VK_0 thru VK_9 are the same as ASCII '0' thru '9' (0x30 - 0x39)
VK_A thru VK_Z are the same as ASCII 'A' thru 'Z' (0x41 - 0x5A) 
#define VK_LWIN           0x5B //左WinKey(104键盘才有)
#define VK_RWIN           0x5C //右WinKey(104键盘才有)
#define VK_APPS           0x5D //AppsKey(104键盘才有)
#define VK_NUMPAD0        0x60 //小键盘0-9
#define VK_NUMPAD1        0x61
#define VK_NUMPAD2        0x62
#define VK_NUMPAD3        0x63
#define VK_NUMPAD4        0x64
#define VK_NUMPAD5        0x65
#define VK_NUMPAD6        0x66
#define VK_NUMPAD7        0x67
#define VK_NUMPAD8        0x68
#define VK_NUMPAD9        0x69
#define VK_MULTIPLY       0x6A //乘
#define VK_ADD                0x6B //加
#define VK_SEPARATOR      0x6C //除
#define VK_SUBTRACT       0x6D //减
#define VK_DECIMAL        0x6E //小数点
#define VK_DIVIDE         0x6F

#define VK_F1             0x70 //功能键F1-F24
#define VK_F2             0x71
#define VK_F3             0x72
#define VK_F4             0x73
#define VK_F5             0x74
#define VK_F6             0x75
#define VK_F7             0x76
#define VK_F8             0x77
#define VK_F9             0x78
#define VK_F10            0x79
#define VK_F11            0x7A
#define VK_F12            0x7B
#define VK_F13            0x7C
#define VK_F14            0x7D
#define VK_F15            0x7E
#define VK_F16            0x7F
#define VK_F17            0x80
#define VK_F18            0x81
#define VK_F19            0x82
#define VK_F20            0x83
#define VK_F21            0x84
#define VK_F22            0x85
#define VK_F23            0x86
#define VK_F24            0x87

#define VK_NUMLOCK        0x90 //Num Lock 键
#define VK_SCROLL         0x91 //Scroll Lock 键
VK_L* & VK_R* - left and right Alt, Ctrl and Shift virtual keys.
Used only as parameters to GetAsyncKeyState() and GetKeyState().
No other API or message will distinguish left and right keys in this way.
#define VK_LSHIFT           0xA0
#define VK_RSHIFT          0xA1
#define VK_LCONTROL        0xA2
#define VK_RCONTROL        0xA3
#define VK_LMENU           0xA4
#define VK_RMENU           0xA5

#if(WINVER >= 0x0400)
#define VK_PROCESSKEY      0xE5
#endif /* WINVER >= 0x0400 */

#define VK_ATTN            0xF6
#define VK_CRSEL           0xF7
#define VK_EXSEL           0xF8
#define VK_EREOF           0xF9
#define VK_PLAY            0xFA
#define VK_ZOOM            0xFB
#define VK_NONAME          0xFC
#define VK_PA1             0xFD
#define VK_OEM_CLEAR       0xFE



“春生,夏长,秋收,冬藏,天之正也。”

结语

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

  • 20
    点赞
  • 84
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
模拟鼠标键盘操作脚本可以通过配合使用定时执行专家和VBS脚本来实现。定时执行专家是一个定时执行任务的工具,而VBS脚本可以实现监控鼠标操作状态和获取鼠标位置的功能。通过两者的配合,可以实现模拟鼠标键盘操作的功能。 具体实现方法如下: 1. 首先,下载并安装定时执行专家软件。 2. 然后,下载并安装VBS脚本。 3. 在VBS脚本中使用C++的GetAsynckeyState(VK_NAME)方法来监控鼠标操作状态,使用GetCursorPos(LPPOINT lp)来获取鼠标位置。 4. 编写录制鼠标键盘操作的脚本,并保存为一个文件。 5. 在定时执行专家软件中设置定时执行任务,并选择要执行的VBS脚本文件。 6. 设置任务的执行时间和频率,然后保存设置。 7. 当定时执行专家到达设定的执行时间时,它将自动运行VBS脚本,并模拟鼠标键盘操作。 通过以上步骤,你可以实现模拟鼠标键盘操作的脚本。请注意,具体的操作步骤可能会因为软件版本和设置的不同而有所差异,请根据实际情况进行操作。 #### 引用[.reference_title] - *1* *3* [自动定时执行键盘鼠标操作的工具软件(附完整VBS脚本) —— 定时执行专家](https://blog.csdn.net/boomworks/article/details/124958325)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [【C++】一个简单的模拟实现鼠标脚本精灵](https://blog.csdn.net/qq_42799236/article/details/107030999)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值