目的:

实现能自动在窗口中实现鼠标点击与键盘输入的操作(以QQ自动发送某些为例)

语言:

C/C++

实现原理:

一、窗口句柄(HWND)
【1】
每个程序窗口都有一个窗口句柄,在程序的一次运行中句柄是不会发生变化的(每当重新开启程序后句柄会发生改变),句柄的类型为HWND
【2】 我们可以用VS自带的Spy++工具获取窗口句柄,窗口类名,与标题
【2.1】 比如下图我们“记事本”的
窗口句柄是:00030B24
窗口类名是:Notepad
窗口标题是:新建文本文档.txt - 记事本

【2.2】 在窗口句柄下还有子窗口句柄,比如编辑框的句柄为:00060B0E ,类名为:Edit

【3】 ※在我们通过使用Spy++工具后能查到窗口的类名与标题。在代码编写中,通过例如 FindWindow 这样的函数可以查找并返回对应窗口的句柄值,并将其赋予窗口句柄(HWND)类型的变量中,在接下来的代码中引用。

【3.1】使用FindWindow函数查找窗口句柄

函数原型:HWND FindWindow(LPCSTR lpClassName,LPCSTR lpWindowName);
其中:lpClassName参数指向类名,lpWindowName指向窗口名,如果有指定的类名和窗口的名字则表示成功返回一个窗口的句柄。否则返回零。(类名与窗口名至少知道一个就可以进行查找)

例:获得窗口
HWND h = FindWindow(L"Notepad", NULL);
HWND h = FindWindow(NULL, L"新建文本文档.txt - 记事本");
在这里通过Spy++查找窗口的类名,知道了记事本窗口的类名Notepad,则可成功查找(或者使用窗口标题)

【3.2】代码

#include <iostream>
#include <Windows.h>   //使用HWND的头文件
using namespace std;
int main()
{HWND h;h = FindWindow(L"Notepad", NULL);cout << hex << (int)h;
}

输出结果(可以看出来和Spy++查到的结果一样):

二、鼠标模拟点击(两种方法):
【第一种方法】
原理:1 获取到窗口的句柄。 2 将窗口坐标保存到坐标结构体RECT中。 3 将物理鼠标的指针指向指定的位置。 4 模拟点击

1 GetWindowRect 函数原型 :BOOL GetWindowRect(HWND hWnd,LPRECT lpRect);
作用:第一个参数为窗口的句柄,第二个参数可以为RECT类的变量,用来保存窗口的x坐标和y坐标
2 SetCursorPos 函数原型 :BOOL SetCursorPos(int X,int Y);
作用:使得现在的物理鼠标指向参数数值的位置
3 mouse_event 函数原型 :
VOID mouse_event(
DWORD dwFlags, // motion and click options
DWORD dx, // horizontal position or change
DWORD dy, // vertical position or change DWORD
dwData, // wheel movement
ULONG_PTR dwExtraInfo //application-defined information );

作用: 执行鼠标的动作,例如下面的代码块就是一次鼠标左键点击操作

HWND h;
h = FindWindow(L"Notepad", NULL);
RECT rect;
GetWindowRect(h, &rect);
SetCursorPos(rect.left + mX, rect.top + mY);
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);

优点:直接根据位置点击,不易失效
缺点:1 如果目标窗口上面有窗口遮挡,则不能点击到目标窗口(因为是完全模拟物理鼠标)
2 在远程服务器端 由于远程服务器的特性(桌面和远程访问端有关的原因),断开连接时,没有桌面窗口与物理鼠标,程序会失效

【第二种方法】
原理:1 获取到窗口的句柄。 2 向窗口中发送鼠标点击的信息 (mX与mY为坐标)

1 FindWindowEx 函数原型 HWND FindWindowEx(HWND hwndParent,HWND
hwndChildAfter,LPCTSTR lpszClass,LPCTSTR lpszWindow);

作用 :
第一个参数为父窗口的句柄;
第二个参数为子窗口句柄,查找从在Z序中的下一个子窗口开始,子窗口必须为hwndParent窗口的直接子窗口而非后代窗口,如果HwndChildAfter为NULL,查找从hwndParent的第一个子窗口开始。
第三个和第四个参数与FindWindow函数相同 2 SendMessage 函数原型 LRESULT
SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM IParam)

作用 :第一个参数为发送信息的目标窗口句柄,第二个参数为指定被发送的消息,第三个与第四个参数为指定附加的消息特定信息

HWND h;
h = FindWindow(L"Notepad", NULL);
SendMessage(h, WM_LBUTTONDOWN, VK_LBUTTON, mX + mY * 65536);
SendMessage(h, WM_LBUTTONUP, 0, mX + mY * 65536);

优点:在窗口最小化时、在远程服务器断开时没有鼠标时,都可以正常点击,并且与物理鼠标操作不冲突
缺点:只能向当前的句柄窗口上发送点击信息。如果点击的位置有子句柄窗口,则必须获取到子窗口的句柄,并向子句柄窗口发送点击信息。(通常我用函数FindWindowEx查找子窗口的句柄,如以下代码段

HWND h,p;
h = FindWindow(L"Notepad", NULL);
p = FindWindowEx(h, NULL, L"Edit", NULL);
SendMessage(p, WM_LBUTTONDOWN, VK_LBUTTON, mX + mY * 65536);
SendMessage(p, WM_LBUTTONUP, 0, mX + mY * 65536);

三、键盘模拟点击(不能具体得到输入框句柄的一种处理方式):
原理:1 激活要输入的程序。 2 确定焦点,并通过鼠标点击激活输入框的光标。 进行键盘模拟

keybd_event 函数原型 VOID keybd_event(BYTE bVk,BYTE bScan,DWORD
dwFlags,DWORD dwExtralnfo)

作用 : 参数:
bVk:定义一个虚拟键码。键码值必须在1~254之间。
bScan:定义该键的硬件扫描码。 dwFlags:定义函数操作的各个方面的一个标志位集。应用程序可使用如下一些预定义常数的组合设置标志位。
KEYEVENTF_EXTENDEDKEY:若指定该值,则扫描码前一个值为OXEO(224)的前缀字节。
KEYEVENTF_KEYUP:若指定该值,该键将被释放;若未指定该值,该键将被按下。
dwExtralnfo:定义与击键相关的附加的32位值。

//此处是模拟一次alt+s的模拟
keybd_event(18, 0, 0, 0);                   //按下alt
keybd_event(83, 0, 0, 0);                   //按下S
Sleep(500);
keybd_event(83, 0, KEYEVENTF_KEYUP, 0);     //抬起S
keybd_event(18, 0, KEYEVENTF_KEYUP, 0);     //抬起alt
Sleep(500);

四、获取某个窗口的截图并将其放入剪贴板中(这一部分代码忘了的原作者的链接,等找到之后补到后面)

void CaptureScreen(HWND h, int Flag)
{//if (Flag == 1)cout << "【现在发送第一张截图" << endl;//else if (Flag = 2)cout << "【现在发送第二张截图" << endl;//获得屏幕宽度int nScreenWidth = GetSystemMetrics(SM_CXSCREEN);//获得屏幕高度int nScreenHeight = GetSystemMetrics(SM_CYSCREEN);//获得桌面窗口设备环境HDC hDC = GetDC(h);//产生全屏幕窗口设备描述表的兼容设备环境HDC hCaptureDC = CreateCompatibleDC(hDC);//产生全屏幕窗口设备描述表的兼容位图HBITMAP hCaptureBitmap = CreateCompatibleBitmap(hDC, nScreenWidth, nScreenHeight);//将兼容位图选入兼容设备环境SelectObject(hCaptureDC, hCaptureBitmap);//将全屏幕窗口位图的象素数据拷贝到兼容设备描述表BitBlt(hCaptureDC, 0, 0, nScreenWidth, nScreenHeight, hDC, 0, 0, SRCCOPY);HBITMAP hBmp = (HBITMAP)SelectObject(hCaptureDC, hCaptureBitmap);if (OpenClipboard(0)){EmptyClipboard();SetClipboardData(CF_BITMAP, hBmp);CloseClipboard();}//QQsend();ReleaseDC(h, hDC);DeleteDC(hCaptureDC);DeleteObject(hCaptureBitmap);
}

实现代码(不完善的):

这个函数前面是通过句柄获得了某个窗口的截图,并将其放入了剪贴板中。
接下来是要将截图发送到qq的某个人
注:这里面使用的是腾讯的TIM软件,windows系统
注:使用时要保证要发送的那个人是在窗口最前

void QQsend() {HWND h = FindWindow(L"TXGuiFoundation", L"鸽");RECT rect;GetWindowRect(h, &rect);ShowWindow(h, SW_RESTORE);                   //激活h窗口SetFocus(h);                             //设置当前窗口为焦点SetForegroundWindow(h);                      //指定窗口的线程设置到前台,激活该窗口。键盘输入转向该窗口cout << "【进行粘贴操作" << endl;//模拟发送按键alt+skeybd_event(18, 0, 0, 0);keybd_event(83, 0, 0, 0);Sleep(500);keybd_event(83, 0, KEYEVENTF_KEYUP, 0);keybd_event(18, 0, KEYEVENTF_KEYUP, 0);Sleep(500);//模拟粘贴按键ctrl+vkeybd_event(17, 0, 0, 0);keybd_event(86, 0, 0, 0);Sleep(500);keybd_event(86, 0, KEYEVENTF_KEYUP, 0);keybd_event(17, 0, KEYEVENTF_KEYUP, 0);Sleep(500);//模拟发送按键alt+skeybd_event(18, 0, 0, 0);keybd_event(83, 0, 0, 0);Sleep(500);keybd_event(83, 0, KEYEVENTF_KEYUP, 0);keybd_event(18, 0, KEYEVENTF_KEYUP, 0);Sleep(500);cout << "【点击发送" << endl;//点击发送SendMessage(h, WM_LBUTTONDOWN, 0, (rect.right - 60) + (rect.bottom - 70) * 65536);SendMessage(h, WM_LBUTTONUP, 0, (rect.right - 60) + (rect.bottom - 70) * 65536);
}

所说的窗口最前是保证要发送信息的那个人的窗口要这个样子

编后记:在这篇记录中只介绍了相关函数的非常一小部分的定义及使用方法,十分建议查找阅读相关的文档深化理解,感谢阅读,欢迎指正。

通过获取窗口句柄模拟键鼠点击的一些方法相关推荐

  1. AutoRunner模拟键鼠操作

    在AR的使用过程中,有些地方需要用到模拟键盘操作,这种键盘的模拟操作命令有很多,具体请见AR界面的:[帮助–脚本命令].那么今天我们一起看一些模拟键盘操作的命令和其使用: 1.inputDown 命令 ...

  2. C++ 模拟键鼠详细总结

    简介 需要使用user32.dll,所以项目中要引入静态链接库 user32.lib #include <Windows.h> 鼠标输入官方例程 下面这些操作,一定要看官方文档,这样能少走 ...

  3. WINIO64位模拟键鼠操作

    最近玩游戏有点入迷,心急升级经验,于是某天开始"挂尸体",一系列手动操作之后决定写一个外挂,模拟一系列键盘和鼠标操作,没做过游戏winform也用得少,开始以为只要简单调用winA ...

  4. 在Node环境中模拟键鼠热键

    robot-cmd utomatically operate the keyboard and mouse, do not need gyp. const robot = require('robot ...

  5. 用51单片机和ch375实现键鼠功能

    用51单片机和ch375实现键鼠功能 说明: 为了参加比赛,我和我的队友设计了一款人机交互系统,我负责接收摄像头数据和模拟键鼠功能,由于当时只是学习了51故用51单片机和ch375模拟一套简单的键鼠功 ...

  6. 获取窗口句柄模拟鼠标点击

    一.任务要求. 需要我们编写一个程序能够自动的进行某些鼠标点击的操作.比如某个客户端,我们利用程序,可以自动点击操作. 二.需求分析. 为了实现这种要求,我们必须首先获得需要操作窗口的句柄.其次是点击 ...

  7. 批量去除PDF水印 —— quicker 键鼠模拟操作

    前言 每一篇我写的教程,都是因为我自身需求催发出来的,且我在网上没找到一个相对较好的解决方案. 目前,很多公众号或者内容生产者都会在PDF中添加水印,这是无可厚非的.一个精美的水印,往往能让内容排版更 ...

  8. python鼠标点击位置_python鼠标点击位置 Python3怎么模拟鼠标点击?

    Python3怎么模拟鼠标点击? Python3怎么模拟鼠标点击?最好简单一点的方法 import win32api,win32condef click(x,y): win32api.SetCurso ...

  9. Windows下C/C++模拟鼠标点击,PC端没有鼠标设备也能够获取鼠标坐标、移动鼠标坐标、模拟鼠标点击事件,方法一 亲测有效

    ------- [ 转载请保留 ] ------- 作者:西_瓜_瓜 博客:https://blog.csdn.net/xi_gua_gua/article/details/105773298 --- ...

最新文章

  1. 修改CodeSmith中的SchemaExplorer.MySQLSchemaProvider
  2. PHP ElasticSearch的使用
  3. h3c服务器 raid 型号,H3C服务器创建Raid
  4. ListView smoothScrollToPosition 定位不准笨方法解决
  5. 【转】VScode快捷键(超无敌详细版)
  6. 【script】python使用pymssql模块访问SQL Server(Mssql)
  7. 重磅!彭博社“机器学习基础”教程视频及讲义下载
  8. HowToDoInJava Spring 教程·翻译完成
  9. babel css3新特性_前端总结(后续不断更新)
  10. BZOJ1036[ZJOI2008]树的统计——树链剖分+线段树
  11. redis 设置不过期_面试时 Redis 内存淘汰总被问,但是总答不好,怎么解决?
  12. 微信APP支付开发步骤及要点
  13. 点云数据处理(分类、分割、检测)PointNet
  14. 一篇文章,带你详细了解华为认证体系证书(1)
  15. 计算机关闭窗口可以使用alt,电脑关闭窗口快捷键
  16. SQL Server-【知识与实战III】年龄查询、条件查询、多表查询、姓氏查询
  17. 51单片机数码管表白
  18. win10访问不了SAMBA
  19. CocosCreator 物理引擎-关节
  20. cap分析zk是cp还是ap

热门文章

  1. 定时播放音乐(几个定时器的实例)
  2. 1: Myeclipse10 优化设置
  3. redis如何更换端口号以及启动方式
  4. JPA - 自定义JPQL替代JPA命名方法
  5. HTML5 页面video标签视频加载播放空白
  6. Found GPU0 TITAN V which requires CUDA_VERSION = 9000 for optimal performance and fast startup time
  7. 基于人脸的常见表情识别(1)——深度学习基础知识
  8. 【Java基础】swing-图形界面学习(上)
  9. HTML技能点--使用base标签设置URL访问基准
  10. 来自自身的信息——“灵魂暗夜”