Forma jest ukryta za innymi formami, gdy ShowModal nazywa się

Moja aplikacja opiera się na formularzach modalnych. Forma główna otwiera jedną formę z ShowModal, ta forma otwiera inną z ShowModal, więc mamy ułożone formy modalne. Czasami pojawia się problem, że gdy nazywamy ShowModal w nowej formie, ukrywa się ona za poprzednimi formami, zamiast pokazywać się na wierzchu. Po naciśnięciu alt+tab, formularz wraca do góry, ale nie jest to dobre rozwiązanie. Czy napotkałeś ten problem i jak sobie z nim poradziłeś?

EDIT :

Używam Delphi 7.

Author: LukLed, 2009-10-28

6 answers

Nie wspomniałeś, która wersja Delphi...

Nowsze wersje Delphi dodały do TCustomForm dwie nowe właściwości: PopupMode i PopupParent. Ustawienie PopupParent okna modalnego NA formularz, który tworzy to okno dialogowe, zapewnia, że formularz potomny pozostaje na wierzchu rodzica. Zazwyczaj rozwiązuje problem, który opisujesz.

Myślę, że ta para właściwości została dodana w Delphi 2006, ale być może był to rok 2005. Na pewno są w Delphi 2007 i w górę.

EDIT: po zobaczeniu, że używasz Delphi 7, jedyną sugestią, jaką mam, jest to, że w kodzie, który wyświetla Twój formularz modalny, wyłączasz formularz tworzący go i włączasz ponownie po powrocie. Powinno to uniemożliwić okno tworzenia odbieranie danych wejściowych, co może pomóc utrzymać poprawną kolejność Z.

Coś takiego może działać (niesprawdzone, ponieważ nie używam już D7):

procedure TForm1.ShowForm2;
begin
  Self.Enabled := False;
  try
    with TForm2.Create(nil) do
    begin
      try
        if ShowModal = mrOk then
          // Returned OK. Do something;
      finally
        Free;
      end;
    end;
  finally
    Self.Enabled := True;
  end;
end;

Jeśli Form2 tworzy okno modalne (jak już wspomniałeś), po prostu powtórz proces-wyłącz Form2, Utwórz Form3 i pokazać go modalnie, a po powrocie ponownie włączyć Form2. Upewnij się, że używasz try..wreszcie, jak pokazałem, tak, że jeśli coś pójdzie nie tak w formie modalnej formularz tworzenia jest zawsze ponownie włączony.

 25
Author: Ken White,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-14 09:26:27

Przepraszam za dodanie osobnej odpowiedzi, ale zrobiłem trochę więcej badań, a niektóre z nich wskazują, że moja poprzednia odpowiedź (DisableProcessWindowsGhosting) nie pomaga. Ponieważ nie zawsze mogę odtworzyć ten problem, nie mogę powiedzieć na pewno.

Znalazłem rozwiązanie, które wydaje się właściwe. Odwołałem się do kodu w Delphi 2007 dla metody CreateParams i pasuje całkiem blisko (bez wszystkich innych kodów obsługujących PopupMode).

Stworzyłem jednostkę, poniżej której podklasy TForm.

unit uModalForms;

interface

uses Forms, Controls, Windows;
type
  TModalForm = class(TForm)
  protected
    procedure CreateParams(var params: TCreateParams); override;
  end;

implementation

procedure TModalForm.CreateParams(var params: TCreateParams);
begin
  inherited;

  params.WndParent := Screen.ActiveForm.Handle;

  if (params.WndParent <> 0) and (IsIconic(params.WndParent)
    or not IsWindowVisible(params.WndParent)
    or not IsWindowEnabled(params.WndParent)) then
    params.WndParent := 0;

  if params.WndParent = 0 then
    params.WndParent := Application.Handle;
end;

To, co robię, to dołączanie tej jednostki do jednostki formularza, a następnie zmiana klasy formularza (w .plik kodu pas) od class(TForm) do class(TModalForm)

Dla mnie działa, wydaje się być blisko rozwiązania CodeGear.
 8
Author: Jim Gilmartin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-19 19:37:07

Z tego linku wynika, że problem jest z "Ghosting window", który został wprowadzony w 2000/XP. Funkcję ghostingu można wyłączyć, wywołując poniższy kod podczas uruchamiania.

procedure DisableProcessWindowsGhosting;
var
  DisableProcessWindowsGhostingProc: procedure;
begin
  DisableProcessWindowsGhostingProc := GetProcAddress(
    GetModuleHandle('user32.dll'),
    'DisableProcessWindowsGhosting');
  if Assigned(DisableProcessWindowsGhostingProc) then
    DisableProcessWindowsGhostingProc;
end; 

Jedynym problemem, który widzę, jest to, że spowoduje problemy z funkcją, która pozwala użytkownikowi zminimalizować, przenieść lub zamknąć główne okno aplikacji, która nie odpowiada . Ale w ten sposób nie musisz pokrywać każdego połączenia kodem Self.Enabled := False.

 2
Author: Jim Gilmartin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-18 19:07:33

Wystarczy ustawić Visible właściwość formularza, który chcesz otworzyć, aby False. Następnie można go otworzyć za pomocą .ShowModal(); i to zadziała.

 1
Author: H. Gokhan Mamaci,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-10-20 09:40:21

Odkryłem, że użycie flagi "zawsze na górze" na więcej niż jednym formularzu powoduje problemy z porządkiem Z. I może również znaleźć potrzebę BringWindowToTop funkcja.

Uruchamiając okno z Komunikatem za pomocą wbudowanego WinAPI (MessageBox), odkryłem, że podanie uchwytu okna wywołującego jest konieczne, aby upewnić się, że monit jest wyświetlany na górze przez cały czas.

 0
Author: Scott W,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-28 21:41:31

Spróbuj OnShowForm: {]}

PostMessage(Self.Handle, WM_USER_SET_FOCUS_AT_START, 0, 0);
 0
Author: Dmitry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-08 07:08:33