Adobe AIRとCatalystでログオン画面のスクリーンセーバーを作ってみた

伝言板になるスクリーンセーバーを作ってみた。主な材料は以下の通り。

Adobe AIR スクリーンセーバー表示用
Catalyst 伝言板データの送信、受信用
Access 伝言板データの保存用
  • Windowsスクリーンセーバーを作る。AIRアプリの実行ファイル(.exe)の拡張子を.scrにすることで作成可能
  • 伝言板のデータを更新する。伝言内容を別途Webアプリで供給し、AIRアプリでAjaxを使って受信する。
  • 動きのあるスクリーンセーバーにする。AIRアプリをAjaxで動かす。
  • AIRアプリ(HTMLベース)で他サイトからデータを受信する。XMLHttpRequestを使用する。
  • スクリーンセーバーにするため、マウス操作/キー入力等で終了する。window.addEventListenerでイベントを拾い、window.nativeWindow.closeで閉じる。(終了処理これでいいんだろうか。適当すぎるかもしれない)
  • ログオン画面のスクリーンセーバーとして登録する。下記レジストリの編集が必要。HKEY_USERS\.Default\Control Panel\Desktop\SCRNSAVE.EXE

メモ:参考になった記事

作業当初、Aptanaで新規AIRプロジェクトの作成に失敗する(ウィザードが起動しない)
上記記事が近いかと思ったが、解決せず。結局Aptanaアンインストール→再インストールで直った。

AIRアプリは以下のような物。html+javascriptで記述。

<html>
       <head>
       <title>Application Sandbox sample</title>
       <link href="sample.css" rel="stylesheet" type="text/css"/>

       <!-- Uncomment the following line to add introspection.  When running the application hit F12 to bring up the introspector -->
       <!-- <script type="text/javascript" src="AIRIntrospector.js"></script> -->

       <!-- Uncomment the following line to use the AIR source viewer -->
       <!-- <script type="text/javascript" src="AIRSourceViewer.js"></script> -->

       <!-- Uncomment the following line to use the AIR Localizer -->
       <!-- <script type="text/javascript" src="AIRLocalizer.js"></script> -->

       <!-- Uncomment the following line to use the AIR Menu Builder -->
       <!-- <script type="text/javascript" src="AIRMenuBuilder.js"></script> -->

       <script type="text/javascript" src="AIRAliases.js"></script>
       <script type="text/javascript">
var objYf1=30; // 文字列の初期配置(x座標)
var objXf1=50; // 文字列の初期配置(Y座標)
var moveYf1=4; // 1度にスクロールする縦幅
var moveXf1=2; // 1度にスクロールする横幅
var speedf1=50; // スクロールする間隔(スピード)(ミリ秒単位)
var received_data=new Array(2);

//              window.addEventListener("mousemove", appClose, false);
               window.addEventListener("click", appClose, false);
               window.addEventListener("keydown", appClose, false);

tf1=0;
function getWinf1(){
       if(document.all){  // ブラウザの横幅、縦幅を取得
               winHeight=document.body.clientHeight;
               winWidth=document.body.clientWidth;
       }
       else {
               winHeight=window.innerHeight;
               winWidth=window.innerWidth;
       }
}
function inif1(){
       if(document.getElementById){
               obj=document.getElementById("ff1");
               obj.style.width=obj.offsetWidth+"px";
                       // スクロール文字の幅を取得→widthを指定
               flyf1();
       }
}
function flyf1(){
       getWinf1();
       if(objYf1>=winHeight-obj.offsetHeight || objYf1<=0){
                       // 端まで進んで向きを変える
               moveYf1*=-1;
       }
       if(objXf1>=winWidth-obj.offsetWidth || objXf1<=0){
               moveXf1*=-1;
       }
       objXf1=objXf1+moveXf1;
       objYf1=objYf1+moveYf1;
       obj.style.top=objYf1+"px"; // 文字列の縦横方向の配置
       obj.style.left=objXf1+"px";
       clearTimeout(tf1);
       tf1=setTimeout(flyf1,speedf1); // スクロールする間隔
}
       function createhttprequest(){
               var request=null;
               if("XMLHttpRequest" in window){
                       request= new XMLHttpRequest();
               }
               else if("ActiveXObject" in window){
                       try{
                               request=new ActiveXobject("Msxml2.XMLHTTP");
                       }
                       catch(e){
                               try{
                                       request=new ActiveXObject("Microsoft.XMLHTTP");
                               }
                               catch(e){
                               }
                       }
               }
               return request;
       }

       var request;
       var xmlData;
       var main;


       function requestsource(url){
               request=createhttprequest();
               request.open("GET",url,true);
               request.onreadystatechange=sourceget;
               request.send(null);
       }

       function sourceget(){
               if (request.readyState == 4 && request.status == 200){
                       received_data=request.responseText.split('|');
                       $("age").innerHTML=received_data[0]+"日";
                       $("date").innerHTML="起算日:"+received_data[1];
//                      $("result").innerHTML=request.responseXML.getElementsByTagName('ff1');
               }
               else{
               }
       }

           function setDisplayState() {
                       window.nativeWindow.stage.displayState =
                               runtime.flash.display.StageDisplayState.FULL_SCREEN_INTERACTIVE;
                       }

       function appInit() {
               setDisplayState();
               requestsource("http://foo/bar");
               inif1();
       }

       function $ (tagId) {
               return document.getElementById(tagId);
       }

       function appClose() {
               window.nativeWindow.close();
       }
</script>
<style type="text/css">
<!--
body {
       color: #fff;
       background-color: #000;
}
#ff1 {
       position: absolute;
       top: 30px;
       left: 50px;
}
-->
</style>

</head>

<body onload="appInit();">
<div id="ff1">
       <table border=0 height=200px>
               <tr><td><font size=+2>
無災害+記録表<br>
<center><div id="age"></div></center><br>
<img src=icons/180px-Smiley.svg.png><br>
<div id="date"></div>
</font></td></tr>
</table>
</div>
</body>
</html>