I assume that the parent window must be the form itself. So if the form does not intercept the key does the event handling return to the active control that is responsive to key strokes, or does the key-handling go from the outermost parent inwards to the active control?
The key goes to the actual component, not to the parent.
So if KeyPreview is true, it will go to the TForm first, otherwise it will arrive directly at the control.
Also see
https://wiki.freepascal.org/LCL_Key_HandlingIs there some other TPanel replacement that responds to key events, or can TPanel be rejigged to accept key events?
Well, you can just expose OnKeyDown for the TPanel and use that.
Create a new project.
Put a TButton and TPanel on the form (in that order).
Double click the form (outside the TPanel) to create the TForm1.FormCreate() event.
Now paste in the following code (over the whole unit1.pas)
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls;
type
TPanel = class(ExtCtrls.TPanel)
published
property OnKeyDown;
end;
type
{ TForm1 }
TForm1 = class(TForm)
Button1: TButton;
Panel1: TPanel;
procedure FormCreate(Sender: TObject);
private
public
procedure MyNewKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
begin
Panel1.TabStop := true;
Panel1.OnKeyDown := @Self.MyNewKeyDown;
end;
procedure TForm1.MyNewKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
Showmessage(chr(Key));
end;
end.
If you run this, the Button1 will have focus. If you press Tab then the TPanel has focus (we set the Panel1.TabStop to true in FormCreate.
If you now press a key, the MyNewKeyDown will be executed.
(Although it's not visible now that Panel1 has focus but that can be done too, of course.)