Sidebar Gadget Tutorial - Wir erstellen und programmieren Minianwendungen für Windows 7 und Vista
Die Webseite wird gerade bearbeitet (19:18 Uhr). Bei Anzeigefehlern laden Sie die Seite bitte neu.

Sidebar Gadget Tutorial

Wie man ein Sidebar-Gadget programmiert und den Code schreiben kann

Einführung

In diesem Tutorial wird gezeigt, wie man Minianwendungen für die Windows Vista und Windows 7 programmiert. Man erlernt einfache Grundlagen, wird aber noch lange nicht zum Profiprogrammierer.

Was man braucht:

  • Windows Vista oder Windows 7
  • Möglicherweise Vorkenntnisse in HTML & Javascript
  • Lust am Programmieren
  • Geduld

Windows Vista/7 Sidebar Gadgets werden gespeichert unter
  • %APPDATA%\..\Local\Microsoft\Windows Sidebar\Gadgets
  • %HOMEDRIVE%\Users\%USERNAME%\AppData\Local\Microsoft\Windows Sidebar\Gadgets
  • %USERPROFILE%\AppData\Local\Microsoft\Windows Sidebar\Gadgets
Sie können diese Adressen einfach im Explorer eingeben und müssen nichts ersetzen
Das alles steht für folgenden Pfad: [Die Festplatte mit dem Windows Ordner und den Programmen - meistens C:]\Users\[Dein Benutzername]\AppData\Local\Microsoft\Windows Sidebar\Gadgets
Der Ordner AppData ist normalerweise versteckt, weshalb mann einen der Pfade oben direkt in die Adressleiste des Windows Explorers eingeben muss. Mann darf sich also nicht wundern, wenn man im Ordner des aktuellen Benutzers keinen Ordner mit dem Namen AppData entdecken kann.

Fragen können Sie auch gerne im neuen Forum posten. (Erst seit 25.12.10 geöffnet)

Das erste Gadget

Die gadget.xml-Datei

Als erstes erstellen wir einen Ordner namens FirstGadget.gadget in einem der oben angegebenen Ordnern. Nun erstellen wir einen Textdatei im Ordner FirstGadget.gadget, die wir anschließend in gadget.xml umbenennen. Dazu müssen wir aber die Dateiendungen bei bekannten Dateitypen einblenden. Dafür müssen wir die Taste Alt drücken und im Menü Extras die Option Ordneroptionen wählen. Im Dialogfeld wählen wir nun die Registerkarte Ansicht. Danach müssen wir nun das Häkchen bei Erweiterungen bei bekannten Dateitypen ausblenden entfernen.
Wie man Dateierweiterungen bei bekannten Dateitypen einblendet - Bitte klicken für Großansicht
Nun übernehmen wir die Einstellungen mit einem Klick auf Übernehmen.
Nun erstellen wir eine zweite Textdatei, die wir in index.html umbenennen. Diese kann auch andere Namen haben, doch in diesem Tutorial rede ich immer von dieser Datei.

Nun öffnen wir die Datei gadget.xml, die wir eben erstellt haben mit dem Editor (Notepad) und tragen folgenden Text ein:
<gadget>
<name>Mein erstes Gadget</name>
<version>1.0</version>
<author name="CyberBoy">
<info url="http://example.com"/>
<logo src="Logo.png" height="130" width="130"/>
</author>
<copyright>&#169; Dein Name</copyright>
<description>Mein erstes Gadget soll ... machen!</description>
<icons>
<icon height="130" width="130" src="Icon.png"/>
</icons>
<hosts>
<host name="sidebar">
<base type="HTML" apiVersion="1.0.0" src="index.html" />
<permissions>Full</permissions>
<platform minPlatformVersion="1.0" />
</host>
</hosts>
</gadget>

Die Beschreibung des Gadget-Aufbaus - Bitte klicken für Großansicht

Auf diesem Bild kann man sehen, was die gadget.xml-Datei bewirkt. Dies ist zwar nicht unser Gadget, doch diese Abbildung eignet sich, zu zeigen, welche Eigenschaften in der gadget.xml definiert sind. Allerdings können wir unser Gadget noch nicht in der Minianwendungsgalerie sehen, da die Logos und die Hauptdatei (index.html) noch nicht existieren.

So ist unsere Datei aufgebaut

Titel (oder Name) Mein erstes Gadget
Version 1.0
Informationen über den Autor Name CyberBoy
Adresse http://example.com
Logo Logo.png mit einer Höhe und Breite von 130 Pixeln
Copyright Dein Name (gehört eigentlich nicht zum Autor)
Beschreibung Mein erstes Gadget soll ... machen!
Icon Icon.png mit einer Höhe und Breite von 130 Pixeln
Gadget-Datei index.html ist die Datei mit dem Hauptinhalt des Gadgets
Es dürfte nun alles klar sein, bis auf die Spalte Gadget-Datei. Die Gadget-Datei wird in dieser Zeile definiert:
<base type="HTML" apiVersion="1.0.0" src="index.html" />
Diese gibt den relativen Pfad an, wo sich die Hauptdatei unserer Minianwendung befindet.
Hinweise
  • Zu beachten gilt, dass alle Icons, das Icon des Gadgets, sowie das Logo des Autors PNG-Dateien sein sollten. Für ein besseres Aussehen der Icons sollte man einen transparenten Hintergrund verwenden. Eine gute Freeware für Bildbearbeitung ist Paint.Net (Download Get Paint.NET!).
  • Die Beschreibung muss alle Sonderzeichen numerisch oder gar nicht kodiert enthalten. Aus ü darf in der Beschreibung nicht &uuml; werden sondern &#252;. Eine gute Tabelle findet man hier. Oder man benutzt meinen XML-Parser, den man hier downloaden kann. Es wird aber .Net Framework 2.0 oder höher benötigt.(Download) Bei Windows 7 erscheint sonst folgende Fehlermeldung:

    Achtung:Bei Vista wird das Gadget in der Galerie bei diesem Fehler einfach nicht angezeigt und man kann stundenlang nach dem Fehler suchen.
  • Damit das Gadget in der Galerie der Minianwenungen angezeigt wird, müssen das Icon, das Logo des Autors und die Haupdatei des Gadgets existieren, sonst wird es in der Minianwendungsgalerie nicht angezeigt. Falls das Icon oder das Logo nicht existiert sollte man die entsprechenden Zeilen aus der gadget.xml entfernen.

Die Hauptdatei

Der Aufbau
Die Hauptdatei unseres Gadgets ist eine einfache HTML-Datei. Man kannn Javascript, Ajax und VBScript einbinden. In diesem Tutorial lernen wir das Erstellen von Gadgets mittels Javascript. Wir werden ein Youtube Gadget erstellen, mit dem man sich die Videos von Youtube direkt mit wenigen Klicks in die Sidebar holen kann, ohne das Gadget umzuschreiben. Der erste Aufbau unserer HTML-Datei sieht so aus:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Unicode" />
<style type="text/css"> /* CSS-Befehle definiert das Aussehen des Gadgets */
body /* definiert den Style oder das Aussehen des body-Tags */
{
margin: 0; /* definiert, dass möglichst kein Abstand zwischen Rand und Inhalt ist (für später) */
width: 130px; /* definiert die Breite des Gadgets (130 Pixel) */
height: 130px; /* definiert die Höhe des Gadgets (ebenfalls 130 Pixel) */
background-color: #000000; /* definiert die Hintergrundfarbe des Gadgets (hier schwarz) */
}
</style>
</head>
<body>
<!-- Zwischen die Body-Tags kommt der Inhalt des Gadgets (das, was man nachher in der Sidebar sieht) !-->
</body>
</html>
Dieser kleine Code hat unser Gadget nun schon wesentlich verändert. Starten wir es doch mal über die Minianwendungsgalerie! Aber wir speichern vorher alle Dateien ab, damit die Änderungen wirksam werden. Dieser Code lässt unser Gadget schon zu einem 130 Pixel * 130 Pixel großen, schwarzen Quadrat werden. Man muss jedoch wissen, dass in HTML mit <!-- Kommentare eingeleitet werden und mit !--> abgeschlossen werden. Das, was zwischen diesen Zeichenfolgen steht, wird vom Browser bzw. der Sidebar nicht interpretiert.
Tipps
  • Falls Sie das erneut Gadget bearbeiten, sollten Sie es solange in der Sidebar schließen, auf keinen Fall deinstallieren, da es sonst gelöscht wird. Sind Sie nach dem Bearbeiten für einen Testvorgang bereit, speichern Sie alle Dateien und starten das Gadget erneut, indem Sie es in der Sidebar schließen und dann über die Minianwendungsgalerie neustarten.
  • Damit das Gadget gut aussieht und nicht "aus der Reihe tanzt" sollte es 130 Pixel breit sein. So breit sind die meisten Gadgets und User mögen es nicht, wenn ein Gadget zum Beispiel überdimensional groß oder klein ist. Sie werden noch lernen, wie man das Gadget auf Wunsch des Users vergrößern kann.

Solch ein schwarzes Quadrat sieht in der Sidebar natürlich überhaupt nicht schön aus und so habe ich mir ein passendes Hintergrundbild für das Gadget ausgesucht:
Youtube-LogoRechtsklick auf das Bild -> Bild/Grafik Speichern unter...
Ich nehme diese Datei als Autoren-Icon und Logo für das Gadget und als Hintergrund. Die Bilder heißen Icon.png, Logo.png und youtube.png. Nun sieht unser Gadget doch schon viel besser aus. Kein klobiger, schwarzer Kasten sondern, ein optisch schönes Youtube-Logo.
Doch fertig ist unser Gadget noch lange nicht. Nun müssen wir die Einstellungen des Gadgets erstellen. Weiter geht's im nächsten Kapitel.

Der Dialog für die Einstellungen

Zuerst müssen wir in der Hauptinhaltsdatei des Gadgets (bei mir index.html) angeben, dass das Dialogfeld für Einstellungen aktiviert werden soll und wir müssen angeben, wo sich die Datei befindet, die die Einstellungen schreibt bzw. erstellt. Die Datei für Einstellungen ist also eine zweite HTML-Datei. Zuerst ändern wir die Datei index.html:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Unicode" />
<style type="text/css">
body
{
margin: 0;
width: 130px;
height: 130px;
/* Änderungen beginnen hier */
background-image:url(youtube.png); /* Hier wird das Hintergrundbild unseres Gadgets definiert. Das Bild liegt im gleichen Verzeichnis, wie die Datei index.html */
}
</style>
<script>
System.Gadget.settingsUI = "Settings.html"; // Hier wird definiert, wo sich die Einstellungen des Gadgets befinden. In diesem Fall liegt die Einstellungsdatei Settings.html im geichen Verzeichnis, wie die index.html
</script>
<!-- Änderungen enden hier !-->
</head>
<body>
</body>
</html>
Nun haben wir den Code verändert, doch das nützt noch nichts, da wir die Datei Settings.html noch gar nicht erstellt haben. Erstellen wir also erneut eine Textdatei und benennen sie um in Settings.html. Wenn wir das Gadget jetzt neustarten werden wir feststellen, dass wenn man die Maus über das Gadget bewegt, oben rechts das Symbol für Einstellungen erscheint:
Das Gadget
So sollte der Dialog im Moment noch aussehen:
Der Dialog für die Einstellungen
Tipp: Solange Sie nur die Einstellungsdatei des Gadgets bearbeiten, müssen Sie das Gadget nicht jedes mal neu starten. Sie müssen lediglich die Einstellungen schließen und erneut öffnen, da diese bei jedem Aufruf neu geladen werden.
Doch wir möchten im Dialog ein Textfeld, in das man den Einbett-Code (Embed-Code) des Youtube-Videos nur hineinkopieren muss und dann das Ganze speichern muss. (Wo finde ich den Embed-Code)

So sieht unsere Datei für Einstellungen aus (Settings.html):
<html>
<head>
<style type="text/css">
body
{
height: 130px; /* Der Dialog soll 250 + 125px groß sein. Gibt man die Höhe 0 an, so ist der Dialog automatisch 125px groß. */
width: 250px; /* Der Dialog soll 250px breit sein. */
}
</style>
<script>
function getattribute(text, attrib, number) //Diese Funktion prüft, ob bestimmte Tags im Code vorhanden sind
{
var start = text.indexOf(attrib) + attrib.length + 2; //Ermittelt die Position des Endes des Funktionsparameters attrib
var schleife = true; //Setzt die Variable schleife auf true
var loop = start; //Setzt die Variable loop auf start
var ausgabe = ""; //Setzt die Variable ausgabe auf einen leeren String (Zeichenkette)
if(text.indexOf(attrib) < 0) //Wenn ein Tag (der Funktionsparameter attrib nicht in der Variable text existiert
{
schleife = false; //Setzt die Variable schleife auf false
}
while(schleife && loop <= text.length) //Solange schleife auf true gesetzt ist und loop die Textlänge nicht überschreitet
{
if(text.charAt(loop) == "'" || text.charAt(loop) == '"') //Wenn im Text an der Position von loop das Zeichen ein ' oder " ist
{
schleife = false; //Setzt die Variable schleife auf false
loop = 0; //Setzt die Variable loop zur Sicherheit auf 0
}
if(schleife) //Wenn schleife auf true gesetzt ist
{
var ausgabe = ausgabe.concat(text.charAt(loop)); //An ausgabe wird das Zeichen an der Position von loop in des Funktionsparameters text angehängt
}
loop = loop + 1; //loop wird um 1 erhöht
}
if(number && (isNaN(ausgabe) || ausgabe <= 0)) //Wenn der Funktionsparameter number auf true gesetzt ist, und ausgabe keine Zahl oder kleiner als 0 ist
{
ausgabe = ""; //Setzt die Variable ausgabe auf einen leeren String
}
return ausgabe; //Die Funktion liefert die Variable ausgabe zurück
}
System.Gadget.onSettingsClosing = save; //Die Funktion save wird ausgeführt, wenn das Gadget geschlossen wirdfunction save(event) //Beginn der Funktion save mit dem Funktionsparameter event, der bestimmt ob der Dialog geschlossen wird oder geöffnet bleibt
function save(event)
{
if (event.closeAction == event.Action.commit) //Wenn die Einstellungen vom Nutzer gespeichert werden
{
System.Gadget.Settings.write("Video", document.getElementById("Video").value); //Schreibt in die Einstellung unter Video (erster Parameter) den Wert der Textarea mit der Id Video (zweiter Parameter)
if(getattribute(document.getElementById("Code").value, "height", true) != "" && getattribute(document.getElementById("Code").value, "width", true) != "" && getattribute(document.getElementById("Code").value, "src", false) != "") //Wenn die Attribute in der Textarea mit der Id Code existieren und nicht leer sind. Unsere eigene Funktion wird aufgerufen
{
System.Gadget.Settings.write("Code", document.getElementById("Code").value); //Schreibt in die Einstellungen unter Code (Parameter1) den Wert des Textfeldes mit der Id Code (Parameter 2)
event.cancel = false; //Das Schließen des Dialogfeldes wird nicht abgebrochen
}
else //Wenn die if-Bedingung oberhalb nicht erfüllt wird
{
document.getElementById("error").style.display="block"; //Macht das Element (hier div-Container) mit der Id error sichtbar
event.cancel = true; //Das Schließen des Dialogfeldes wird abgebrochen
}
}
}
function loadSettings() //Diese Funktion lädt die Einstellungen in die Textboxen
{
document.getElementById("Code").value=System.Gadget.Settings.read("Code"); //Mit dem Befehl System.Gadget.Settings.read("Name"); wird die Einstellung abgerufen, die man mit System.Gadget.Settings.write("Name", "Wert"); abgespeichert hat (dieses Beispiel würde Wert liefern)
document.getElementById("Video").value=System.Gadget.Settings.read("Video"); //liest die Einstellung Video in das Textfeld mit der Id Video
}
</script>
</head>
<body alink="#0000FF" vlink="#0000FF" link="#0000FF" onLoad="loadSettings();"><!-- Wenn der body geladen wird, wird die Funktion loadSettings aufgerufen !-->
<div id="error" style="display: none; color: red; font-weight: bold;">Ungültiger Code<br/></div><!-- der unsichtbare div-Container, der sichtbar gemacht wird, wenn ein Fehler auftritt !-->
Geben Sie hier den Einbett-Code eines Videos von <a href="http://youtube.com" target="_blank">Youtube</a> ein:<br/>
<textarea id="Code">
</textarea><br/>
Geben Sie hier den Titel des Videos ein:<br/>
<input type="text" id="Video">
</body>
</html>
Achtung: Das Textfeld mit der Id Code/Video ist nicht das Gleiche, wie die Einstellungen namens Code/Video. Nun haben wir unsere Einstellungen abgespeichert, doch leider können wir Sie nicht nutzen, da wir das FlyOut noch nicht programmiert haben. Das nächste Kapitel klärt auf.

Das FlyOut

Das FlyOut? Was ist das? Das FlyOut ist ein Fenster, das erscheint, wenn man auf das Gadget klickt oder eine ähnliche Situation auslöst. Hier ist der Screenshot eines FlyOuts:
Das FlyOut unseres Gadgets
Das ist - äh ups - soll unser Gadget werden. Ich habe ein wenig vorgearbeitet. Hier auf dem Bild verwende ich das Video Achmed the Dead Terrorist. Ein FlyOut ist also ein Fenster, dass sich öffnet, wenn man eine bestimmte Aktion ausführt und schließt, wenn man außerhalb des Fensters klickt. Zuerst müssen wir im Ordner des Gadgets eine Datei namens FlyOut.html erstellen. Die Datei kann hier natürlich auch anders heißen, doch ich nenne hier immer den Namen dieser Datei. Die Datei wird so aussehen:
<html>
<head>
<style type="text/css">
body
{
margin: 0; /*keinen Abstand zum Rand des FlyOuts, ohne diese Angabe käme es zu Unschönheiten*/
}
</style>
<script>
function getattribute(text, attrib, number) //Diese Funktion prüft, ob bestimmte Tags im Code vorhanden sind
{
var start = text.indexOf(attrib) + attrib.length + 2; //Ermittelt die Position eines Tags
var schleife = true; //Setzt die Variable Schleife auf true
var loop = start; //Setzt die Variable loop auf start
var ausgabe = ""; //Setzt die Varieble ausgabe auf einen leeren String (Zeichenkette)
if(text.indexOf(attrib) < 0) //Wenn ein Tag nicht in der Variable text existiert
{
schleife = false; //Setzt die Variable schleife auf false
}
while(schleife && loop <= text.length) //Solange schleife auf true gesetzt ist und loop die Textlänge nicht überschreitet
{
if(text.charAt(loop) == "'" || text.charAt(loop) == '"') //Wenn im Text an der Position von loop das Zeichen ein ' oder " ist
{
schleife = false; //Setzt die Variable schleife auf false
loop = 0; //Setzt die Variable loop zur Sicherheit auf 0
}
if(schleife) //Wenn schleife auf true gesetzt ist
{
var ausgabe = ausgabe.concat(text.charAt(loop)); //An ausgabe wird das Zeichen an der Position von loop in der Variable text angehängt
}
loop = loop + 1; //loop wird um 1 erhöht
}
if(number && (isNaN(ausgabe) || ausgabe <= 0)) //Wenn die Variable number auf true gesetzt ist und ausgabe keine Zahl oder kleiner als 0 ist
{
ausgabe = ""; //Setzt die Variable ausgabe auf einen leeren String
}
return ausgabe; //Die Funktion liefert die Variable ausgabe zurück
}
</script>
</head>
<body>
<script>
document.body.style.height = getattribute(System.Gadget.Settings.read("Code"), "height", true); //Setzt die Höhe des FlyOuts auf die Höhe des Videos
document.body.style.width = getattribute(System.Gadget.Settings.read("Code"), "width", true); //Setzt die Breite des FlyOuts auf die Breite des Videos
document.write(System.Gadget.Settings.read("Code")); //Schreibt den Code des Videos in das Dokument -> Das Video wird dargestellt und kann abgespielt werden
</script>
</body>
</html>

So dieser Code liest die Maße des Videos aus und passt die Größe des Gadgets an. Dann wird das Video im FlyOut dargestellt.

Ich muss schon sagen, dass wir nun ein schönes FlyOut haben. Doch leider, leider, leider kann man es noch nicht öffnen. Das lässt sich ändern. Dazu müssen wir in der Datei index.html definieren, wo sich das FlyOut befindet, und vor allem wann es geöffnet werden soll. Wir rufen diese Datei also nochmal auf und ändern sie folgendermaßen:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Unicode" />
<style type="text/css">
body
{
margin-left: 7px;
margin-top: 3px;
margin-bottom: 0;
margin-right: 8px;
font-size:12px;
width: 130px;
height: 130px;
background-image:url(youtube.png);
}
</style>
<script>
System.Gadget.Flyout.file="FlyOut.html"; //Die Datei für das FlyOut heißt FlyOut.html
System.Gadget.settingsUI = "Settings.html"; //Die Datei für die Einstellungen heißt Settings.html
System.Gadget.onSettingsClosed = SettingsClosed; //Wenn der Einstellungsdialog geschlossen wird, soll die Funktion SettingsClosed ausgeführt werden (, die das Gadget neu lädt)
function SettingsClosed()
{
location.reload(); //Seite (=Gadget) neu laden
}
</script>
</head>
<body onClick="if(System.Gadget.Settings.read('Code') != '') {System.Gadget.Flyout.show = true;}" onMouseover="if(System.Gadget.Settings.read('Code') != '') {this.style.cursor='pointer';}"><!-- Wenn auf das Gadget geklickt wird und die Einstellungen existieren, soll das FlyOut gezeigt werden !-->
<div align="center"><b><script>document.write(System.Gadget.Settings.read('Video')); //Gibt auf dem Gadget den Text des Titels aus</script></b></div>
</body>
</html>

Ein Gadget veröffentlichen

Nun haben wir das Gadget programmiert. Doch bis jetzt ist es nur auf dem eigenen PC nutzbar, da es ein ganzer Ordner voller Dateien ist. Doch was ist kompakt und nennt sich Zip-Archiv? Genau. Die Lösung dieses Problems. Wir kopieren ganz einfach die Unterverzeichnisse und Dateien des Gadget-Stammordners in ein kompaktes Zip-Archiv, allerdings ohne den Ordner selbst. Dieses benennen wir nun in Gadget-Name.gadget um, sodass die Dateierweiterung *.zip durch *.gadget ersetzt wird. Doch vorher muss dazu dieser Schritt erfolgt sein. Wenn die eigentliche Zip-Datei erfolgreich in *.gadget umbenannt wurde kann man es mit einem Klick starten. Nun sollte folgende Meldung erscheinen:

Falls diese Meldung nicht erscheint, überprüfen Sie am besten, ob das Gadget erfolgreich umbenannt wurde.

Die wichtigsten Gadget-Befehle auf einen Blick

Hier noch einmal die wichtigsten Gadget-Befehle auf einen Blick. Diese müssen alle in script-Tags oder Events, wie onClick, onLoad usw.
Beschreibung Programmcode
In Einstellungen schreiben System.Gadget.Settings.write("Name der Einstellung", "Wert");
Wert einer Einstellung auslesen System.Gadget.Settings.read("Name der Einstellung");
Die Datei des FlyOuts festlegen System.Gadget.Flyout.file="Dateipfad zur FlyOut-Datei";
FlyOut öffnen oder schließen System.Gadget.Flyout.show = true; oder System.Gadget.Flyout.show = false;
Datei für die Einstellungen festlegen System.Gadget.settingsUI = "Dateipfad zur Einstellungs-Datei";
Alle Codes mit "!

Das Gadget zum Download

Alle Projektdateien des fertigen Gadgets finden Sie hier auch noch einmal zum Herunterladen:
Zip-ArchivSidebar Gadget

Und das war auch schon das Gadget Tutorial. Ich werde noch weitere Abschnitte hinzufügen, wenn ich Zeit habe. Falls Sie einen Fehler entdecken oder etwas fehlen sollte, senden Sie mir doch eine Nachricht über das Feedback-Formular unten! Vielen Dank!

Sonstige Links

Hier findest du weitere Links zu Gadget Tutorials und Referenzen.

Feedback

Ich würde mich sehr freuen, wenn du mir noch ein kleines Feedback geben würdest, was an diesem Artikel noch zu verbessern ist. Ist er verständlich erklärt?
Verständlichkeit:
Information:
E-Mail:(nur benötigt, wenn eine Antwort angefordert wird)
Feedback:

Werbung: