背景:我的表单有一个TWebBrowser。我想用ESC关闭窗体,但是TWebBrowser吃了击键 - 所以我决定用键盘挂钩。键盘钩子问题
问题是表单可以在多个实例中同时打开。
无论我做什么,在某些情况下,如果有两个实例打开我的表单,关闭其中一个关闭另一个。
我附上了一些示例代码。对导致此问题的原因有何看法?
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;
谢谢,这似乎工作得很好! – Steve 2010-04-06 18:43:56