route127の日記: Win32環境においてPerlでダイアログからファイルを複数選択する為のモジュール選択およびオプション指定
Win32::GUIではファイル選択ダイアログから複数選択できなさそうなのでWin32::FileOp使ったが、よく調べたらWin32::GUIでも出来た。
----------
Perlからファイル選択ダイアログを呼び出すのはWin32::GUIのGetOpenFileName使えば出来てワンライナで試すならこんな感じ。
perl -MWin32::GUI -e "print Win32::GUI::GetOpenFileName(-directory=>'.');"
ただこれだとファイルの複数選択ができない。
元々のWin32APIにあるGetOpenFileName関数であればOFN_ALLOWMULTISELECTフラグを立てることでファイルの複数選択が可能になるはずなのだが、どうもWin32::GUIのGetOpenFileNameその辺のオプションを受付けないように見えた。
そこでWin32::GUIではなくOFN_系のフラグを立てられるWin32::FileOpを使うことにした。
perl -MWin32::FileOp -e "$Win32::FileOp::BufferSize=131071;print OpenDialog {title=>'test',dir=>'.',filters=>['All files'=>'*'],options=>OFN_ALLOWMULTISELECT}"
ただこれだけだと見た目が古くなるのでお好みでOFN_EXPLORERフラグも。
perl -MWin32::FileOp -e "$Win32::FileOp::BufferSize=131071;print OpenDialog {title=>'test',dir=>'.',filters=>['All files'=>'*'],options=>OFN_ALLOWMULTISELECT && OFN_EXPLORER}"
activestateのBBSに載ってたがフラグはこんな感じで定義されているらしい。
use constant OFN_ALLOWMULTISELECT => 0x00000200;
use constant OFN_CREATEPROMPT => 0x00002000;
use constant OFN_EXPLORER => 0x00080000;
use constant OFN_HIDEREADONLY => 0x00000004;
use constant OFN_NODEREFERENCELINKS => 0x00100000;
use constant OFN_NOREADONLYRETURN => 0x00008000;
use constant OFN_OVERWRITEPROMPT=> 0x00000002;
試しにフラグを即値で書いてみると確かに動きはするが可読性よくない。
perl -MWin32::FileOp -e "$Win32::FileOp::BufferSize=131071;print OpenDialog {title=>'test',dir=>'.',filters=>['All files'=>'*'],options=>0x00080200}"
と、ここまで調べてからWin32::GUIのサンプルに-multiselオプションで複数選択出来る例が書かれていることに気付いた。
perl -MWin32::GUI -e "print Win32::GUI::GetOpenFileName(-directory=>'.',-multisel=>10);
-multiselの値が1でも1つのファイルしか選べないというわけではないらしい。
バッファ確保のヒントに使ってるっぽい。
Win32::FileOpだとその辺のメモリ管理は自分で$Win32::FileOp::BufferSize確保してね、と任せられているがWin32::GUIは自動で確保してくれるらしい。
とんでもなく長いファイル名をものすごく沢山扱う場合なんかには問題になりそう。
Win32環境においてPerlでダイアログからファイルを複数選択する為のモジュール選択およびオプション指定 More ログイン