📜 ⬆️ ⬇️

Writing Windows Sidebar gadget from scratch

Recently, I needed to create a gadget for Windows Sidebar. I didn’t have any skills in this, therefore, having a little googling and having read the documentation , we proceed.

Immediately show what happened in the end



The gadget will receive information from the site in the form of xml, parse and, in fact, display. Also, the gadget will check for new versions, and if they are present, refuse to work :)
Initially, for the sake of gaining experience, I wanted to write a gadget entirely in VBScript (since I have not dealt with it yet), but eventually I had to do inserts in JavaScript.
Let's go directly to the code. Here I will not consider all code, I will show only highlights. Link to the finished gadget - at the end of the article.
The main file of the gadget - its manifest - the Gadget.xml file. It should be called that way and be located in the root of our archive (the gadget is nothing but a ZIP archive with the .gadget extension).
')
<?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> 


Consider it in more detail.
The <base> element must contain apiVersion, equal to 1.0.0 (at the moment), as well as the src attribute, which indicates the main file of our gadget;
<permissions> - permissions for the gadget. Set to full;
The <platform> is the minimum version of Widows Sidebar. At the moment - 1.0;
Parameters <name> - the name of the gadget, <version> - version, <author> - information about the author, <info> - link to the page with the gadget, <icon> - icon of the gadget and <descrtiption> will be displayed on the installed gadgets panel.

The main.html file is a regular html file, I will not give it completely, I’ll dwell only on some points.
Using the element g: background sets the background of the gadget. Let's make it transparent.

 <g:background id="background" style="position:absolute; z-index:-1; top:0; left:0;" opacity="0"></g:background> 


The gadget can be in two states - docked (on the left on the screenshot above), and undocked (on the right). We will store the current state of the gadget in the JavaScript variable 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> 


We will need the isDocked wrapper function in the future to find out the current state of the gadget from VBScript (as I didn’t try, but I couldn’t implement it on pure VBScript). Another note is that the scripts work correctly in this order, i.e. We first describe the VBScript scripts, then the JavaScript.

The remaining elements in main.html are represented by DIV elements with absolute positioning. Subsequently, from the scripts we will contact them by their id.

  <div id="small_needupdate"></div> 


Using JavaScript, we will set the docked and undocked states for the gadget, as well as specify the settings file (main.js)

 System.Gadget.onDock = resize; System.Gadget.onUndock = resize; System.Gadget.settingsUI = "settings.html"; System.Gadget.onSettingsClosed = SettingsClosed; docked=0; //   resize(); // 


As you can see from the listing above, when the gadget changes its state, the resize () function will be called.

 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); } 


You can also describe the function of saving settings. They are not in my gadget, but for example I'll show you how this is done.

 function SettingsClosed(event) { if (event.closeAction == event.Action.commit) { //alert System.Gadget.Settings.readString('test'); } } 


readString - reads a previously saved string, writeString, respectively, writes.
Methods System.Gadget.beginTransition (); and System.Gadget.endTransition (); needed for a “smooth” resizing of the gadget. In Windows Seven, they are ignored , but I still left them for backward compatibility.

As mentioned above, the server provides us with weather information in xml format.

 <?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> 


Download and parse xml will be on 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 


The mySleep function will check our connection for a timeout.

 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 


Upon successful download, objXML.readyState will be equal to four, and the status (objXML.status) will return the value 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 


In this case, save the file to the Windows temporary folder.

 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 


and start parsing the file.

 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 


Check for new versions in the same way.
Do not forget to create a settings file - settings.html, the existence of which we announced above.

 <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> 


That's all. I would be glad if my (first :)) article was useful to someone.

Used sources:
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;
well, and of course http://google.com .

Link to the gadget - http://info.kovonet.ru/test.gadget .

Source: https://habr.com/ru/post/132042/


All Articles