快捷方式触发第一个创建的表单上的TAction而不是具有焦点的表单

时间:2015-01-05 14:08:02

标签: delphi delphi-2010 tactionmanager

我发现(在Delphi 2010中)快捷方式总是最终出现在具有该操作的第一个表单(由主表单拥有)上,但不是当前关注的表单。我的TMainFrm拥有多个TViewFrm。每个TActionManager都有相同的TActons

我看到了一些方法,但是想知道最好的解决办法......(而不是糟糕的黑客攻击)

  • 使用一个调用其Hide()和Show()的tabset来导航表单。我没想到隐藏的表格会收到按键。我做错了吗?
  • 似乎操作快捷方式始终从主窗体开始,并使用TCustomForm.IsShortCut()分发给自有窗体。我认为没有任何逻辑可以尊重隐藏的窗口,我应该覆盖它并让它首先触发聚焦形式吗?
  • 禁用TViewFrm.Hide()中的所有TA??
  • TActionToolBar移至TMainFrm,但这是一堆蛇和最后的手段。

1 个答案:

答案 0 :(得分:0)

我找到了一个对我来说足够好的解决方法;我的主窗体现在覆盖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;

另一个解决方案是更改DispatchShortCut()以检查组件是否可见和/或启用,但这可能会影响到我想要的更多。我想知道原代码架构师是否有理由不通过设计。最好的是它会被调用两次:首先优先考虑可见+启用的组件,然后第二次调用作为正常行为的回退。