如何使用Delphi屏幕键盘表单的窗口焦点消息

Bri*_*ost 8 forms delphi keyboard focus

我的应用程序中需要一个内置的屏幕数字小键盘.由于各种原因,我无法使用TMS软件或其他商业组件产品.我对下面显示的基于按钮的解决方案非常满意,但我还不知道如何解决焦点切换问题,单击按钮激活键盘形式,我失去了我想要角色的聚焦控制.如果我将键盘按钮保持在目标表单中,但我想要一个独立于表单的解决方案,我的解决方案是有效的.有没有办法禁用按钮激活或知道焦点来自哪里,以便我可以使用像Scree.ActiveControl:= ?? 把它还掉?

在此输入图像描述

And*_*eas 5

您可以在键盘上使用TSpeedButton执行此任务.TSpeedButton并没有为Focus提供支持.但表格确实如此.这很丑陋,即使你把焦点放回到你的主要形式,两个形式之间的焦点也会闪烁.所以我会尝试创建一个没有焦点的表单.

名为WS_EX_NOACTIVATE的标志可用于创建窗口(窗体),该窗口在用户单击时不会成为前台窗口.此外,当用户最小化或关闭前景窗口时,系统不会将此窗口置于前台.

要创建不可激活的表单,请将CreateParams方法覆盖为:

procedure TMainForm.CreateParams(var Params: TCreateParams) ;
 //const WS_EX_NOACTIVATE = $8000000;
 begin
   inherited;
   Params.ExStyle := Params.ExStyle + WS_EX_NOACTIVATE;
 end;
Run Code Online (Sandbox Code Playgroud)

当Delphi创建表单时,Create方法调用CreateWindowEx API函数来创建实际窗口.

在执行CreateWindowEx之前,会调用CreateParams方法 - CreateParams允许您在创建窗口时更改窗口的默认样式以满足您的特定需求.


小智 2

我不知道如何创建带有框架的窗口,当您单击它时,该框架无法聚焦,因此下面的窗口是无边框的。正如 Andreas 提到的,使用 TSpeedButtons。

type
  TKeypadForm = class(TForm)
    SpeedButton1: TSpeedButton;
    procedure SpeedButton1Click(Sender: TObject);
  private
    procedure CreateParams(var Params: TCreateParams); override;
    procedure WMMouseActivate(var Message: TWMMouseActivate); message WM_MOUSEACTIVATE;
  end;

procedure TKeypadForm.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  Params.Style := WS_POPUP or WS_THICKFRAME;
end;

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

procedure TKeypadForm.SpeedButton1Click(Sender: TObject);
begin
  PostMessage(GetFocus, WM_KEYDOWN, VK_NUMPAD1, MakeLong(0, MapVirtualKey(VK_NUMPAD1, 0)));
end;
Run Code Online (Sandbox Code Playgroud)

这是显示键盘窗口的方法

procedure TForm18.Edit1KeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  case Key of
    VK_RETURN: ShowWindow(KeypadForm.Handle, SW_SHOWNOACTIVATE);
    VK_ESCAPE: ShowWindow(KeypadForm.Handle, SW_HIDE);
  end;
end;
Run Code Online (Sandbox Code Playgroud)