Delphi中使用鉤子完成QQ聊天窗口的更改
發(fā)表時(shí)間:2024-02-18 來(lái)源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]有人曾為公司不讓用QQ、MSN等聊天工具而煩惱嗎?看了下面的小程序你就會(huì)打消這種看法了。 當(dāng)初公司做校園一卡通的項(xiàng)目時(shí),里面的機(jī)房客戶端需要用到系統(tǒng)的低級(jí)鍵盤鉤子WH_KEYBOARD_LL,這也是我第一次接觸到Windows中的Hook,因?yàn)閃H_KEYBOARD_LL和其他鉤子不一樣,在De...
有人曾為公司不讓用QQ、MSN等聊天工具而煩惱嗎?看了下面的小程序你就會(huì)打消這種看法了。
當(dāng)初公司做校園一卡通的項(xiàng)目時(shí),里面的機(jī)房客戶端需要用到系統(tǒng)的低級(jí)鍵盤鉤子WH_KEYBOARD_LL,這也是我第一次接觸到Windows中的Hook,因?yàn)閃H_KEYBOARD_LL和其他鉤子不一樣,在Delphi的Windows幫助以及windows.pas文件中都沒(méi)有定義,但microsoft的msdn中確有WH_KEYBOARD_LL的介紹,所以一路解決后就對(duì)Windows的系統(tǒng)鉤子產(chǎn)生了興趣。之后相繼做過(guò)鼠標(biāo)鉤子WH_MOUSE、低級(jí)鼠標(biāo)鉤子WH_MOUSE_LL以及消息鉤子WH_GETMESSAGE的小例子,都很有意思。
這次我用到的是另外一個(gè)系統(tǒng)鉤子:WH_CBT。
看了delphi中的幫助,發(fā)現(xiàn)CBTProc中有很多功能:
HCBT_ACTIVATE
HCBT_CREATEWND
HCBT_DESTROYWND
HCBT_MINMAX
HCBT_MOVESIZE
HCBT_SETFOCUS
HCBT_SYSCOMMAND
(具體就不介紹了,看看幫助里寫的很清楚)
隨后便開(kāi)始試驗(yàn)起來(lái),最終完成了這個(gè)小程序。下面我簡(jiǎn)單介紹一下:
運(yùn)行程序后自動(dòng)隱藏,當(dāng)你提取QQ或者M(jìn)SN的消息時(shí)會(huì)驚奇的發(fā)現(xiàn)聊天窗口的那個(gè)討厭的“與XX聊天”的標(biāo)題沒(méi)有了,而標(biāo)題換成了“我的文檔”。這時(shí)如果你再將此聊天窗口的圖標(biāo)換成文檔樣式的圖標(biāo),那么誰(shuí)還能看出那就是你的聊天窗口呢?(更換圖標(biāo)的方法也很多,可以用程序,也可以用軟件直接修改QQ的資源文件,這部分我沒(méi)有做,這里只是提供大家一個(gè)思路,有興趣的朋友可以自己嘗試一下,呵呵)。
下面將代碼帖出:
library HookPrj;
uses
SysUtils,
Classes,
QQTitleHook in ’QQTitleHook.pas’;
exports
EnableWheelHook, DisableWheelHook;
begin
hkQQChat:= 0;
end.
==========================================================
unit QQTitleHook;
interface
uses
Windows, Messages, SysUtils, Dialogs, CommCtrl, StrUtils;
var
hkQQChat: HHOOK;
//聊天窗口的句柄
hwQQChat: HWnd ;
//聊天窗口的標(biāo)題
tlQQChat: string;
//窗口類名
clsName: string;
buf: array [0..1024] of char;
const
//QQ聊天窗口的類名
csQQ = ’#32770’;
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
//鉤子的處理函數(shù)
function TitleHookProc(Code: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
Result:= 0;
if Code<0 then
begin
Result:= CallNextHookEx(hkQQChat, Code, wParam, lParam);
Exit;
end
else
if Code = HCBT_ACTIVATE then
begin
//獲取激活窗口的句柄,以及窗口類名,然后判斷此窗口類名是否為#32770。
hwQQChat:= HWND(wParam);
GetClassName(hwQQChat, buf, 1024);
clsName:= string(buf);
if clsName = csQQ then
begin
//如果窗口類名是#32770,則遍枚舉所有窗口,并將窗口句柄傳入
//【這里僅僅做演示用,因?yàn)閃indows中很多窗口的類名均為#32770,所以這樣判斷效率會(huì)很底,】
//【有興趣的朋友可以根據(jù)QQ聊天窗口的特性來(lái)增加判斷條件,從而提高效率。】
EnumWindows(@EnumWindowsTitleFunc, hwQQChat);
end;
end;
end;
function EnumWindowsTitleFunc(Handle: THandle; lParam: LPARAM): boolean ; stdcall;
begin
if (Handle = lParam) and boolean(GetWindowText(Handle, buf, 256)) then
begin
//根據(jù)窗口句柄獲得窗口標(biāo)題
tlQQChat:= string(buf);
//然后判斷標(biāo)題中是否包含“與...聊天”等相關(guān)字符,如果包括則此窗口為QQ聊天窗口
if ((pos(’與’, tlQQChat)>0) and (pos(’聊天中’, tlQQChat)>0)) then
begin
//確定為聊天窗口后遍修改窗口標(biāo)題。
tlQQChat := AnsiReplaceStr(tlQQChat, ’與’ , ’我的文檔’);
tlQQChat := AnsiReplaceStr(tlQQChat, ’聊天中’, ’’ );
SetWindowText(Handle, pchar(tlQQChat));
end;
//【同上,這個(gè)地方大家可以自由控制,不僅僅局限在QQ、MSN等聊天窗口。】
//【而且想要將標(biāo)題改成什么也可以自由控制,如果能根據(jù)修改后的窗口圖標(biāo)來(lái)確定標(biāo)題】
//【比如通過(guò)修改將窗口圖標(biāo)替換成Delphi的圖標(biāo),然后標(biāo)題修改為Delphi7,誰(shuí)還能看出破綻呢?哈哈】
if ((pos(’群 -’, tlQQChat)>0) or (pos(’高級(jí)群 -’, tlQQChat)>0)) then
begin
tlQQChat := AnsiReplaceStr(tlQQChat, ’群 -’, ’我的文檔’);
tlQQChat := AnsiReplaceStr(tlQQChat, ’高級(jí)’ , ’’ );
SetWindowText(Handle, pchar(tlQQChat));
end;
//MSN
if pos(’ - 對(duì)話’, tlQQChat)>0 then
begin
tlQQChat := AnsiReplaceStr(tlQQChat, ’ - 對(duì)話’ , ’我的文檔’);
SetWindowText(Handle, pchar(tlQQChat));
end;
end;
Result :=True;
end;
//啟動(dòng)鉤子
function EnableWheelHook: Boolean; stdcall; export;
begin
if hkQQChat=0 then
begin
hkQQChat := SetWindowsHookEx(WH_CBT, @TitleHookProc, Hinstance, 0);
Result := True;
end
else
Result := False;
end;
//卸載鉤子
function DisableWheelHook: Boolean; stdcall; export;
begin
if hkQQChat<>0 then
begin
UnHookWindowsHookEx(hkQQChat);
hkQQChat := 0;
Result := True;
end
else
Result := False;
end;
end.
====================================
調(diào)用的應(yīng)用程序就很簡(jiǎn)單了,調(diào)用EnableWheelHook后隱藏就可以了,退出時(shí)DisableWheelHook就OK啦。
程序僅僅提供大家一個(gè)思路,還有很多不完善的地方,希望有興趣的朋友聯(lián)系我,共同交流提高。