Autor Beitrag
galagher
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2556
Erhaltene Danke: 45

Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
BeitragVerfasst: Fr 16.06.06 13:01 
Hallo zusammen!
only_one.pas verhindert, dass eine zweite Instanz eines Programms gestartet wird. Das funktioniert auch. Es soll aber das Fenster der laufenden Instanz in den Vordergrund bringen, und das funktioniert nicht. Kann das jemand zum Laufen bringen? Hier der Code:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
{
 Diese Unit erlaubt es, ein Programm nur 1x zu starten.
 Wichtig: Application.Title muss ein String zugewiesen sein!
}



unit only_one;

interface

implementation

uses
  forms, windows;

var
  mutex : THandle;
  h     : HWnd;

initialization
  mutex := CreateMutex(nil,true,PChar(Application.Title));
  if getLastError = ERROR_ALREADY_EXISTS then begin
  h := 0;
  repeat
  h := FindWindowEx(0,h,'TApplication',PChar(Application.Title))
  until h <> application.handle;
  if h <> 0 then
  begin
    Windows.ShowWindow(h, SW_ShowNormal);
    windows.SetForegroundWindow(h);  //Klappt nicht - warum?
  end;
  halt;
end;

finalization
  ReleaseMutex(mutex);
end.

_________________
gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Fr 16.06.06 13:17 
Moin!

Guckst du

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
galagher Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2556
Erhaltene Danke: 45

Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
BeitragVerfasst: Fr 16.06.06 14:10 
user profile iconNarses hat folgendes geschrieben:
Guckst du

Ja, das verhindert den Programmstart schon bei der 1. Instanz!

_________________
gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Fr 16.06.06 14:34 
Moin!

Der Code funktioniert, ich verwende ihn genau so (natürlich mit angepasstem Formular-/Klassen-Namen).

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
galagher Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2556
Erhaltene Danke: 45

Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
BeitragVerfasst: Fr 16.06.06 14:51 
Vielleicht bin ich zu dämlich! Ich mache das so, und es ist wie vorher (der Sinn ist es ja, eine eigene Unit dafür zu haben, wie ich einen solchen Mutex in die *.dpr einbinde, weiss ich):
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
{
 Diese Unit erlaubt es, ein Programm nur 1x zu starten.
 Wichtig: Application.Title muss ein String zugewiesen sein!
}



unit only_one;

interface

implementation

uses
  forms, windows;

var
  mutex     : THandle;
  hWndFirst, hWndApp : HWnd;

initialization
(*  mutex := CreateMutex(nil,true,PChar(Application.Title));
  if getLastError = ERROR_ALREADY_EXISTS then begin
  h := 0;
  repeat
  h := FindWindowEx(0,h,'TApplication',PChar(Application.Title))
  until h <> application.handle;
  if h <> 0 then
  begin
    Windows.ShowWindow(h, SW_ShowNormal);
    windows.SetForegroundWindow(h);
  end;
  halt;
*)


Mutex := CreateMutex(NIL, TRUE, PChar(Application.Title));
if (GetLastError() = ERROR_ALREADY_EXISTS) then
begin
  hWndFirst := FindWindow(PChar(Application.Title), NIL);
  if (hWndFirst <> 0then
  begin
    hWndApp := GetWindow(hWndFirst, GW_OWNER); // Owner-Handle holen (Handle des TApplication-Fensters)
    if IsIconic(hWndApp) then
      ShowWindow(hWndApp, SW_RESTORE); // restoren wenn minimiert
    // Hauptfenster in den Vordergrund holen
    SetForegroundWindow(hWndFirst);
    BringWindowToTop(hWndFirst);
  end;
  CloseHandle(Mutex);
  Exit; // 2. Instanz kann gestartet werden
        //Halt oder Application.Terminate: 1. Instanz kommt nicht in den Vordergrund
end;

finalization
//  ReleaseMutex(mutex);
  CloseHandle(mutex);  //Ändert auch nichts
end.

_________________
gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Fr 16.06.06 18:21 
Moin!

Da ist dein Problem:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
if (GetLastError() = ERROR_ALREADY_EXISTS) then
begin
  hWndFirst := FindWindow(PChar(Application.Title)NIL);
  if (hWndFirst <> 0then

Da muss der Klassenname deines Hauptformulars rein, also z.B. "TForm1". ;) Was für einen Titel deine Applikation hat, ist mal eher Wurst... :D

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
galagher Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2556
Erhaltene Danke: 45

Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
BeitragVerfasst: Fr 16.06.06 20:43 
Ok, so geht es:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
{
 Diese Unit erlaubt es, ein Programm nur 1x zu starten.
 Wichtig: Application.Title muss ein String zugewiesen sein!
}



unit only_one;

interface

implementation

uses
  forms, windows;

var
  mutex: THandle;
  hWndFirst, hWndApp: HWnd;

initialization

Mutex := CreateMutex(NIL, TRUE, PChar(Application.Title));

if (GetLastError() = ERROR_ALREADY_EXISTS) then
begin
  hWndFirst := FindWindow('TForm1'NIL);
  if (hWndFirst <> 0then
  begin
    hWndApp := GetWindow(hWndFirst, GW_OWNER); // Owner-Handle holen (Handle des TApplication-Fensters)
    if IsIconic(hWndApp) then
      ShowWindow(hWndApp, SW_RESTORE); // restoren wenn minimiert
    // Hauptfenster in den Vordergrund holen
    SetForegroundWindow(hWndFirst);
    BringWindowToTop(hWndFirst);
  end;
  CloseHandle(Mutex);
  Halt;
end;

finalization
//  ReleaseMutex(mutex);
  CloseHandle(mutex);
end.


Danke! Bleibt aber die Frage: Was ist der Unterschied zwischen ReleaseMutex(mutex) und CloseHandle(mutex)? Oder ist das egal? Und gibt es etwas eleganteres als Halt oder Application.Terminate? Und wie ersetzt man 'Form1' durch den jeweiligen Klassennamen?

_________________
gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!