Laden...

Click outside Form

Erstellt von DirtDevil vor 19 Jahren Letzter Beitrag vor 19 Jahren 6.409 Views
D
DirtDevil Themenstarter:in
6 Beiträge seit 2005
vor 19 Jahren
Click outside Form

Hi Leute!

Wie so oft, wenn man sich einem Forum anschließt, hat man eine wichtige Frage.

Mich interessiert, wie ich einen Mouse-Klick ausserhalb einer Form registriere. Konkret: Mein Program soll sich automatisch minimieren, wenn ein Mouse-Klick ausgelöst wird, der nicht im Fenster meines Programs stattfindet...

vielen Dank schon mal 😉

49.485 Beiträge seit 2005
vor 19 Jahren

Hallo DirtDevil,

ich habe keine fertige Lösung, aber ich denke, dass bei einer Lösung die auf true gesetzte Eigenschaft Control.Capture (hier dann Form.Capture) eine Rolle spielen wird.

HTH

herbivore

1.985 Beiträge seit 2004
vor 19 Jahren

Morgen DirtDevil,

ich weiß nicht obs funktioniert, aber könntest Du nicht das LostFocus Ereignis Deiner Form abfragen? Wenn Du neben dein Programm klickst, sollte das Fenster ja den Fokus verlieren und Du könntest es minimieren.

Gruß,
Fabian

"Eine wirklich gute Idee erkennt man daran, dass ihre Verwirklichung von vornherein ausgeschlossen erscheint." (Albert Einstein)

Gefangen im magischen Viereck zwischen studieren, schreiben, lehren und Ideen umsetzen…

Blog: www.fabiandeitelhoff.de

D
DirtDevil Themenstarter:in
6 Beiträge seit 2005
vor 19 Jahren

Original von Fabian
ich weiß nicht obs funktioniert, aber könntest Du nicht das LostFocus Ereignis Deiner Form abfragen? Wenn Du neben dein Programm klickst, sollte das Fenster ja den Fokus verlieren und Du könntest es minimieren.

Ja, genau diese Idee hatte ich ja auch schon. Dabei kann man ja eigentlich auch nichts falsch machen: Form im Designer auswählen -> unter Eigenschaften LostFocus-Event hinzufügen -> entsprechenden Code hinzufügen... Aber es hat nicht funktioniert!

Original von herbivore
ich habe keine fertige Lösung, aber ich denke, dass bei einer Lösung die auf true gesetzte Eigenschaft Control.Capture (hier dann Form.Capture) eine Rolle spielen wird.

Möglich, dass Das eine Lösung ist. Leider konnte ich im Netz keine Informationen dazu finden, die mir auf die Sprünge helfen...

Trotzdem schon mal ein Dank an euch Jungs... Hat sonst noch jemand eine Idee?

49.485 Beiträge seit 2005
vor 19 Jahren

Hallo DirtDevil,

Möglich, dass Das eine Lösung ist. Leider konnte ich im Netz keine Informationen dazu finden, die mir auf die Sprünge helfen...

Ich habe schon öfter gelesen, dass auf nicht vorhandene Doku verwiesen wird. Das wundert mich, weil ihr doch alle das .NET-Framework-SDK installiert haben müsst, oder?. Und da ist doch die sehr gute '.NET Framework SDK-Dokumentation' dabei. Aus der stammen folgende Infos:

Control.Capture-Eigenschaft

Ruft einen Wert ab, der angibt, ob die Maus vom Steuerelement erfasst wurde, oder legt diesen fest.

public bool Capture {get; set;}

Eigenschaftenwert
true, wenn die Maus vom Steuerelement erfasst wurde, andernfalls false.

Hinweise
Wenn die Maus vom Steuerelement erfasst wurde, erhält dieses eine Mauseingabe, unabhängig davon, ob der Cursor sich innerhalb der Begrenzungen des Steuerelements befindet. Die Maus wird i. d. R. nur während eines Ziehvorgangs erfasst.

Nur das Vordergrundfenster kann die Maus erfassen. Wenn ein Hintergrundfenster dies versucht, erhält das Fenster nur Meldungen für Mausereignisse, die eintreten, wenn der Mauszeiger sich im sichtbaren Bereich des Fensters befindet. Außerdem kann der Benutzer auf ein anderes Fenster klicken und es so zum Vordergrundfenster machen, selbst wenn das Vordergrundfenster die Maus erfasst hat,

Wenn die Maus erfasst wurde, funktionieren die Tastenkombinationen nicht.

.NET Framework-Sicherheit:

UIPermission für alle Fenster, um diesen Eigenschaftenwert festzulegen. Zugeordnete Enumeration: UIPermissionWindow.AllWindows

Ja, genau diese Idee hatte ich ja auch schon. Dabei kann man ja eigentlich auch nichts falsch machen: Form im Designer auswählen -> unter Eigenschaften LostFocus-Event hinzufügen -> entsprechenden Code hinzufügen... Aber es hat nicht funktioniert!

Das kann daran liegen, dass nicht das Formular selbst, sondern die enthaltenen Controls den Fokus haben. Im Zweifel muss man wohl LostFocus von allen Controls berücksichtigen (und Fokuswechsel innerhalb der Form aussortieren).

HTH

herbivore

D
DirtDevil Themenstarter:in
6 Beiträge seit 2005
vor 19 Jahren

Original von herbivore
Ich habe schon öfter gelesen, dass auf nicht vorhandene Doku verwiesen wird. Das wundert mich, weil ihr doch alle das .NET-Framework-SDK installiert haben müsst, oder?. Und da ist doch die sehr gute '.NET Framework SDK-Dokumentation' dabei.

In die Doku hatte ich auch schon geschaut, bin daraus aber nicht ganz schlau geworden.

Dass der Fokus auf den Kontrols liegen könnte, hatte ich auch im Hinterkopf, allerdings ist mein Tool mittlerweile rellativ komplex, so dass ich unmöglich jedem Element innerhalb der Form einen LostFocus-Event hinzufügen kann. Der Quelltext würde enorm unübersichtlich werden. Ich fürchte ich muss mal ein wenig rumprobieren...

502 Beiträge seit 2004
vor 19 Jahren

Ich bin zwar nicht ganz sicher, ob Dir das weiterhelfen wird, aber es ist ganz einfach allen Controls Deiner Form ein Event zuzuweisen: Einfach über die Controls Eigenschaft iterieren (evtl. auch noch rekursiv, damit Du die Sub-Controls erwischt) und in der Schleife die Methode zuweisen.
Ein (prinizipielles) Beispiel hab ich sogar grad parat:

			foreach(Control ctrl in this.Controls)
			{	
				ctrl.KeyDown +=new KeyEventHandler(UniversalKeyDown);
			}

Bart Simpson

BTW: Wenn grad jemand dabei ist sowas ähnliches auszubaldowern 🙂
Kennt irgendjemand auch 'ne Möglichkeit , wie ich "globale" Mausevents abfangen kann? Konkretes Beispiel: Ich hab 'ne App die minimiert ist (da facto: Hidden, weil nur noch im Tray) und würde gerne mitkriegen, wenn der User irgendwo klickt bzw. die Maus bewegt...

Praxis ist wenn alles funktioniert und keiner weiss warum.
Theorie ist wenn man alles weiss, aber nichts funktioniert.

Bei uns wird Theorie und Praxis vereint: Nichts funktioniert und keiner weiss warum...

49.485 Beiträge seit 2005
vor 19 Jahren

Hallo Bart,

ja, ich habe mich auch schon gefragt, warum "der Quelltext [dadurch] enorm unübersichtlich werden" würde.

Zu Deinem Problem der "globale" Mausevents:

Ich habe zwar - wie gesagt - keine fertige Lösung, aber ich denke, dass bei einer Lösung die auf true gesetzte Eigenschaft Control.Capture (hier dann Form.Capture) eine Rolle spielen wird.

HTH

herbivore

P
939 Beiträge seit 2003
vor 19 Jahren

Um globale Mouse-Ereignisse abzufangen, benötigt man Mouse-Hooks. Musst mal bei KirKone anfragen, er verwendet sowas in seiner Bildschirm-Lupe. Ist aber nicht ganz einfach, mit .Net-Bordmitteln geht es nicht.

Eine Lupe mit C#

D
DirtDevil Themenstarter:in
6 Beiträge seit 2005
vor 19 Jahren

Original von Mr. Bart Simpson
Ich bin zwar nicht ganz sicher, ob Dir das weiterhelfen wird, aber es ist ganz einfach allen Controls Deiner Form ein Event zuzuweisen: Einfach über die Controls Eigenschaft iterieren und in der Schleife die Methode zuweisen.

Die Idee ist gut, mal sehen, ob mir Das weiterilft. Momentan habe ich das Design der App komplett verworfen und erstelle es neu..

Original von herbivore
ja, ich habe mich auch schon gefragt, warum "der Quelltext [dadurch] enorm unübersichtlich werden" würde.

Das Problem ist, dass ich eigene custom Controls verwende, die wiederrum aus mehreren Kontrol bestehen. Desweiteren werden je nach Benutzereingabe Controls dynamisch generiert und während der Laufzeit des Porgramms hinzugefügt. Spätestens ab hier wird es unübersichtlich allen Kontrol einen Fokus-Event hinzuzufügen.

So funktioniert es nicht einem Panel einen globalen Event hinzu zu fügen, da er nicht auf den darin enthaltenen Controls greift. Wenn ich weiterhin diesen Controls einen Event gebe, muss ich ständig zwischen ihnen und der übergeordneten Form unterscheiden...

Meiner Meinung nach wird es hier zumindest etwas kompliziert 😉

49.485 Beiträge seit 2005
vor 19 Jahren

Hallo DirtDevil,

ich will nicht streiten! Ich denke nur, dass sich die Komplexität des Codes nicht so sehr erhöhen würde, wenn du bei jeder Erzeugung eines Controls noch den EnventHandler hinzufügst. Bei mir besteht die Erzeugung einen Controls (egal ob direkt im Forum oder in irgendwelchen UserControl) immer aus ein mehreren Zeilen, z.B.


ctrlCurr = new PictureBox ();
ctrlCurr.Location = new Point (iX*iWidth, iY*iHeight);
ctrlCurr.Size = new Size (iWidth, iHeight);
((PictureBox)ctrlCurr).Image = bitmTile;
ctrlCurr.BackColor = Color.Green;
ctrlCurr.TabStop = false;
Controls.Add (ctrlCurr);

Wenn da noch die Zeile


ctrlCurr.LostFocus +=new EventHandler(UniversalLostFocus);

hinzukommt, verlängert sich zwar der Code etwas, aber m.E. nicht die Komplexität des Programms.

HTH

herbivore

D
DirtDevil Themenstarter:in
6 Beiträge seit 2005
vor 19 Jahren

Hallo herbivore

Ich hab das schon verstanden, nur erklät mir folgendes:

Wenn der LostFocus-Event auf den Controls eines untergeordneten Panels ausgelöst wird: Wie bringe ich dem Panel bei, ob sich der Fokus auf einem übergeordneten Control befindet, oder auf einem anderen Panel, das dem übergeordneten Control untergeordnet ist... Klingt kompliziert ...und ja, das ist es auch 😉

Wenn ich den LostFocus-Event immer von der Grund-Form aus abfrage, kann ich natürlich prüfen, ob sich der Fokus sich auf einem der untergeordneten Controls/Panels befindet. Aber ich kann nicht mehr ohne weiteres prüfen, ob der Fokus (noch tiefer) sich auf einem der Controls des Panels befindet. Von hier aus würde Das ein reines Hin- und Her geben...

X
2.051 Beiträge seit 2004
vor 19 Jahren

?? Control.ContainsFocus-Eigenschaft ??

49.485 Beiträge seit 2005
vor 19 Jahren

Hallo DirtDevil,

ich denke mal, dieser UniversalLostFocus-Handler müsste es tun:


protected void UniversalLostFocus (Object sender, EventArgs e)
{
   if (Form.ActiveForm != null) {
      // Fokus hat intern gewechselt
   } else {
      // Fokus wurde vollständig verloren
   }
}

HTH

herbivore

X
2.051 Beiträge seit 2004
vor 19 Jahren

Original von DirtDevil
Hi Leute!

Wie so oft, wenn man sich einem Forum anschließt, hat man eine wichtige Frage.

Mich interessiert, wie ich einen Mouse-Klick ausserhalb einer Form registriere. Konkret: Mein Program soll sich automatisch minimieren, wenn ein Mouse-Klick ausgelöst wird, der nicht im Fenster meines Programs stattfindet...

vielen Dank schon mal 😉

ich habe nicht den ganzen thread jetzt gelesen, aber irgendwie geht ihr an die ganze Sache von falscher Richtung ran.

  1. also wenn man ausserhalb eines Forms klickt wird Deactivate-Ereignis ausgelöst.
  2. wenn man nich in ein anderes Form der Anwendung klickt ist Form.ActiveForm-Eigenschaft gleich null
  3. Daraus ergibt sich Folgendes:

private void Form2_Deactivate(object sender, System.EventArgs e)
{
		if (Form.ActiveForm == null)
			WindowState = FormWindowState.Minimized;
}

D
DirtDevil Themenstarter:in
6 Beiträge seit 2005
vor 19 Jahren

Hi herbivore und Xqgene!

Ich habe jetzt schon annähernd die gesamte Core meiner Anwendung optimiert, um sie besser an eine Form anpassen zu können. Ich werde heute noch mit dem neuen Design beginnen und sehen, was sich machen läßt...

Ich bin Euch und allen Anderen auf jeden Fall dankbar für die Unterstützung, und probiere Eure Vorschläge aus. Ich denke auch, dass sich die neue Struktur der From einfacher umsetzen und flexibler an anpassen lassen wird.