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!

3
  • 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. Commented Sep 12, 2022 at 7: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... Commented Sep 12, 2022 at 7:58
  • Agreed, just that a Post will anyways happen after the close. Commented Sep 12, 2022 at 8:37

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.