Активное окно после закрытия модальной формы

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Активное окно после закрытия модальной формы

Сообщение Climber » 05.08.2010 13:40:45

У меня есть такой примерно код:
Код: Выделить всё
procedure TBaseSet.ShowDialog(AMode: TControllerMode);
var p: TStringList;
begin
  p:=TStringList.Create;
  try
    PrepareParameters(p);
    with FSubDialogClass.Create do
      try
        Form.ShowModal;
      finally
        Free;
      end;
  finally
    p.Free;
  end;
  Update;
end;
FSubDialogClass - это класс-наследник TObject, в его конструкторе создается форма, в деструкторе форма уничтожается. После вызова конструктора форма выводится на экран в модальном режиме. А дальше происходит что-то непонятное.
Я запускаю программу из Far, в программе открываю немодальное окно, а в нем уже это окно, код которого выше. Потом закрываю модальное окно и активным окном становится окно Far, а окна моей прогаммы уходят "под" него. Это почему может быть?
Climber
постоялец
 
Сообщения: 415
Зарегистрирован: 03.06.2007 20:09:57
Откуда: Москва

Re: Активное окно после закрытия модальной формы

Сообщение .wOvAN » 05.08.2010 16:48:23

Попробуйте создавать диалог или от Application или от какой либо формы;


Код: Выделить всё
procedure TBaseSet.ShowDialog(AMode: TControllerMode);
var p: TStringList;
begin
   p:=TStringList.Create;
  try
    PrepareParameters(p);
    with FSubDialogClass.Create do
      try
        Form.Parent:={Application|Form1};
        Form.ShowModal;
      finally
        Free;
      end;
  finally
    p.Free;
  end;
  Update;
end;


как нибудь так
Form.Parent:={Application|Form1};
.wOvAN
постоялец
 
Сообщения: 118
Зарегистрирован: 16.04.2010 06:36:12

Re: Активное окно после закрытия модальной формы

Сообщение Climber » 05.08.2010 17:14:57

Спасибо, попробую...
Climber
постоялец
 
Сообщения: 415
Зарегистрирован: 03.06.2007 20:09:57
Откуда: Москва

Re: Активное окно после закрытия модальной формы

Сообщение Climber » 09.08.2010 17:13:39

Не помогло.
Если окну установить свойство Parent - то вообще наступает "конец света" - программа перестает реагировать на любые воздействия. На экране отображается новое окно поверх старого, дальше - только убить процесс через ctrl - alt - del.
Если установить Owner при создании окна, то результат один и тот же если делать Owner'ом Application, nil или какую-либо форму.
Climber
постоялец
 
Сообщения: 415
Зарегистрирован: 03.06.2007 20:09:57
Откуда: Москва

Re: Активное окно после закрытия модальной формы

Сообщение Odyssey » 09.08.2010 18:13:24

Поведение может зависеть от того, как в FSubDialogClass.Create создаётся форма. Если так:
Код: Выделить всё
Form := TFormXXX.Create(XXX);
то можно попробовать заменить на:
Код: Выделить всё
Application.CreateForm(TFormXXX, Form);
Odyssey
энтузиаст
 
Сообщения: 580
Зарегистрирован: 29.11.2007 17:32:24

Re: Активное окно после закрытия модальной формы

Сообщение .wOvAN » 09.08.2010 18:43:06

Смотрим реализацию ShowModal

Код: Выделить всё
function TCustomForm.ShowModal: Integer;

  procedure RaiseShowModalImpossible;
  begin
    DebugLn('TCustomForm.ShowModal Visible=',dbgs(Visible),' Enabled=',dbgs(Enabled),
      ' fsModal=',dbgs(fsModal in FFormState),' MDIChild=',dbgs(FormStyle = fsMDIChild));
    raise EInvalidOperation.Create('TCustomForm.ShowModal impossible ');
  end;

  procedure RestoreFocusedForm;
  begin
    // needs to be called only in ShowModal
    Perform(CM_DEACTIVATE, 0, 0);
    if Screen.FSaveFocusedList.Count > 0 then
    begin
      Screen.FFocusedForm := TCustomForm(Screen.FSaveFocusedList.First);
      Screen.FSaveFocusedList.Remove(Screen.FFocusedForm);
    end
    else
      Screen.FFocusedForm := nil;
  end;

var
  DisabledList: TList;
  SavedFocusState: TFocusState;
  ActiveWindow: HWnd;
begin
  if Self = nil then
    raise EInvalidOperation.Create('TCustomForm.ShowModal Self = nil');
  if Application.Terminated then
    ModalResult := 0;
  // cancel drags
  DragManager.DragStop(false);
  // close popupmenus
  if ActivePopupMenu <> nil then
    ActivePopupMenu.Close;
  if Visible or not Enabled or (fsModal in FFormState) or (FormStyle = fsMDIChild) then
    RaiseShowModalImpossible;
  // Kill capture when opening another dialog
  if GetCapture <> 0 then
    SendMessage(GetCapture, LM_CANCELMODE, 0, 0);
  ReleaseCapture;

  Application.ModalStarted;
  try
    Include(FFormState, fsModal);
    ActiveWindow := GetActiveWindow;
    SavedFocusState := SaveFocusState;
    Screen.FSaveFocusedList.Insert(0, Screen.FFocusedForm);
    Screen.FFocusedForm := Self;
    Screen.MoveFormToFocusFront(Self);
    Screen.MoveFormToZFront(Self);
    ModalResult := 0;

    try
      if WidgetSet.GetLCLCapability(lcModalWindow) = LCL_CAPABILITY_NO then
        DisabledList := Screen.DisableForms(Self)
      else
        DisabledList := nil;
      Show;
      try
        // activate must happen after show
        Perform(CM_ACTIVATE, 0, 0);
        TWSCustomFormClass(WidgetSetClass).ShowModal(Self);
        repeat
          { Delphi calls Application.HandleMessage
            But HandleMessage processes all pending events and then calls idle,
            which will wait for new messages. Under Win32 there is always a next
            message, so it works there. The LCL is OS independent, and so it uses
            a better way: }
          try
            WidgetSet.AppProcessMessages; // process all events
          except
            if Application.CaptureExceptions then
              Application.HandleException(Self)
            else
              raise;
          end;
          if Application.Terminated then
            ModalResult := mrCancel;
          if ModalResult <> 0 then
          begin
            CloseModal;
            if ModalResult<>0 then break;
          end;
          Application.Idle(true);
        until False;

        Result := ModalResult;
        if HandleAllocated and (GetActiveWindow <> Handle) then
          ActiveWindow := 0;
        RestoreFocusedForm;
      finally
        Screen.EnableForms(DisabledList);
        { guarantee execution of widgetset CloseModal }
        TWSCustomFormClass(WidgetSetClass).CloseModal(Self);
        Hide;
        // free handles to save resources and to reduce overhead in the interfaces
        // for bookkeeping changing between Show and ShowModal.
        // (e.g.: the gtk interface creates some specials on ShowModal, so the
        //  combination ShowModal, Close, Show makes problems.)
        DestroyHandle;
      end;
    finally
      RestoreFocusState(SavedFocusState);
      if LCLIntf.IsWindow(ActiveWindow) then
        SetActiveWindow(ActiveWindow);
      Exclude(FFormState, fsModal);
    end;
  finally
    Application.ModalFinished;
  end;
end;               


Может перед вызовом ShowModal воспользоваться SetActiveWindow(Form1.Handle);

вобще не знаю, не могу вопроизвести ситуацию.

заупускаю из фара и все путем.

Добавлено спустя 24 минуты 56 секунд:
Вот демка:

http://turbobit.net/huaz2yfj4yzr.html
.wOvAN
постоялец
 
Сообщения: 118
Зарегистрирован: 16.04.2010 06:36:12

Re: Активное окно после закрытия модальной формы

Сообщение oleg_t » 12.01.2012 13:56:52

Попал на такую-же ситуацию, когда
Код: Выделить всё
if (not Assigned(unit4.form4)) then unit4.form4 := TForm4.Create(Self);
  form4.ShowModal;
  FreeAndNil(form4);     


не работало, выдавалась ошибка "'TCustomForm.ShowModal impossible "

сделал так:
Код: Выделить всё
if (not Assigned(unit4.form4)) then unit4.form4 := TForm4.Create(Self);
  form4.Visible:=false;
  form4.ShowModal;
  FreeAndNil(form4);     


все заработало
oleg_t
незнакомец
 
Сообщения: 1
Зарегистрирован: 12.01.2012 11:30:11


Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: Alex2013 и гости: 201

Рейтинг@Mail.ru