Delphi onshow основная форма / модальная форма - PullRequest
8 голосов
/ 19 января 2012

У меня есть проект, который имеет основную форму и некоторые другие формы. Когда приложение загружается, оно должно выполнить некоторые задачи и отобразить результаты в модальной форме поверх основной формы. Проблема, с которой я столкнулся, заключается в том, что если я вызову функцию для выполнения задач / создания и покажу модальную форму в событии onshow основных форм, появится модальная форма, но основной формы нет, пока модальная форма не будет закрыта, что что я ожидал бы случиться. Чтобы противостоять этому, я добавил таймер в основную форму и запустил его на событии показа основных форм, таймер вызывает функцию для выполнения задач / создания и отображения модальной формы. Так что теперь основная форма предстает перед модальной формой.

Однако я не вижу, чтобы это было лучшим решением, и мне было интересно, кто-нибудь может предложить лучшее.

Я использую Delphi 7

Colin

Ответы [ 3 ]

10 голосов
/ 19 января 2012

Один из наиболее часто используемых вариантов - отправить сообщение в форме OnShow.Как это:

const
  WM_SHOWMYOTHERFORM = WM_USER + 0;

type
  TMyMainForm = class(TForm)
    procedure FormShow(Sender: TObject);
  protected
    procedure WMShowMyOtherForm(var Message: TMessage); message WM_SHOWMYOTHERFORM;
  end;

...


procedure TMyMainForm.FormShow(Sender: TObject);
begin
  PostMessage(Handle, WM_SHOWMYOTHERFORM, 0, 0);
end;

procedure TMyMainForm.WMShowMyOtherForm(var Message: TMessage);
begin
  inherited;
  with TMyOtherForm.Create(nil) do begin
    try
      ShowModal;
    finally
      Free;
    end;
  end;
end;
2 голосов
/ 19 января 2012

Почему вы не используете событие MainForm OnActivate, как это?

procedure TMyMainForm.FormActivate(Sender: TObject);
begin
  //Only execute this event once ...
  OnActivate := nil;

  //and then using the code David Heffernan offered ...
  with TMyOtherForm.Create(nil) do begin
    try
      ShowModal;
    finally
      Free;
    end;
end;

Если для события установлено значение nil, этот код будет запускаться только один раз при запуске.

0 голосов
/ 19 января 2012

Событие OnShow наступает непосредственно перед вызовом функции Windows API ShowWindow. Именно этот вызов ShowWindow фактически приводит к появлению окна на экране.

Так что в идеале вам нужно что-то запустить сразу после вызова ShowWindow. Оказывается, код VCL, который управляет всем этим, находится внутри обработчика сообщений TCustomForm для CM_SHOWINGCHANGED. Этот обработчик сообщений запускает событие OnShow и затем вызывает ShowWindow. Итак, отличное решение - показать вашу модальную форму сразу после запуска обработчика для CM_SHOWINGCHANGED. Как это:

type
  TMyMainForm = class(TForm)
  private
    FMyOtherFormHasBeenShown: Boolean;
  protected
    procedure CMShowingChanged(var Message: TMessage); message CM_SHOWINGCHANGED;
  end;

.....

procedure TMyMainForm.CMShowingChanged(var Message: TMessage);
begin
  inherited;
  if Showing and not FMyOtherFormHasBeenShown then begin
    FMyOtherFormHasBeenShown := True;
    with TMyOtherForm.Create(nil) do begin
      try
        ShowModal;
      finally
        Free;
      end;
    end;
  end;
end;
...