2

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

我看到了一些出路,但想知道最好的解决方法是什么..(而不是一个糟糕的黑客)

  • 表单使用调用其 Hide() 和 Show() 的选项卡集进行导航。我没想到隐藏的表单会收到按键。难道我做错了什么?
  • 似乎动作快捷方式总是从主表单开始,并使用TCustomForm.IsShortCut()get 分发到拥有的表单。我看不到尊重隐藏窗口的逻辑,我应该覆盖它并让它首先触发焦点表单吗?
  • 禁用 TViewFrm.Hide() 中的所有 TAction .. ?
  • 移动TActionToolBarTMainFrm但那是一个蛇坑和最后的手段。
4

1 回答 1

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()以检查组件是否可见和/或启用,但这可能会影响到我想要的更多。我想知道最初的代码架构师是否有理由不这样做——出于设计。最好将它调用两次:第一次优先考虑可见+启用的组件,第二次调用作为正常行为的后备。

于 2015-01-07T07:19:33.317 回答