熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Delphi編程 >> 正文

Delphi中利用鉤子實現QQ聊天窗口的修改

2013-11-23 17:35:43  來源: Delphi編程 
  你曾為公司不讓用QQMSN等聊天工具而煩惱嗎?看了下面的小程序你就會打消這種看法了

  當初公司做校園一卡通的項目時裡面的機房客戶端需要用到系統的低級鍵盤鉤子WH_KEYBOARD_LL這也是我第一次接觸到Windows中的Hook因為WH_KEYBOARD_LL和其他鉤子不一樣在Delphi的Windows幫助以及windowspas文件中都沒有定義但microsoft的msdn中確有WH_KEYBOARD_LL的介紹所以一路解決後就對Windows的系統鉤子產生了興趣之後相繼做過鼠標鉤子WH_MOUSE低級鼠標鉤子WH_MOUSE_LL以及消息鉤子WH_GETMESSAGE的小例子都很有意思

  這次我用到的是另外一個系統鉤子WH_CBT

  看了delphi中的幫助發現CBTProc中有很多功能

  HCBT_ACTIVATE
  HCBT_CREATEWND
  HCBT_DESTROYWND
  HCBT_MINMAX
  HCBT_MOVESIZE
  HCBT_SETFOCUS
  HCBT_SYSCOMMAND

  (具體就不介紹了看看幫助裡寫的很清楚)

  隨後便開始試驗起來最終完成了這個小程序下面我簡單介紹一下

  運行程序後自動隱藏當你提取QQ或者MSN的消息時會驚奇的發現聊天窗口的那個討厭的與XX聊天的標題沒有了而標題換成了我的文檔這時如果你再將此聊天窗口的圖標換成文檔樣式的圖標那麼誰還能看出那就是你的聊天窗口呢?(更換圖標的方法也很多可以用程序也可以用軟件直接修改QQ的資源文件這部分我沒有做這裡只是提供大家一個思路有興趣的朋友可以自己嘗試一下呵呵)

  下面將代碼帖出

library HookPrj;

uses
 SysUtils
 Classes
 QQTitleHook in QQTitleHookpas;

 exports
EnableWheelHook DisableWheelHook;

begin
 hkQQChat:= ;
end

unit QQTitleHook;

interface

uses
 Windows Messages SysUtils Dialogs CommCtrl StrUtils;

var
 hkQQChat: HHOOK;
 //聊天窗口的句柄
 hwQQChat: HWnd ;
 //聊天窗口的標題
 tlQQChat: string;
 //窗口類名
 clsName: string;
 buf: array [] of char;

 const
  //QQ聊天窗口的類名
  csQQ = #;

 function TitleHookProc(Code: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
 function EnumWindowsTitleFunc(Handle: THandle; lParam: LPARAM): boolean ; stdcall;
 function EnableWheelHook : Boolean; stdcall; export;
 function DisableWheelHook: Boolean; stdcall; export;

 implementation
 
 //鉤子的處理函數
 function TitleHookProc(Code: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
 begin
  Result:= ;
  if Code< then
  begin
   Result:= CallNextHookEx(hkQQChat Code wParam lParam);
   Exit;
  end
  else
   if Code = HCBT_ACTIVATE then
   begin
    //獲取激活窗口的句柄以及窗口類名然後判斷此窗口類名是否為#
    hwQQChat:= HWND(wParam);
    GetClassName(hwQQChat buf );
    clsName:= string(buf);
    if clsName = csQQ then
    begin
  //如果窗口類名是#則遍枚舉所有窗口並將窗口句柄傳入
//【這裡僅僅做演示用因為Windows中很多窗口的類名均為#所以這樣判斷效率會很低】
//【有興趣的朋友可以根據QQ聊天窗口的特性來增加判斷條件從而提高效率
     EnumWindows(@EnumWindowsTitleFunc hwQQChat);
    end;
   end;
  end;

 function EnumWindowsTitleFunc(Handle: THandle; lParam: LPARAM): boolean ; stdcall;
 begin
  if (Handle = lParam) and boolean(GetWindowText(Handle buf )) then
  begin
   //根據窗口句柄獲得窗口標題
   tlQQChat:= string(buf);
   //然後判斷標題中是否包含聊天等相關字符如果包括則此窗口為QQ聊天窗口
   if ((pos( tlQQChat)>) and (pos(聊天中 tlQQChat)>)) then
   begin
    //確定為聊天窗口後遍修改窗口標題
    tlQQChat := AnsiReplaceStr(tlQQChat 我的文檔);
    tlQQChat := AnsiReplaceStr(tlQQChat 聊天中 );
    SetWindowText(Handle pchar(tlQQChat));
   end;
   //【同上這個地方大家可以自由控制不僅僅局限在QQMSN等聊天窗口
   //【且想要將標題改成什麼也可以自由控制如果能根據修改後的窗口圖標來確定標題】
   //【比如通過修改將窗口圖標替換成Delphi的圖標然後標題修改為Delphi誰還能看出破綻呢?哈哈】
   if ((pos(群 - tlQQChat)>) or (pos(高級群 - tlQQChat)>)) then
   begin
    tlQQChat := AnsiReplaceStr(tlQQChat 群 - 我的文檔);
    tlQQChat := AnsiReplaceStr(tlQQChat 高級 );
    SetWindowText(Handle pchar(tlQQChat));
   end;
   //MSN
   if pos( 對話 tlQQChat)> then
   begin
    tlQQChat := AnsiReplaceStr(tlQQChat 對話 我的文檔);
    SetWindowText(Handle pchar(tlQQChat));
   end;
  end;
  Result :=True;
 end;

 //啟動鉤子
 function EnableWheelHook: Boolean; stdcall; export;
 begin
  if hkQQChat= then
  begin
   hkQQChat := SetWindowsHookEx(WH_CBT @TitleHookProc Hinstance );
   Result := True;
  end
  else
   Result := False;
  end;

  //卸載鉤子
  function DisableWheelHook: Boolean; stdcall; export;
  begin
   if hkQQChat<> then
   begin
    UnHookWindowsHookEx(hkQQChat);
    hkQQChat := ;
    Result := True;
   end
   else
    Result := False;
   end;

  end

  調用的應用程序就很簡單了調用EnableWheelHook後隱藏就可以了退出時DisableWheelHook就OK啦

  程序僅僅提供大家一個思路還有很多不完善的地方希望有興趣的朋友聯系我共同交流提高


From:http://tw.wingwit.com/Article/program/Delphi/201311/24742.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.