如何在 Delphi 屏幕键盘窗体中使用窗口焦点消息
我的应用程序中需要一个内置的屏幕数字键盘。由于各种原因,我无法使用 TMS 软件 或其他商业组件产品。我对下面所示的基于按钮的解决方案感到非常满意,但我还不知道如何解决焦点切换问题,即单击按钮会激活键盘表单,并且我失去了我想要的角色的焦点控制。如果我将键盘按钮保留在目标表单内,我的解决方案就有效,但我想要一个独立于表单的解决方案。有没有办法禁用按钮激活或知道焦点来自哪里,以便我可以使用类似 Scree.ActiveControl :=?? 的东西?把它放回去?
I need a built-in on screen numeric keypad in my Application. For various reasons I cannot use the TMS Software or other commercial component offerings. I'm very happy with a button-based solution shown below but I cannot yet see how to solve the focus switch issue where clicking the button activates the keypad form and I lose the focused control into which I wanted the characters. My solution works if I keep the keypad buttons within the target form but I would like a form-independent solution. Is there a way of disabling the button activation or knowing where the focus came from so that I can use something like Scree.ActiveControl :=?? to put it back?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以在键盘上使用 TSpeedButton 来执行此任务。 TSpeedButton 不支持 Focus。但表格确实如此。这很丑陋,即使你将焦点放回主窗体,焦点也会在两个窗体之间闪烁。所以我会尝试创建一个没有焦点的表单。
名为 WS_EX_NOACTIVATE 的标志可用于创建一个窗口(窗体),当用户单击它时,该窗口不会成为前台窗口。此外,当用户最小化或关闭前台窗口时,系统不会将此窗口置于前台。
要创建不可激活的窗体,请重写 CreateParams 方法:
当 Delphi 创建窗体时,Create 方法调用 CreateWindowEx API 函数来创建实际的窗口。
在执行 CreateWindowEx 之前,会调用 CreateParams 方法 - CreateParams 允许您在创建窗口时更改窗口的默认样式以满足您的特定需要。
You can use a TSpeedButton for this task on your Keypad. TSpeedButton does not steel the Focus. But the Form does. And this is ugly, even if you give the focus back to your main form, the focus flickers between the two forms. So I would try to create a form without focus.
A flag named WS_EX_NOACTIVATE can be used to create a window (form) that does not become the foreground window when the user clicks it. Also, the system does not bring this window to the foreground when the user minimizes or closes the foreground window.
To create a non activatable form, override the CreateParams method as:
When Delphi creates a form, the Create method calls the CreateWindowEx API function to create the actual window.
Before executing the CreateWindowEx, the CreateParams method is called - CreateParams allows you to change the default style of a window when it is created to suit your particular needs.
我不知道如何创建带有框架的窗口,当您单击它时,该框架无法聚焦,因此下面的窗口是无边框的。正如 Andreas 提到的,使用 TSpeedButtons。
这是显示键盘窗口的方法
I don't know how to create window with the frame which is unfocusable when you click it, so the following one is without border. And as Andreas mentioned, use TSpeedButtons.
And here's how to show the keypad window
我的最终解决方案如下。这将创建一个带有边框的数字键盘,并且 - 是的 - 如果单击边框或调整大小,它确实会激活,但单击按钮不会窃取目标窗体/控件的焦点。简单地使用 CreateParams 对我来说不起作用 - 它似乎需要 WMMouseActivate 消息。
我将其与我发现的例程结合起来,该例程将密钥发布到操作系统,而不仅仅是集中控制。请注意,下面的代码假设来自祖先表单的一些简单支持用于设置默认大小和位置。感谢您的帮助。
My final solution is as follows. This creates a numeric pad with a border and - yes- it does activate if the border is clicked or resized, but clicking the buttons does not steal focus from the target form / control. Simply using CreateParams did not work for me - it seemed to need the WMMouseActivate message instead.
I've combined it with a routine that I found that posts the key to the OS, not just the focused control. Note that code below assumes some simple support from an ancestor form for setting a default size and position. Thanks for all your help.