Autor Beitrag
Singlepin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 36
Erhaltene Danke: 4

WinXP
Delphi6 MySQL
BeitragVerfasst: Do 14.08.14 19:15 
Hallo Gemeinde,

mein Problem ist folgendes, um den doppelten Programmstart zu verhindern hatte ich bisher folgendes.

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:
var
  Flash: FLASHWINFO;
Initialization

hFMapping:=CreateFileMapping(INVALID_HANDLE_VALUE,NIL,PAGE_READWRITE,
                            0,sizeof(Application.Handle),
                            appName);
if hFMapping<>0
 then
  begin
  if GetLastError=ERROR_ALREADY_EXISTS
   then
    begin
    FSpeicher:=MapViewOfFile(hFMapping,FILE_MAP_READ,0,0,0);
    FHandle:=FSpeicher^;
    UnmapViewOfFile(FSpeicher);
    Windows.ShowWindow(FHandle,SW_Normal); // Fenster auf Normal
    Windows.SetForegroundWindow(FHandle);  // in den Vordergrund bringen
    halt;
    end
   else
    begin
    FSpeicher:=MapViewOfFile(hFMapping,FILE_MAP_WRITE,0,0,0);
    FSpeicher^:=Application.Handle;
    UnmapViewOfFile(FSpeicher);
    end;
  end
 else
  begin
  Application.MessageBox('Fehler beim Erstellen des Mapping','Abbruch',MB_OK);
  Halt;
  end;

Mit Win7 geht
ausblenden Delphi-Quelltext
1:
2:
    Windows.ShowWindow(FHandle,SW_Normal); // Fenster auf Normal
    Windows.SetForegroundWindow(FHandle);  // in den Vordergrund bringen

nicht mehr.

Dafür möchte ich jetzt, daß das Programm in der Taskleiste blinkt.
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:
var
  Flash: FLASHWINFO;
Initialization

hFMapping:=CreateFileMapping(INVALID_HANDLE_VALUE,NIL,PAGE_READWRITE,
                            0,sizeof(Application.Handle),
                            appName);
if hFMapping<>0
 then
  begin
  if GetLastError=ERROR_ALREADY_EXISTS
   then
    begin
    FSpeicher:=MapViewOfFile(hFMapping,FILE_MAP_READ,0,0,0);
//    FHandle:=FSpeicher^;
    UnmapViewOfFile(FSpeicher);
    FHandle:=FindWindow(NIL,PChar('Programmname'));
    FillChar(Flash, SizeOf(Flash), 0);
    Flash.cbSize:=SizeOf(Flash);
    Flash.hwnd:=FHandle;
    Flash.uCount:=5;
    Flash.dwTimeOut:=2000;
    Flash.dwFlags:=FLASHW_ALL;
    FlashWindowEx(Flash);
//    Windows.ShowWindow(FHandle,SW_Normal); // Fenster auf Normal
//    Windows.SetForegroundWindow(FHandle);  // in den Vordergrund bringen
    halt;
    end
   else
    begin
    FSpeicher:=MapViewOfFile(hFMapping,FILE_MAP_WRITE,0,0,0);
    FSpeicher^:=Application.Handle;
    UnmapViewOfFile(FSpeicher);
    end;
  end
 else
  begin
  Application.MessageBox('Fehler beim Erstellen des Mapping','Abbruch',MB_OK);
  Halt;
  end;

Das geht zwar, aber mich stört
ausblenden Delphi-Quelltext
1:
    FHandle:=FindWindow(NIL,PChar('Programmname'));					


Wie komme ich zum richtigen Handle?

Moderiert von user profile iconNarses: Titel erweitert.
Moderiert von user profile iconNarses: Topic aus Sonstiges (Delphi) verschoben am Fr 15.08.2014 um 09:38
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Do 14.08.14 19:45 
Das einfachste ist ein Broadcast an eine von allen Instanzen mit RegisterWindowMessage erstellten Botschaft. Die kann dann die erste Instanz auswerten und sich selbst um die Anzeige kümmern. Oder diese könnte auch einfach z.B. einen Balloon Hint auf dem Tray Icon anzeigen oder so, sprich selbst viel mehr machen als nur blinken lassen.
Und du kannst auch weitere Infos übergeben (Parameter, ...).

An das Fensterhandle kannst du (wenn du es doch damit machen möchtest) kommen, indem du nicht anhand des Fenstertitels vorgehst, sondern über den Klassennamen gehst. Der sollte natürlich dann gut gewählt sein, sprich eindeutig.

Nebenbei:
Statt das in Initialization zu machen und dann mit Halt das Programm gegen einen Baum zu fahren kannst du auch einfach im Projektquelltext das Application.Run nur ausführen, wenn nicht schon eine Instanz lief...
Das ist viel eleganter und sauberer.
Singlepin Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 36
Erhaltene Danke: 4

WinXP
Delphi6 MySQL
BeitragVerfasst: Do 14.08.14 20:18 
Danke jaenicke
für die schnelle Antwort.
Die Anregungen werde ich mal durchgehen.
In diesem Fall dachte ich, das ich über das Applikatinshande das Fensterhandle ermitteln kann und fertig.
Die Frage ist wie.
hathor
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Do 14.08.14 20:35 
user profile iconSinglepin hat folgendes geschrieben Zum zitierten Posting springen:

...
Das geht zwar, aber mich stört
ausblenden Delphi-Quelltext
1:
    FHandle:=FindWindow(NIL,PChar('Programmname'));					


Wie komme ich zum richtigen Handle?


ausblenden Delphi-Quelltext
1:
   FHandle:= FindWindow( Pchar(string(TForm2.Classname)), Nil );					


Zuletzt bearbeitet von hathor am So 17.08.14 00:14, insgesamt 1-mal bearbeitet
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Do 14.08.14 22:58 
user profile iconhathor hat folgendes geschrieben Zum zitierten Posting springen:
ausblenden Delphi-Quelltext
1:
   FHandle:=Windows.FindWindow(NIL,PChar(UpperCase(ExtractFileName(ParamStr(0)))));					
Was hat der Dateiname der Exe mit dem Fenstertitel zu tun? :gruebel:
mandras
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 429
Erhaltene Danke: 107

Win 10
Delphi 6 Prof, Delphi 10.4 Prof
BeitragVerfasst: Fr 15.08.14 09:16 
Ich habe da was aus meiner Mottenkiste ausgegraben um unter Win7 ein Fenster in den Vordergrund zu bekommen:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
procedure WinToTop (Handle: hWnd);
var ThreadID1, ThreadID2: integer;
begin
 if Handle = GetForeGroundWindow then exit;
 ThreadID1 := GetWindowThreadProcessID (GetForeGroundWindow, Nil);
 ThreadID2 := GetWindowThreadProcessID (Handle, Nil);
 if ThreadID1 <> ThreadID2 then begin
  AttachThreadInput (ThreadID1, ThreadID2, true);
  SetForeGroundWindow (Handle);
  AttachThreadInput (ThreadID1, ThreadID2, false);
 end else
  SetForeGroundWindow (Handle);
 if IsIconic (Handle) then ShowWindow (handle, sw_restore) else
  ShowWindow (handle, sw_Show);
end;



Vielleicht hilft es ja
hathor
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: So 17.08.14 00:17 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconhathor hat folgendes geschrieben Zum zitierten Posting springen:
ausblenden Delphi-Quelltext
1:
   FHandle:=Windows.FindWindow(NIL,PChar(UpperCase(ExtractFileName(ParamStr(0)))));					
Was hat der Dateiname der Exe mit dem Fenstertitel zu tun? :gruebel:


Ich habe es oben geändert in:

ausblenden Delphi-Quelltext
1:
 FHandle:= FindWindow( Pchar(string(TForm1.Classname)), Nil );					
Singlepin Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 36
Erhaltene Danke: 4

WinXP
Delphi6 MySQL
BeitragVerfasst: Fr 22.08.14 15:28 
Ich bin einen Schritt weiter.

mit
ausblenden Delphi-Quelltext
1:
2:
3:
4:
    FHandle:=FindWindow(NIL,PChar('Artikel suche'));
    AllowSetForegroundWindow(FHandle);
    Windows.ShowWindow(FHandle,SW_Normal); // Fenster auf Normal
    Windows.SetForegroundWindow(FHandle);  // in den Vordergrund bringen


bekomme ich meine Anwendung in den Vordergrund.
Somit besteht mein Problem nur noch darin, daß ich mit
ausblenden Delphi-Quelltext
1:
    FSpeicher^:=Application.Handle;					

seit Windows 7 nicht mehr das richtige Handle in meinem MemoryMappedFile speichere.
Wie schon gesagt ich möchte nicht mit FindWindow nach dem "Falschen" suchen sondern das richtige Handle einfach auslesen.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Fr 22.08.14 16:00 
Das Application-Handle ist (bis Delphi 2007 oder mit MainFormOnTaskbar auf False) das Fenster, das den Taskleistenknopf anzeigt. Das hat aber eigentlich nichts mit dem angezeigten Fenster zu tun. Meinst du vielleicht Application.MainForm.Handle?
Singlepin Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 36
Erhaltene Danke: 4

WinXP
Delphi6 MySQL
BeitragVerfasst: Fr 22.08.14 16:47 
Hallo Jaenicke,

bei Application.MainForm.Handle gibt es einen Laufzeitfehler, aber Application.MainFormHandle ist die Lösung.
Nun muß ich das Ganze nur noch richtig verstehen.

Danke für die Hilfe.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19272
Erhaltene Danke: 1740

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Fr 22.08.14 18:41 
user profile iconSinglepin hat folgendes geschrieben Zum zitierten Posting springen:
bei Application.MainForm.Handle gibt es einen Laufzeitfehler
Dann gibt es in dem Moment noch kein Hauptformular, sprich es ist noch nicht fertig erzeugt.