我有一个只包含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事件直接从表单表面(或者可能是模板顶部框架的面板)排列表单的拖动,以及添加关闭按钮.挑战在于让它在视觉上可以接受.