Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Mutex und Programm nicht doppelt starten (https://www.delphipraxis.net/84451-mutex-und-programm-nicht-doppelt-starten.html)

kingflo 17. Jan 2007 08:07


Mutex und Programm nicht doppelt starten
 
Hallo...
ich verhindere auf folgende art und weise, das mein Programm nur einmal gestartet werden kann:

Delphi-Quellcode:
unit mutex;

interface

implementation

uses windows,Dialogs,sysutils,login;

var mHandle: THandle;   // Mutexhandle

Initialization
  mHandle := CreateMutex(nil,True,'Stryyke Client');

  if GetLastError = ERROR_ALREADY_EXISTS then begin
     Halt;
  end;

finalization  // ... und Schluß
  if mHandle <> 0 then
    CloseHandle(mHandle)
end.
jetzt würde ich aber ganz gerne bei der laufenden Anwendung eine funktion aufrufen, weiß aber nicht wie ich das machen kann?

Alse wenn mein Prog schon läuft, dann soll die Anwendung (dort wo jetzt Halt; steht) eine Funktion bei der laufenden instanz aufrufen. Kann man das irgendwie machen?

hsg 17. Jan 2007 08:16

Re: Mutex und Programm nicht doppelt starten
 
schickt ihr eine Message und rufe vom Message-Handler dann deine Funktion auf, also in etwa so:

Delphi-Quellcode:
h := 0;
repeat
  h := FindWindowEx(0,h,'TApplication',PCHar(Application.Title));
until h <> Application.Handle;
if h <> 0 then begin
  Windows.SendMessage(h,SW_USER+4711,0,0);
end;
Achtung: so ins unreine getippt, also Fehler nicht ausgeschlossen

kingflo 17. Jan 2007 08:49

Re: Mutex und Programm nicht doppelt starten
 
ich kriegs nicht hin... mit deinem Code kommt es nicht vor, dass h <>0 ist.

dann dachte ich,´dass es so gehen müsste:
Delphi-Quellcode:
  mHandle := CreateMutex(nil,True,'Stryyke Client');

  if GetLastError = ERROR_ALREADY_EXISTS then begin
     ShowMessage('test');
     Windows.SendMessage(mHandle,WM_USER,0,0);
     Halt;
  end;
dann wollte ich die ApplicationEvents abfangen, dass habe ich so gemacht:

Delphi-Quellcode:
procedure TLoginForm.ApplicationEvents1Message(var Msg: tagMSG;
  var Handled: Boolean);
begin
 if MSg.message = WM_USER then begin
   ShowMessage('Angekommen');
 end;
end;

leider bekomme ich die ShowMessage('Angekommen'); nie zu sehen :cry:

daraus schließe ich, dass das Windows.SendMessage(mHandle,WM_USER,0,0); nicht richtig geht oder?

hsg 17. Jan 2007 08:57

Re: Mutex und Programm nicht doppelt starten
 
Dein mHandle ist das Handle des Mutex, das geht natürlich nicht!
Was du brauchst ist das Handle auf die bereits laufende Instanz des Programmes, daher das Findwindow. Ich schrieb ja, das dort ein Fehler sein könnte. Such mal hier im Forum nach Mutex und Fenster nach vornebringen, dort gibt es funktionierende Lösungen.

Edit:
Habe eben in der Newsgruppe de.comp.language.delphi.misc ein Beispiel gefunden, (ist von Nineberry, der weiss was er tut)
Delphi-Quellcode:
procedure CheckOnce;
const
  TestTitle = 'Nicoles Einweganwendung testing...';
  AppTitle = 'Nicoles Einweganwendung';
var
  hWnd: THandle;
begin
  // einen anderen Titel setzen, so dass wir uns
  // nicht selbst finden
  Application.Title:= TestTitle;
  hWnd:= FindWindow('TApplication', AppTitle);

  if hWnd <> 0 then
  begin
    // Eine andere Instanz läuft schon;

    // Falls minimiert, wiederherstellen
    if IsIconic(hWnd) then
      ShowWindow(hWnd, SW_SHOW);

    // Diese in den Vordergrund bringen
    SetForegroundWindow(hWnd);

    // Uns selbst schließen
    Halt;
  end;

  // Wir sind die erste Instanz -> Titel setzen, so
  // dass weitere unsfinden
  Application.Title:= AppTitle;
end;
Damit müsstest du deine andere Instanz finden, der schickst du dann die Message (und wenn du WM_USER + 4711 sendest, dann musst du natürlich auch auf WM_USER + 4711 abfragen)
/Edit

kingflo 17. Jan 2007 09:21

Re: Mutex und Programm nicht doppelt starten
 
Arghhh... es geht leider nicht, er findet das fenster handle nicht...

meine unit sieht jetzt so aus:


Delphi-Quellcode:
unit mutex;

interface

implementation

uses windows,Dialogs,sysutils,forms,login,messages;

const
  TestTitle = 'StryykeclientTest';
  AppTitle = 'Stryykeclient';
var
  hWnd: THandle;

Initialization


  // einen anderen Titel setzen, so dass wir uns
  // nicht selbst finden
  Application.Title:= TestTitle;
  hWnd := FindWindow('TApplication', AppTitle);
  ShowMessage(Application.Title);
  if hWnd <> 0 then
  begin
    // Eine andere Instanz läuft schon;
    ShowMessage('gefunden');
    // Falls minimiert, wiederherstellen
    if IsIconic(hWnd) then
      ShowWindow(hWnd, SW_SHOW);

    // Diese in den Vordergrund bringen
    SetForegroundWindow(hWnd);

    // Uns selbst schließen
    Halt;
  end;

  // Wir sind die erste Instanz -> Titel setzen, so
  // dass weitere unsfinden
  Application.Title:= AppTitle;
  ShowMessage(Application.Title);
finalization  // ... und Schluß

end.

hsg 17. Jan 2007 09:30

Re: Mutex und Programm nicht doppelt starten
 
Was funktioniert denn nicht?
Ich habe eben deinen Source mal in ein neues Projekt eingefügt und ausprobiert, da passierte das erwartete.

kingflo 17. Jan 2007 09:32

Re: Mutex und Programm nicht doppelt starten
 
ok ok jetzt gehts... danke mein application.titel war nach der initialisierung anders...

kingflo 17. Jan 2007 09:35

Re: Mutex und Programm nicht doppelt starten
 
jetzt hab ich aber das Problem, das die Windows Message trotzdem nicht ankommt :|

Delphi-Quellcode:
Windows.SendMessage(hWnd,WM_USER+4711,0,0);
Delphi-Quellcode:
procedure TLoginForm.ApplicationEvents1Message(var Msg: tagMSG;
  var Handled: Boolean);
begin
 if MSg.message = WM_USER+4711 then begin
   ShowMessage('Angekommen');
 end;
end;

Robert Marquardt 17. Jan 2007 09:40

Re: Mutex und Programm nicht doppelt starten
 
Das Programm mittels Halt zu beenden ist nicht die beste Wahl.
Besser ist es den Mutex im .dpr file zu platzieren und dort einfach die "Application."-Zeilen in ein if einzuschliessen.
Wenn Application.Run nicht aufgerufen wird, dann macht das Programm auch nichts.

hsg 17. Jan 2007 10:05

Re: Mutex und Programm nicht doppelt starten
 
Sorry, kann ich nachvollziehen, verstehe es aber momentan auch nicht.
Das Handle ist richtig, FindWindow liefert das korrekte Fenster, nur das Senden geht irgendwie ins Nirvana und kommt nicht in der Application an (auch Windows-mässig nicht).

Hab leider keine Zeit, da auf Forschung zu gehen. :(


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:50 Uhr.
Seite 1 von 2  1 2      

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