0

Create an application with two forms, where the main form is created automatically, and the second form is created as needed. I've defined a custom message to pass a certain parameter from the secondary form (which is displayed in a non-modal way) to the main form, where I've defined a handler for this message. After sending the message, the secondary form is closed (and the closing action is set to Free).

The problem, that when I used PostMessage to send the message, the main form is minimized in response, and the action I defined in the message handler was not called (that is, the message was not displayed with the selected action). When I used SendMessage, the message was indeed read and processed, but the secondary form was closed only after closing the message box (as expected...).

What can I do to send the message and return immediately (so that the secondary form closes immediately) but not cause the primary form to minimize?

Here is the code I use:

MainFormUnit.pas

unit MainFormUnit;

...

const
  SM_MY_MESSAGE = WM_USER + 1;

type TMyAction = (ma0, ma1);

type
  TMainForm = class(TForm)
  ...
  procedure DoMyAction(Action: TMyAction);
  procedure SMMYMESSAGE(var Msg: TMessage); message SM_MY_MESSAGE;
  procedure ShowChildForm;
  ...
end;

var
  MainForm: TMainForm;

implementation

uses
  ChildFormUnit;
...

procedure TMainForm.SMMYMESSAGE(var Msg: TMessage);
begin
  DoMyAction(TMyAction(Msg.WParam));
end;

procedure TMainForm.DoMyAction(Action: TMyAction);
begin
  ShowMessage(Format('The selected action is: %d', [Ord(Action)]));
end;

procedure TMainForm.ShowChildForm;
var
  ChildForm: TChildForm;
begin
  ChildForm := TChildForm.Create(Self);
  ChildForm.Show;
end;

ChildFormUnit.pas

unit ChildFormUnit;

...
const SM_MY_MESSAGE = WM_USER + 1;

type
  TChildForm = class(TForm)
  ...
  procedure SendActionToMain(ActionNum: Integer);
  procedure ChildFormClose(Sender: TObject; var Action: TCloseAction);
  ...
end;

implementation

uses MainFormUnit;
...
procedure TChildForm.SendActionToMain(ActionNum: Integer);
begin
  PostMessage(MainForm.Handle, SM_MY_MESSAGE, ActionNum, 0);
  close;
end;
...
procedure TChildForm.ChildFormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree;
end;

Edit:

When I added in the SMMYMESSAGE handler additional code for processing (in my case it was ShowMessage(Format('The WParam is: %d', [Msg.WParam]));) before calling DoMyAction, the main form is minimized, the message "The WParam is.. .” did not appear, but the message specified in DoMyAction did appear! I really don't understand what is going on here??? PostMessage does send the message and it is received by the handler, and things happen that I didn't want!

yonni
  • 248
  • 2
  • 11
  • TL;DR. What about first calling `close` and then `PostMessage`? Sheer despair, as for me everything makes sense. You could try an other SM_MY_MESSAGE, WM_USER + 100 or so. – Joop Eggen Sep 12 '22 at 07:51
  • 1
    @Joop I did also try to set another value for the message as you suggested, and without any change. I haven't tried calling Close before SendMessage, but I think that won't do anything... – yonni Sep 12 '22 at 07:58
  • Agreed, just that a Post will anyways happen after the close. – Joop Eggen Sep 12 '22 at 08:37

0 Answers0