Delphi - 打开对话框时激活键盘钩子

RBA*_*RBA -1 delphi delphi-xe

在一个应用程序上,我有一个键盘钩子,当按下Escape按钮时它会关闭MDI子窗体.打开TOpenDialog类后代时出现问题(使用Execute).考虑以下代码(仅作为示例)

unit Unit4;

interface

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

type
  TForm4 = class(TForm)
    OpenDialog1: TOpenDialog;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

function KeyboardProc(code: integer; wp: WPARAM; lp: LPARAM): LResult stdcall;
function CanDoCloseOnEscape: boolean;

var
  Form4: TForm4;
  KeybHook : HHook;


implementation

{$R *.dfm}

function CanDoCloseOnEscape: boolean;
var
  Control: TWinControl;
  Form: TForm;
begin
  Control := Screen.ActiveControl;
  Form := Screen.ActiveForm;
  Result := true;
end;

function KeyboardProc(code: integer; wp: WPARAM; lp: LPARAM): LResult stdcall;
begin
  case wp of
    VK_ESCAPE:
      if CanDoCloseOnEscape then
      begin
        PostMessage(Screen.ActiveForm.Handle, WM_Close, 0, 0);
        exit;
      end;
  end;
end;

procedure TForm4.Button1Click(Sender: TObject);
begin
 if OpenDialog1.Execute then
  begin
    ShowMessage('executed');
  end;
end;

initialization
  KeybHook := SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, hInstance,GetWindowTask(application.Handle));

finalization
  UnhookWindowsHookEx(KeybHook);

end.
Run Code Online (Sandbox Code Playgroud)

Control:= Screen.ActiveControl;

  • 没有将opendialog作为主动控制.

因此,即使对话框仍然打开,执行键盘钩子并关闭表单.

Dav*_*nan 6

根本问题是你(ab)使用键盘钩子.这是一个全局事件,您需要检测更多本地键盘事件.你应该安排你的Delphi表格来听取ESC被按下的键.

在我的头脑中,我不确定MDI表格或MDI儿童是否会收到该活动,但无论您需要在那里处理它.可能你会需要设置KeyPreviewTrue这个工作.

更一般地说,如果要采用全局方法,键盘钩子仍然是错误的工具.您使用的工具将是对象的OnMessage事件Application.这连接到应用程序的主消息队列,任何Delphi模态消息泵都从ShowModal调用运行.将处理放在那里意味着您将检测发往VCL表单的键盘事件,但是您不会为非VCL模式窗口(如文件对话框,Win32消息框等)选取键盘事件.