AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Delphi Mal wieder: Doppeltes starten einer Anwendung unterbinden
Thema durchsuchen
Ansicht
Themen-Optionen

Mal wieder: Doppeltes starten einer Anwendung unterbinden

Ein Thema von dust258 · begonnen am 11. Feb 2010 · letzter Beitrag vom 17. Feb 2010
Antwort Antwort
dust258

Registriert seit: 18. Aug 2008
62 Beiträge
 
#1

Mal wieder: Doppeltes starten einer Anwendung unterbinden

  Alt 11. Feb 2010, 12:34
Mahlzeit,
ich versuche ein Programm per ShellExecute in ein anderes Programm einzubinden.
Dabei darf diese Anwendung immer nur 1x gestartet werden.
Wenn man versucht die Anwendung ein 2. mal zu starten soll die 1. Instanz in den Vordergrund geholt werden.

Ich habe also im Quelltext der aufzurufenden Anwendung folgenden Code hinterlegt. Der Aufruf und das Unterbinden von Mehrfachstarts funktionieren, aber die Anwendung wird nur beim 1. Versuch in den Vordergrund geholt...

Ich vermute das "BringWindowToTop" der falsche Befehl ist, aber "ShowWindow" bringt auch nicht den Erwünschten Erfolg (Es wird nur ein kleines Blaues Fenster über der Taskleiste angezeigt). Was anderes habe ich in den anderen Threads nicht gefunden... Sieht Jemand was ich falsch mache?

Delphi-Quellcode:
{$R *.res}
  const
    MutexName = 'ErweiterteListen';
  var
    hMutex: THandle;
  NextHandle: Hwnd;
  foundedHandle : Hwnd;
  NextTitle: array[0..260] of char;
  foundHandle : Boolean;
    begin
    Application.Initialize;
    Application.MainFormOnTaskbar := True;
    Application.CreateForm(TListStatSchnittForm, ListStatSchnittForm);
    foundHandle := false;
    hMutex := CreateMutex(NIL, True, MutexName);
    if (hMutex = 0) OR (GetLastError = ERROR_ALREADY_EXISTS) then
    begin
      //Ab hier wird die schon gestartete Anwendung gesucht
      CloseHandle(hMutex);
      begin
        NextHandle := GetWindow(Application.Handle, GW_HWNDFIRST);
        while (NextHandle > 0) and (foundHandle = false) do
        begin
          GetWindowText(NextHandle, NextTitle, 255);
          if (Pos(ListStatSchnittForm.Caption, StrPas(NextTitle)) <> 0)
            and (NextHandle <> application.Handle)
            and (NextHandle <> ListStatSchnittForm.Handle) then
          begin
            foundedHandle := NextHandle;
            foundHandle := true;
          end
          else
            NextHandle := GetWindow(NextHandle, GW_HWNDNEXT);
        end;
      end;
      if foundHandle then
      begin
        BringWindowToTop(foundedHandle);
        //ShowWindow(foundedHandle, SW_SHOW);
        halt;
      end
    end;
  Application.Run;
end.
  Mit Zitat antworten Zitat
dust258

Registriert seit: 18. Aug 2008
62 Beiträge
 
#2

Re: Mal wieder: Doppeltes starten einer Anwendung unterbinde

  Alt 11. Feb 2010, 12:56
Kennt Ihr das: In DEM MOMENT in dem ich hier den Thread abgesendet habe finde ich die Lösung
Danke fürs Kopfzerbrechen, ich musste nur "FindWindow('TListStatSchnittForm', nil);" nutzen ^^

Delphi-Quellcode:
{$R *.res}

  const
    MutexName = 'ErweiterteListen';
  var
    hMutex: THandle;
  NextHandle: Hwnd;
  foundedHandle : Hwnd;
  NextTitle: array[0..260] of char;
  foundHandle : Boolean;
    begin
    Application.Initialize;
    Application.MainFormOnTaskbar := True;
    Application.CreateForm(TListStatSchnittForm, ListStatSchnittForm);
    foundHandle := false;
    hMutex := CreateMutex(NIL, True, MutexName);
    if (hMutex = 0) OR (GetLastError = ERROR_ALREADY_EXISTS) then
    begin
      CloseHandle(hMutex);
      begin
        NextHandle := FindWindow('TListStatSchnittForm', nil);
        while (NextHandle > 0) and (foundHandle = false) do
        begin
          GetWindowText(NextHandle, NextTitle, 255);
          if (Pos(ListStatSchnittForm.Caption, StrPas(NextTitle)) <> 0)
            and (NextHandle <> application.Handle)
            and (NextHandle <> ListStatSchnittForm.Handle) then
          begin
            foundedHandle := NextHandle;
            foundHandle := true;
          end
          else
            NextHandle := GetWindow(NextHandle, GW_HWNDNEXT);
        end;
      end;
      if foundHandle then
      begin
        BringWindowToTop(foundedHandle);
        //ShowWindow(foundedHandle, SW_SHOW);
        halt;
      end
    end;
  Application.Run;
end.
  Mit Zitat antworten Zitat
Schwedenbitter

Registriert seit: 22. Mär 2003
Ort: Finsterwalde
622 Beiträge
 
Turbo Delphi für Win32
 
#3

Re: Mal wieder: Doppeltes starten einer Anwendung unterbinde

  Alt 17. Feb 2010, 00:58
Zitat von dust258:
Kennt Ihr das: In DEM MOMENT in dem ich hier den Thread abgesendet habe finde ich die Lösung
Danke fürs Kopfzerbrechen, ich musste nur "FindWindow('TListStatSchnittForm', nil);" nutzen ^^
Nur zu Genüge! Ich bekomme mit der Vorgehensweise aber immer nur ein graues Fenster. Ich kann es verschieben, aber nicht minimieren, nicht schließen und - wie gesagt - ich sehe keine Komponenten mehr auf dem Fenster.

Ich persönlich finde es auch etwas kompliziert:
Den Code zum Finden des Fenster-Handle gibt einem WinSpy wesentlich kürzer aus. Da Du Deinen Titel und die Klasse kennst, ist das Fenster auch eindeutig identifizierbar. So kannst Du das herausfiltern des Fensternamens sparen, wenn Du bei FindWindow statt nil als zweiten Parameter, den Titel angibst.
Ich mag mich irren, aber Handle ist Handle und dann sollte BringWindowToTop() auch gehen. Und schließlich würde ich Deinen Code vor Application.Initialize platzieren. Das spart Zeit, Speicher etc. weil gleich als erstes geprüft wird, ob bereits ein Instanz läuft.

Ich "löse" mein Problem etwas unorthodox - allerdings Dank Deines Schemas - dann so (dpr-Datei):
Delphi-Quellcode:
Const
   MutexName   ='Eindeutiger Name für ein Chat-Programm';
Var
   hMutex : THandle;
   Wnd : Hwnd;
Begin
   hMutex:=CreateMutex(nil, True, MutexName);
   If GetLastError = ERROR_ALREADY_EXISTS Then
   Begin
      CloseHandle(hMutex);
      Wnd:=FindWindow('TChat', 'Nachrichten');
      If Wnd <> 0 Then
      Begin
         SendMessage(Wnd, WM_2ndInstance, 0, 0);
         Halt;
      End;
   End;

   Application.Initialize;
   Application.ShowMainForm:=False;
   Application.CreateForm(TChat, Chat);
   Application.Run;
End.
In der Unit fürs MainForm reagiere ich dann so:
Delphi-Quellcode:
Const
   WM_2ndInstance = $0406;
Type
   TChat = Class(TForm)
                       ...
                     Private
                       Procedure WM2ndInstance(Var Msg: TMessage); Message WM_2ndInstance;
                       ...
                     End;
...

Procedure TChat.WM2ndInstance(Var Msg: TMessage);
Begin
   Show;
End;
Keine Ahnung, ob man das so macht. Aber es funktioniert.

Gruß, Alex
Alex Winzer
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:12 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz