Minianwendungen („Gadgets“) für die Windows Vista Sidebar entwickeln

by Christian Haberl Oktober 16, 2007 01:04

Nachdem ich im Büro recht gute PC Lautsprecher, aber kein Radio habe, höre ich gerne Internet Radio. Auch bin ich oft in Amerika und höre dann gerne österreichische Radiosender von dort aus.

Mein Musikgeschmack ist ziemlich vielfältig, ich höre gerne Radio Stephansdom, gelegentlich Ö1, manchmal FM4, und auch oft Radio Wien. Ö3 höre ich selten bis gar nicht bzw. nur beim Autofahren.

Als ich davon hörte, dass es ein Ö3-Windows Sidebar Gadget gibt, wollte ich mir dieses dennoch herunterladen, weil ich wissen wollte, was dahinter steckt, Windows Sidebar Gadgets sollen ja so schön und relativ einfach zu entwickeln sein. Leider war das Sidebar Gadget damals vorübergehend nicht verfügbar, und ein paar Webcasts und Blog-Artikel später beschloss ich einfach ein eigenes Sidebar Gadget für österreichische Radiosender zu bauen, zumal mir Ö3 alleine ohnehin nicht reichen würde.

Ein Vista Gadget, auf Deutsch auch "Minianwendung" bezeichnet, besteht im Wesentlichen aus einigen Files die im Verzeichnis C:\Users\%USERNAME%\AppData\Local\Microsoft\Windows Sidebar\Gadgets abgelegt sind.

Das Unterverzeichnis ATRadio07.gadget enthält diese Files:

  • gadget.xml
  • atradio.html, atradio.css, atradio.js
  • flyout.html, flyout.css, flyout.js
  • settings.html
  • atradio.png, glass130.png, glass130c.png, logo.png

 

 

 

Das File gadget.xml, die Manifest-Datei, enthält alle Definitionen für das Gadget:

gadget.xml

<?xml version="1.0" encoding="utf-8"?>
<gadget>
<name>ATRadio</name>
<namespace>this.at.radio</namespace>
<version>0.4</version>
<author name="Christian Haberl">
<info url="http://www.this.at" text="www.this.at" />
<logo src="logo.png" />
</author>
<copyright>© 2007</copyright>
<description>Radio aus Österreich.</description>
<icons>
<icon height="64" width="64" src="atradio.png" />
</icons>
<hosts>
<host name="sidebar">
<base type="HTML" apiVersion="1.0.0" src="atradio.html" />
<permissions>full</permissions>
<platform minPlatformVersion="1.0" />
<defaultImage src="atradio.png" />
</host>
</hosts>
</gadget>

Wenn das Manifest File vorhanden ist, wird das Gadget auch automatisch im Vista Gadget Auswahlfenster angezeigt:

atradio.html ist der Hauptteil des Gadgets, den Javascript Code habe ich in atradio.js ausgelagert, die Styles in atradio.css.

Der Aufbau ist recht einfach: Es gibt einen Button der gleichzeitig den Radiosender anzeigt und das Flyout öffnet um den Sender zu wechseln. Es gibt ein Windows Media Player Objekt und einen Start und einen Stop Button.

Im Wesentlichen wird das Windows Media Player Objekt mittels Javascript angesteuert, um die Radiostreams abzuspielen.

Wenn ein Stream gespielt wird, zeigt das Media Center Objekt eine Visualisierung, sonst wird der Status angezeigt, etwa "Buffering…" oder "Error".

Error bedeutet übrigens so gut wie immer, dass der Streaming Server überlastet ist, was bei Ö3 und Radio Wien an einem Arbeitstag unter Tags recht oft vorkommt, wenigstens in letzter Zeit.

atradio.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>ATRadio</title>
<link rel="stylesheet" type="text/css" href="atradio.css">
<script src="atradio.js" language="javascript" type="text/javascript"></script>
</head>  
<body id="gadgetContent" onload="SetupGadget();">
<input type="button" value="select station" id="stationname" onclick="toggleFlyout()"><br>
<div id="whichState">...</div>
<div id="mplayerdiv">
    <object id="Player" classid="CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6">
        <param name="autoStart" value="False">
        <param name="SendPlayStateChangeEvents" value="True">
        <param name="SendErrorEvents" value="True">
        <param name="SendOpenStateChangeEvents" value="True">
        <param name="TransparentAtStart" value="True">
        <param name="uimode" value="none">
    </object>
</div>
<br>
<input type="button" name="BtnPlay" value="play" onclick="StartMeUp()" id="BtnPlay">
<input type="button" name="BtnStop" value="stop" onclick="ShutMeDown()" id="BtnStop">
</body>
</html>
 
atradio.js

function SetupGadget()

{
System.Gadget.Flyout.file = "flyout.html";
/*System.Gadget.settingsUI = "settings.html";*/
System.Gadget.Flyout.onShow = FlyoutShowing;
System.Gadget.Flyout.onHide = FlyoutHidden;
var iFlyoutTimerID;
Player.attachEvent("StatusChange", UpdateStateController);
if(System.Gadget.Settings.read("Station Name")!=""){
stationname.value=System.Gadget.Settings.read("Station Name");
Player.error.clearErrorQueue();
Player.URL=System.Gadget.Settings.read("Station URL");
}
}
function FlyoutShowing() {
iFlyoutTimerID = window.setInterval('UpdateStation();', 100);
}
function FlyoutHidden() {
window.clearInterval(iFlyoutTimerID)
}
function UpdateStation() {
if (System.Gadget.Flyout.show==true) {
if (stationname.value!==System.Gadget.Settings.read("Station Name")) {
if (System.Gadget.Settings.read("Station Name")!=="") {
stationname.value=System.Gadget.Settings.read("Station Name");
}
Player.error.clearErrorQueue();
Player.URL=System.Gadget.Settings.read("Station URL");
StartMeUp ();
}
} else {
UpdateStateController();
window.ClearInterval(iFlyoutTimerID);
}
}
function StartMeUp () {
Player.controls.play();
UpdateStateController();
}
function ShutMeDown () {
Player.controls.stop();
UpdateStateController();
}
function toggleFlyout() {
if (System.Gadget.Flyout.show==false) {
System.Gadget.Flyout.show=true;
UpdateStateController();
} else {
System.Gadget.Flyout.show=false;
UpdateStateController();
}
}
function UpdateState(whichStateText, showHide) {
    if (showHide == "hide") {
        mplayerdiv.style.visibility='visible';
        whichState.style.visibility='hidden';
}
if (showHide == "show") {
        mplayerdiv.style.visibility='hidden';
        whichState.style.visibility='visible';
}
whichState.innerText = whichStateText;
}
function UpdateStateController() {
     if (Player.error.errorCount > 0) {
          UpdateState("Error!", "show");
          /* whichState.innerText = Player.error.item(Player.error.errorCount - 1).errorCode; */ 
          return;
     }
if (Player.playState==3){        
         UpdateState("Playing...", "hide");
         return; } else {
         switch (Player.openState) {
         case 10:
         UpdateState("Connecting...", "show");
         break;    
         case 11:
         UpdateState("Loading...", "show");
         break;        
         case 12:
         UpdateState("Opening...", "show");
         break;
         }
         switch (Player.playState) {
         case 1:
         UpdateState("Stopped", "show");
         break;    
         case 6:
         UpdateState("Buffering...", "show");
         break;        
         case 7:
         UpdateState("Waiting...", "show");
         break;
         case 8:
         UpdateState("Media Ended", "show");
         break;    
         case 11:
         UpdateState("Reconnected", "show");
         break;        
         }
        }
}

Da ich die Sender über das Flyout ändere, habe ich das Settings-Fenster momentan auskommentiert.
Viele Gadgets verwenden es, daher möchte ich es hier auch kurz anschneiden:
Die Zeile System.Gadget.settingsUI = "settings.html"; würde bewirken, dass seitlich vom Gadget ein Settings-Button auftaucht, der das Gadget selbst verkleinert und settings.html anzeigt.

 

 

 

 

 

 

 

 

flyout.html ist das Flyout-Fenster, welches sich öffnet, wo man den Sender auswählen und damit umschalten kann. Nachdem der Sender ausgewählt wurde wird er mittels System.Gadget.Settings.write in die Gadget-spezifischen Variablen geschrieben.

flyout.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>ATRadio</title>
<link rel="stylesheet" type="text/css" href="flyout.css">
<script src="flyout.js" language="javascript" type="text/javascript"></script>
</head>
<body onload="Init();">
<select id="Station" multiple="multiple" onchange="WriteSettings();" onclick="WriteSettings();" name="Station">
<option value="mms://stream4.orf.at/oe1-wort">Ö1 Live</option>
<option value="mms://stream4.orf.at/oe1-news">Ö1 Inforadio</option>
<option value="mms://stream4.orf.at/radiowien_live">Radio Wien</option>
<option value="mms://stream2.orf.at/oe3_live">Ö3</option>
<option value="mms://stream1.orf.at/fm4_live">FM4</option>
<option value="http://www.kronehit.at:8081/stream.m3u">Krone Hit Radio</option>
<option value="http://www.energy.at/cont/energylive/nrjmedia.asx">Energy 104.2</option>
<option value="http://srvhost24.serverhosting.apa.net:8000/rsdstream128.m3u">Radio Stephansdom</option>
<option value="http://streamintern.orange.or.at/live3.m3u">Orange</option>
</select>
</body>
</html>

 

flyout.js

function Init()
{
Station.selectedIndex=System.Gadget.Settings.readString("Station Index");
}
function WriteSettings ()
{
System.Gadget.Settings.write("Station Name",Station.options[Station.selectedIndex].text);
System.Gadget.Settings.write("Station URL",Station.options[Station.selectedIndex].value);
System.Gadget.Settings.writeString("Station Index",Station.selectedIndex);
System.Gadget.Flyout.show=false;
}

 

Da man ein Flyout nur vom Haupt-Gadget (atradio.htm) aus- und einklappen kann, ich aber wollte, dass es sich automatisch einklappt, sobald ein neuer Sender ausgewählt wurde, verwende ich - wie übrigens viele andere Gadget-Developer auch – "Polling", um zu sehen ob sich im Flyout etwas geändert hat. Das ist etwas "dirty", lässt sich aber meines Wissens nach nicht besser lösen. Ich polle natürlich nur solange das Flyout offen ist, ob es einen neuen Sender in den System.Gadget.Settings gibt, wenn ja, starte ich diesen, und schließe das Flyout. All das ist vom Haupt Gadget aus notwendig und nur mit Polling möglich, es lässt sich nicht vom Flyout auf das Hauptgadget zugreifen!

Zum Testen muss man das Gadget immer wieder zur Sidebar hinzufügen bzw. schließen. Außerdem empfiehlt es sich, Skriptdebugging einzuschalten, damit man Javascript Fehlermeldungen bekommt.

So sieht nun das fertige Gadget in der Sidebar aus, mit ausgeklapptem Flyout:

Ziemlich genial funktioniert das Packaging des neuen Gadgets: Einfach alle Files zippen, und die Endung von .zip in .gadget umbenennen! Fertig!

Mein Gadget bekommt man unter http://www.this.at/ATRadio07.zip

Man kann mein Gadget auch schon bei http://vista.gallery.microsoft.com/ herunterladen und bewerten.

Würde mich auch über Feedback freuen!

 

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Tags:

Windows Vista

Kommentare

04.03.2010 10:12:05 #

Filippo Galli

Sehr gute ideee und Ausführung! Bei mir funktioniert halt leider nur Radio Stephandsdom und Orange! Kann man dass reparieren????

lg. Galli

Filippo Galli Austria

13.03.2010 00:38:44 #

x3rox

sehr genial Smile
thx
nur bei mir kommt beim kronehit immer ein error Frown
ausserdem wärs genial wenn die anderen kronehit sender auch noch dabei wären Smile

x3rox Austria

28.03.2010 09:22:02 #

ChristianH

Hi - das Gadget ist aus dem Jahr 2007 und sehr lange nicht mehr aktualisiert worden, sodaß die Links nicht mehr stimmen. Die Idee war, das mal an ein Radio Verzeichnis wie Shoutcast oder Radiotime anzubinden. Weiß nicht ob/wann ich dafür Zeit finden werde.

ChristianH United States

29.10.2011 19:41:38 #

Felicia Streater

And one more comment:

In my opinion Sitecore has the upper hand on this one, especially if you wish to keep a similar content structure in multiple languages.
There are packages available for Umbraco, which will accomplish the exact same thing.

Anyway, nice blogpost! Going to read the follow-ups too.
The only thing from keeping me to try/switch-to Sitecore is; it isn't free.

Felicia Streater United States

18.11.2011 16:57:10 #

Yaz lawyer

I simply needed to say thanks once again. I'm not certain the things I could possibly have used without these advice shared by you relating to that field.

Yaz lawyer Egypt

22.11.2011 16:09:13 #

klinik hypnotherapy jakarta

Hello.This article was really remarkable, especially because I was searching for thoughts on this subject last Friday.

klinik hypnotherapy jakarta United States

04.12.2011 12:29:01 #

Jennifer Hudson Weight Loss

Great post there. FYI I shared %BLOGTITLE% with my DIGG account and it got some people chatterring.

Jennifer Hudson Weight Loss United States

25.12.2011 12:10:05 #

how to make a tahitian hip band

I am glad to be a  visitant of this  thoroughgoing  blog ! , thanks  for this rare  information! .

how to make a tahitian hip band United States

01.01.2012 06:36:13 #

michael jordan

Have been reading this blog via rss for quite sometime now, i wanted to finally make a comment and say hello. I ought to put in some effort because you definitly do.

michael jordan United States

06.01.2012 01:37:39 #

billards

I would also love to add that if you do not surely have an insurance policy or maybe you do not form part of any group insurance, chances are you'll well take advantage of seeking the help of a health insurance broker. Self-employed or those with medical conditions typically seek the help of any health insurance dealer. Thanks for your writing.

billards United States

02.03.2012 08:31:33 #

Fundraising

We stumbled over here  different web address and thought I might check things out. I like what I see so now i'm following you. Look forward to checking out your web page yet again.

Fundraising United States

12.03.2012 12:45:58 #

White Card Training

Hey there I am so excited I found your weblog, I really found you by mistake, while I was browsing on Bing for something else, Regardless I am here now and would just like to say cheers for a fantastic post and a all round exciting blog (I also love the theme/design), I don’t have time to look over it all at the minute but I have saved it and also included your RSS feeds, so when I have time I will be back to read more, Please do keep up the fantastic work.

White Card Training United States

14.05.2012 20:54:53 #

Colton Auyer

rank-1.co.uk help me out so much. Check em out!

Colton Auyer United States

Kommentar schreiben


(Zeigt dein Gravatar icon)

  Country flag

biuquote
  • Kommentar
  • Live Vorschau
Loading



Powered by BlogEngine.NET 1.5.0.7
Theme by Mads Kristensen | Modified by Mooglegiant

Facebook

Über den Autor

MCTS

Christian Haberl Christian Haberl ist seit mehr als 10 Jahren als EDV Berater, Vortragender und Trainer tätig. Er kann sich nicht für ein Spezialgebiet entscheiden, drum heißt dieser Blog auch "Kraut & Rüben Blog" - Unter seine Interessen fallen Web-Entwicklung auf ASP.NET Basis, Information Worker & Productivity Technologien (Windows, Office), Server (Windows Server, Small Business, Virtualisierung, Exchange), Scripting, Spam Filtering/Security und Digital Home. Christian Haberl ist auch einer der führenden Produktspezialisten für Windows Media Center und Windows Home Server und ist Direktor des ClubDigitalHome.
Im Jahr 2008 hat Christian Haberl über 200 Vorträge und Schulungen durchgeführt.
Im Frühjahr 2009 wurde Christian Haberl von Microsoft Österreich zum "Influencer" ernannt, weiters wurde er Microsoft Certified Technology Specialist / Microsoft Certified Connected Home Integrator sowie Microsoft Certified Consumer Sales Specialist.


Netzwerk Management

Bandwidth

RecentComments

Comment RSS