VBGood网站全文搜索 Google

搜索VBGood全站网页(全文搜索)

VB爱好者乐园(VBGood)

 找回密码
 立即注册
搜索
查看: 8975|回复: 6

[求助] 如何通过Hook拦截菜单句柄

[复制链接]
 楼主| 发表于 2010-6-4 19:36:24 | 显示全部楼层 |阅读模式
本帖最后由 dljdlj70000 于 2010-6-4 19:50 编辑

如何通过Hook拦截菜单句柄
我想获得弹出式或动态菜单的菜单句柄,以便进行控制,例如添加菜单项
 楼主| 发表于 2010-6-4 19:39:35 | 显示全部楼层
有一段delphi代码,哪位大侠帮我转成vb代码
功能简介: 通过Hook拦截菜单句柄,包括Tedit的右键菜单
        作者: Deityfox
         QQ : 58193693
        MSN: Deityfox@hotmail.com
}
unit MenuSubClass;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms;

const
WM_SPECIAL=$01E2; //SPECIAL menu
MENU_CLASS = '#32768';
EDIT_CLASS='TEdit';

type
  TCallbackThunk = packed record
    POPEDX: Byte;
    MOVEAX: Byte;
    SelfPtr: Pointer;
    PUSHEAX: Byte;
    PUSHEDX: Byte;
    JMP: Byte;
    JmpOffset: Integer;
  end;


  TMenuHookCallback =
      procedure(code: Integer; wparam: WPARAM; lparam: LPARAM) of object;

  TOSType=( Win32s,WinNT3,Win95,Win98,WinME,WinNT4,Win2000,WinXP,Win2003);
  TMenuSubClass = class(TComponent)
  private
    { Private declarations }
    log:tstringlist;
    FHook                 : HHOOK;
    FThunk,FThunk1        : TCallbackThunk;
    bSysMenu              : Boolean;
    NewProc               : Pointer;
    OldProc               : Longint;
    HookProc              : Pointer;


    function MenuCallBack(code: Integer; wparam: WPARAM; lparam: LPARAM): LRESULT;stdcall;

  protected
    { Protected declarations }

  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;


  published
    { Published declarations }
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('foxVCL', [TMenuSubClass]);
end;



{ TMenuSubClass }


//hook CallBack Procedure
function TMenuSubClass.MenuCallBack(code: Integer; wparam: WPARAM;
  lparam: LPARAM): LRESULT;
var
  cwps: TCWPStruct;
  lRet: Longint;
  szClass: array[0..8] of char;
  MenuHwnd:Hwnd;
begin
if (Code = HC_ACTION) then
begin
  CopyMemory(@cwps, Pointer(lParam), SizeOf(CWPSTRUCT));
  case cwps.message of
    WM_CONTEXTMENU:
    begin
      //判断是否Tedit
      GetClassName(cwps.wParam, szClass, Length(szClass)-1);
      if (lstrcmpi(szClass,EDIT_CLASS) = 0) then
      begin
       //Tedit 的句柄
        log.add('TEdit Handle: '+inttostr(cwps.wParam));
      end;
    end;
    WM_INITMENUPOPUP:
    begin
    log.add('WM_INITMENUPOPUP ');
    //判断是否系统菜单
    if (getSystemmenu(cwps.hwnd,false)=cwps.wParam) or (hiword(cwps.lParam)<>0) then
      bSysMenu:=true
    else
      bSysMenu:=false;
    end;
    //特殊的菜单??如果没有这个消息好像在9x有些菜单钩不住
    WM_SPECIAL: //$01E2 SPECIAL Menu???
    begin
      log.add('WM_SPECIAL '+inttostr(CWPs.hwnd));
      GetClassName(cwps.hwnd, szClass, Length(szClass)-1);
       // Window name for menu is #32768
       if (lstrcmpi(szClass, MENU_CLASS) = 0) and (not bSysMenu) then
       begin
          log.add('WM_SPECIAL '+inttostr(CWPs.hwnd));
           //cwps.hwnd就是菜单的句柄     
           ////
          //可以对菜单进行子类化
         end;
       end;
    end;

    WM_CREATE:
    begin

      GetClassName(cwps.hwnd, szClass, Length(szClass)-1);
       // Window name for menu is #32768
       if (lstrcmpi(szClass, MENU_CLASS) = 0) and (not bSysMenu) then
       begin
          log.add('WM_CREATE '+inttostr(CWPs.hwnd));
           //cwps.hwnd就是菜单的句柄     
           ////
           //可以对菜单进行子类化
         end;
       end;
    end;
    WM_UNINITMENUPOPUP:bSysMenu:=false;
  end;
  Result:=0;
end;
// Call the next hook in the chain
Result := CallNextHookEx(WH_CALLWNDPROC, Code, wParam, lParam);

end;



constructor TMenuSubClass.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  log:=tstringlist.Create;
  if not (csDesigning in ComponentState) then
  begin
    FThunk.POPEDX:= $5A;
    FThunk.MOVEAX:= $B8;
    FThunk.SelfPtr:= Self;
    FThunk.PUSHEAX:= $50;
    FThunk.PUSHEDX:= $52;
    FThunk.JMP:= $E9;
    FThunk.JmpOffset:= Integer(@TMenuSubClass.MenuCallBack)-Integer(@FThunk.JMP)-5;
    FHook:= SetWindowsHookEx(WH_CALLWNDPROC, TFNHookProc(@FThunk), 0, MainThreadID);
  end;
end;

destructor TMenuSubClass.Destroy;
begin
  log.SaveToFile('e:\log.txt');
  log.Free;
  if not (csDesigning in ComponentState) then
    UnhookWindowsHookEx(FHook);
  inherited Destroy;
end;
end.
回复 支持 反对

使用道具 举报

发表于 2010-6-5 00:18:30 | 显示全部楼层
这个消息: WM_INITMENUPOPUP
wParam 就是弹出菜单的句柄。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-6-5 07:12:17 | 显示全部楼层
WM_INITMENUPOPUP好像只能hook菜单栏上的菜单,不能hook动态菜单或textbox右键菜单
如何hook到textbox右键菜单的菜单句柄啊?
回复 支持 反对

使用道具 举报

发表于 2010-6-5 10:44:06 | 显示全部楼层
先参观一下楼主的Delphi代码……

动态菜单或textbox右键菜单,我是用API钩子 TrackPopupMenuEx实现的……你搜索一下我那个山寨2003菜单看看……
回复 支持 反对

使用道具 举报

发表于 2010-6-5 13:40:55 | 显示全部楼层
4# dljdlj70000

那是你hook的时候用的是me.hwnd,用text1.hwnd应该就可以了。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-6-27 19:06:34 | 显示全部楼层
哦 谢谢
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

文字版|手机版|小黑屋|VBGood  

GMT+8, 2019-9-22 01:43

VB爱好者乐园(VBGood)
快速回复 返回顶部 返回列表