Autor |
Beitrag |
Singlepin
Beiträge: 36
Erhaltene Danke: 4
WinXP
Delphi6 MySQL
|
Verfasst: Do 14.08.14 19:15
Hallo Gemeinde,
mein Problem ist folgendes, um den doppelten Programmstart zu verhindern hatte ich bisher folgendes.
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); Windows.SetForegroundWindow(FHandle); 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
Delphi-Quelltext 1: 2:
| Windows.ShowWindow(FHandle,SW_Normal); Windows.SetForegroundWindow(FHandle); |
nicht mehr.
Dafür möchte ich jetzt, daß das Programm in der Taskleiste blinkt.
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); 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); 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
Delphi-Quelltext 1:
| FHandle:=FindWindow(NIL,PChar('Programmname')); |
Wie komme ich zum richtigen Handle?
Moderiert von Narses: Titel erweitert.Moderiert von Narses: Topic aus Sonstiges (Delphi) verschoben am Fr 15.08.2014 um 09:38
|
|
jaenicke
Beiträge: 19284
Erhaltene Danke: 1742
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: 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
Beiträge: 36
Erhaltene Danke: 4
WinXP
Delphi6 MySQL
|
Verfasst: 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
|
Verfasst: Do 14.08.14 20:35
Singlepin hat folgendes geschrieben : |
...
Das geht zwar, aber mich stört
Delphi-Quelltext 1:
| FHandle:=FindWindow(NIL,PChar('Programmname')); |
Wie komme ich zum richtigen Handle? |
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
Beiträge: 19284
Erhaltene Danke: 1742
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Do 14.08.14 22:58
|
|
mandras
Beiträge: 430
Erhaltene Danke: 107
Win 10
Delphi 6 Prof, Delphi 10.4 Prof
|
Verfasst: Fr 15.08.14 09:16
Ich habe da was aus meiner Mottenkiste ausgegraben um unter Win7 ein Fenster in den Vordergrund zu bekommen:
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
|
Verfasst: So 17.08.14 00:17
|
|
Singlepin
Beiträge: 36
Erhaltene Danke: 4
WinXP
Delphi6 MySQL
|
Verfasst: Fr 22.08.14 15:28
Ich bin einen Schritt weiter.
mit
Delphi-Quelltext 1: 2: 3: 4:
| FHandle:=FindWindow(NIL,PChar('Artikel suche')); AllowSetForegroundWindow(FHandle); Windows.ShowWindow(FHandle,SW_Normal); Windows.SetForegroundWindow(FHandle); |
bekomme ich meine Anwendung in den Vordergrund.
Somit besteht mein Problem nur noch darin, daß ich mit
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
Beiträge: 19284
Erhaltene Danke: 1742
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: 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
Beiträge: 36
Erhaltene Danke: 4
WinXP
Delphi6 MySQL
|
Verfasst: 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
Beiträge: 19284
Erhaltene Danke: 1742
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 22.08.14 18:41
Singlepin hat folgendes geschrieben : | bei Application.MainForm.Handle gibt es einen Laufzeitfehler |
Dann gibt es in dem Moment noch kein Hauptformular, sprich es ist noch nicht fertig erzeugt.
|
|
|