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