Delphi 快捷方式在第一个创建的窗体上触发TAction,而不是在有焦点的窗体上触发TAction

Delphi 快捷方式在第一个创建的窗体上触发TAction,而不是在有焦点的窗体上触发TAction,delphi,delphi-2010,tactionmanager,Delphi,Delphi 2010,Tactionmanager,我发现(在Delphi2010中)快捷方式总是出现在第一个具有该动作的表单(由主表单拥有)上,而不是当前关注的表单。我的tmainfm拥有多个TViewFrm。每个都有一个战术管理器,具有相同的战术 我看到了一些出路,但不知道最好的解决办法是什么。。(而且还不错) 使用一个选项卡集来导航表单,该选项卡集调用表单的Hide()和Show()。我没想到隐藏的表单会收到按键。我做错什么了吗 似乎操作快捷方式总是从主窗体开始,并使用TCustomForm.IsShortCut()将其分发到所属窗体。我

我发现(在Delphi2010中)快捷方式总是出现在第一个具有该动作的表单(由主表单拥有)上,而不是当前关注的表单。我的
tmainfm
拥有多个
TViewFrm
。每个都有一个
战术管理器
,具有相同的
战术

我看到了一些出路,但不知道最好的解决办法是什么。。(而且还不错)

  • 使用一个选项卡集来导航表单,该选项卡集调用表单的Hide()和Show()。我没想到隐藏的表单会收到按键。我做错什么了吗
  • 似乎操作快捷方式总是从主窗体开始,并使用
    TCustomForm.IsShortCut()
    将其分发到所属窗体。我看不出有任何逻辑来尊重隐藏窗口,我应该覆盖它并让它先触发聚焦窗体吗
  • 是否禁用TViewFrm.Hide()中的所有触觉
  • tractiontoolbar
    移动到
    tmainfm
    ,但那是一个蛇窝,也是最后的选择

    • 我找到了一个对我来说足够好的解决办法;我的主窗体现在覆盖
      TCustomForm.IsShortcut()
      ,并首先从编辑器选项卡列表中检查可见窗口

      我已经很方便地列出了一个清单,所以这可能不适合所有人

      // Override TCustomForm and make it check the currently focused tab/window first.
      function TFormMain.IsShortCut(var Message: TWMKey): Boolean;
        function DispatchShortCut(const Owner: TComponent) : Boolean; // copied function unchanged
        var
          I: Integer;
          Component: TComponent;
        begin
          Result := False;
          { Dispatch to all children }
          for I := 0 to Owner.ComponentCount - 1 do
          begin
            Component := Owner.Components[I];
            if Component is TCustomActionList then
            begin
              if TCustomActionList(Component).IsShortCut(Message) then
              begin
                Result := True;
                Exit;
              end
            end
            else
            begin
              Result := DispatchShortCut(Component);
              if Result then
                Break;
            end
          end;
        end;
      var
        form : TForm;
      begin
        Result := False;
      
        // Check my menu
        Result := Result or (Menu <> nil) and (Menu.WindowHandle <> 0) and
          Menu.IsShortCut(Message);
      
        // Check currently focused form   <-------------------  (the fix)
        for form in FEditorTabs do
          if form.Visible then
          begin
            Result := DispatchShortCut(form);
            if Result then Break;
          end;
        // ^ wont work using GetActiveWindow() because it always returns Self.
      
        // Check all owned components/forms (the normal behaviour)
        if not Result then
          Result := inherited IsShortCut(Message);
      end;
      
      //重写TCustomForm并使其首先检查当前聚焦的选项卡/窗口。
      函数TFormMain.IsShortCut(变量消息:TWMKey):布尔值;
      函数分派快捷方式(常量所有者:TComponent):布尔;//复制的函数不变
      变量
      I:整数;
      组件:TComponent;
      开始
      结果:=假;
      {发送给所有儿童}
      对于I:=0到Owner.ComponentCount-1 do
      开始
      组件:=所有者。组件[I];
      如果组件是TCustomActionList,则
      开始
      如果TCustomActionList(组件).IsShortCut(消息),则
      开始
      结果:=真;
      出口
      结束
      结束
      其他的
      开始
      结果:=分派快捷方式(组件);
      如果结果是这样的话
      打破
      结束
      结束;
      结束;
      变量
      形式:TForm;
      开始
      结果:=假;
      //查看我的菜单
      结果:=结果或(菜单无)和(菜单.WindowHandle 0)和
      Menu.IsShortCut(消息);
      
      //检查当前关注的表单我认为此新闻组对话是相关的:当表单被隐藏时,禁用操作管理器没有
      TActionManager.Enabled
      ,我必须设置
      TAction.Enabled
      或使用其
      TAction.OnUpdate()
      。是否有像操作列表那样的
      状态
      属性?是否有
      状态
      属性。。我没看到。我找到了一个解决办法(见我的答案),但这也可能是一个答案!不要担心我们没有的列表,“屏幕”的“形式”总是保持它们尊重z顺序。