今天闲来无事突然想qq只能即时发送消息,能不能够使用其他的程序来控制qq发送指定的程序呢,后来参考了部分资料才发现,可以先通过获得qq的聊天窗口的句柄,然后通过模拟按键来实现qq消息的模拟发送。话不多说,先来看看效果吧:
qq消息定时发送
大致用法说明:首先,你要在定时过程中保证改好友的聊天窗口时打开没有关闭的,然后选中好友的聊天窗口后你就可以在下面的框框内部输入你要定时发送的消息了,然后设定发送间隔时间,如果点击发送,那么就会直接发送,点击设置,然后会在左下角显示还有多少秒要发送消息了,在这个过程中,你随时可以点击暂停来停止这个定时发送,时间到之后,便会发送指定的消息。

一:程序思路
对于一个qq窗口,使用程序来发送程序可以首先将要发送的消息复制到剪切板,然后在待发送qq朋友的窗口获得键盘焦点的时候,默认的输入焦点在发送信息的输入框里面,所以就可以定时将qq朋友的窗口设置为最前端窗口,然后模拟键盘按下ctrl+v便可以把将要发送的数据粘贴进入输入框,然后模拟按下alt+s就可以发送消息了,是不是很简单呢,下面就带大家做一下。
二:程序编写
1.首先获得要发送qq消息的好友的聊天框窗口的句柄,此处我们使用的操作方式和visual studio自带的那个spy++获得窗口句柄的方式有点类似,都是在十字标位置按下鼠标,然后在指定的窗口上面松开鼠标就可以获得窗口的句
柄了。
(1). 此处为了实现spy++的那种效果,我们需要用到一个函数SetCapture,函数使用说明如下:
HWND SetCapture(
HWND hWnd // 要捕获全局鼠标消息的控件的句柄
);
由于十字标的那个pic控件的大小有限,如果鼠标在按下状态移出了这个pic控件,那么就没有办法继续追踪到鼠标抬起的消息,这个SetCapture函数的作用就是从此刻开始,不管鼠标有什么消息都要把消息发送给我这个控件,不要发送给其他控件,这样子就可以在鼠标移出本控件后可以继续追踪到鼠标抬起的消息。这样子可以设定程序在鼠标抬起的时候检测此处的窗口句柄(具体代码实现下面介绍)
(2). 但是如果一直将鼠标的消息都发送给这个控件是很危险的一件事情,其他控件接收不到鼠标消息就相当于电脑鼠标失灵一样,只能点击这个控件有用,所以,在SetCapture之后,要在适当的时候释放鼠标使得鼠标可以给其他控件传递发送消息。这时候要用ReleaseCapture在鼠标抬起的时候及时的释放鼠标消息,函数使用方式如下:
BOOL ReleaseCapture(VOID);
//---------------------------pic十字标控件鼠标按下代码参考--------------------------

//这个函数处理的是那个十字标的pic控件被鼠标按下产生的事件
void picCross_MouseDown(int button, int shift, int x, int y)
{
	//当用户在这个里面点击鼠标的时候,自动把鼠标变为十字标
	//此代码由老师提供,大家可以在我的程序的具体内容中探究具体的实现方式
	pApp->MousePointerGlobalSet(IDC_Cross);
	//捕获全部的鼠标事件
	SetCapture(form1.Control(ID_picCross).hWnd());
}

(3). 此处我们用到的是一个WindowFromPoint的API函数来在鼠标抬起时获得具体的好友的窗口句柄。下面是这个函数的使用说明:
HWND WindowFromPoint(
POINT Point // 这个是鼠标位置的一个结构体
);
然后返回的就是当前的鼠标位置的一个窗口的句柄。为了获得当前鼠标的位置,我们可以使用GetCursorPos这个函数来获得鼠标的位置(注意:此处的位置是相对于整个电脑屏幕的绝对坐标),函数用法:
BOOL GetCursorPos(
LPPOINT lpPoint // 鼠标位置结构体的指针
);
//------------------------------鼠标抬起查找窗口参考代码---------------------------------

//这个是pic十字标控件鼠标抬起的消息处理函数
void picCross_MouseUp(int button, int shift, int x, int y)
{
	//如果用户的鼠标抬起,那么开始监测这个位置有没有要监测的窗口内容
	//首先恢复鼠标的显示
	pApp->MousePointerGlobalSet(IDC_Arrow);
	TCHAR sWindText[64]={0};
	//寻找鼠标位置,找到窗口句柄
	POINT pPont;
	GetCursorPos(&pPont);
	m_hWndQQSend=WindowFromPoint(pPont);
	GetWindowText(m_hWndQQSend, sWindText,sizeof(sWindText));
	m_sWindName =sWindText;
	//然后在那个编辑框显示找到的窗口的句柄
	//此代码由老师提供,大家可以在我的程序的具体内容中探究具体的实现方式
	form1.Control(ID_txtHwndFind).TextSet(Str((int)m_hWndQQSend));
	form1.Control(ID_txtWindName).TextSet(sWindText);
	//释放鼠标
	ReleaseCapture();
}

此处你已经实现了最基本的查找窗口功能了,现在来一起看看效果吧,寻找好友消息窗口
2. 找到窗口了,下一步虚拟按键的使用了
具体的发送虚拟按键的使用我们把代码都放在发送按钮的点击事件中来统一编写。
(1). 在虚拟按键之前,我们需要把待发送消息的窗口置于最前端,并且要正常显示,这里我们用到了两个函数分别是 SetForegroundWindow 和 ShowWindow,具体用法如下:
BOOL SetForegroundWindow(
HWND hWnd // 要放置在最前端的窗口句柄
);
BOOL ShowWindow(
HWND hWnd, // 窗口句柄
int nCmdShow // 窗口显示状态
);
ShowWindow函数的第二个参数具体可以查阅MSDN,本博文不做详细介绍。此处用到的是SW_SHOW(正常显示)。

(2). 虚拟按键的实现,只需要一个按键就可以,keybd_event函数,他可以模拟所有的键盘动作,具体用法如下:
VOID keybd_event(
BYTE bVk, // 虚拟键码
BYTE bScan, // 不用管,设置为0即可
DWORD dwFlags, // 虚拟按键的按下还是抬起状态的设定
DWORD dwExtraInfo // 不用管,设置为0即可
);
注意虚拟按键函数的使用规范:首先在一个按键按下的过程执行完毕后一定要有抬起的动作,其二,函数执行比较快,如果要使用虚拟按键,最好是在中间加入Sleep函数来使得程序等待一段时间,否则虚拟按键容易因为代码执行速度过快而失效。

void cmdSend_Click()
{
	//发送消息框里面的信息
	//具体实现,将内容复制到剪切板,然后模拟按键实现发送
	tstring sText = form1.Control(ID_txtSend).Text();
	//==========================准备工作===============================
	if (sText == TEXT(""))
	{
		MsgBox(TEXT("请输入您要发送的信息不能为空!"), TEXT("发送消息为空"),mb_OK, mb_IconInformation);
		timSend.EnnabledSet(false);
	}
	else if (m_hWndQQSend == NULL)
	{
		MsgBox(TEXT("还没有选定待发送消息的窗口,请选择聊天窗口!"), TEXT("窗口句柄为空"),mb_OK, mb_IconInformation);
		timSend.EnnabledSet(false);
	}
	else
	{
		//首先还应该判断窗口是否已经关闭,如果关闭,不再进行下面的发送操作
		//设置窗口最前端
		if (!SetForegroundWindow(m_hWndQQSend))
		{
			MsgBox(TEXT("该窗口被关闭,无法发送消息到指定窗口!"),TEXT("请检查该窗口是否被关闭"),mb_OK,mb_IconQuestion);
			m_hWndQQSend = NULL;
			form1.Control(ID_txtHwndFind).TextSet(TEXT(""));
			return;
		}
		//===========================================================

		//=====================核心代码==============================
		//这里还要让窗口正常显示,否则也不行
		ShowWindow(m_hWndQQSend, SW_NORMAL);
		//复制文本到剪切板
		//此代码由老师提供,大家可以在我的程序的具体内容中探究具体的实现方式
		ClipboardSetText(sText);
		//首先模拟 ctrl+v 的按键输入内容,然后进行发送操作
		keybd_event(VK_CONTROL, 0, KEYEVENTF_EXTENDEDKEY|0, 0);
		keybd_event(86, 0, KEYEVENTF_EXTENDEDKEY|0, 0);
		Sleep(10);//需有一定的间隔时间
		keybd_event(86, 0, KEYEVENTF_EXTENDEDKEY|KEYEVENTF_KEYUP, 0);
		keybd_event(VK_CONTROL, 0, KEYEVENTF_EXTENDEDKEY|KEYEVENTF_KEYUP, 0);

		//此处还是给用户一个自己设定的空间,毕竟不同的窗口的快捷键可能不同
		Sleep(10);//需有一定的间隔时间
		keybd_event(18, 0, KEYEVENTF_EXTENDEDKEY|0, 0);
		keybd_event(83, 0, KEYEVENTF_EXTENDEDKEY|0, 0);
		Sleep(10);//需有一定的间隔时间
		keybd_event(83, 0, KEYEVENTF_EXTENDEDKEY|KEYEVENTF_KEYUP, 0);
		keybd_event(18, 0, KEYEVENTF_EXTENDEDKEY|KEYEVENTF_KEYUP, 0);
		
		//清空内容的显示
		form1.Control(ID_txtSend).TextSet(TEXT(""));
}

恭喜你,现在你已经可以通过本程序不操作qq窗口就可以来发送qq消息了,是不是很厉害呢,一起来看看吧!
发送实现
3. 定时功能和左侧列表的实现
定时功能的实现主要是通过windows为我们提供的定时器API函数来实现的。其中主要的实现函数有两个SetTimer和KillTimer,SetTimer用于创建一个定时器,而KillTimer主要用于删除一个定时器,本博客对于此处的具体代码实现不做过多的介绍,本程序的源代码已经将内容封装成一个CBTimer的类,有兴趣的可以下载源代码看看具体的实现过程。
4. 小tip
本程序还有部分开发功能,循环发送,即俗称的消息轰炸,用户仅仅通过修改部分源代码便可以控制循环发送的内容了,本程序暂时并没有实现左侧列表管理,就是只能够一个程序定时发送一个消息,要想发送多个,需要等一个消息发送完毕后自定义下一个消息的发送定时时间才可以,欢迎大家提出对源代码的建议并且有兴趣继续做的可以增加一些更加高端的功能。

//
//来,这里是一个分界线
///
考虑到原来的那个程序的使用略有一定的不方便性,后来对他进行了一个全面的升级,先看一下效果吧

1.新增功能是等间隔发送,并且可以设置很多个人,并且如果重叠到一个窗口会自动找到对应的人发送内容,不用为每一个人都分列一个窗口,大大的增加了使用的方便性

2.定时发送,有时候大家更倾向于的是定时发送而不是定间隔发送,所以此次增加了新的内容
在这里插入图片描述
3.定时关机,此处不演示了,之前用过自己的电脑进行测试,效果还行,可以实现关机
在这里插入图片描述
//
代码新功能的实现大致和上面的原理差不多,快速切换聊天窗口,用的是快捷键Ctrl+Tab,大致实现过程一样,定时器为了提高效率,每秒检测一次,看看是否有需要发送的内容,如果有就发送,没有就删除该定时器,用户重新点击开始再创建一个定时器。

程序的下载见下方的百度网盘链接(程序永久有效):
链接:https://pan.baidu.com/s/1GQSCo9_gGa4uG9RSdgN3mg
提取码:hedw
复制这段内容后打开百度网盘手机App,操作更方便哦
源代码就不给大家提供下载了,如果有想要的可以私信我。
(如果大家感觉不错,希望能给我点个赞,哈哈哈哈,卑微求赞)

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐