国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

制作QQ消息炸彈

2019-11-18 18:27:57
字體:
來源:轉載
供稿:網友
 

QQ聊天機器人隨想

原作:hottey(阿風)

  前幾日,看到雜志上有一篇關于開發QQ聊天機器人的文章。談到了對QQ循環發送消息內容,感覺倒也很好玩,于是拿起Delphi開始了我的QQ聊天機器人之路。
  首先要明白自己要做什么,大家都用過QQ,知道給別人發送消息的整個過程吧!要實現循環發送消息的功能該有以下幾個條件:
  1.必須是在聊天模式里進行。這樣發送完一條消息后,QQ窗體還存在。
  2.其次是要找到QQ文本窗體的句柄。
  3.向QQ文本窗體中貼上你想說的話。然后自己點擊發送按鈕。
  思路很簡單,接著我們就要開始實施了。
  首先要找到QQ文本窗體的句柄。這時我用到了SPY來查看QQ的窗體。結果如下圖:這樣思路就出來了。要找到QQ文本窗體的句柄就得先找到它的父類即:標志為00620252 Class Name:AfxWnd42 Control ID:00000000。而要找到它就必須找到QQ消息對話框即:006B294“冷問梅 - 發送消息”#32770〔Dialog〕的句柄。
這時要用到幾個Api函數:
1.FindWindowEx(
    hWnd1:Long, //在其中查找子的父窗口,如設為0,表示使用桌面窗口(通常說的頂級窗口都認為是桌面的子窗口)
    hWnd2:Long, //從這個窗口后開始查找。如設為0,表示對第一個子窗口開始搜索。
    Lpsz1:String, //欲搜索的類名,0表示忽略。
    Lpsz2:String //欲搜索的類名,0表示忽略。
  );
2.GetWindow(
    hWnd:Long, //源窗口。
    wCmd:Long //指定結果窗口與源窗口的關系(這里用GW_CHILD)表示尋找源窗口的第一個子窗口。
      );
3. GetDlgItem(
     hWnd:Long, //源窗口的句柄。
     Int: nIDDlgItem //要在其中查找的窗口的ID號
   );
  其實剛開始找QQ對話窗口時,我先想到的是FindWindow(),這個函數可以直接通過窗口標題名來查找窗體句柄。
  我是這樣找的:
var hparent:HWND;
hparent:=FindWindow(nil, '發送信息'); //這對2003以前的版本還是很有效的^_^
  結果卻是返回錯誤。Why?
  后來仔細一看,發現每次QQ2003的標題都在變:如上圖是:冷問梅 - 發送消息,要是你又對一個人發信息就會變成:藍色的風 – 發送消息(舉個例子)。
  這也許是QQ2003采取的一種安全措施吧!呵呵!你們也許會看見網上針對QQ2003發送消息炸彈的工具有時要是輸入對方的昵稱的原因。(便于通過昵稱得到窗體句柄)。
  不過有沒有更好的方法呢!有!這時就要用到FindWindowEx()了。仔細看一下它的參數,關鍵是第二個hWnd2——我們可以通過它來多次調用FindWindowEx找到符合條件的子窗口。以下是我的代碼:
var hparent:HWND; //定義為全局變量。來記錄每次調用FindWindowEx()后找到的窗體的句柄。
PRocedure TForm1.FormCreate(Sender: TObject);
begin
  hparent:=0; //初始化,查找桌面所有的頂級窗口開始。
end;
procedure TForm1.Timer1Timer(Sender: TObject);
var hbutton,hbutton1:HWND;
begin
  repeat
    hparent:=findwindowex(0,hparent,'#32770',nil); //QQ對話框的類為#32770,這樣循環調用FindWindowEx()就能每次時鐘生效時更新hparent的值。從已查找的句柄為hparent的窗體后查找符合要求的窗體。
    hbutton:=findwindowEX(hparent,0,nil,'發送(&S)'); //每次判斷找到的窗口的句柄,看這個窗體中是否存在'發送(&S)'按鈕。存在即找到了正確的QQ對話框。
  until  hbutton<>0; //找到QQ對話框后跳出循環。
  hbutton1:=findwindowex(hparent,0,nil,'聊天模式(&T)') ; //找到QQ對話窗體后,查找聊天模式按鈕句柄。  
  if hbutton1<>0 then //若此時存在聊天模式按鈕即現在QQ窗體處于消息模式狀態。
    sendmessage(hbutton1,BM_CLICK,0,0); //給聊天模式按鈕發送單擊消息。將窗體轉換為聊天模式。
end;
  這樣我們就成功的找到的QQ對話框。和成功設置對話框為聊天模式了。任務總算先完成了一些,呵呵!更郁悶我的還在后頭了。
  接著,就要開始查找QQ輸入文本的那個窗體的句柄了。這時我用到的是GetDlgItem()大家知道一個窗體中某一類控件的Control ID在這個窗體類中是不變的(除去一些靜態文體外)過SPY我獲知QQ輸入文本的那個窗體的Control ID為0000037E。于是我寫了下面的語句。
Var hmemo:HWND;
hmemo:=GetDlgItem(hparent,$0000037E);
  結果發現寫得東東完全沒有自己預想的效果。呵呵!還是拿起SPY,哈!發現竟然不止一個控件的ID為0000037E。并且我們想要得到QQ輸入文本的那個窗體的位置也不是最前一個(要是最前一個,通過上面的語句也是可以找到的^_^)。郁悶了不是。沒辦法還是從它的父類開始吧!可不能在一步求成了。仔細看看上圖。發現了吧!
  標志為00620252 Class Name:AfxWnd42 Control ID:00000000的即是QQ輸入文本的那個窗體的父類,并且它是所有Class Name:AfxWnd42中位置最前的那一個。于是我們就可以找到它的句柄。跑不掉了。有了它,QQ輸入文本的那個窗體的句柄也就很容易找到了,哈哈!以下是我的代碼:
Var hmemo,hmemo1:HWND;
hmemo=GetDlgItem(hparent,$00000000); //找到父類。
hmemo1=GetWindow(hmemo1,GW_CHILD); //得到父類下的第一個子窗口句柄(hmemo1即QQ輸入文本的那個窗體的句柄^_^大功告成)
  這里順便說一下GetWindow()用法:
GetWindow(
  Hwnd:Long, //源窗口句柄。
  wCnd:Long //指定結果窗口與源窗口的關系。(GW_CHILD為得到源窗體下的第一個子窗口句柄)
)
  更多的常數關系你們就去查看MSDN吧!這里就不必占用寒泉的空間了。哈!
  到此,QQ對話框和QQ輸入文本窗口的句柄我們都已經得到了,以下的步驟就是把你要寫的話,貼進QQ輸入文本窗口,點一下發送,就郁悶別人吧!
  現在貼出我的一段代碼以供大家參考:
procedure TForm1.FormCreate(Sender: TObject);
begin
  i:=0;
  //導入文件內容到combobox控件。
  combobox1.Items.LoadFromFile(extractfilepath(application.ExeName)+'text.txt');
  combobox1.Text:=combobox1.Items.Strings[0];
end;
procedure TForm1.Timer1Timer(Sender: TObject);
var hmemo1:HWND; //hmemo1為找到的QQ文本輸入框句柄
begin
  if checkbox1.Checked then //點擊了循環發送復選框。
  begin
    if i>combobox1.Items.Count-1 then
      i:=0;
    edit1.Text:=combobox1.Items.Strings[i];
    edit1.SelectAll;
    edit1.CopyToClipboard; //拷貝到剪切板
    sendmessage(hmemo1,WM_PASTE,0,0); //對QQ輸入文本窗體發送粘貼消息。
    sendmessage(hbutton,BM_CLICK,0,0); //點擊發送按鈕
    i:=i+1;   
  end;
  if checkbox1.Checked=false then  //沒有點擊了循環發送復選框。
  begin
    edit1.Text:=combobox1.Text;
    edit1.SelectAll;
    edit1.CopyToClipboard;
    sendmessage(hmemo1,WM_PASTE,0,0);
    sendmessage(hbutton,BM_CLICK,0,0);
  end;
end;
  附上簡要說明:由于本人所知有限,不太會用剪切板函數對將已知字串拷貝到剪切板的方法還不知道。所以只能借道于控件上。因為所有文本類控件都有一個方法即——edit1.CopyToClipboard,所以只能先將Edit1變為不可見控件。每次先將要發送的內容傳給Edit1,而后在將Edit1的內容CopyToClipboard。哈!這只是一個取巧的法子,大家要是知道有什么更好的方法還望告知在下,呵!
后記:
  以上代碼是針對QQ2003版本。雖然網上有如:飄葉千夫指的好工具。不過作為一個小小菜鳥。但又喜歡編程的人來說。自己DIY(do it youtself)一個也是很爽的一件事吧!我自己也參照飄葉千夫指做了一個,感覺具備了它的使用功能吧!還不錯。其實也沒有太多技術性的東西,只是運用了幾個API函數而已。只希望對剛剛學Delphi的朋友有所幫助,當然高手是用不著的了。

注明:QQ2004有些改動.為了方便我把新改的代碼帖上來:

procedure TForm1.Timer1Timer(Sender: TObject);
var hbutton,hbutton1,hmemo,hmemo1,hparent1:HWND;
begin
  repeat
     hparent:=findwindowex(0,hparent,'#32770',nil);

//QQ2004就是多了下面這句,Memo上又多了一層窗口
     hparent1:=findwindowex(hparent,0,'#32770',nil);
  until  hparent1<>0;
  hbutton:=findwindowEX(hparent1,0,nil,'發送(&S)');
  hbutton1:=findwindowex(hparent1,0,nil,'聊天模式(&T)');
  if hbutton1<>0 then
     sendmessage(hbutton1,BM_CLICK,0,0);
     hmemo1:=GetDlgItem(hparent1,$00000000);
     hmemo:=getwindow(hmemo1,GW_CHILD);
  if hmemo<>0 then
  begin
  if  checkbox1.Checked then
  begin
    if i>combobox1.Items.Count-1 then
       i:=0;
       edit1.Text:=combobox1.Items.Strings[i];
       edit1.SelectAll;
       edit1.CopyToClipboard;
       sendmessage(hmemo,WM_SETTEXT,0,0);
       sendmessage(hmemo,WM_PASTE,0,0);
       sendmessage(hbutton,BM_CLICK,0,0);
       i:=i+1;  
  end;
  if checkbox1.Checked=false then
  begin
    edit1.Text:=combobox1.Text;
    edit1.SelectAll;
    edit1.CopyToClipboard;
    sendmessage(hmemo,WM_SETTEXT,0,0);
    sendmessage(hmemo,WM_PASTE,0,0);
    sendmessage(hbutton,BM_CLICK,0,0);
  end;
end;
end;
  有需要的朋友請到我的網站去下載(位于我的作品里):
  作者網站:http://asp.itdrp.com/hottey 

    hottey   于2004-5-30日修改 


上一篇:一個新算法的表達式求值的函數

下一篇:VCL源碼分析方法論

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
學習交流
熱門圖片

新聞熱點

疑難解答

圖片精選

網友關注

主站蜘蛛池模板: 温宿县| 东乡县| 嵊泗县| 祥云县| 莎车县| 永兴县| 苏尼特左旗| 凉山| 二连浩特市| 张北县| 南京市| 沅陵县| 施甸县| 曲松县| 铜鼓县| 长兴县| 安吉县| 彩票| 靖边县| 临泉县| 西乌| 如东县| 大理市| 南京市| 信丰县| 苍溪县| 沈阳市| 吉安县| 法库县| 澜沧| 大城县| 安泽县| 洪泽县| 高碑店市| 咸阳市| 珲春市| 南涧| 夏河县| 清河县| 体育| 宝清县|