C# API unter Windows 7, 8 und 8.1

Mit der Einführung von Windows 7 hat Microsoft mehrere neue und erweiterte API Funktionen bereitgestellt, die Entwickler auch in eigenen Anwendungen verwenden können. Während Funktionen wie Hyper-V oder Multitouch nicht unbedingt für jede Anwendung geeignet sind, gibt es andere, die jede Anwendung sinnvoll erweitern. In diesem Beitrag möchte ich mich auf die API-Funktionen für die Windows Taskbar und die neuen Dialoge konzentrieren, welche meiner Ansicht nach in jeder Anwendung sinnvoll sind und bestehende Funktionen erweitern.

Da diese Art der neuen Funktionalitäten leider bisher nicht den Weg in das .NET-Framework gefunden hat, muss hierfür das Package mittels NuGet nachträglich eingbunden werden. Hier kann in der Online-Bibliothek nach „Windows 7 API Code Pack“ gesucht werden. Mehr Informationen hier finden Sie hier: http://archive.msdn.microsoft.com/

Um zu prüfen, ob das ausführende Betriebssystem in der Lage ist, die neuen API-Funktionalitäten zu verwenden, hat Microsoft hier eine einfache Abfrage implementiert mit der die Nutzung der neuen Funktionen geprüft werden kann. Ob das eigene Betriebssystem unterstützt wird, kann mit diesem Code abgefragt werden:

if (TaskbarManager.IsPlatformSupported)
{
	MessageBox.Show("Dieses Betriebssystem wird von der API unterstützt!");
}

Alternativ kann dies auch ohne die API wie folgt geprüft werden:

Environment.OSVersion.Version.Major >= 6;

Wird das Betriebssystem unterstützt, lohnt sich ein genauer Blick auf die neuen Erweiterungen. Beginnen wir zunächst mit den recht schnell erklärten „Overlay Icons„. Diese werden in der Taskbar einfach über das bestehende Anwendungssymbol gelegt. Hierzu wird eine Icon-Datei in der Ressource der Anwendung als Symbol abgelegt. Anschließend kann das Ganze wie folgt verwendet werden:

TaskbarManager.Instance.SetOverlayIcon(Properties.Resources.MyIcon, "Some Icon");

Um das Overlay Icon wieder zu entfernen, wird folgender Code ausgeführt:

TaskbarManager.Instance.SetOverlayIcon(null, string.Empty);

OverlayIconDies könnte zum Beispiel wie nebenstehend aussehen (Overlay Icon oben sichtbar und unten wieder entfernt). Ebenso einfach lässt sich die ProgressBar über diese API steuern. Hier sollte jedoch beachtet werden, dass diese nur in der Lage ist Werte in Integer-Schritten anzunehmen und dass der Minimalwert bei 0 liegt (der Maximalwert kann jedoch frei bestimmt werden). Soweit es mir bisher bekannt ist, kann dies auch nicht geändert werden. Zudem lässt sich der Fortschritt allem Anschein nach nur absolut und leider nicht relativ setzen.

Um nun den Wert zu setzen muss die Methode „SetProgressValue“ auf der Instanz des TaskbarManager-Singletons aufgerufen werden. Eine Implementierung könnte z.B. wie folgt aussehen:

int maxValue = 100;
for (int i = 0; i <= maxValue; i++)
{
    TaskbarManager.Instance.SetProgressValue(i, maxValue);
    Thread.Sleep(50);
}

ProgressAls Ergebnis erhalten wir nun einen Fortschrittsbalken auf der Taskbar. Dieser sieht z.B. so wie auf der Abbildung links aus. Auch können wir den Status des Fortschrittbalkens setzen. Dies erfolgt über die Methode „SetProgressState“ auf der TaskbarManager Instanz. Hier gibt es die einzelnen Stufen Normal (Grün), Paused (Gelb), Error (Rot) und Inderterminate (Endlos – hier ist der Progress-Wert egal). Gehen wir als nächstes zur ApplicationID über.

Die Application ID gibt dem Entwickler die Möglichkeit die zusätzlichen Fenster einer Anwendung in der Taskbar zu gruppieren. Normalerweise werden alle weiteren Fenster, die ein Programm öffnet auch dieser Anwendung zugeordnet. Hat ein Programm beispielsweise mehrere Fenster geöffnet, wird dies auch in der Taskbar deutlich dargestellt. Dabei werden die Fenster wie gewohnt ganz normal mittels Konstruktor und Show angezeigt (bzw. über etwaige ViewModels oder Ahnliches). Das Ganze kann über folgenden Code genutzt werden:

TaskbarManager.Instance.ApplicationId = "Eine für die Anwendung eindeutige ID";

JumplistNun haben wir gar nicht mal mehr so viel übrig aus der API. Machen wir also weiter mit der Jumplist. Dies ist die Liste, die sich bei einem Rechtsklick auf ein Icon in der Taskbar öffnet. Da hier die verschiedensten Icons der einzelnen Anwendungen gebraucht werden, kommt die API auch mit einer entsprechenden Funktionalität, um Icon-Dateien aus anderen Assemblys laden zu können. Dies geht über die Klasse „IconReference“ , welche als ersten Parameter den Pfad zur ausführbaren Datei bekommt und anschließend, in der Regel, den Parameter 0. Um die auf der Grafik links zu sehende Liste hinzubekommen, benötigt man folgenden Sourcecode:

string systemFolder = Environment.GetFolderPath(Environment.SpecialFolder.System);
JumpList jumpList = JumpList.CreateJumpList();

jumpList.ClearAllUserTasks();

jumpList.AddUserTasks(new JumpListLink(System.IO.Path.Combine(systemFolder, "calc.exe"), "Taschenrechner")
    {
        IconReference = new IconReference(System.IO.Path.Combine(systemFolder, "calc.exe"), 0)
    });

jumpList.AddUserTasks(new JumpListLink(System.IO.Path.Combine(systemFolder, "mspaint.exe"), "Paint")
    {
        IconReference = new IconReference(System.IO.Path.Combine(systemFolder, "mspaint.exe"), 0)
    });

jumpList.Refresh();

Dies kann auch mit eigenen Kategorien, neben oder anstatt „Aufgaben“, ausgestattet werden. Für eigene Kategorien und eigene Befehle, zum Beispiel mit Start-Parametern, kann folgender Sourcecode vor dem „jumpList.Refresh()“ ausgeführt werden:

string ownPath = Assembly.GetEntryAssembly().Location;

JumpListCustomCategory personalCategory = new JumpListCustomCategory("Persnliche Kategorie");
jumpList.AddCustomCategories(personalCategory);

JumpListLink commandA = new JumpListLink(ownPath, "Befehl A ausfhren")
    {
        IconReference = new IconReference(Assembly.GetEntryAssembly().Location, 0), 
        Arguments = "Command-A"
    };

personalCategory.AddJumpListItems(commandA);

JumpListLink commandB = new JumpListLink(ownPath, "Befehl B ausfhren")
    {
        IconReference = new IconReference(Assembly.GetEntryAssembly().Location, 0), 
        Arguments = "Command-B"
    };

personalCategory.AddJumpListItems(commandB);

ThumbnailNun wären auch die Jumplist Handlings soweit durch. Weiter geht es mit den ThumbnailToolBarButtons. Um diese wie rechts auf der Grafik verwenden zu können, wird der unten stehende Sourcecode benötigt. Dies sind quasi Mini-Buttons unter der Anwendung. Große Anwendungen, die diese Funktionalität verwenden sind z.B. Skype und VLC. Hier können simple Click-Handles verwendet werden, um anschließende Prozesse zu triggern. Zum Beispiel könnte hier auch das Starten und Stoppen eines Workflows eingebunden werden. Diese Buttons unterstützen Ähnliches wie die Standard-WPF / WinForms Buttons auch. Nur das diese – bis auf das Icon – kein anderes Design bekommen können.

ThumbnailToolBarButton thumbnailButton = new ThumbnailToolBarButton(Properties.Resources.MyIcon, "Some Icon");
thumbnailButton.Click += delegate { MessageBox.Show("Thumbnail clicked!"); };

TaskbarManager.Instance.ThumbnailToolBars.AddButtons(new WindowInteropHelper(this).Handle, thumbnailButton);

ClipNun gibt es auch noch die Funktionalität Thumbnail Clips zu erstellen. Hierbei werden teile einer Anwendung näher heran gezoomt um diese in der Vorschau größer darzustellen. So stellt zum Beispiel das Bild rechts ein Vergrößerten Bereich des gleichen Thumbnails aus dem vorherigen Schritt dar. Um dies zu erreichen wird jedoch eine Referenz auf System.Drawing benötigt. Die Verwendung ist denkbar einfach wie am Sourcecode unten zu sehen ist. Auch hier wird wieder nur auf der Singleton-Instanz des TaskbarManagers eine einzelne Methode aufgerufen ,welche mit entsprechenden Parametern angereichert worden ist.

Point sourcePoint = new Point(Convert.ToInt32(Width / 4), 0);
Size targetSize = new Size(Convert.ToInt32(Width / 3), Convert.ToInt32(Height / 4));

System.Drawing.Rectangle clippingRectangle = new System.Drawing.Rectangle(sourcePoint, targetSize);
TaskbarManager.Instance.TabbedThumbnail.SetThumbnailClip(new WindowInteropHelper(this).Handle, clippingRectangle);

Als letztes haben wir die sehr schön erweiterten Task Dialoge. Da diese allerdings nur eine Erweiterung zu den bestehenden MessageBox-Implementierung bieten, habe ich hier keine grafischen Vorschauen erstellt. Die Verwendung dieser Dialoge ähnelt auch sehr der normalen Win32-MessageBox. Nur das die Methoden hier nicht Statisch gestaltet sind sondern über eine Instanz eines „TaskDialog“ gehandhabt werden. Hier kann z.B. ein Timer eingebunden werden oder die Option, dass das Fenster nicht nochmal angezeigt werden soll (die Logik muss natürlich selbstständig implementiert werden) stehen zur Verfügung. Auch Fortschrittsbalken, Fehlerdialoge, verbesserte Dateibrowser usw. sind nun kein Problem mehr. Wer hierzu mehr Informationen möchte, kann sich im folgenden PDF-Dokument mehr Informationen zur API und auch zu den TaskDialogen holen:

http://www.hinzberg.net/api7/api7/downlaods_files/windows7api.pdf