【问题标题】: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+FForm2 是活动的,没有热键。用户在Form2 上按Ctrl+FForm1 处理热键。这是完全不正确的,因为我们看到了非活动形式的活动。我该如何解决?

【问题讨论】:

  • Form1 是 MainForm 对吧?这就是重点
  • 你有两个无模式表单,对吧?这就是 Windows 键盘加速器的工作原理。
  • Form1 和 Form2 不是主窗体。
  • 我只想让热键只在活动表单上工作。我们的客户也是如此。

标签: forms delphi hotkeys


【解决方案1】:

我使用动作来实现所有快捷键处理。如果您这样做,那么您可以使用操作、操作列表、操作管理器等提供的集中化功能,根据表单是否处于活动状态来启用和禁用所有操作。

例如,通过在表单的OnActivateOnDeactivate 事件处理程序上设置操作列表的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;
    

    【讨论】:

      猜你喜欢
      • 2023-04-07
      • 2015-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-17
      • 2011-08-28
      • 1970-01-01
      相关资源
      最近更新 更多