Недавно мне понадобилось создать гаджет для Windows Sidebar. Навыков в этом у меня не было, поэтому, немного погуглив и почитав документацию, приступаем.
Сразу покажу то, что получилось в итоге

Гаджет будет получать информацию с сайта в виде xml, парсить и, собственно, отображать. Также гаджет будет проверять наличие новых версий, и в случае их присутствия, отказываться работать :)
Изначально, ради получения опыта, хотел написать гаджет полностью на VBScript (так как с ним еще не имел дела), но в конечном итоге пришлось делать вставки на JavaScript.
Перейдем непосредственно к коду. Весь код здесь я рассматривать не буду, покажу лишь основные моменты. Ссылка на готовый гаджет – в конце статьи.
Главный файл гаджета – его манифест – файл Gadget.xml. Он должен называться именно так и располагаться в корне нашего архива (гаджет есть ни что иное, как архив ZIP с расширением .gadget).
Рассмотрим его более подробно.
Элемент <base> должен содержать apiVersion, равный 1.0.0 (на данный момент), а также атрибут src, в котором указан главный файл нашего гаджета;
<permissions> — разрешения для гаджета. Устанавливаем равным full;
<platform> — минимальная версия Widows Sidebar. На данный момент – 1.0;
Параметры <name> — имя гаджета, <version> — версия, <author> — информация об авторе, <info> — ссылка на страницу с гаджетом, <icon> — иконка гаджета и <descrtiption> будут отображаться на панели установленных гаджетов.
Файл main.html – обычный html файл, приводить его полностью не буду, остановлюсь лишь на некоторых моментах.
С помощью элемента g:background задается фон гаджета. Сделаем его прозрачным.
Гаджет может находиться в двух состояниях – docked (слева на скрине выше), и undocked (справа). Будем хранить текущее состояние гаджета в переменной JavaScript docked.
Функция-обертка isDocked потребуется нам в дальнейшем, чтобы из VBScript узнать текущее состояние гаджета (как я не старался, но реализовать это на чистом VBScript не смог). Еще одно замечание – скрипты корректно работают именно в этом порядке, т.е. сначала описываем скрипты VBScript, потом JavaScript.
Остальные элементы в main.html представлены элементами DIV с абсолютным позицированием. Впоследствии из скриптов мы будем обращаться к ним по их id.
С помощью JavaScript зададим состояния docked и undocked для гаджета, а так же укажем файл настроек (main.js)
Как видно из листинга выше, при смене состояний гаджета будет вызываться функция resize().
Также можно описать функцию сохранения настроек. В моем гаджете их нет, но для примера покажу как это делается
readString – читает ранее сохраненную строку, writeString, соответственно, записывает.
Методы System.Gadget.beginTransition(); и System.Gadget.endTransition(); нужны для “плавного» изменения размера гаджета. В Windows Seven они игнорируются, но я все же оставил их для обратной совместимости.
Как уже говорилось выше, сервер предоставляет нам информацию о погоде в формате xml.
Скачивать и парсить xml будем на VBScript.
Функция mySleep будет проверять наше соединение на таймаут.
В случае успешного скачивания objXML.readyState будет равен четырем, а статус (objXML.status) вернет значение 200.
В этом случае сохраняем файл во временную папку Windows
и начинаем парсить файл.
Проверка на новые версии производится точно таким же способом.
Не забываем создать файл настроек — settings.html, о существовании которого мы объявили выше.
Вот, собственно, и все. Буду рад, если моя (первая :)) статья оказалась кому-то полезной.
Использованные источники:
http://www.script-coding.com/XMLDOMscripts.html;
http://msdn.microsoft.com/en-us/library/bb508511%28v=VS.85%29.aspx;
VBScript Programmers Reference, 3rd Edition;
ну, и, конечно, http://google.com.
Ссылка на гаджет – http://info.kovonet.ru/test.gadget.
Сразу покажу то, что получилось в итоге

Гаджет будет получать информацию с сайта в виде xml, парсить и, собственно, отображать. Также гаджет будет проверять наличие новых версий, и в случае их присутствия, отказываться работать :)
Изначально, ради получения опыта, хотел написать гаджет полностью на VBScript (так как с ним еще не имел дела), но в конечном итоге пришлось делать вставки на JavaScript.
Перейдем непосредственно к коду. Весь код здесь я рассматривать не буду, покажу лишь основные моменты. Ссылка на готовый гаджет – в конце статьи.
Главный файл гаджета – его манифест – файл Gadget.xml. Он должен называться именно так и располагаться в корне нашего архива (гаджет есть ни что иное, как архив ZIP с расширением .gadget).
<?xml version="1.0" encoding="utf-8" ?>
<gadget>
<name>Weather from Info.Denms.Ru</name>
<version>1.0.1232</version>
<hosts>
<host name="wdenms">
<base type="HTML" apiVersion="1.0.0" src="main.html" />
<permissions>Full</permissions>
<platform minPlatformVersion="1.0" />
</host>
</hosts>
<icons>
<icon width="64" height="64" src="icon.png" />
</icons>
<author name="cvs">
<info url="http://info.denms.ru" />
</author>
<description>Weather Widget (Info.Denms.Ru)</description>
</gadget>
Рассмотрим его более подробно.
Элемент <base> должен содержать apiVersion, равный 1.0.0 (на данный момент), а также атрибут src, в котором указан главный файл нашего гаджета;
<permissions> — разрешения для гаджета. Устанавливаем равным full;
<platform> — минимальная версия Widows Sidebar. На данный момент – 1.0;
Параметры <name> — имя гаджета, <version> — версия, <author> — информация об авторе, <info> — ссылка на страницу с гаджетом, <icon> — иконка гаджета и <descrtiption> будут отображаться на панели установленных гаджетов.
Файл main.html – обычный html файл, приводить его полностью не буду, остановлюсь лишь на некоторых моментах.
С помощью элемента g:background задается фон гаджета. Сделаем его прозрачным.
<g:background id="background" style="position:absolute; z-index:-1; top:0; left:0;" opacity="0"></g:background>
Гаджет может находиться в двух состояниях – docked (слева на скрине выше), и undocked (справа). Будем хранить текущее состояние гаджета в переменной JavaScript docked.
<SCRIPT Language="VBScript">
'Вызов функции JavaScript из области VBS
function isDocked
isDocked = isDockedJS()
End Function
</script>
<script src="main.vbs" type="text/vbscript"></script>
<SCRIPT Language="JavaScript">
docked = 0;
function isDockedJS() {
return docked;
}
</SCRIPT>
<script type="text/javascript" src="main.js"></script>
Функция-обертка isDocked потребуется нам в дальнейшем, чтобы из VBScript узнать текущее состояние гаджета (как я не старался, но реализовать это на чистом VBScript не смог). Еще одно замечание – скрипты корректно работают именно в этом порядке, т.е. сначала описываем скрипты VBScript, потом JavaScript.
Остальные элементы в main.html представлены элементами DIV с абсолютным позицированием. Впоследствии из скриптов мы будем обращаться к ним по их id.
<div id="small_needupdate"></div>
С помощью JavaScript зададим состояния docked и undocked для гаджета, а так же укажем файл настроек (main.js)
System.Gadget.onDock = resize;
System.Gadget.onUndock = resize;
System.Gadget.settingsUI = "settings.html";
System.Gadget.onSettingsClosed = SettingsClosed;
docked=0; //начальное состояние гаджета
resize(); //инициализация
Как видно из листинга выше, при смене состояний гаджета будет вызываться функция resize().
function resize() {
bd = document.body.style;
System.Gadget.beginTransition();
if (System.Gadget.docked) {
// small state
bd.width=148; //устанавливаем размеры гаджета
bd.height=201;
docked = 1;
bd.background='url(images/gadget.png) no-repeat'; //устанавливаем фон
//далее следует перенос значений из состояния undocked в docked и обнуление элементов для состояния undocked
document.getElementById("small_needupdate").innerHTML = document.getElementById("big_needupdate").innerHTML;
document.getElementById("big_needupdate").innerHTML = "";
//...
} else {
// big state
bd.width=230;
bd.height=160;
bd.background='url(images/gadgeth.png) no-repeat';
docked=0;
//перенос значений из состояния docked в undocked и обнуление элементов для состояния docked
document.getElementById("big_needupdate").innerHTML = document.getElementById("small_needupdate").innerHTML;
document.getElementById("small_needupdate").innerHTML = "";
//...
}
System.Gadget.endTransition(System.Gadget.TransitionType.morph,1);
}
Также можно описать функцию сохранения настроек. В моем гаджете их нет, но для примера покажу как это делается
function SettingsClosed(event) {
if (event.closeAction == event.Action.commit) {
//alert System.Gadget.Settings.readString('test');
}
}
readString – читает ранее сохраненную строку, writeString, соответственно, записывает.
Методы System.Gadget.beginTransition(); и System.Gadget.endTransition(); нужны для “плавного» изменения размера гаджета. В Windows Seven они игнорируются, но я все же оставил их для обратной совместимости.
Как уже говорилось выше, сервер предоставляет нам информацию о погоде в формате xml.
<?xml version="1.0"?>
<all>
<day id="today">
<temp>1.7</temp>
<cloudyim>41</cloudyim>
<cloudy>пасмурно</cloudy>
<air>снег</air>
<humidity>87</humidity>
<wind_direction>Ю-З</wind_direction>
<wind_speed>5</wind_speed>
<min>-3</min>
<max>-1</max>
</day>
<day id="ПТ">
<min>-1</min>
<cloudyim>26</cloudyim>
<max>1</max>
</day>
<day id="СБ">
<min>-9</min>
<cloudyim>41</cloudyim>
<max>0</max>
</day>
…
</all>
Скачивать и парсить xml будем на VBScript.
Sub DownloadXML2
Set objXML = CreateObject("Microsoft.XmlHttp")
objXML.Open "GET", "http://info.kovonet.ru/weather.xml", True
objXML.OnReadyStateChange = GetRef("objXML_onreadystatechange")
objXML.setRequestHeader "If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT"
objXML.Send
iTimeoutID = window.SetTimeout("mySleep", 1000)
End Sub
Функция mySleep будет проверять наше соединение на таймаут.
Sub mySleep
if bRespReceived = "false" then 'ответ еще не получен
iTimeout = iTimeout + 1
if (iTimeout > 30) then 'таймаут
timerFirstRun = window.SetTimeout("Update", 60000) 'попытка повторного обновления через минуту
else 'таймаут еще не достигнут, продолжаем считать секунды
iTimeoutID = window.SetTimeout("mySleep", 1000)
end if
end if
End Sub
В случае успешного скачивания objXML.readyState будет равен четырем, а статус (objXML.status) вернет значение 200.
Function objXML_onreadystatechange()
If (objXML.readyState = 4) Then
'msgbox objXML.statusText
If (objXML.status = 200) Then
bRespReceived=true
SaveFile(objXML.responseText)
else
timerFirstRun = window.SetTimeout("Update", 60000) 'попытка повторного обновления через минуту
End If
End If
End Function
В этом случае сохраняем файл во временную папку Windows
Function SaveFile(what)
Set fso = CreateObject("Scripting.FileSystemObject")
tempFolder = fso.GetSpecialFolder(2)
filepath = tempFolder+"\weather.xml"
Dim fso1, tf
Set fso1 = CreateObject("Scripting.FileSystemObject")
Set tf = fso1.CreateTextFile(filepath, True, True) 'rewrite, unicode
tf.Write(what)
tf.Close
ParseXML
End Function
и начинаем парсить файл.
Sub ParseXML
Set fso = CreateObject("Scripting.FileSystemObject")
tempFolder = fso.GetSpecialFolder(2)
filepath = tempFolder+"\weather.xml"
Set xmlDoc = CreateObject("Msxml2.DOMDocument")
xmlDoc.async="false"
xmlDoc.load(filepath)
'главная нода – в нашем случае <all>
Set currNode = xmlDoc.documentElement
'дни недели – <day>
Set dayNode = currNode.firstChild
While Not dayNode Is Nothing
Set currNode = dayNode.firstChild
While Not currNode Is Nothing
if currNode.parentNode.getAttribute("id") = "today" then 'сегодняшний день
if currNode.nodeName = "temp" then document.getElementById(prefix+"maintemp").innerHTML = currNode.childNodes(0).text+Chr(176)
'отображаем остальные элементы
Else 'не сегодняшний день, отображаем более мелко
'...
end If
Set currNode = currNode.nextSibling
Wend
Set dayNode = dayNode.nextSibling
Wend
End Sub
Проверка на новые версии производится точно таким же способом.
Не забываем создать файл настроек — settings.html, о существовании которого мы объявили выше.
<html>
<head>
<title>Настройки</title>
<style type="text/css">
body { width:220px; height:120px; }
</style>
</head>
<body>
<div style="text-align:center">
<strong>Weather from Info.Denms.Ru<br/><script type="text/javascript">document.write(System.Gadget.version);</script></strong><br/>
© cvs, 2011<br/>
<a href="http://info.denms.ru">http://info.kovonet.ru</a><br/><br/>
</div>
</body>
</html>
Вот, собственно, и все. Буду рад, если моя (первая :)) статья оказалась кому-то полезной.
Использованные источники:
http://www.script-coding.com/XMLDOMscripts.html;
http://msdn.microsoft.com/en-us/library/bb508511%28v=VS.85%29.aspx;
VBScript Programmers Reference, 3rd Edition;
ну, и, конечно, http://google.com.
Ссылка на гаджет – http://info.kovonet.ru/test.gadget.