That's not quite so: the flow should be something like:
if (Form.KeyPreview) and Assigned(Form.OnKeyPress) then
Form.OnKeyPress();
if Assigned(Control.OnKeyPress) then
Control.OnKeyPress();
But it doesn't matter, because the problem here is other: the grid is apparently gobbling up some key messages (<Esc>, in this case)
before the form has an oportunity to see them, and that is contrary to what KeyPreview is for.
It's easy to see this: You just have to modify jcmontherock's example like this:
procedure TForm1.FormKeyPress(Sender: TObject; var Key: char);
begin
if Ord(Key) > 32 then
ShowMessage('Form KeyPress: ' + Key)
else
ShowMessageFmt('Form KeyPress: #%d', [Ord(Key)]);
if Key = #$1B {#27} then Close;
end;
and you'll see that SynEdit, even though it is a known "glutton" for key presses, lets the form see all keys before it does, while the grid doesn't, which means the grid is somehow bypassing the normal mechanisms to set itself as target for key messages.