library TmHook; uses 
  SysUtils, 
  Classes, 
  Windows, 
  Messages, 
  CommCtrl; 
var 
  hhook: Windows.HHOOK; 
  hwndListView: HWND; 
  na:array[0..300] of char; 
  oldWndProc: Integer; 
{$R *.res} 
function WindowProc(hwnd: HWND; msg: UINT; wp: WPARAM; lp: LPARAM): LRESULT; stdcall; 
  begin 
  case Msg of 
    WM_LBUTTONDOWN: 
    MessageBox(hwndListView,'你好!','提示',MB_OK); 
  end; 
  Result := CallWindowProc(TFNWndProc(oldWndProc), hwnd, msg, wp, lp); 
end; 
function TmHookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): Integer; stdcall; 
var 
  cwp: PCwpStruct; 
  m:TPoint; 
begin 
  Result := 0; 
  if (nCode < 0) then 
  begin 
    Result := CallNextHookEx(hhook, nCode, wParam, lParam); 
    exit; 
  end; 
  cwp := PCwpStruct(lParam); 
  if cwp^.message <> WM_COMMAND then 
  begin 
    Result := CallNextHookEx(hhook, nCode, wParam, lParam); 
    exit; 
  end; 
  GetCursorPos(m); 
  GetWindowText(WindowFromPoint(m),na,299); 
  if lstrcmpi('发送(S)',na) <>0 then 
  begin 
    Result := CallNextHookEx(hhook, nCode, wParam, lParam); 
    exit; 
  end; 
  hwndListView:=WindowFromPoint(m); 
  oldWndProc := SetWindowLong(hwndListView, GWL_WNDPROC, Integer(@WindowProc)); 
  end; 
procedure Hook(bEnable: Boolean); stdcall; export; 
begin 
  if bEnable then 
  begin 
    if hhook = 0 then 
    begin 
      hhook := SetWindowsHookEx(WH_CALLWNDPROC, TmHookProc, HInstance, 0); 
    end; 
  end 
  else 
  begin 
    if hhook <> 0 then 
    begin 
      UnhookWindowsHookEx(hhook); 
      hhook := 0; 
    end; 
  end; 
end; 
exports 
  Hook; 
begin 
  hhook := 0; 
  hwndListView := 0; 
  oldWndProc:=0; 
end. 
到底哪里错了,一运行,qq就自动关闭?? 
我在学子类化,这段代码测试了很久,都没有找出原因?

解决方案 »

  1.   

    etomahawk 很忙。呵呵,帮你顶一下。
      

  2.   

    公司把网络封了,不能上网,现在只能回来看看。在我这里测试没有你说的问题,不知道是不是QQ版本的问题。我的是QQ 2008 Beta1.可能是QQ做了保护,不允许你这样做。
      

  3.   


    etomahawk,你的意思是说,qq2008测试我上面的代码一切正常吗?
      

  4.   

    首先,你的hhook不是全局共享的,因为Hook和TmHookProc不是在一个进程空间中执行的
    其次,你应该用Spy++先看一下,貌似新的QQ的聊天窗体都是全部自绘的(所以才那么好看),按钮根本没有句柄
      

  5.   

    GetCursorPos(m); 
    GetWindowText(WindowFromPoint(m),na,299); 
    if lstrcmpi('发送(S)',na) <>0 then 
    用这种方法好像失去了钩住WM_COMMAND的意义!建议更换钩子类型。如果楼主可以提供一个编程环境,5分钟内解决你的问题,而且是无DLL的钩子。你不能,所以我再次路过...
      

  6.   

    为学习,请教三个专家.可见,我急于得到代码的心情
    本想得到三种不同风格的代码,让我推敲.用这种方法好像失去了钩住WM_COMMAND的意义!建议更换钩子类型。 
    更换钩子类型可以,但一定要子类化,我就学它吗?
      

  7.   

    http://topic.csdn.net/u/20081118/16/2fb814e9-76af-4883-8e81-9b599bb83ebc.html?seed=1656828274