The owner of a form isn't necessarily another form. The Owner property is just TComponent, which could be anything, including nil. But if the owner is a form, you can send it a message like this:
if Owner is TForm then
SendMessage(TForm(Owner).Handle, am_Foo, 0, 0);
You might not need to know the owner, though. The MDI parent form is always the main form of the project, and the main form is always designated by Application.MainForm. Send a message to that form's handle.
SendMessage(Application.MainForm.Handle, am_Foo, 0, 0);
The list of MDI children will be in Application.MainForm.MDIChildren. Your child forms can check that list for themselves rather than have the MDI parent do it. Here's a function either of your forms can use to find instances of any MDI child class. (If the forms that want to communicate aren't MDI children, you can still use this technique, but instead of Application.MainForm.MDIChildren, search the Screen.Forms list.)
function FindMDIChild(ChildClass: TFormClass): TForm;
var
i: Integer;
begin
for i := 0 to Pred(Application.MainForm.MDIChildCount) do begin
if Application.MainForm.MDIChild[i].InheritsFrom(ChildClass) then begin
Result := Application.MainForm.MDIChildren[i];
exit;
end;
end;
Result := nil;
end;
Your first child class could use it like this:
var
SecondChild: TForm;
begin
SecondChild := FindMDIChild(TSecondChild);
if Assigned(SecondChild) then begin
SendMessage(SecondChild.Handle, am_Foo, 0, 0);
end;
end;
When window messages are sent to windows in the same thread as the sender (which is always the case for any two VCL forms), their handlers are called immediately while the sender waits for a response. That's just like an ordinary function call, so you might wish to skip the messages and make regular functions in your form classes. Then you could use code like this:
var
SecondForm: TSecondForm;
begin
SecondForm := TSecondForm(FindMDIChild(TSecondForm));
if Assigned(SecondForm) then begin
SecondForm.Foo(0, 0);
end;
end;