delphi 如何为PopupList.窗口挂接WH_KEYBOARD?

1cklez4t  于 2023-02-22  发布在  其他
关注(0)|答案(1)|浏览(126)

我需要知道是否按下F11时,托盘图标的弹出菜单是打开和终止程序。不希望RegisterHotKey。文档指出,“PopupList.Window提供了对处理弹出菜单消息的隐藏窗口的窗口句柄的访问”。因此,我的计划是拦截键盘消息到该窗口,但相反,这是发生了什么:
项目Project2.exe引发异常类$C0000005,并显示消息“在0x00020003发生访问冲突:写入地址0x2014fd38 '。

unit Unit2;

interface

uses
    Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
    Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ImgList, Vcl.Menus, Vcl.ExtCtrls;

type
    TForm2 = class(TForm)
        TrayIcon1: TTrayIcon;
        PopupMenu1: TPopupMenu;
        N11: TMenuItem;
        N21: TMenuItem;
        ImageList1: TImageList;
        procedure PopupMenu1Popup(Sender: TObject);
private
    function hook(code: Integer; w: WPARAM; p : LPARAM): Lresult stdcall;
public
    { Public declarations }
end;

var
    Form2: TForm2;
    HookID: hhook;
implementation

{$R *.dfm}
function TForm2.hook(code: Integer; w: WPARAM; p: LPARAM): Lresult stdcall;
begin
    if code < 0 then
    begin
        Result := CallNextHookEx(0, code, w, p);
        Exit;
    end;

    Result := CallNextHookEx(0, code, w, p);
end;

procedure TForm2.PopupMenu1Popup(Sender: TObject);
begin
    HookID := SetWindowsHookEx(WH_KEYBOARD, @TForm2.hook, 0,
        GetWindowThreadProcessId(PopupList.Window, nil));
end;

end.
e0uiprwp

e0uiprwp1#

你的钩子函数是TForm2的一个方法,因此传递了一个额外的(隐藏的)self参数。你应该把这个函数放在TForm2之外:

TForm2 = class(TForm)
        TrayIcon1: TTrayIcon;
        PopupMenu1: TPopupMenu;
        N11: TMenuItem;
        N21: TMenuItem;
        ImageList1: TImageList;
        procedure PopupMenu1Popup(Sender: TObject);
    private
    public
        { Public declarations }
    end;

    function hook(code: Integer; w: WPARAM; p : LPARAM): Lresult stdcall;

implementation

function hook(code: Integer; w: WPARAM; p: LPARAM): Lresult stdcall;
begin
    if code < 0 then
    begin
        Result := CallNextHookEx(0, code, w, p);
        Exit;
    end;

    Result := CallNextHookEx(0, code, w, p);
end;

相关问题