スポンサーサイト
投稿日時 : -------- --:--
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
-------- --:-- | スポンサー広告
Firefoxの右クリックメニューからSleipnirで開く
投稿日時 : 2008-09-21 23:11
 このあたりを参考にuserChrome.jsを導入。この解説の中で右クリックメニューから現在開いているページをIEで開く「LaunchIE」が紹介されていたが、同じTridentエンジンならSleipnirで開きたいのでLaunchIE.uc.jsをちょこっと改造してLaunchPnir.uc.jsを作ってみた。userChrome.jsとSub-Script/XUL Loaderなどのサブスクリプトローダの導入が完了していることが前提です。
 

■LaunchPnir.uc.jsのダウンロード

 

■sleipnir.exeのパスの設定

 ダウンロードしたらsleipnir.exeのパスをソース内5行目の「Sleipnir_Path: ""」のところに記述してください。円マーク(バックスラッシュ)はエスケープすることに注意。
/* :::::::: LaunchPnir (cf. IE View) ::::::::::::::: */

var LaunchPnir = {
	//input the path of sleipnir.exe
	Sleipnir_Path: "",
(省略)
たとえばこんな感じになります。
/* :::::::: LaunchPnir (cf. IE View) ::::::::::::::: */

var LaunchPnir = {
	//input the path of sleipnir.exe
	Sleipnir_Path: "C:\\Program Files\\Sleipnir\\bin\\Sleipnir.exe",
(省略)
 同じような要領で他のプログラムのパスを指定すればSleipnir以外のものでもURLを渡して起動することができます。
 

■コンテキストメニューの表示名に日本語を使う

 デフォルトではコンテキストメニュー(右クリックメニュー)には「LaunchPnir」と表示されますが、これを「Sleipnirで開く」と日本語で表示したい場合は以下の箇所を
(省略)
	init: function()
	{
		this.mItem = document.createElement("menuitem");
		this.mItem.setAttribute("label", "LaunchPnir");
(省略)
こんな感じにします。
(省略)
	init: function()
	{
		this.mItem = document.createElement("menuitem");
		this.mItem.setAttribute("label", "Sleipnir\u3067\u958B\u304F");
(省略)
日本語をそのまま書くと文字化けするのでUnicodeエスケープしたものを記述します。  

■chromeフォルダに移動

 編集が終わったらchromeフォルダに移動させてください。chromeフォルダのパスは環境によって異なりますがだいたい以下のような感じじゃないかと。
C:\Documents and Settings\[ユーザ名]\Application Data\Mozilla\Firefox\Profiles\[ランダムな英数字].default\chrome\LaunchPnir.uc.js
 

■右クリックメニューからLaunchPnirを選択

 Firefoxを再起動させて適当なページを開いたら右クリックメニューから「LaunchPnir」を選択して下さい。
LaunchPnri demo
 
現在Firefoxで開いているページがSleipnirで開いたハズです。
 
メニューを日本語化した場合は以下のような感じになっているかと。
 LaunchPnir Japanese menu
 
 
スポンサーサイト
2008-09-21 23:11 | Javascript | Comment(8) | Trackback(0)
中央管理型イベントマネージャ『evtmgr.js』 0.04 beta
投稿日時 : 2008-09-17 15:56
 Javascriptのメモリリークレスな中央管理型イベントマネージャのevtmgr.jsのバージョン0.04betaを公開します。今バージョンで複数ウィンドウのイベントを親ウィンドウで中央管理できるようになりました。また、ウィンドウ単位でのイベント全削除にも対応。
 
このページの情報は古くなっている可能性があります。evtmgr.jsに関する最新情報はカテゴリ:evtmgr.jsを参照して下さい。
 

■evtmgr.js の特徴

 初期バージョンから徹底していることはすべてのイベント管理をevtmgrというObject一つで完結させることです。親ウィンドウにevtmgrというグローバル変数を1つ追加し、HTMLElementにイベントハンドラーを追加する以外、いかなる名前空間の汚染、仕様外のプロパティ追加などを行わない、イベントの完全な中央管理を実現しています。その他詳細は [Javascript] 中央管理型イベントマネージャ 『evtmgr.js』ドキュメントデモを参照してください(*ドキュメントとデモは現時点では0.03beta用のままです。)。
 

■evtmgr.js 0.04 beta 変更点

  • 複数ウィンドウのイベントが中央管理可能に。
  • 登録オブジェクトにwinプロパティ追加。
  • winプロパティを使ってウィンドウ単位でのイベント検索やイベント全削除が可能に。
  • isGarbage()メソッド追加。登録オブジェクト単体でのガーベッジ判定をプログラマが任意のタイミングで実行可能に。
  • isOverlap()メソッド追加。重複登録チェックをプログラマが任意のタイミングで実行可能に。
  • 重複登録チェックが少し高速化。
  • 0.03betaで追加されたrepaer()メソッド及びlifeプロパティ廃止。
登録オブジェクトのwinプロパティには、add()メソッドでのイベント登録時にelemプロパティに指定されたHTMLElementオブジェクトが所属する実行コンテキストのグローバルオブジェクト(各ウィンドウのWindowオブジェクト)が自動的に格納されます。登録時に設定しても上書きされます。
 

■evtmgr.js 0.04 beta のダウンロード

 使用は自己責任でお願いします。evtmgr.jsが原因で発生したいかなる損害に対しても作者itmstはその責任を負いません。
 
最新バージョンはカテゴリ:evtmgr.jsを参照して下さい。
 
evtmgr.js 0.04 beta (2008/09/17 20:03) 動作確認:Firefox 3.0.1 / Firefox 2.0.0.14 / Opera 9.52 / Safari 3.1.2 / IE 7.0 / IE 6.0 / IE 5.5 / Mozilla 1.8b / NN 9.0.0.5
 

■新機能を使ったサンプルコード

 0.04betaから追加した機能を使ったサンプルコードを載せておきます。
 
子ウィンドウを閉じる前に子ウィンドウのイベントを全削除する
//子ウィンドウを生成して参照を得る
var child = window.showModelessDialog("child.hta");

//イベント登録
evtmgr.add({
	type:"unload",
	elem:child,
	func:function(){evtmgr.selectRemove({win:child})},
	inst:child
});
子ウィンドウのWindowオブジェクトのchildでunloadイベントが発生したら、条件に一致するイベントを一括削除するselectRemove()メソッドに、winプロパティにchildが設定された条件指定用のオブジェクトを渡すようにイベント登録。これで子ウィンドウに設定したイベントはunloadイベント発生時に全て削除されます。このように複数のウィンドウのイベントを中央で管理できるようになりました。
 
子ウィンドウの中の0番目の"onclick"イベントを削除する
//登録イベントを検索して結果(Array)をfoundに格納
var found = evtmgr.find({
	type:"click",
	win:child
});

//結果が0件でないなら0番目のイベントを削除
if(found.length){
	evtmgr.remove(found[0]);
}
検索条件指定Objectのwinプロパティにchildとイベントタイプclickを設定してfind()メソッドに渡すと子ウィンドウ中のclickイベントを含む登録オブジェクトへの参照Arrayが返る。この0番目の登録オブジェクトをremove()メソッドに渡してイベントを削除する。
 
ガーベッジ化したイベントかどうか調べる
<div id="mOverDiv">マウスオーバー</div>
<script>
var moverdiv = document.getElementById("mOverDiv");
function mOver(){alert('onmouseover!')}
var regObj = evtmgr.add({
	type:"mouseover",
	elem:moverdiv,
	func:mOver,
	inst:window
});
//ガーベッジ判定
alert(evtmgr.isGarbage(regObj)); //「false」と表示

//エレメントを削除してイベントをガーベッジ化させる
moverdiv.parentNode.removeChild(moverdiv);

//ガーベッジ判定
alert(evtmgr.isGarbage(regObj)); //「true」と表示

//削除
evtmgr.remove(regObj);

</script>
イベント登録後にelemプロパティが参照しているHTMLElementが消えた場合、今後イベントが発生する可能性が全くないガーベッジ(ゴミ)になる。isGarbage()メソッドに登録オブジェクトを渡してみて、ガーベッジ化しているかどうか判定できる。ガーベッジ化している場合はこのサンプルコードのように個別に削除するか、GC(ガーベッジコレクション)を実行するgc()メソッドを呼び出せばよい。GCはgcAutoStart()メソッドで自動実行させることもできる。
 
 
重複登録かどうかチェックする
//登録オブジェクト生成
var regObj1 = {
	type:"keydown",
	elem:document,
	func:showKeyCode,
	inst:window
};

//イベント登録
evtmgr.add(regObj1);

//まったく同じ条件の登録オブジェクトを新たに生成
var regObj2 = {
	type:"keydown",
	elem:document,
	func:showKeyCode,
	inst:window
};

//重複登録チェック
if(evtmgr.isOverlap(regObj2)){
	alert("重複したイベントです");
}
まったく同じ構成での重複登録はデフォルトでは許可されません。isOverlap()メソッドに登録しようとしているObjectを渡してみて重複かどうか判定できます。ちなみにevtmgr.overlap = true;とすればaddメソッド時の自動重複チェックが実行されなくなります。正しく設計されたプログラムなら重複してイベントを登録することはないと思われるので、登録時の負荷軽減のために重複を許可する方がよい。
 
 
2008-09-17 15:56 | evtmgr.js | Comment(0) | Trackback(0)
USBメモリをNTFSでフォーマットする
投稿日時 : 2008-09-15 01:50
 PATRIOT X-Porter BOOST USB2.0 8GBで2GB以上4GB未満のファイルを読もうとするとCRCエラーが出ることが何度かあった。デフォルトのファイルシステムのFAT32の4GB制限に引っかかっているわけではないのは確かなので、あとは物理的な故障の可能性が高いけどなんとなくFAT32がダメな気がしてw、NTFSにフォーマットしてみようと思い立った。が、ドライブの右クリックメニューのフォーマットにはFAT32しか選択肢がない。調べるとこんなのが見つかった。
 
リムーバブルメディアの NTFS フォーマットについて
 
要するに「ハードウェアの安全な取り外し」を使わずにリムーバブルメディア引っこ抜く人がたくさんいるのでデータ破損を避ける為に遅延書き込みなNTFSフォーマットには簡単に変換できないようにしときましたということらしい。
 

■設定

 以下の設定をすればいいらしい。
リムーバブルメディアの NTFS フォーマットについて
[マイコンピュータ] よりドライブを選択し、 [プロパティ] -> [ハードウェア] -> [全ディスク ドライブ] から当該リムーバブルドライブをあらためて選択し、 [プロパティ] -> [ポリシー] の [書き込みキャッシュと安全な取り外し] のオプションを「クイック削除のために最適化する」から「パフォーマンスのために最適化する」に変更します。
 
usb memory setting 1
 

■NTFSフォーマット実行

 これだけでドライブ右クリック - フォーマットでNTFSが選択できるようになっています。既存データは削除されるのでバックアップは忘れずに。
 
format ntfs
 

■Acronis Disk Director Suite使えば設定なしでいける

 後になって気づきましたがAcronis Disk Director Suite 10.0使えば何もせずにNTFSフォーマットできますね。ただしDisk Directorでも既存のデータを保ったままのフォーマットはできないようです。
 
acronis disk director
 

■「クイック削除のために最適化する」に戻す

 やっぱりリムーバブルメディアはいつでもリムーバブルでありたいのでさっき「パフォーマンスのために最適化する」に設定したのを「クイック削除のために最適化する」に戻しておく。
 

■その後の経過

 NTFSフォーマット後今のとこCRCエラー問題は再現していませんが、やはり物理故障の可能性も十分あるのでもうちょっと様子見。
 
 
2008-09-15 01:50 | Windows | Comment(0) | Trackback(0)
[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ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。