データの保存
便利で実用的なツールをガジェットで提供するには、システムから情報を取得するだけでは不十分です。例えば、メモやToDoリストの機能を提供するガジェットを開発しようと考えた場合、ユーザーが入力した情報に従ってデータを保存しなければなりません。しかし、セキュリティの都合上、JavaScriptから自由にシステム上のファイルを書き換えることはできません。誰も、そのような危険なガジェットを望まないでしょう。
ガジェットから情報を保存するには、ファイルに書き込むのではなくWindows Sidebarが提供するSystem.Gadget.Settingsオブジェクトを使います。このオブジェクトは、現在実行しているガジェットの設定情報を保存するために、書き込みと読み込みを行うメソッドを提供しており、主に、ユーザーが入力する設定情報を管理するために使います。
ガジェットの情報を保存するにはwrite()メソッドを使います。write()メソッドは、指定した名前で任意の文字列を保存します。
System.Gadget.Settings.write(strWriteSettingName, strWriteSettingInit)
strWriteSettingNameパラメータには保存する文字列に関連付ける名前を、strWriteSettingInitには指定した名前で保存する任意の文字列を指定します。保存した値は、write()メソッドの最初のパラメータで指定した名前に関連付けられます。保存した値を読み込むにはread()メソッドを使います。
[ strResult = ] System.Gadget.Settings.read(strSettingName)
read()メソッドは、strSettingNameパラメータに読み込む値の名前を指定します。この名前はwrite()メソッドの最初のパラメータに指定した名前に対応します。このメソッドの結果は、指定した名前で保存されていた値となります。
<html> <head> <title>Gadget sample</title> <script> function readMemo() { var value = System.Gadget.Settings.read('value'); if (value == '') label.innerText = '値がありません'; else label.innerText = 'value=' + value; } function writeMemo() { label.innerText = 'Writed'; System.Gadget.Settings.write('value', memo.value); } </script> </head> <body style='margin:5px; width:125px; height:100px' onload='readMemo()'> <span id='label'>label</span> <input type='text' size='12' value='' id='memo' /><br /> <input type='button' value='保存' onclick='writeMemo()' /> <input type='button' value='読み込み' onclick='readMemo()' /> </body> </html>

Sample 04は、テキストボックスに入力されている任意のテキストを[保存]ボタンでSystem.Gadget.Settingsオブジェクトに保存し、[読み込み]ボタンを押すと保存した文字列を読み込むプログラムです。[保存]ボタンを押すとonclickイベントが発生してwriteMemo()関数が呼び出されます。writeMemo()関数はwrite()メソッドに、テキストボックスに入力されている値をvalueという名前で保存します。[読み込み]ボタンを押すと、今度はreadMemo()関数が実行され、read()メソッドからvalueという名前を持つ値を読み込みます。上部のspan要素に、保存したテキストが表示されます。
System.Gadget.Settingsに保存する情報は永続的なものではありません。ガジェットをSidebarから削除すると、自動的に保存されていたSystem.Gadget.Settingsオブジェクトの情報も破棄されます。しかし、Sidebarそのものが終了するときにはガジェットの情報が保存されます。そのため、ガジェットを実行し続けていれば、ログオフやシャットダウンによってSidebarが終了されるときに、ガジェットの情報が自動的に保存されます。この情報は、再びSidebarが起動されたときにSystem.Gadget.Settingsから読み込むことができます。
設定ダイアログの表示
ガジェットに対してユーザーが何らかの設定を行えるようにする場合、小さなガジェットの領域内に入力フォームを構築するのは困難です。そのため、ガジェットは通常の表示領域とは別に、設定用のダイアログボックスを表示することができます。このダイアログも、HTMLファイルで構築することができます。
設定用ダイアログをガジェットに追加するにはSystem.GadgetオブジェクトのsettingsUIプロパティに、ダイアログとして表示するHTMLファイルの名前を指定します。このプロパティが設定されている場合、ガジェットに設定用ダイアログを表示するボタンが追加されます。
[ strGetSettingsUI = ] System.Gadget.settingsUI(strInitSettingsUI)
settingsUIプロパティは、設定用ダイアログのHTMLファイルを設定・取得することができます。通常、設定用ダイアログ内でユーザーに入力してもらうフォームを表示し、System.Gadget.Settingsオブジェクトに設定情報を保存します。この情報はガジェットで共有することができるため、ダイアログを閉じた後、ガジェット内で設定情報をread()メソッドから取得することができます。
設定ダイアログが表示されたり、閉じられたりしたタイミングを知るにはSystem.Gadgetオブジェクトが公開しているイベントを使います。ダイアログが表示されるときはonShowSettingsイベントが、ダイアログが閉じられたときにはonSettingsClosedイベントが発生します。
System.Gadget.onShowSettings = handler
System.Gadget.onSettingsClosed = handler
設定ダイアログには、最初から[OK]ボタンと[キャンセル]ボタンが附属されているため、ダイアログの終了処理をコードで書く必要はありません。ダイアログが閉じられる直前にデータを保存するには、いずれかのボタンが押され、ダイアログが閉じられる前に発生するonSettingsClosingイベントを処理します。
System.Gadget.onSettingsClosing = handler
通常、このイベントは設定ダイアログ側のスクリプトで処理します。onSettingsClosingイベントを受けるイベントハンドラは、パラメータにSystem.Gadget.Settings.ClosingEvent型のオブジェクトを受けることができます。このオブジェクトのcloseActionプロパティから、設定ダイアログが「OK」ボタンから閉じられようとしているのか、[キャンセル]ボタンから閉じられようとしているのかを知ることができます。
[ strCloseAction = ] System.Gadget.Settings.ClosingEvent.closeAction
このプロパティが返す値は、[OK]ボタンが押されて閉じられようとしている場合と、[キャンセル]ボタンが押されて閉じられようとしている場合で異なります。[OK]が押されて閉じられようとしている場合、closeActionの結果はevent.Action.commitと等しくなります。
<html> <head> <title>Gadget sample</title> <script> System.Gadget.settingsUI = 'settings.html'; System.Gadget.onSettingsClosed = dialogClosed; function dialogClosed(event) { readMemo(); } function readMemo() { var value = System.Gadget.Settings.read('value'); if (value == '') label.innerText = '値がありません'; else label.innerText = 'value=' + value; } </script> </head> <body style='margin:5px; width:125px; height:100px' onload='readMemo()'> <span id='label'>label</span> </body> </html>
<html> <head> <title>設定ダイアログ</title> <script> System.Gadget.onSettingsClosing = closing; function closing(event) { if (event.closeAction == event.Action.commit) System.Gadget.Settings.write('value', textField.value); } </script> </head> <body style='width:400px; height:200px;'> <p>テキストを入力してください</p> <p><input type='text' size='40' id='textField' /></p> </body> </html>

Sample 05を実行すると、ガジェットに設定ボタンが追加されていることを確認できます。このボタンを押すと、System.Gadget.settingsUIに設定したHTMLファイルが表示されます。

今回のプログラムでは、単純にテキストを入力するテキストボックスのみを表示しています。何らかの文字を入力して[OK]ボタンを押すと、System.Gadget.Settingsオブジェクトにvalueという名前で値が保存されます。この値を「test.html」内でread()メソッドから取得すれば、設定を反映させることができます。ダイアログが閉じられようとしているときに発生するonSettingsClosingイベントが発生した時に呼び出されるclosing()関数内では、[OK]ボタンが押されたかどうかを調べているため、[キャンセル]ボタンが押された場合は設定されないことにも注目してください。
作成したガジェットの配布
ガジェットを開発するときは、これまでのように「Gadgets」フォルダ内に「.gadget」で終わるフォルダを作成し、その中にマニフェストやHTMLファイルを置きます。しかし、「Gadgets」フォルダは隠しフォルダである「AppData」フォルダ内にあるため、インターネットなどを通して広く一般に提供するには、この配置方法は使えません。一般のユーザーに、指定したフォルダ内にガジェットのファイルを展開するように指示するのは困難です。
開発したガジェットを公開する場合は、別のインストールと実行方法があります。まず、ガジェットを構成するマニフェストやHTML、画像ファイルなどをZIP形式のファイルに圧縮します。そして、圧縮したZIPファイルの拡張子を「.gadget」に変更してください。これで作業は終了です。Windows Vistaでは、拡張子.gadgetが最初から関連付けられているため、.gadgetファイルを直接実行してインストールすることができます。
最後に
本稿では、ガジェットを用いてデータを保存する作業までを解説しましたが、最後のSample 05を改良すれば、デスクトップ上に常に貼り付けておくメモ用紙や、やらなければいけない仕事を列挙するToDoリストなどを管理するガジェットを作ることができます。また、スクリプトを駆使したミニゲームや、計算機などのツールも開発することができます。
ガジェットは、Windowsアプリケーションや、データベースと連携するWebアプリケーションのような大規模なプログラムにはなりません。作業領域やアクセス可能なデータが限られているため、作ることができるソフトウェアの種類はある程度限定されてしまいます。しかし、自由度の高い本格的なアプリケーション開発の世界は、個人開発者には敷居が高く、既に大規模な企業やプロフェッショナルの開発組織でなければ、なかなか実用的なものにまで仕上げるのは難しいほど複雑化しています。一方のガジェットは、限られた機能の中で作らなければならないため、開発組織の規模よりも、開発者のアイデア次第といったところがあります。大規模な開発ツールや、新しい複雑なプログラミング言語の学習も不要で、以前から使われているWeb開発技術を流用できるところも大きな魅力です。
