Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi application.ondeactivate (funktioniert nur bei focus) (https://www.delphipraxis.net/102833-application-ondeactivate-funktioniert-nur-bei-focus.html)

taveuni 5. Nov 2007 19:35


application.ondeactivate (funktioniert nur bei focus)
 
Hallo Gemeinde,

Wieder einmal gehts bei mir nicht weiter.
Folgende Ausgangslage:
Es gibt ein MainForm und ein Form2.
Das Form2 wird irgendwann als eine Art PopUp geöffnet und über eine andere Applikation gelegt. Die Koordinaten kommen von dieser Fremdapplikation via COM Callback.
Nun sollte es so sein dass bei einem Klick irgendwo ausserhalb dieser Form 2 diese geschlossen werden soll. Wir haben dies mit Mainform.FormDeActivate und Application.DeActivate realisiert.
Leider ist es nun aber so dass Application.OnDeactivate nur funktioniert wenn vorher der Focus einmal auf der eigenen Applikation gelegen hat. Alle Versuche nach dem Show dieser den Focus zu geben sind gescheitert.
Zur Veranschaulichung:

Delphi-Quellcode:
procedure TForm1.FormDeactivate(Sender: TObject);
begin
   if Form2.activated then
   form2.Close;
end;

procedure TForm1.ApplicationEvents1Deactivate(Sender: TObject);
begin
   form2.Close;
  form2.activated := False;
end;

// falls form 2 über den Button ausgelöst wird funktioniert alles
procedure TForm1.Button1Click(Sender: TObject);
begin
  form2.Left := StrToInt(edit1.Text);
  form2.Top := StrToInt(edit2.Text);
  form2.Show;
  SetWindowPos(form2.handle, HWND_TOPMOST, 0, 0, 0, 0,
                 SWP_NOMOVE or SWP_NOSIZE or SWP_SHOWWINDOW)
end;


// Als Versuch mit einem Timer Applikation starten und einmal auf den Desktop klicken. Nun muss zuerst der Focus mit Klick wieder auf die eigene Applikation gelegt werden bevor Application.OnDeActivate ausgelöst wird.

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  timer1.Enabled := False;
 
  form2.Left := StrToInt(edit1.Text);
  form2.Top := StrToInt(edit2.Text);
  form2.Show;
  SetWindowPos(form2.handle, HWND_TOPMOST, 0, 0, 0, 0,
                 SWP_NOMOVE or SWP_NOSIZE or SWP_SHOWWINDOW)
end;


Kennt jemand einen Workaround?

Gruss Werner

Ich habe dieses Problem schon in Delphi-Source gepostet http://forum.dsdt.info/viewtopic.php?t=34652

Deep-Sea 6. Nov 2007 07:29

Re: application.ondeactivate (funktioniert nur bei focus)
 
Das ein Deaktivierungsereginis erst eintreten kann, wenn etwas auch mal aktiv war, leuchtet ja eigentlich ein ^^
Für was nutzt du "TForm1.FormDeActivate"? Sollte das OnDeactivate nicht bei Form2 sein? ...

Aber vlt. hilft dir ja das hier weiter: http://www.swissdelphicenter.ch/de/showcode.php?id=261

PS: Ich weiß ja nicht, was du noch mit "Form2.activated" machst, aber währe TForm.Visible nicht evtl. das, was du suchst?

taveuni 6. Nov 2007 08:01

Re: application.ondeactivate (funktioniert nur bei focus)
 
Hallo Deep-Sea,

Zitat:

Das ein Deaktivierungsereginis erst eintreten kann, wenn etwas auch mal aktiv war, leuchtet ja eigentlich ein ^^
Darum habe ich geschrieben:
Zitat:

Alle Versuche nach dem Show dieser den Focus zu geben sind gescheitert
Zu diesen Versuchen gehören auch alle aus Deinem geposteten Link.
Mit dem anderen hast Du natürlich recht es wäre Form2.FormDeactivate. Ich habe den geposteten Code einfach so sinngemäss ungetestet hingeschrieben.
Das ist aber nicht relevant für mein Problem.

Die Frage anders formuliert:
Aus einem Timer wird Form2.Show aufgerufen. Danach wird Form2 Topmost gesetzt. Wie aktiviere ich nun Form2 so dass bei einem Mausklick ausserhalb meiner Application ApplicationDeactivate ausgelöst wird? Und dies ohne einen Systemweiten Maushook.

Deep-Sea 6. Nov 2007 08:15

Re: application.ondeactivate (funktioniert nur bei focus)
 
Also ich habe es gerade mit Hilfe des im Link enthaltenen Tipps getestet (D2006) und es klappt :-D

Habe dazu
Delphi-Quellcode:
procedure SwitchToThisWindow(h1: hWnd; x: bool); stdcall;
  external user32 Name 'SwitchToThisWindow';
genutzt ...

taveuni 6. Nov 2007 08:22

Re: application.ondeactivate (funktioniert nur bei focus)
 
Hast Du bevor der Timer Form2.Show auslöst mal auf den Desktop geklickt?
(Damit der Fokus nicht mehr auf Deiner Applikation liegt)
Bei mir (Delphi 7 Ent) funktioniert es dann nicht!

Deep-Sea 6. Nov 2007 08:27

Re: application.ondeactivate (funktioniert nur bei focus)
 
Zitat:

Zitat von taveuni
Hast Du bevor der Timer Form2.Show auslöst mal auf den Desktop geklickt?

Ich bin ja nicht doof :P ...
Was klappt denn nicht? Bekommt die 2. Form mit "SwitchToThisWindow" (oder einer anderen Funktion dieser Art) keinen Fokus? Oder kommt, obwohl sie den Fokus hat, kein OnDeactivate?

Wozu dient eig. der TTimer? Nur zum Testen oder soll der später drinnen bleiben?

DeddyH 6. Nov 2007 08:27

Re: application.ondeactivate (funktioniert nur bei focus)
 
Unter Delphi 5 auf XP funktioniert es.

taveuni 6. Nov 2007 08:49

Re: application.ondeactivate (funktioniert nur bei focus)
 
Liste der Anhänge anzeigen (Anzahl: 1)
@Deep-Sea - Natürlich ist der Timer nur zum testen.
Ich hab mein Testprojekt angehängt. Bitte Programm starten, dann auf den Desktop klicken, dann warten bis der Timer Form2 ausgelöst hat, dann wieder auf den Desktop klicken. Wird bei Euch nun Application Deactivate ausgelöst? Bei mir nicht.
Wenn ich das Ding nur starte ohne zuerst den Focus auf ein anderes Fenster zu legen gehts bei mir auch.
Könnt Ihr das noch mal checken?
Thanks.

DeddyH 6. Nov 2007 08:58

Re: application.ondeactivate (funktioniert nur bei focus)
 
Hast Recht, Form2 gibt den Fokus nicht wieder her, wie es scheint.

Deep-Sea 6. Nov 2007 09:04

Re: application.ondeactivate (funktioniert nur bei focus)
 
Bei mir klappt es im Debugger, aber nicht beim "normalen" ausführen :shock: ...


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:40 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