Autor |
Beitrag |
ripmav
Beiträge: 19
|
Verfasst: Di 02.03.10 16:09
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
Beiträge: 2021
Erhaltene Danke: 6
Win XP Prof
C# 2.0 (#D für NET 2.0, dazu Firebird); früher Delphi 5 und Delphi 2005 Pro
|
Verfasst: 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
Beiträge: 222
Erhaltene Danke: 16
Win XP, Win 7 64-Bit
C# 4.0 (VS2010)
|
Verfasst: Di 02.03.10 19:23
Mir fällt da auch spontan kein Event ein...
Dann schreiben wir eben unser eigenes
editiert
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
Beiträge: 19
|
Verfasst: 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
Beiträge: 2021
Erhaltene Danke: 6
Win XP Prof
C# 2.0 (#D für NET 2.0, dazu Firebird); früher Delphi 5 und Delphi 2005 Pro
|
Verfasst: 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
Beiträge: 19
|
Verfasst: 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
Beiträge: 2021
Erhaltene Danke: 6
Win XP Prof
C# 2.0 (#D für NET 2.0, dazu Firebird); früher Delphi 5 und Delphi 2005 Pro
|
Verfasst: 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
Beiträge: 222
Erhaltene Danke: 16
Win XP, Win 7 64-Bit
C# 4.0 (VS2010)
|
Verfasst: 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
Beiträge: 19
|
Verfasst: 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
Beiträge: 222
Erhaltene Danke: 16
Win XP, Win 7 64-Bit
C# 4.0 (VS2010)
|
Verfasst: 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).
|
|