一、引言
QQ一直是國內最令人矚目的及時通訊軟件,近6年的經營使其在IM市場有了"世界第一"名號。在國內市場,QQ的市場占有率已經超過了70%,用戶群龐大,本人就是騰訊QQ的一個用戶。不知QQ會員是否能夠消息群發,但我這個免費用戶是享受不了這個服務的,給同事和朋友們發通知好辛苦啊。在網上Google了一下,找到幾個小軟件,可是消息後面又加個廣告尾巴。還是自己動手吧:
如果要分析騰訊QQ協議來編寫發送QQ消息是很復雜的一件事情,那麼,有沒有簡單的辦法呢?答案是肯定的:有!
既然Windows使用消息循環來處理輸入信息,那麼如果我們能夠用程序模擬產生"操作QQ時鼠標和鍵盤操作所發出的消息" ,那麼就應該可以實現程序發送QQ消息,進而批量發送QQ消息,即消息群發。
二、具體實現
QQ給某個人發送消息時,將創建如下圖所示的窗口(對話框窗口),我們發消息就是填寫消息內容,然後點擊發送。要模擬QQ消息發送,我們就需要填寫消息內容,然後模擬按鍵發送。
第一步,找到聊天主窗口,該窗口的標題是與*****聊天中,我們可以通過使用FindWindowEx函數來找到這個窗口。
第二步,找到輸入消息的控件並在裡面填寫消息。注意:可能是騰訊公司為了安全,在窗口裡又套了幾個窗口,如果有興趣,可以用微軟的工具SPY++自己看看。通過使用SPY++觀察,發現該控件是一個RichEdit類,位置如上圖所示,我們還是用 FindWindowEx函數來找到它,然後取得指針,通過指針往裡面些數據。
第三步,模擬鼠標點發送按鈕的操作,可以通過取得該按鈕的指針,然後發送一個BM_CLICK消息就可以了。
通過程序模擬,實現的非常好。用VC6建立一個簡單的對話框程序,添加一個按鈕(改Caption值為發送),為該按鈕填加以下執行代碼:
void CMySMSDlg:: QQSendMessage()
{
CString str;
CWnd* pMainWnd = AfxGetMainWnd()->GetWindow(GW_HWNDFIRST);
while (pMainWnd)
{
HWND hWnd,hNext;
hWnd = pMainWnd->m_hWnd;
pMainWnd->GetWindowText(str);
if(str.Find ("聊天")>-1){//找到聊天主窗口Begin
//找RichEdit
hWnd=FindWindowEx(pMainWnd->m_hWnd,NULL,"#32770",NULL);
pMainWnd = CWnd::FromHandle(hWnd);
hWnd=FindWindowEx(pMainWnd->m_hWnd,NULL,"AfxWnd42",NULL);
CWnd* pChildWnd=CWnd::FromHandle(hWnd);
int nLen = str.GetLength ();
hNext = FindWindowEx(pChildWnd->m_hWnd,NULL,"RICHEDIT",NULL);
if(hNext){//找到消息填寫控件
CRichEditCtrl* pRich=(CRichEditCtrl*)(CWnd::FromHandle(hNext));
pRich->GetWindowText (str);
pRich->SetSel (nLen,nLen);
pRich->ReplaceSel ("成都外國語學校 黃東");//填上將要發送的內容
}else return;
//找消息發送按鈕
hWnd=FindWindowEx(pMainWnd->m_hWnd,NULL,NULL,NULL);
while (hWnd) {
pChildWnd=CWnd::FromHandle(hWnd);
pChildWnd->GetWindowText(str);
if(str.Find ("發送")>-1){
pChildWnd->SendMessage (BM_CLICK);//發送
return;// 退出
}
hWnd=FindWindowEx(pMainWnd->m_hWnd,hWnd,NULL,NULL);
}
return;
}//找到聊天主窗口End
else pMainWnd = pMainWnd->GetWindow(GW_HWNDNEXT); //繼續找
}//While
}
至此,主要部件已經實現了,如何讓程序自動為每個好友打開聊天窗口,和這個也差不了太多,就留給各位去研究吧,這條思路適合目前所有的IM軟件。
程序在VC6下編譯通過(文件很小,只有20KB),操作系統為Windows 2000 SP4,QQ版本為2004 SP1,按發送按鈕之前需要打開一個聊天窗口。