Entry

HTAからWin32APIにマルチバイト文字を渡す

とあるHTAプログラムを作成中、Windows XP以降のエクスプローラと同様のファイル名ソートをする事になった。そのためには、shlwapi.dllに含まれるStrCmpLogicalWという関数を使用する必要がある事が分かった。
ところが、ここで問題となるのがHTAから、このようなwin32apiを呼び出す方法。調べてみたところ、以下のサイトが参考になった。

コマンドラインからマウスを操作する方法 (rundll32.exeで動くDLLの作成法) – 主に言語とシステム開発に関して
コマンドプロンプトから,Win32 APIや任意のDLLを呼び出して実行しよう (コマンドプロンプトから画面キャプチャする方法の仕組みを理解) – 主に言語とシステム開発に関して

個人的に、外部ライブラリを新たに追加する方法は除外。管理が面倒だし、スクリプトファイル単体でお手軽に使いたいから。また、今回は戻り値の取得が必要なので、戻り値の取得できないrundll32.exeを使用する方法は使えない。そんなわけで、今回は上記サイトにある「(3)VBAのCALL関数を,WSHやコマンドプロンプトから呼び出す」を採用。いやまぁ、Excelが必要じゃないかというツッコミ所があるのだけど、今回使用する環境ではOfficeがインストールされている可能性が高いのでその辺は妥協。

で、VBAのCALL関数を使って以下のように変数AとBの文字列を比較してみた。

Excel.ExecuteExcel4Macro( "CALL(\"shlwapi\", \"StrCmpLogicalW\", \"JCC\", \"" + A + "\", \"" + B + "\")" );

ところがこれは上手くいかなかった。正確に言うと、マルチバイト文字で正しく動作していなかった。理由を色々調べてみると、どうもCALL変数に渡すデータ型の指定が良くないようだ。CALL 関数と REGISTER 関数の使い方 – Excel – Office.com

更に調べていくと、マルチバイト用のデータ型指定という物が存在する事が分かった。ただし、Excel 2007以降のみ。

Excel 2007 のアドイン (XLL) の開発
Excel XLL CALL REGISTER DataTypes | Smurf on Spreadsheets

それによると、マルチバイト文字はデータ型C, Fの後ろに「%」をつけてC%、F%となるそうな。そんなわけで、修正後は以下のようになる。

Excel.ExecuteExcel4Macro( "CALL(\"shlwapi\", \"StrCmpLogicalW\", \"JC%C%\", \"" + A + "\", \"" + B + "\")" );

これで日本語でも正しくエクスプローラ同様のソートが行えるようになった。多分。
ちなみに、JavaScriptでソートする場合は以下のような感じ。

items.sort( function(A, B) {
	return Excel.ExecuteExcel4Macro( "CALL(\"shlwapi\", \"StrCmpLogicalW\", \"JC%C%\", \"" + A + "\", \"" + B + "\")" );
});

Comments (0 件)

コメントを残す

メールアドレスが公開されることはありません。