在一个应用程序上,我有一个键盘钩子,当按下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;
因此,即使对话框仍然打开,执行键盘钩子并关闭表单.
根本问题是你(ab)使用键盘钩子.这是一个全局事件,您需要检测更多本地键盘事件.你应该安排你的Delphi表格来听取ESC被按下的键.
在我的头脑中,我不确定MDI表格或MDI儿童是否会收到该活动,但无论您需要在那里处理它.可能你会需要设置KeyPreview为True这个工作.
更一般地说,如果要采用全局方法,键盘钩子仍然是错误的工具.您使用的工具将是对象的OnMessage事件Application.这连接到应用程序的主消息队列,任何Delphi模态消息泵都从ShowModal调用运行.将处理放在那里意味着您将检测发往VCL表单的键盘事件,但是您不会为非VCL模式窗口(如文件对话框,Win32消息框等)选取键盘事件.
| 归档时间: |
|
| 查看次数: |
755 次 |
| 最近记录: |