Владелец формы Delphi пропускает вызов ShowMessage / Dialog в FormClose компонента - PullRequest
2 голосов
/ 21 января 2010

В моем приложении Delphi 2010 есть ряд немодальных форм, которые создаются и принадлежат основной форме. В одной из этих форм есть процедура formclose, которая открывает диалоговое окно с вопросом, хотят ли они сохранить изменения. Если пользователь закрывает основную форму, вызывается процедура FormClose «собственной» формы, однако диалоговое окно не отображается, и пользователь не имеет возможности сохранить.

Есть предложения? Я вижу, что процедура вызывается в отладчике, но, похоже, просто пропускает диалог. То же самое происходит с демонстрационным сообщением. Форма владельца каким-то образом перекрывает фактическое отображение этих диалогов?

Спасибо

Расти

Ответы [ 3 ]

2 голосов
/ 21 января 2010

Когда основная форма закрыта, приложение закрывается, что освобождает основную форму, что, в свою очередь, освобождает принадлежащие ей формы. Собственные формы не закрываются, они просто освобождаются, поэтому их событие OnClose обычно вообще не запускается.

Если вы видите, что ShowMessage вызывается из события OnClose собственной формы, но диалоговое окно не отображается, это, вероятно, потому, что приложение уже завершено и больше не обрабатывает сообщения. Это означает, что событие OnClose в пользовательской форме инициируется где-то в вашем собственном коде, но слишком поздно.

Один из способов воспроизвести это поведение - отправить сообщение WM_CLOSE в собственную форму из события OnClose основной формы. Затем сообщение обрабатывается собственной формой в более поздний момент, когда приложение уже завершено, любая попытка вызвать ShowMessage или любую модальную форму больше не имеет никакого эффекта.

Я согласен с Майклом, что OnCloseQuery лучше подходит для отображения подсказки для пользователя. К сожалению, это само по себе не помогает, поскольку собственные формы освобождаются, а не закрываются. Вы должны вызвать их OnCloseQuery событие вручную, например:

procedure TFormMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
var
  I: Integer;
begin
  CanClose := False;
  for I := 0 to ComponentCount - 1 do
    if Components[I] is TCustomForm then
      if not TCustomForm(Components[I]).CloseQuery then
        Exit;
  CanClose := True; // or another check if the main form can be closed, too
end;
2 голосов
/ 21 января 2010

Такие вещи должны идти в событии OnCloseQuery. Установите CanClose в false в обработчике, чтобы отменить закрытие (что является более или менее стандартным: в таких ситуациях Да, Нет и Отмена являются обычными ответами, а Отмена прерывает процесс закрытия).

0 голосов
/ 22 января 2010

Я недавно столкнулся с чем-то подобным. Я обнаружил, что просто добавив код:

if not Visible then
  Show;
BringToFront;

прямо перед тем, как отобразится диалоговое окно сохранения изменений, вся путаница исчезнет. Родительская форма отображается, если ее не видно, и переносится вверх в zorder к передней части стопки, затем поверх этого отображается диалоговое окно.

...