我发现(在Delphi 2010中)快捷方式总是最终出现在具有该操作的第一个表单(由主表单拥有)上,但不是当前关注的表单。我的TMainFrm
拥有多个TViewFrm
。每个TActionManager
都有相同的TActons
。
我看到了一些方法,但是想知道最好的解决办法......(而不是糟糕的黑客攻击)
TCustomForm.IsShortCut()
分发给自有窗体。我认为没有任何逻辑可以尊重隐藏的窗口,我应该覆盖它并让它首先触发聚焦形式吗?TActionToolBar
移至TMainFrm
,但这是一堆蛇和最后的手段。答案 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()
以检查组件是否可见和/或启用,但这可能会影响到我想要的更多。我想知道原代码架构师是否有理由不通过设计。最好的是它会被调用两次:首先优先考虑可见+启用的组件,然后第二次调用作为正常行为的回退。