背景:我的表单有一个TWebBrowser。我想用ESC关闭表单,但是TWebBrowser吃了键盘 - 所以我决定使用键盘钩。
问题是Form可以在多个实例中同时打开。
无论我做什么,在某些情况下,如果我的表单有两个实例打开,关闭其中一个也会关闭另一个。
我附上了一些示例代码。有关导致问题的原因的任何想法?
var
EmailDetailsForm: TEmailDetailsForm;
KeyboardHook: HHook;
implementation
function KeyboardHookProc(Code: Integer; wParam, lParam: LongInt): LongInt; stdcall;
var
hWnd: THandle;
I: Integer;
F: TForm;
begin
if Code < 0 then
Result := CallNextHookEx(KeyboardHook, Code, wParam, lParam)
else begin
case wParam of
VK_ESCAPE:
if (lParam and $80000000) <> $00000000 then
begin
hWnd := GetForegroundWindow;
for I := 0 to Screen.FormCount - 1 do
begin
F := Screen.Forms[I];
if F.Handle = hWnd then
if F is TEmailDetailsForm then
begin
PostMessage(hWnd, WM_CLOSE, 0, 0);
Result := HC_SKIP;
break;
end;
end; //for
end; //if
else
Result := CallNextHookEx(KeyboardHook, Code, wParam, lParam);
end; //case
end; //if
end;
function TEmailDetailsForm.CheckInstance: Boolean;
var
I, J: Integer;
F: TForm;
begin
Result := false;
J := 0;
for I := 0 to Screen.FormCount - 1 do
begin
F := Screen.Forms[I];
if F is TEmailDetailsForm then
begin
J := J + 1;
if J = 2 then
begin
Result := true;
break;
end;
end;
end;
end;
procedure TEmailDetailsForm.FormCreate(Sender: TObject);
begin
if not CheckInstance then
KeyboardHook := SetWindowsHookEx(WH_KEYBOARD, @KeyboardHookProc, 0, GetCurrentThreadId());
end;
procedure TEmailDetailsForm.FormDestroy(Sender: TObject);
begin
if not CheckInstance then
UnHookWindowsHookEx(KeyboardHook);
end;
答案 0 :(得分:1)
您可以使用TApplicationEvents.OnMessage
执行此操作。使用以下代码在应用程序的主窗体上删除TApplicationEvents组件:
procedure TMainForm.ApplicationEvents1Message(var Msg: tagMSG;
var Handled: Boolean);
var
C: TControl;
H: HWND;
begin
if (Msg.message = WM_KEYDOWN) and (Msg.wParam = VK_ESCAPE) then begin
H := Msg.hwnd;
while GetParent(H) <> 0 do
H := GetParent(H);
C := FindControl(H);
if C is TEmailDetailsForm then begin
TEmailDetailsForm(C).Close;
Handled := True;
end;
end;
end;
如果你想继续使用键盘钩子,你应该只挂钩一次,而不是每个表格一次,特别是因为你覆盖了一个全局变量。尝试添加一个HookCount全局变量,如果它是唯一的形式,则只挂钩/取消挂钩。
答案 1 :(得分:0)
背景:我的表格有一个 TWebBrowser。我想关闭表格 用ESC但是TWebBrowser吃掉了 击键 - 所以我决定去一个 键盘钩。
可能有一个更简单的解决方案。您是否尝试将表单的KeyPreview属性设置为True
?
答案 2 :(得分:0)
好吧,两个表格都已注册接收键盘通知,因此它们都关闭了。 你需要在那里放置代码来决定“这是我的ESC吗?”。也许通过确定你是否是焦点窗口。如果它不是您的ESCape,那么请不要关闭。
但是,这一切看起来都相当激烈。必须有一种更简单,非突兀的方法来检测此APP中的ESC,而无需监控整个系统的键盘。