Main Form not displaying when showing modal form i

2019-08-06 10:57发布

问题:

I have created one application in which Main Form Calls Sub Form on FormShow event of Main Form. Sub Form is displayed and gives two options to choose. If First option on sub form is selected then then a Message is displayed and after that Main form will be displayed. Now when application runs on first time then after option selected on subform Meassage will be displayed. But i want to display message with Main Form as Background. So any solution to this. below is the FormShow code.

Procedure TMainForm.FormShow(Sender:TObject);
begin
  if (SubForm.ShowModal = mrOK) and bOption1 then
  begin
    ShowMessage('Enter the value');
  end;
end;

回答1:

If I understand correctly then your problem is that when the message box show up your main form is still invisible.

If this is the case then you have two options:

  1. Don't show your SubForm from the OnShow event of the main form, but at a later time
  2. Don't show the message directly after ShowModal returns, but at a later time

For point number 2 you can use a similar approach as I suggested here, using PostMessage. So your code would look somethind like this:

procedure TMainForm.FormShow(Sender:TObject);
begin
  if (SubForm.ShowModal = mrOK) and bOption1 then
  begin
    PostMessage(Self.Handle, WM_SHOWMYDIALOG, 0, 0);
  end;
end;

The handler of WM_SHOWMYDIALOG then displays the actual message. This approach can also work for point 1, see ain's answer.

PostMessageposts a message to your application's message queue which will be processed after the main form finished becoming visible.



回答2:

Another Option would be to use OnActivate of the Mainform instead of onShow.



回答3:

If I understand you right you want

const
    UM_AFTERSHOW   = WM_APP + 1;

type
  TForm1 = class(TForm)
  protected
    procedure UMAfterShow(var Msg: TMessage); message UM_AFTERSHOW;
    procedure DoShow; override;
  end;


procedure TForm1.DoShow;
begin
  inherited;
  PostMessage(Self.Handle, UM_AFTERSHOW, 0, 0);
end;

procedure TForm1.UMAfterShow(var Msg: TMessage);
begin
  ShowMessage('Enter the value');
end;

By showing your message in the UMAfterShow handler you give the main form opportunity to become visible and thus to be in background.



回答4:

The problem you are seeing (if I understand properly) is that FormShow is called before your main form is actually visible. So the message dialog shows before your main form.

What you need to do is use PostMessage to post a message to your main form that you then handle. This will allow your FormShow code to finish and the code will be triggered after the form is shown.

Take a look here for an example.



回答5:

Yet another option would be to drop a TTimer component on your main form to trigger the message dialog.

Drop a TTimer component on your main form and set the enabled property to False and change the time from 1000 to 100. Code your message dialog and also set the Timer.Enabled property to False in the timer event to avoid repeated firings.

Now you can Enable the Timer at the point where you would have shown the message dialog in your main form's OnShow event.