Problem z ShowWindow - brak kontrolek na pokazanym oknie

0

Witam
Mam taki problem:
Program po uruchomieniu ma mieć niewidoczne główne okno.
Jeśli ponownie uruchomimy program to wyświetli on dotychczas niewidoczne okno z pierwszej kopi programu po czym zostanie zamknięty.
Efektem tego ma być wyświetlenie okna ustawień w pierwszej kopi programu.
Okno faktycznie zostaje wyświetlone (SW_SHOW, SW_RESTORE) ale kontrolki na nim nie są wyświetlane.
Proszę o pomoc. W czym tkwi problem?

begin
  CreateMutex(nil, False, 'bobobob');
    if GetLastError() = 0
      then
        begin
          Application.ShowMainForm := False;
          Application.Initialize;
          Application.Title := 'bobobo';
          Application.CreateForm(TForm1, Form1);
          Application.Run;
        end
      else
        begin
          ShowWindow(FindWindow(nil, 'bobobo - Hide'), SW_SHOW);
          Halt;
        end;
end.
3

To się robi trochę inaczej robiłem to kiedyś w jakimś moim programie tylko nie mogę sobie przypomnieć w którym ale powinieneś wysyłać komunikat do zminimalizowanego / ukrytego głównego okna aplikacji a to powinno go obsłużyć czyli w głównym oknie coś w stylu:

const
  UM_RESTOREAPP = WM_USER + 1001;

type
  TForm1 = class(TForm)
  private
    { Private declarations }

    procedure UMRestoreApp(var Msg: TMessage); message UM_RESTOREAPP;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.UMRestoreApp(var Msg: TMessage); 
//tu nie jestem pewien czy właściwie reaguje na wszystko tylko tak "na oko" musisz sobie sam przetestować
begin
  if IsIconic(Application.MainForm.Handle) then
    Application.Restore;
  if not IsWindowVisible(Application.MainForm.Handle) then
    Application.MainForm.Show;
  Application.BringToFront;
  SetForegroundWindow(Application.MainForm.Handle);
end;

A na początku programu:

begin
  CreateMutex(nil, False, 'bobobob');
  if GetLastError() = 0 then
  begin
    Application.Initialize;
    Application.MainFormOnTaskbar := True;
    Application.CreateForm(TForm1, Form1);
    Application.Run;
  end
  else
  begin
    PostMessage(FindWindow(nil, 'bobobo - Hide'), UM_RESTOREAPP, 0, 0); //tu wysylasz komunikat
    Application.Terminate;
  end;
end.
1

Application.Terminate nie jest potrzebny – program sam zakończy działanie, jeśli metoda Application.Run nie zostanie wywołana. Natomiast Halt jest jeszcze bardziej zbędny, bo polecą wycieki pamięci. W tym kontekście nie ma to większego znaczenia, bo proces aplikacji i tak jest ubijany, więc system sobie posprząta, ale jeśli debugujemy program poprzez IDE z dodatkowym menedżerem pamięci, to ten będzie zawracał głowę tymi wyciekami.

0

Wszystko super - dzięki !!!

//edit
Jednak to o co mi głównie chodziło działa czyli pokazywanie ukrytego okna.
Przywracanie zminimalizowanego już jednak nie działa...

2

Musisz sam sobie to dopracować póki co tak na szybko takie zmiany aby odpowiednio reagowało , bo prawidłowy kod jest zależny od systemu (ten powinien działać w 7 i 10) i wersji Delphi (u mnie najnowsza).

procedure TForm1.UMRestoreApp(var Msg: TMessage);
  //znaleiona w necie metoda wymusza wysłanie okna na wierzch mimo że uzytkownik
  //działał na innym oknie np. Eksloratorze Windows
  procedure ForceSetForegroundWindow(AHandle: THandle);
  var
    Input: TInput;
  begin
    ZeroMemory(@Input, SizeOf(Input));
    SendInput(1, Input, SizeOf(Input));
    SetForegroundWindow(AHandle);
  end;
begin
  if IsIconic(Application.MainForm.Handle) then
    Application.Restore;
  if not IsWindowVisible(Application.MainForm.Handle) then
    Application.MainForm.Show;
  Application.BringToFront;
  //SetForegroundWindow(Application.MainForm.Handle);
  //zamiast tego w nowych systemach lepiej działa to co nizej
  ForceSetForegroundWindow(Application.MainForm.Handle);
end;

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