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.
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.
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)
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
.
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.
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.
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);
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