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

Uwe*_*abe 7 delphi focus window

我有一个只包含一个简单的表单TTouchKeyboard.表单BorderStyle设置为bsToolWindow.为了避免在单击触摸键盘时获得焦点,我WM_MOUSEACTIVATE使用此实现处理消息:

procedure TKeyboardForm.WMMouseActivate(var Message: TWMMouseActivate);
begin
  Message.Result := MA_NOACTIVATE;
end;
Run Code Online (Sandbox Code Playgroud)

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

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

procedure TKeyboardForm.CreateParams(var Params: TCreateParams);
begin
  inherited;
  Params.ExStyle := Params.ExStyle or WS_EX_NOACTIVATE;
end;
Run Code Online (Sandbox Code Playgroud)

Tom*_*erg 2

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

键盘表单(带有BorderStyle = bsToolWindow)具有WM_MOUSEACTIVATE(正如您已经拥有的)和的消息处理程序WM_NCACTIVATE。后者用于使用编辑控件将焦点重置到窗口。

此外,键盘窗体将跟踪哪个窗体拥有具有焦点的编辑(或其他)控件,并通过引入一种新的显示方法(我将其称为 )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;
Run Code Online (Sandbox Code Playgroud)

键盘窗体由编辑控件的以下公共代码调用:

procedure TForm17.EditClick(Sender: TObject);
begin
  KbdForm.ShowUnfocused(self.Handle);
  (Sender as TWinControl).SetFocus;
end;
Run Code Online (Sandbox Code Playgroud)

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