mousecursorの初期化

2chNScripterスレ(18)で、mousecursor命令によってマウスカーソルを変更した後、デフォルトに戻すにはどうすればよいか、と言う疑問が呈された。
これについてつらつらと考えたことについて、記す。
まず、デフォルトで存在する命令で戻すことはできないようだ。
これはそもそも、ゲームの統一されたデザインの一部としてマウスカーソルを変更するためであり、戻すことを想定していないためだと思われる。
そこで、戻すための手法を二つ考えた。

  1. デフォルトの*.curを取得する。
  2. mousecursorを使わずに外見上マウスカーソルを変更したように見せかける。

先に2について説明する。

つまるところ、mousemode命令によってデフォルトのマウスカーソルを非表示にしておいて、スプライト(重ねあわせを考えると0番が最適)をマウスカーソルとして扱う手法である。
nsluaのluacall animationを使用して、細かい時間単位内で「非表示にしたマウスの位置取得→その位置にマウススプライトを移動→再描画」を繰り返すことになる。
デフォルトのマウスカーソルに戻すのは、mousemodeでマウスカーソルを再表示、マウススプライトを非表示にするだけで済む。
ただし、luacall animationのタイミングや、bexecなどの入力系、時間をかけたprint系との兼ね合いがあるため、安定したシステムを作るのは苦労するかもしれない。
mousecursor命令が非推奨だった時期にやろうと思ったら、これしかないのだが。

1について説明する。

実は、デフォルトのマウスカーソルのファイル名を取得する方法は存在する。
マウスカーソルのファイル名はレジストリに記述されているので、それをgetreg命令によって取得すればよい。

getreg $0,"Control Panel\Cursors","Arrow"

このようにすれば、デフォルトの状態のマウスカーソルのファイル名が、$0の中に入る。これをあらかじめ取得しておけば一件落着、とはいかない。
実際に取得すると、この中身がこのようになっている場合が多い。

%SystemRoot%\cursors\aero_arrow.cur

%SystemRoot%の部分は、環境変数と言う奴で、それぞれのマシンによって違う値が割り当てられている。実際のところ、C:\Windowsであることがほとんどだろうが、なかにはC以外にインストールしていたりする猛者もいるかも知れないので、環境変数を動的に取得するのがプログラマとしての義務ではある。
で、環境変数を取得する方法もまた、二つ考えられる。

  1. NScripterWindowsバッチファイルで行う。
  2. DLL、プラグインを使う。

ここでもまた、2から説明する。

Windowsプログラミングをしていれば全くの初歩だが、たとえば、
.NET TIPS Windowsフォルダのパスやドライブ名を取得するには? - C# VB.NET - @IT
こう言ったページを参照にして、Windows APIを叩くプラグインを作れば、一発で取得できる。
ただし、言うまでもないが、これはNScripterプラグインを作る能力が前提になる。
※加えて、プラグインが作れるなら最初からプラグインで全部やってしまえばいいんじゃ、と言う話でもある。

1を説明する。

環境変数は、Windowsのシェルに以下のスクリプトを投げれば、実値に変換して取得できる。

echo %SystemRoot%\cursor\cursor.cur

取得しやすいように、最後にファイルに出力するといいだろう。

echo %SystemRoot%\cursor\cursor.cur > env.txt

こうすれば、変換した内容がenv.txtに格納されるので、それをNScripterから読み出せばいい。
そこで、環境変数が含まれる文字列を渡すと、それを実値に変換してから返す命令、env_readを作成するスクリプトを作ってみた。

Aパート

define節、game以上に記述する。

stralias env_bat,"env.bat"
stralias env_shortcut,"env.vbs"
stralias env_res,"env.txt"
numalias env_exist,%0:inc %0
numalias env_res,%0:inc %0
defsub env_read
Bパート

start節、end以下に記述する。

*env_read
	getparam s%env_res,$env_exist ; 環境変数を含むと思われる文字列を期待している。

	fileremove env_res ; 初期化

	; env.batを作成
	csvopen env_bat,"w"
	csvwrite "echo "+$env_exist+" > "+env_res
	csvclose

	; 作成したenv.batを実行
	shell env_shortcut
	
	; 結果が出るまで待機
	fileexist %env_exist,env_res
	if %env_exist=0 wait 1:skip -1

	; 結果を取得
	csvopen env_res,"r"
	csvread $%env_res
	csvclose

	fileremove env_res ; 初期化
return
Cパート

nscr.exeと同じディレクトリに適当なテキストを作り、以下の内容を記述して保存した後、ファイル名を"env.vbs"にする。

Set ws = CreateObject("Wscript.Shell")
ws.run "cmd /c env.bat",vbhide
説明
env_read $0,$1

このようにする。$1には、環境変数を含む(含まなくてもいい。その場合、何も変換はなされない)文字列を与える。
変換された値が$0に入ってくる。

問題点

もしかしたら、セキュリティとかの問題でユーザー環境では実行できないこともあるかもしれないけどどうだろう。
後、実際にデフォルトのマウスカーソルに変更してみたら、なんかおっきくなった。大きさのパラメータのどっかにあるみたいだけどよくわからん。