MFC 如何实现对任务栏下的QQ好友发送消息
请问, 网上有各种QQ群发器,有些群发器 基本操作方式是:1. 指定QQ好友,或者QQ群,
2. 获取任务栏上的QQ用户,3. 发送QQ消息。 请问这种群发功能,是否涉及到 QQ协议, 到底是怎么实现的,
请各位高手给点思路, 最好提供一些实现功能所涉及的函数,谢谢了。
[解决办法]
QQ群发器这种软件,大概实现思路有这么几种:
1.类似于按键精灵的实现方式,模拟输入、模拟发送,发送消息时会打开聊天窗口,用SendInput()来模拟鼠标键盘输入。缺点:效率低、操作是在前台进行的,容易受用户操作干扰、不稳定。
2.也是模拟输入模拟发送,不过不用SendInput(),而是用发送消息的形式SendMessage()对QQ聊天窗口发windows消息WM_CHAR/WM_KEYDOWN/WM_KEYUP/WM_LBUTTONDOWN/WM_LBUTTONUP之类的消息来模拟键盘鼠标输入。不过要注意的是,由于QQ聊天窗口是DirectUI绘制,它的文本框没有句柄,不能直接发送WM_SETTEXT/WM_GETTEXT消息来直接在文本框中输入内容。这种方式同样要求发送消息时打开聊天窗口,但模拟发送时可以在后台操作,不容易被用户操作干扰。
3.使用QQ通信协议,假如我们能分析出QQ客户端与服务端的通信协议(应用层协议),照着这个协议来,我们可以写一个软件,直接与QQ服务器进行交互(类似于脱机外挂),在后台稳定、高效、并行的进行群发QQ消息操作。这种无疑是最好的办法,可是目前貌似没人做到,因为太难了太复杂了,QQ的通信协议肯定是加密的,分析难度过大。
4.使用WEBQQ通信协议,网上已经有人分析出来并公布了,由于WEBQQ是基于HTTP协议的,对于那些高手来说,分析抓到的HTTP包和WEBQQ的JS文件,就能基本掌握它的协议,然后用此协议,写个软件与WEBQQ服务器进行交互也可实现群发操作。QQ农场外挂的实现应该也是这种思路。
3、4两种方式做出来的QQ群发软件可以不用启动QQ客户端,静默的在背后群发消息,稳定、高效,但难度明显比前两种大很多。
[解决办法]
看上去第四种方式是最好可行的方案
[解决办法]
还有比较简单的方式. 模拟ctrl+V.
只需要知道聊天窗口句柄(聊天窗口的名字即是昵称或者群名,spy++一看即知).
然后操作剪切板, 把要发的内容放到剪切板中, 再向要发送消息的群或者好友聊天窗口发送ctrl+V消息即可.
做过一个相关软件.
void PostCtrlAndKey(HWND hWnd, BYTE vkey)
{
keybd_event( VK_CONTROL,0,KEYEVENTF_EXTENDEDKEY,0 );
SendMessage(hWnd, WM_KEYDOWN, vkey, 0);
SendMessage(hWnd, WM_KEYUP, vkey, 0);
Sleep(100);
// Simulate a key release
keybd_event( VK_CONTROL,0,KEYEVENTF_KEYUP
[解决办法]
KEYEVENTF_EXTENDEDKEY,0);//*/
}
void PostAltAndKey(HWND hWnd, BYTE vkey)
{
::PostMessage(hWnd, WM_SYSKEYDOWN, vkey, 1<<29);
}
BOOL SendKey(HWND hParentWnd, LPCTSTR strTitle)
{
HWND hWnd = ::FindWindow(NULL, strTitle);
if(hWnd)
{
if( ::IsIconic(hWnd))
{
::ShowWindow(hWnd, SW_RESTORE);
::SetForegroundWindow(hParentWnd);
//::SetFocus(hParentWnd);
//::SetTimer(hParentWnd, 1000, 1000, NULL);
//::SendMessage(hWnd, WM_PASTE, 0, 0);
//PostCtrlAndKey(hWnd, 'A');
}
//else
{
::SendMessage(hWnd, WM_PASTE, 0, 0);
PostCtrlAndKey(hWnd, VK_RETURN);
}
return TRUE;
}
else
{
CString Str = TEXT("请先打开 [ ");
Str += strTitle;
Str += TEXT(" ] 群聊天窗口");
MessageBox(NULL, Str, TEXT("未打开群"), MB_OK);
return FALSE;
}
}
void CopyToClipboard(HWND hWndOwner, LPCTSTR strText)
{
if( !OpenClipboard(hWndOwner))
{
return;
}
EmptyClipboard();
size_t cbStr = (_tcslen(strText) + 1) * sizeof(TCHAR);
HGLOBAL hData = GlobalAlloc(GMEM_MOVEABLE, cbStr);
memcpy_s(GlobalLock(hData), cbStr, strText, cbStr);
GlobalUnlock(hData);
// For the appropriate data formats...
UINT uiFormat = (sizeof(TCHAR) == sizeof(WCHAR)) ? CF_UNICODETEXT : CF_TEXT;
if (::SetClipboardData(uiFormat, hData) == NULL)
{
DWORD dwErro = GetLastError();
}
CloseClipboard();
GlobalFree(hData);
}
调用代码如下:
CopyToClipboard(m_hWnd, strName);//复制数据到剪切板//发送Ctrl+V相关操作.
CString Str;
GetDlgItemText(IDC_GROUP_NAME, Str);//得到群名
return SendKey(m_hWnd, Str);