Einzelnen Beitrag anzeigen

Hansa

Registriert seit: 9. Jun 2002
Ort: Saarland
7.554 Beiträge
 
Delphi 8 Professional
 
#8
  Alt 7. Nov 2002, 18:40
Hi Leute,

habt ihr nichts zu tun ? Code folgt noch. Habe hier eine Function, die in das DPR rein muß, z.B.

IF BereitsAktiv THEN
Aplication.Terminate;

Mutex ist meiner Ansicht nach nicht so gut. Mit Semaphoren (griech.: Signalflagge) wird Windows angezeigt, daß die Anwendung bereits läuft. Bei meinem Bsp. sieht das folgendermaßen aus.

1. User startet Programm und gibt eine halbe Rechnung ein.
2. User macht was anderes und vergißt die halbe Rechnung.
3. Er startet Programm wieder.
4. Semaphore teilt dem Programm mit es sei gestartet, schließt die zweite Instanz und startet sich selbst, wobei es wieder genau mitten in der halben Rechnung steht. Also genau nach dem "Zwischenfall".

Delphi-Quellcode:
unit sema;

interface

uses
  Windows, Messages,SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

function BereitsAktiv: Boolean;

IMPLEMENTATION

function BereitsAktiv: Boolean;
var
  semName,
  appClass: PChar;
  hSem : THandle;
  hWndMe : HWnd;
  appTitle: Array[0..MAX_PATH] of Char;
begin
  // Init
  Result := FALSE;
  GetMem(semName,15);
  GetMem(appClass,15);
  StrPCopy(semName,'sema');
  StrPCopy(appClass,'TApplication');
  StrPCopy(appTitle,ExtractFileName(Application.Title));

  // Create a Semaphore in memory. If this is the
  // first instance, then hSem's value should be 0.
  hSem := CreateSemaphore(nil,0,1,semName);

  // Check to see if the semaphore exists
  if (hSem <> 0) and (GetLastError() =
                      ERROR_ALREADY_EXISTS) then
    begin
      CloseHandle(hSem);

      // Get the current window's handle then change
      // its title so we can look for the other instance
      hWndMe := FindWindow(appClass,appTitle);
      SetWindowText(hWndMe,'ZZZZZZZ');

      // Search for other instance of this window then bring
      // it to the top of the Z-order stack. We find it by
      // matching the Application Class and
      // Application Title.
      hWndMe := FindWindow(appClass,appTitle);
      if (hWndMe <> 0) then
        begin
          BringWindowToTop(hWndMe);
          ShowWindow(hWndMe,SW_SHOWNORMAL);
        end;

      Result := TRUE;
    end;

  // Destroy PChars
  FreeMem(semName,15);
  FreeMem(appClass,15);
end;

end.
Wem das nicht reicht, soll sich mit Mutex (warum aber ?) beschäftigen. Mir ging es darum, zu verhindern, daß ein Programm 10mal in der Taskleiste steht, was vorher nicht eingeplant war. Mit diesem Bsp. kann man es so oft starten, wie man will, es landet immer nur bei einer Instanz. Ein Start mehrerer wird verhindert, da es immer bei der ersten landet.

Quelltext ist getestet und funktioniert, bis auf die Einbindung in DPR. Da könnte ein Fehler drin sein, aber die eventuelle Korrektur kann ich nachliefern.

Gruß
Hansa
  Mit Zitat antworten Zitat