0

I'm creating a small Windows Sidebar Gadget for taking notes in a simple textarea.

enter image description here

I have, as usual, a gadget.xml manifest file and a .html file, see below.

How is it possible to read some data / save some data in a Gadget?

I know this is usually impossible with JavaScript only (note: using localstorage is not possible because I want persistance of data), so how to save/read data inside a Windows Gadget ?


<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=Unicode" />
        <title>NeverForget</title>
        <style type="text/css">
        body
        {
            margin: 0;
            width: 300px;
            height: 200px;            
            background-color: transparent;
        }
        #gadgetContent 
        {
            width: 100%;
            height: 100%;
            overflow: hidden;
            border: none;
            background-color: transparent;
        }
        </style>
        <script type="text/jscript" language="jscript">
            function init() {
                // how to load notes from a file here on startup?
            }
            window.onkeydown = function () {
                // how to save data to file?
            }
        </script>
    </head>

    <body onload="init()">
            <textarea id="gadgetContent">Bonjour</textarea>
    </body>
</html>
Basj
  • 41,386
  • 99
  • 383
  • 673

1 Answers1

1

Try one of these:

  1. There are the inbuilt methods of the System.Gadget.Settings object which can be used to to read/write from the Settings.ini file (stored in C:\Users\[user]\AppData\Local\Microsoft\Windows Sidebar) but this information will be lost if the gadget is closed or uninstalled.

  2. Use the FileSystemObject to create or read or write folders/files anywhere. Limitation: file can only be saved as unicode or ascii.

  3. Use an ADO Stream object to create or read or write files anywhere. Limitation: can't create folders - must be used in conjunction with the FileSystemObject. Advantage: can use any codepage that exists on your computer.

Since I like saving text files with utf-8 the example below uses the third method but you may well decide to dispense with some of the error handling. (NB - this example is based on a script published by Andrew Urquhart)

Fortunately the sidebar is able to use knownfolders and knownfolderpaths so finding the path to your documents folder for example is as easy as

var docs = System.Shell.knownFolderPath("Documents");

Remember that the backslash is an escape character in javascript so that paths in strings must have their backslashes doubled.

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>NeverForget</title>
<style type="text/css">
<!--
body {margin:0;width:300px;height:200px;background-color:transparent;padding:10px;}
#gadgetContent {width:280px;height:144px;overflow:auto;border:1px solid black;background-color:#eee;}
button {margin-left:66px;margin-top:10px;}
#message {display:none;width:280px;height:180px;position:absolute;top:10px;left:10px;background-color:#eee;border:1px solid red;}
#messageContent {width:278px;height:144px;word-wrap:break-word;overflow-y:auto;}
#newButton {position:absolute;bottom:10px;left:54px;}
-->
</style>
<script type="text/jscript">
//globals
var myFolderPath=System.Shell.knownFolderPath("Documents")+"\\myFiles";
//end globals
function showMessage(msg){
 message.style.display="block";
 messageContent.innerText=msg;
}
function closeMessage(){
 message.style.display="none";
 messageContent.innerText="";
}
function loadFile(strAbsoluteFilePath, strCharSet){
 var adReadAll=-1, adReadLine=-2, strFileContents="", objStream=new ActiveXObject("ADODB.Stream"), fso=new ActiveXObject("Scripting.FileSystemObject");
 try{
  if(!strAbsoluteFilePath){
   throw new Error(1, "Required parameter \"strAbsoluteFilePath\" was not defined");
  }
  if(!strCharSet){
   throw new Error(2, "Required parameter \"strCharSet\" was not defined");
  }
  if(!fso.FolderExists(myFolderPath)){
   throw new Error(3, "Folder \""+myFolderPath+"\" does not exist");
  }
  objStream.Open();
  try{
   objStream.CharSet=strCharSet;
   objStream.LoadFromFile(strAbsoluteFilePath);
   strFileContents=objStream.ReadText(adReadAll);
   gadgetContent.innerText=strFileContents;
  }
  catch(err){
   throw new Error(err.number, "Loading failed:\r\n" + err.description);
  }
  finally{
   objStream.Close(); // Always close the stream regardless of what happens
   objStream=null;
   fso=null;
  }
 }
 catch(err){
  showMessage("Function loadFile() failed with parameters strAbsoluteFilePath=\"" + strAbsoluteFilePath + "\", strCharSet=\"" + strCharSet + "\". Message=\r\n" + err.description+"\r\nError Number: "+err.number);
 }
}
function saveFile(strAbsoluteFilePath, strCharSet, strFileContents, blnOverwrite){
 var adSaveCreateNotExist=1, adSaveCreateOverWrite=2, objStream = new ActiveXObject("ADODB.Stream"), fso=new ActiveXObject("Scripting.FileSystemObject");
 try{
  if(!strAbsoluteFilePath){
   throw new Error(1, "Required parameter \"strAbsoluteFilePath\" was not defined");
  }
  if(!strCharSet){
   throw new Error(2, "Required parameter \"strCharSet\" was not defined");
  }
  if(typeof strFileContents != "string"){
   throw new Error(3, "Required parameter \"strFileContents\" was not a string");
  }
  if(!fso.FolderExists(myFolderPath)){
   fso.CreateFolder(myFolderPath);
  }
  objStream.Open();
  try{
   objStream.CharSet=strCharSet;
   objStream.WriteText(strFileContents);
   objStream.SaveToFile(strAbsoluteFilePath, (blnOverwrite ? adSaveCreateOverWrite : adSaveCreateNotExist));
   return true;
  }
  catch(err){
   throw new Error(err.number, "SaveToFile failed:\r\n" + err.description);
  }
  finally{
   objStream.Close(); // Always close the stream regardless of what happens
   objStream=null;
   fso=null;
  }
  return false;
 }
 catch(err){
  showMessage("Function saveFile() failed with parameters strAbsoluteFilePath=\"" + strAbsoluteFilePath + "\", strCharSet=\"" + strCharSet + "\", strFileContents=\"" + strFileContents + "\", blnOverwrite=\"" + blnOverwrite + "\". Message=\r\n" + err.description+"\r\nError Number: "+err.number);
 }
}
function init(){
 loadButton.onclick=function(){loadFile(myFolderPath+"\\myFile.txt","utf-8");};
 saveButton.onclick=function(){saveFile(myFolderPath+"\\myFile.txt", "utf-8", gadgetContent.innerText, true);};
 closeButton.onclick=closeMessage;
}
</script>
</head>
<body onload="init()">
 <textarea id="gadgetContent">Bonjour</textarea>
 <div id="message">
  <div id="messageContent"></div>
  <div id="newButton"><button id="closeButton">Close</button></div>
 </div>
 <button id="loadButton">Load</button><button id="saveButton">Save</button>
</body>
</html>
mystifeid
  • 276
  • 2
  • 4
  • Waw thanks so much @mystifeid! This is really great! Last thing: how to make the textbox and the body totally transparent? ie we see the Desktop under the text, and no white/grey background. – Basj Jan 06 '15 at 10:50
  • Try using a 1px x 1px transparent png as a g:background (see Remarks [here](http://msdn.microsoft.com/en-us/library/ff486136.aspx) for how to declare in html) then size it to 100% width and height (of the body size) in your onload function.(ie: imgBackground.style.width="100%"; imgBackground.style.height="100%";) – mystifeid Jan 06 '15 at 12:29
  • Black text added via html or normal javascript methods is likely to appear magenta in colour when using a transparent g:background. You might be able to resolve this by adding/removing text as [g:text objects](http://msdn.microsoft.com/en-us/library/ff486146.aspx). This, btw, is outside the scope of your original question. Please try searching, reading and having a decent attempt yourself. If, after a few days, you can make no more progress, ask another question and provide your css/script/html. – mystifeid Jan 06 '15 at 12:58