ShowModal - forma zasłonięta przez inną

0

Witam.

Próbuje przenieść banalny serwis www do aplikacji desktopowej i napotkałem mały błąd.
Użytkownik wybiera "przeglądaj" z menu i powinien dostać listę rekordów z bazy danych, DbGrid wstawiony jest na oddzielnej formie którą pokazuje przez ShowModal.
Programik testowałem na paru komputerach, na większości jest ok a na jednym dostaje coś takiego:
ShowModal.jpg

Próbowałem w OnShow pokazywanej formy dodać BringToFront ale nie przyniosło to rezultatu ...

0

A forma główna ma zmieniane jakieś standardowe właściwości? Np. FormStyle z fsStayOnTop? Podaj najlepiej treść źródła formularza (plik dmf) dokładniej fragnent dotyczący form.

0

Mnie to bardziej na bug LCLa wygląda, niż błędne ustawienie; Pokazanie formularza modalnie zawsze powinno go wyświetlić ponad formularzem wywołującym i go aktywować; Widać inaczej to zaimplementowali;

Jeśli formularz wywołujący ma ustawioną właściwość FormStyle na fsSystemStayOnTop - jest problem; Modalnie wywołany formularz chowa się pod wywołujący, ale posiada focusa; Przynajmniej z szybkich testów to wynika; Jeśli natomiast ustawisz tę właściwość na standardowe fsStayOnTop - problemu nie będzie;

Jeżeli natomiast chcesz, aby główny formularz posiadał ustawienie fsSystemStayOnTop i nie było problemów z modalnym oknem - ten modalny także powinien mieć ustawioną właściwość na fsSystemStayOnTop (a co najmniej na fsStayOnTop);

U mnie takie ustawienia działają bez zarzutu - mam Lazarusa 1.0.14 i FPC 2.6.2.

2

@furious programming powinno ale nie zawsze tak jest - zaczyna się to rozjeżdżać jeśli masz co najmniej dwie modalne formy - wtedy ta druga potrafi się schować pod aplikacją. Odpowiedzialny za to jest menadżer okien z XPka i wyższych (ten, który wyłapuje zawieszone okna). Można go wyłączyć dla naszej aplikacji przez

procedure DisableWindowsGhosting;
var
  User32: HMODULE;
  DisableProcessWindowsGhosting: TProcedure;
begin
  User32 := GetModuleHandle('USER32');
  if User32 <> 0 then
  begin
    DisableProcessWindowsGhosting := GetProcAddress(User32, 'DisableProcessWindowsGhosting');
    if Assigned(DisableProcessWindowsGhosting) then
      DisableProcessWindowsGhosting;
  end;
end;

i w oknach, które są modalne

unit ModalForm;

interface

uses
  Forms, Controls;

type
  TModalForm = class(TForm)
  protected
    procedure CreateParams(var params: TCreateParams); override;
  end;

implementation

uses
  Windows;
  
{ TModalForm }

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

  if Screen.ActiveForm <> nil then
    params.WndParent := Screen.ActiveForm.Handle
  else if Application.MainForm <> nil then
    params.WndParent := Application.MainForm.Handle
  else
    params.WndParent := Application.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;

end.

W D7 niweluje problem z oknami modalnymi na windowsach od XP do 8.1

0

Dziękuję za pomoc Panowie.
Problem póki co rozwiązała banalna sprawa, a mianowicie Application.ProcessMessages przed ShowModal - dzięki temu główne okno zostaje "odwieszone" i prawidłowo chowa się pod to wywoływane.

1 użytkowników online, w tym zalogowanych: 0, gości: 1