2015-01-05 19 views
1

我发现(在Delphi 2010中)快捷方式总是以第一种形式(由主窗体拥有)结束,而不是当前着重的形式。我的TMainFrm拥有几个TViewFrm。每个人都有TActionManagerTActons相同。快捷方式触发器第一次创建窗体而不是焦点窗体的检测

我看到一些方法,但是不知道什么最好的修复。(而不是一个坏的黑客)

  • 的形式使用它调用其隐藏()和show()一个标签集导航。我不希望隐藏的表单接收按键。难道我做错了什么?
  • 看来,行动捷径始终始于主窗体,并使用TCustomForm.IsShortCut()获得分配给拥有的窗体。我没有看到任何逻辑来尊重隐藏的窗口,我是否应该重写它并让它首先触发集中的窗体?
  • 禁用TViewFrm.Hide()..中的所有TActions?
  • TActionToolBar移动到TMainFrm,但这是一个蛇坑和最后的手段。
+0

我想这个新闻组对话关系: http://codeverge.com/embarcadero.delphi.vcl.using/shortcut-problem-suspect-taction/1076571 –

+0

当窗体隐藏,禁止行为管理 –

+0

有不是'TActionManager.Enabled',我必须设置'TAction.Enabled'或使用它的'TAction.OnUpdate()'。 –

回答

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()检查组件可见和/或启用,但可能会影响比我更想。我怀疑原始代码架构师是否有理由不通过设计。最好是让它调用两次:首先优先考虑可见+启用的组件,然后再调用回退到正常行为。

+1

不要担心我们没有的列表,'屏幕'的'形式'总是让他们尊重z顺序。 –