スポンサーサイト
投稿日時 : -------- --:--
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
-------- --:-- | スポンサー広告
[win32api.js] システム時計を設定するHTA
投稿日時 : 2008-09-10 18:40
 win32api.jsを使ったシステム時計を設定するサンプルコードです。ボタンを押してシステム時計を1分単位で進めたり戻したりできます。GUIはHTAです。
 
SetLocalTime()とGetLocalTime()のサンプルHTAのスクリーンショット
 
 直接Win32API関数を呼んでもいいんですが、JavascriptのDateオブジェクトを渡してシステム時計の設定ができた方が使いやすいと思われるので専用の関数を定義してみます。あとSYSTEMTIME構造体とJavascript Dateオブジェクトの相互変換関数も定義します。これらの関数は「htalib」というObjectのメソッドとして実装することにします。システムローカル時間の設定にはSetLocalTime、取得にはGetLocalTimeのWin32API関数を使います。これらのAPI関数はwin32api.jsで定義されています。
 サンプルコードを.htaで保存して実行して下さい。動作にはwin32api.js及びSFC miniが必要です。
 
SetLocalTimeとGetLocalTimeサンプル.hta
<html>
<head>
<title>(Set|Get)LocalTimeサンプル</title>
<script type="text/javascript" language="javascript" src="win32api.js"></script>
<script type="text/javascript" language="javascript">
window.resizeTo(300,100); //ウィンドウサイズ調整

//このObject(HTA Library)に関数を追加していく
var htalib = {}; 

//jsDateからSYSTEMTIME構造体へ変換
htalib.Date2SYSTEMTIME = function(jsDate){
    if(!(jsDate instanceof Date)) return NULL;
    var systemtime = new SYSTEMTIME(); 
    systemtime.wYear = jsDate.getFullYear();
    systemtime.wMonth = jsDate.getMonth() + 1;
    systemtime.wDayOfWeek = jsDate.getDay();
    systemtime.wDay = jsDate.getDate();
    systemtime.wHour = jsDate.getHours();
    systemtime.wMinute = jsDate.getMinutes();
    systemtime.wSecond = jsDate.getSeconds();
    systemtime.wMilliseconds = jsDate.getMilliseconds();
    return systemtime;
}

//SYSTEMTIME構造体からjsDateへ変換
htalib.SYSTEMTIME2Date = function(systemtime){
    try{
        var jsDate = new Date();
        jsDate.setFullYear(systemtime.wYear);
        jsDate.setMonth(systemtime.wMonth - 1);
        jsDate.setDate(systemtime.wDay);
        jsDate.setHours(systemtime.wHour);
        jsDate.setMinutes(systemtime.wMinute);
        jsDate.setSeconds(systemtime.wSecond);
        jsDate.setMilliseconds(systemtime.wMilliseconds);
        return jsDate;
    }catch(e){
        return NULL;
    }
}

//Win32APIでシステムローカル時間設定
htalib.SetLocalTime = function(jsDate){
    if(!(jsDate instanceof Date)) return NULL;
    
    //jsDateからSYSTEMTIME構造体へ変換
    var systemtime = htalib.Date2SYSTEMTIME(jsDate);
    
    //変換成功ならAPI関数に構造体ポインタを渡す
    if(systemtime == NULL) return NULL;
    return SetLocalTime(systemtime); //API呼び出し
}

//Win32APIでシステムローカル時間取得
htalib.GetLocalTime = function(){
    var systemtime = new SYSTEMTIME();
    GetLocalTime(systemtime); //API呼び出し
    
    //SYSTEMTIME構造体からjsDateへ変換して返す
    var jsDate = htalib.SYSTEMTIME2Date(systemtime);
    return jsDate;
}


//設定
function set(mode){
    //現在時刻を基準に1分進める/戻す
    var setvalue = (mode ? 1 : -1) * 1000 * 60;
    var jsDate = new Date(new Date().getTime() + setvalue);
    
    //Dateを渡してシステムローカル時間を設定してもらう
    htalib.SetLocalTime(jsDate);
}

//取得
function get(){
    //Win32APIで取得したシステムローカル時間をDateオブジェクトで受け取る
    var jsDate = htalib.GetLocalTime();
    
    //現在日時を表示
    alert(jsDate.toLocaleDateString() + ' ' + jsDate.toLocaleTimeString());
}
</script>
</head>
<body>
<input type="button" value="1分進める" onclick="set(1)">
<input type="button" value="1分戻す" onclick="set(0)">
<input type="button" value="現在日時" onclick="get()">
</body>
</html>
スポンサーサイト
2008-09-10 18:40 | win32api.js | Comment(0) | Trackback(0)
Sleipnir2.8.1のサイトルート相対パスの解釈がおかしい
投稿日時 : 2008-09-10 11:56
 『SleipnirでGMarksもどきを実現してみる』と同じ手順で追加したRSSフィードが「通信エラーが発生しました」と表示されてデータが受信できない。
 
Sleipnir Gmarks Error
 
とりあえずSleipnir再起動したりしてみたけどダメだったので手順をワンステップごとに確認していくと追加フィードのURLがおかしいことを発見。
 
Sleipnir Gmarks URL 変
 
http://www.google.com/bookmarks//bookmarks/lookup?(...略)
なんだこれ?
 
以下のように修正。
http://www.google.com/bookmarks/lookup?(...略)
 
これで問題解決。
 

■原因はSleipnirのサイトルート相対パス解釈のバグ

 原因ですが、これはSleipnirのサイトルート相対パスの解釈がおかしいと思われます。Sleipnirの「フィードの追加」が見ているだろうlink要素のソースは以下のようになっています。
<link rel=alternate type="application/rss+xml" title="Google ブックマーク" href="/bookmarks/lookup?q=label:Win32API&hl=ja&num=1000&output=rss" />
href属性のURIが「/」から始まっているんだから、これはサイトルート相対パス(またはコンテキスト相対パス)と言われるやつでサイトルートである「http://www.google.com/」からの相対パスでなければなりません。これをドキュメント相対パスとして解釈しているものだからGoogleブックマークのドキュメントルートである「http://www.google.com/bookmarks/」の後ろにくっつけてしまって「http://www.google.com/bookmarks//bookmarks/」みたいなおかしなことになっていると思われます。
 
 昔は問題なかったわけだからいつかのアップデートで紛れ込んだっぽいですね。
 
2008-09-10 11:56 | Windows | Comment(0) | Trackback(0)
JavascriptでWin32APIが利用しやすくなる『win32api.js』
投稿日時 : 2008-09-10 02:33
 Javascript(JScript)からSFC mini経由でWin32APIを簡単に利用できるようにするwin32api.jsを作ったので公開します。win32api.jsをインポートするとWin32APIで定義されている定数6315個、構造体クラス412個、API関数2007個がグローバル変数として展開されます。これでCなどで書かれたWin32APIなコードを比較的簡単にHTAなどのJavascriptアプリに流用できそうです。
 

■経緯

 JavascriptやVBScriptからWin32APIを使用できるActiveX(COM)にSFC miniというものがあります。最近ウェブ上のWin32APIを使ったサンプルコードをこのSFC miniで試していました。はじめはHTAアプリでも普通のWin32なプログラムと同じことができるということにかなり感動していたんですが、数時間でCやらVBやらで書かれたサンプルコード中の定数の値を調べるのが苦痛になってきました。MSDNにも値はほとんど載ってません。で、もう定数は先に全部宣言してしまおうということに。
 正規表現でパパっと置換できそうな、定数名とその値がずらーっと書いてあるファイルなりページなりを探しているとここに置いてあるwin32api.exeに含まれているVB用のWIN32API.TXTがどうやら条件に該当しそうなことがわかったので早速置換作業開始。
 さくっと終わるかと思いきや16000行もある上に誤植だらけだったり書式がバラバラだったりで意外に苦戦しましたがまあできました。名前空間をどうするか悩んだけど利便性を優先してグローバルオブジェクト直下に。
 

■win32api.jsの概要

  • win32api.jsはWIN32API.TXTをSFCmini+Javascript用に変換したもの
  • win32api.jsをインポートするとWin32APIで定義されている定数、構造体クラス、API関数がグローバル変数として展開される
  • 現在定義されているのは 定数:6315個 / 構造体クラス:412個 / API関数:2007個(Alias関数を含む)
  • 動作保証一切なしの完全ベータ版
  • 修正・追記・改変・配布は自由
 そもそもWIN32API.TXTには多数の誤植があることが有名な上、基本的には正規表現で機械的に変換したものです。手動で修正したものもありますがすべてをチェックするのは行数的に気力が持ちません。何か気づいた点などありましたらメールやコメントなどで指摘していただけると助かります。修正・追記・改変・配布は自由に行ってもらって構いません。もちろん改変した旨をお知らせいただければありがたく利用させてもらいますw  

■win32api.jsダウンロード

 お約束ですが使用は自己責任でお願いします。win32api.jsが原因で発生したいかなる損害も作者itmstはその責任を負いません。動作保証も一切ありません。
 
win32api.js 0.01b (2008/09/10 02:14)
win32api.js_0.01b_20080910_0214.zip
 
ミラー:
win32api.js_0.01b_20080910_0214.zip
 
MD5:
DA78797BE35760A46127A0FD54E45EAD
テスト環境 : XPProSP3/2.66GHz/1GB/SFC mini1.0.1
 

■SFC miniのダウンロード

Vector
SFC mini(WindowsNT/2000/XP/Vista / プログラミング)
 

■win32api.jsで何が変わるか

 当初の予定では定数だけ定義するつもりでしたが、構造体クラスやAPI関数も定義してしまえば直接Win32APIを叩いている使用感にできることが分かったので全部やってしまいました。入れ子の構造体にも対応。まあつまりWin32APIのラッパーであるSFC miniのラッパーということでしょうか。
 で何が変わるかということですが、コードがかなり簡潔になります。例えばGetLocalTimeにSYSTEMTIME構造体のポインタを渡してローカル時間を取得してMessageBoxで表示する場合、従来のSFC miniを使ったコードは以下のようになります。
従来のコード
//SYSTEMTIME構造体定義
var SYSTEMTIME = new ActiveXObject("SfcMini.Structure")(
	"wYear","Integer",
	"wMonth","Integer",
	"wDayOfWeek","Integer",
	"wDay","Integer",
	"wHour","Integer",
	"wMinute","Integer",
	"wSecond","Integer",
	"wMilliseconds","Integer"
);
var GetLocalTime = new ActiveXObject("SfcMini.DynaCall"); //DynaCallオブジェクト生成
GetLocalTime.Declare("kernel32","GetLocalTime"); //GetLocalTime関数として宣言
GetLocalTime(SYSTEMTIME); //構造体のポインタを渡す
var MessageBox = new ActiveXObject("SfcMini.DynaCall"); //DynaCallオブジェクト生成
MessageBox.Declare("user32","MessageBox"); //MessageBox関数として宣言
var MB_OK = 0x00000000; //定数定義
var NULL = 0; //定数定義
MessageBox(NULL,SYSTEMTIME.wYear.toString(),"年表示",MB_OK);//「2008」と表示
これに対してwin32api.jsをインポートした後は以下のコードで同じことができます。
win32api.jsをインポートしたコード
var systemtime = new SYSTEMTIME(); //SYSTEMTIME構造体インスタンス
GetLocalTime(systemtime); //構造体のポインタを渡す
MessageBox(NULL,systemtime.wYear.toString(),"年表示",MB_OK);//「2008」と表示
煩雑な手順は全部win32api.jsが済ましてくれているのでこういうコーディングが可能になります。ちなみにソース見れば分かりますが構造体宣言のnew演算子は無くても可。でも気持ち的につけたいのでw。
 

■導入までの簡単な手順説明

 win32api.jsの各定義変数にアクセス可能になるまでの手順をHTAに組み込む場合を例に簡単に説明しておきます。まずSFCminiがインストール済みであることが前提。SFC miniをダウンロードして解凍、CPUに合わせてinstall-INTEL.vbsかinstall-AMD.vbsかどちらかを実行(要管理者権限)。SFCminiがインストールできたら後はwin32api.jsを
<script type="text/javascript" language="javascript" charset="shift-jis" src="win32api.js"></script>
などとしてロードする。これで使用準備は完了。定数、構造体クラス、API関数がグローバル変数として展開されています。
 

■サンプルコード完全版

以下は先ほどのシステム時間を表示するサンプルコードの完全版。
GetLocalTime.hta
<html>
<script type="text/javascript" language="javascript" src="win32api.js"></script>
<script type="text/javascript" language="javascript">
var systemtime = new SYSTEMTIME(); //SYSTEMTIME構造体宣言
GetLocalTime(systemtime); //構造体のポインタを渡す
MessageBox(NULL,systemtime.wYear.toString(),"年表示",MB_OK); //「2008」と表示
</script>
</html>
GetLocalTime Demo
 
[関連]
[win32api.js] システム時計を設定するHTA
 
 
2008-09-10 02:33 | win32api.js | Comment(0) | Trackback(0)
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。