你曾为公司不让用QQ
MSN等聊天工具而烦恼吗?看了下面的小程序你就会打消这种看法了
当初公司做校园一卡通的项目时里面的机房客户端需要用到系统的低级键盘钩子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啦
程序仅仅提供大家一个思路还有很多不完善的地方希望有兴趣的朋友联系我共同交流提高