delphi – 如何在拖动时避免表单获得焦点

我有一个只包含TTouchKeyboard的简单表单.表单BorderStyle设置为bsToolWindow.为了避免在单击触摸键盘时获得焦点,我使用此实现处理WM_MOUSEACTIVATE消息:
procedure TKeyboardForm.WMMouseActivate(var Message: TWMMouseActivate);
begin
  Message.Result := MA_NOACTIVATE;
end;

BorderStyle设置允许使用标题栏拖动表单,但在这种情况下,表单仍然获得焦点.有没有办法避免这种情况?

更新:我尝试在CreateParams中将WS_EX_NOACTIVATE添加到ExStyle,但不幸的是,这不会阻止表单在拖动时获得焦点.

procedure TKeyboardForm.CreateParams(var Params: TCreateParams);
begin
  inherited;
  Params.ExStyle := Params.ExStyle or WS_EX_NOACTIVATE;
end;

解决方法

WMMouseActivate(),WMNCActivate()和重置焦点的以下组合似乎满足您的愿望:

键盘形式(使用BorderStyle = bsToolWindow)具有WM_MOUSEACTIVATE(正如您已有)和WM_NCACTIVATE的消息处理程序.后者有一个点,用编辑控件将焦点重置到窗口.

此外,keyboardform将跟踪哪个表单保存了具有焦点的编辑(或其他)控件,并通过引入一个新的显示方法(我称之为ShowUnfocused())和一个名为FocusedForm:THandle的字段来实现.

procedure TKbdForm.ShowUnfocused(FocusedWindow: THandle);
begin
  FocusedForm := FocusedWindow;
  Show;
end;

procedure TKbdForm.FormShow(Sender: TObject);
begin
  SetForegroundWindow(FocusedForm);
end;

procedure TKbdForm.WMMouseActivate(var Message: TWMMouseActivate);
begin
  Message.Result := MA_NOACTIVATE;
end;

procedure TKbdForm.WMNCActivate(var Message: TWMNCActivate);
begin
  Message.Result := 1; // important
  SetForegroundWindow(FocusedForm);
end;

Keyboardform由以下编辑控件的常用代码调用

procedure TForm17.EditClick(Sender: TObject);
begin
  KbdForm.ShowUnfocused(self.Handle);
  (Sender as TWinControl).SetFocus;
end;

上述内容的替代方法可以是设置BorderStyle = bsNone并使用Mouse Down,Move,Up事件直接从表单表面(或者可能是模板顶部框架的面板)排列表单的拖动,以及添加关闭按钮.挑战在于让它在视觉上可以接受.

相关文章

 从网上看到《Delphi API HOOK完全说明》这篇文章,基本上都...
  从网上看到《Delphi API HOOK完全说明》这篇文章,基本上...
ffmpeg 是一套强大的开源的多媒体库 一般都是用 c/c+&#x...
32位CPU所含有的寄存器有:4个数据寄存器(EAX、EBX、ECX和ED...
1 mov dst, src dst是目的操作数,src是源操作数,指令实现的...