当表单没有焦点时,如何防止表单处理热键?
Posted
技术标签:
【中文标题】当表单没有焦点时,如何防止表单处理热键?【英文标题】:How to I keep forms from handling hotkeys when they don't have the focus? 【发布时间】:2013-03-20 03:05:08 【问题描述】:我们有一个 Delphi XE2 应用程序。 Form1
有热键 Ctrl+F,Form2
是活动的,没有热键。用户在Form2
上按Ctrl+F 和Form1
处理热键。这是完全不正确的,因为我们看到了非活动形式的活动。我该如何解决?
【问题讨论】:
Form1 是 MainForm 对吧?这就是重点 你有两个无模式表单,对吧?这就是 Windows 键盘加速器的工作原理。 Form1 和 Form2 不是主窗体。 我只想让热键只在活动表单上工作。我们的客户也是如此。 【参考方案1】:我使用动作来实现所有快捷键处理。如果您这样做,那么您可以使用操作、操作列表、操作管理器等提供的集中化功能,根据表单是否处于活动状态来启用和禁用所有操作。
例如,通过在表单的OnActivate
和OnDeactivate
事件处理程序上设置操作列表的State
属性来做到这一点:
procedure TMyForm.FormActivate(Sender: TObject);
begin
ActionList.State := asNormal;
end;
procedure TMyForm.FormDeactivate(Sender: TObject);
begin
ActionList.State := asSuspended;
end;
【讨论】:
如果您的 MyForm 中有其他表单,这将无法正常工作。然后 MyForm 可能会在它仍然具有焦点时被停用。 所以我宁愿推荐一个 WM_ACTIVATE 处理程序: if msg.wParam = WA_INACTIVE then actionList.state := asSuspended else actionList.state := asNormal;【参考方案2】:您可以在热键处理程序中添加对active form 的检查,即
if(Screen.ActiveForm <> Self)then Exit;
这是假设事件处理程序由Form1
实现(即Self
然后在处理程序内部)。
【讨论】:
【参考方案3】:只需覆盖捕获动作的非活动窗口的以下函数:
function IsShortCut(var Message: TWMKey): Boolean; override;
function TMainForm.IsShortCut(var Message: TWMKey): Boolean;
begin
if MainForm.Active then
result := inherited IsShortCut( Message )
else
result := false;
end;
【讨论】:
以上是关于当表单没有焦点时,如何防止表单处理热键?的主要内容,如果未能解决你的问题,请参考以下文章
JavaScript / DOM:如果焦点丢失到另一个窗口(应用程序),如何防止模糊事件
防止用户在后台处理时单击表单上的任何内容的最佳方法是啥? [关闭]
当initialValues通过\绑定到props.object时,如何使用Formik表单将焦点设置在TextField\input上?