Laden...

Vorlage für eine Windows Vista/7 Tray Application

Letzter Beitrag vor 14 Jahren 10 Posts 8.222 Views
Vorlage für eine Windows Vista/7 Tray Application

Beschreibung:

Wer schon einmal mit Windows Vista oder 7 gearbeitet hat, wird sicher wissen, dass die Tray-Anwendungen einen recht schicken Style haben (siehe Screen im nächsten Post). Wie man in diesem und diesem Thread sieht, gibt es seitens der Community auch eine gewisse Nachfrage, diesen Style nachzuprogrammieren. Und Maximilian hat mit seinem Projekt feedCarrier eine kleine Anwendung geschrieben, die einen ähnlichen Style benutzt.
Ich selber habe mich zu dem Zeitpunkt, als m0rius im verlinkten Thread nachgefragt hat, wie man diesen Style hinbekommt, einmal dran gemacht, das ganze umzusetzen. Gestern hab ich mich, nach dem ich den feedCarrier gesehen hab, wieder daran erinnert und meiner Beispielanwendung noch ein wenig Feinschliff verpasst und möchte euch diese hier zur Verfügung stellen.

**Features:***Form-Style wie die Windows-Vista/7-Tray-Anwendungen ohne ControlBox, aber mit Originalrahmen *Form ist nicht resizable *Form platziert sich automatisch in der unteren rechten Bildschirmecke *Verliert die Form den Fokus, verschwindet die Form (die Anwendung läuft aber weiter) *Abwärtskompatibilität bis Windows 2000 (.NET 2.0) *Ändert der User während der Laufzeit den Windows-Style von Aero auf Basic oder Klassisch (oder vice versa), passt sich die Form, genau wie Vorbildanwendungen von Vista/7 seine Position und Form an (grauer 1-Pixel-Rahmen, kein Abstand mehr zum Desktoprand; in diesem Anzeigemodus befindet sich die Anwendung auch auf Betriebssystemen unter Vista) *Die Schriftart der Form wird automatisch auf den Systemfont umgestellt, so bekommt man unter Vista/7 ein schöneres Schriftbild

Was noch fehlt:
Was ich nicht hinbekommen habe ist folgendes UI-Verhalten: Wenn man eine Windows-Trayanwendung wie z.B. den Kalender oder die Audio-Einstellungen per Klick auf das Tray-Icon öffnet, und anschließend das Icon wieder anklickt, schließt sich das Fenster. Bei meiner Projektvorlage schließt sich das Fenster kurzzeitig (durch den Fokus-Verlust), öffnet sich dann aber gleich wieder (durch den Klick auf das Tray-Icon). Ich habe leider keine elegante und zuverlässig funktionierende Lösung zu diesem Problem gefunden. Meine Versuche mit einem Timer waren nur mäßig befriedigend. Falls jemand eine gute Lösung parat hat oder findet, werde ich diese gerne integrieren.

Wer sich zudem mit Visual Studio Item bzw. Project Templates auskennt, kann gerne etwas entsprechendes mit dieser Beispielanwendung basteln.

Credits:
Dank geht an winSharp93, von dem die Lösung zum Problem mit den Resizing-Cursors stammt. 🙂
Danke auch an ErfinderDesRades, der die Lösung zum Problem beim De-/Aktivieren der Form bei Fokus-Verlust bzw. Tray-Icon-Klick (siehe oben) gepostet hat.

Updates:
29.07.10:*Fehler beim Deaktivieren der TrayApp durch Klick auf das TrayIcon (NotifiyIcon wurde nicht umgestellt) behoben. Danke an blutiger_anfänger *Form wird jetzt wieder ausgeblendet, wenn das Kontextmenü aufgemacht wird

Schlagwörter: Windows, Vista, 7, Seven, Tray Application, Tray-Anwendung

Beispielscreen der Kalender-Tray-Anwendung in Windows 7:

Sieht sehr schick aus. Hast du das mal auf 'ner XP Maschine ausgeführt? Gibt es da Kompatibilitätsprobleme?

Grüße,
Raffi

Wenn ich nicht hier bin, findest du mich auf code-bude.net.

Das ganze ist wie gesagt bis Windows 2000 abwärtskompatibel, bzw. .NET 2.0.

Ich habe jedoch bewusst nicht versucht, den Aero-Style für die anderen Betriebssysteme nachzustellen, da ich eher die Philosophie verfolge, dass eine Anwendung auf jedem OS nativ aussehen soll. Sprich, dass das OS den Style der Anwendung bestimmt, und nicht die Anwendung selber.

(Edit: So viele Tippfehler...)

Hier mal ein Screen wie eine Anwendung auf den Betriebssystemen Windows 2000, XP (kein Standard-Windows-Theme allerdings) und 7 aussehen würde:

Und hier das Test-Programm dafür, kannst ja mal schauen wie es auf deinem System aussieht.

Bei meiner Projektvorlage schließt sich das Fenster kurzzeitig (durch den Fokus-Verlust), öffnet sich dann aber gleich wieder (durch den Klick auf das Tray-Icon).

Ich check mittels MouseMove-Überwachung, ob der FocusVerlust vom Click auf das Tray-Icon herrührt - in dem Falle wird beim Deaktivieren nicht gehidet. Stattdessen normales umschalten im _Click


      private Point _LastMouse;
      private void applicationNotifyIcon_MouseMove(object sender, MouseEventArgs e) {
         _LastMouse = Control.MousePosition;
      }
      private void TrayApplicationFormDeactivate(object sender, EventArgs e) {
         if(Control.MousePosition == _LastMouse) return;
         SetLightBulbOffIcon();
         Hide();
      }
      private void ApplicationNotifyIconMouseClick(object sender, MouseEventArgs e) {
         if(e.Button != MouseButtons.Left) return;
         if(Visible) { Hide(); return; }
         SetLightBulbOnIcon();
         Show();
         Activate();
      }

Der frühe Apfel fängt den Wurm.

Hallo ErfinderDesRades,

danke für deinen Input! Hab's eingebaut und funktioniert super, zwar nicht hunderprozentig so, wie es die Windows-7-Tray-Anwendungen machen (kleinere Probleme bei schnellen Klicks, da gibt's Verzögerungen bzw. die erwartete Reaktion bleibt manchmal aus), aber so wie es jetzt ist passt es trotzdem und ist viel besser als das vorherige Verhalten. 🙂

EDIT: Achja, ganz vergessen zu erwähnen. Den Startbeitrag hab ich editiert und eine neue Version des Projekts hochgeladen, in dem dein Lösungsvorschlag integriert ist.

Grüße,
Andreas

Entweder mir hat sich die Logik noch nciht ganz erschlossen oder folgende Methode müsste so

private void ApplicationNotifyIconMouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button != MouseButtons.Left)
                return;

            if (Visible)
            {
                Hide();
                SetLightBulbOffIcon();
                return;
            }

            SetLightBulbOnIcon();
            Show();
            Activate();
        }

anstatt so


private void ApplicationNotifyIconMouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button != MouseButtons.Left)
                return;

            if (Visible)
            {
                Hide();
                return;
            }

            SetLightBulbOnIcon();
            Show();
            Activate();
        }

aussehen... 😉
( siehe: SetLightBulbOffIcon(); )

Wenn ich nicht hier bin, findest du mich auf code-bude.net.

Hallo blutiger_anfänger,

stimmt du hast Recht, hab das glatt übersehen. 🙂
Wobei das LightBulbIcon hier eh nur ein Gimmick ist, speziell das Ändern des Symbol-Status. 😉

Hab's korrigiert, dankeschön! 🙂

Grüße,
Andreas

Bitte, bitte - sicher ist es nicht super wichtig - aber irgendwie hat es mich vom Applicationflow her verwirrt... (Böses Denglisch - gibt es überhaupt ein Wort wie "Applicationflow"?) ;D

Wenn ich nicht hier bin, findest du mich auf code-bude.net.