Entwickler-Ecke
WinForms - Event, wenn Anwendung Focus verliert
ripmav - Di 02.03.10 16:09
Titel: Event, wenn Anwendung Focus verliert
Hallo,
ich habe mehrere Fenster in meiner Anwendung offen. Das Event soll nur aufgerufen werden, wenn wirklich alle Fenster meiner Anwendung nicht den Focus haben, d.h. das Fenster einer anderen Anwendung legt sich über die Fenster meiner Anwendung.
LostFocus und Deactivate sind nicht die richtigen Events dafür.
Gibt es dafür ein Event oder muss man die WinAPI benutzen?
MfG
JüTho - Di 02.03.10 16:20
Hallo,
ich glaube, eine solche Möglichkeit ist in .NET nicht enthalten. Aber du kannst es prüfen: Benutze eines der denkbaren Form-Ereignisse; Deactivate dürfte am ehesten passen. Hole Application.OpenForms und frage alle darin enthaltenen Formulare nach ContainsFocus ab.
Gruß Jürgen
norman2306 - Di 02.03.10 19:23
Mir fällt da auch spontan kein Event ein...
Dann schreiben wir eben unser eigenes :)
editiert
C#-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: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118:
| using System; using System.Windows.Forms; using System.Threading; using System.Diagnostics; using System.Runtime.InteropServices;
namespace WindowsFormsApplication1 { static class Program {
[DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)] private static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)] private static extern Int32 GetWindowThreadProcessId(IntPtr hWnd, out Int32 lpdwProcessId);
public delegate void AppFocusEvent();
public static event AppFocusEvent AppLostFocus;
public static event AppFocusEvent AppGotFocus;
[STAThread] static void Main() { Thread ALFThr = new Thread(() => { bool LostFoc = false; while (true) { IntPtr hwnd = GetForegroundWindow(); Int32 fgwPID = 0; GetWindowThreadProcessId(hwnd, out fgwPID); int cpPID = Process.GetCurrentProcess().Id; if (fgwPID != cpPID && !LostFoc) { LostFoc = true; if (AppLostFocus != null) AppLostFocus(); } else if (fgwPID == cpPID && LostFoc) { LostFoc = false; if (AppGotFocus != null) AppGotFocus(); } Thread.Sleep(100); } }); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false);
AppLostFocus += new AppFocusEvent(Program_AppLostFocus); AppGotFocus += new AppFocusEvent(Program_AppGotFocus); ALFThr.Start(); Application.Run(new Form1()); }
static void Program_AppGotFocus() { }
static void Program_AppLostFocus() { } } } |
Hoffe, das hilft dir:)
Moderiert von
Christian S.: Beiträge zusammengefasst
ich dokumentiere das nachher noch, wenn du das möchtest. muss aber jetzt zum sport... keine zeit
Edit:
Getestet, etwas optimiert, dokumentiert und noch ein "AppGotFocus" hinzugefügt :) na wenn das mal kein Service ist
ripmav - Mi 03.03.10 16:30
@JüTho:
Leider funktioniert die Methode mit Application.OpenForms nicht :(
@norman2306:
Genau das ist es! Und auch schon alles fertig geschrieben. Vielen Dank!!
Schade das es mit einer Schleife realisiert werden muss, wo doch Windows eigtl ein eventgesteuertes System sein soll.. Aber es gibt wohl keine andere Möglichkeit
JüTho - Mi 03.03.10 17:11
ripmav hat folgendes geschrieben : |
@JüTho:
Leider funktioniert die Methode mit Application.OpenForms nicht :( |
Rein interessehalber:
was funktioniert daran nicht? Ich habe es nicht selbst geprüft, aber theoretisch sollte es klappen. Jürgen
ripmav - Mi 03.03.10 17:14
Eine Form hat den Focus (ContainsFocus==true), obwohl das Fenster im Hintergrund ist.. Das ist nur der Fall, wenn man STRG+ALT+ENTF drückt. Kann sein, dass das nur unter Windows 7 auftritt, da ja Windows XP in best. Einstellungen sofort den Taskmanager öffnet.
JüTho - Mi 03.03.10 17:18
Oops, mit so etwas habe ich bei meinem Vorschlag natürlich nicht gerechnet. Danke für den Hinweis! Jürgen
norman2306 - Mi 03.03.10 18:13
ripmav hat folgendes geschrieben : |
Schade das es mit einer Schleife realisiert werden muss, wo doch Windows eigtl ein eventgesteuertes System sein soll.. Aber es gibt wohl keine andere Möglichkeit |
Korrigiere mich, aber im Prinzip lassen sich alle internen System-Events (also Events, die nicht auf einem elektrischen Signal beruhen) auf eine Abfrage-Schleife zurückführen. Zum Beispiel erfolgt die Abfrage von Windows-Meldungen auch in einer sog. MessageLoop (so erfährt dein Program das es sich abschiessen muss, wenn du z.B. runterfährst und das Event wird ausgelöst)
ripmav - Mi 03.03.10 18:15
Ja, das stimmt, aber die MessageLoop basiert auf der Funktion GetMessage und diese wartet ("sleept") solange, bis wirklich eine Message da ist..
norman2306 - Mi 03.03.10 18:39
Joop, aber irgendwo hängt da mal eine Endlosschleife. Entweder ich habe einen physikalischen Schalter, der irgendein Event auslöst (z.B. Tastendruck) oder irgendwas läuft in einer Abfrage-Schleife (Permanente Abfrage, ob was da ist) oder in einer Sende-Schleife (Läuft solang in einer Schleife und blockiert, bis was zum Senden da ist).
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!