...ing logging 4.0

はてなブログに移行しました。D言語の話とかいろいろ。

DFL: GetOpenFileName と GetSaveFileName

DFL の OpenFileDialog では GetOpenFileName が使われていて、SaveFileDialog では GetSaveFileName が使われています。それぞれ、表示されるダイアログがプレースバーがないタイプでした。

プレースバーがあるタイプのダイアログにするには OPENFILENAME 構造体の Flags メンバに OFN_EXPLORER を指定するのだと勘違いしてしばらくはまっていましたが、そうではありませんでした。 OFN_EXPLORERエクスプローラスタイルにするためのもので、上記のスタイルが既にエクスプローラスタイルでした。

オールドスタイルはこちら。

エクスプローラスタイルのダイアログには、さらに2種類あって、XP スタイルと Vista スタイルがあるようです。プレースバーがないのが XP スタイルです。

Vista スタイルにしたダイアログがこちら。

Vista スタイルにするためには、OPENFILENAME 構造体の Flags メンバに OFN_EXPLORER を指定するとともに、OFN_ENABLEHOOK を指定してはいけません。 フックプロシージャを有効にすると、強制的に XP スタイルになってしまいます。

互換性の理由から、 FlagsがOFN_ENABLEHOOKに設定され、lStructSizeがOPENFILENAME_SIZE_VERSION_400に設定されている場合、Places Bar は非表示になります。

公式には上記のように書いてありますが、Flags と lStructSize のいずれかがこのとおりになっている場合、プレースバーが表示されないようです。最初は AND 条件なのかと思いましたが、OFN_ENABLEHOOK を指定するだけで、プレースバーは非表示になりました。

さて、そうすると、プレースバーを表示した場合、フックプロシージャが使えませんので、ヘルプボタンを表示してもクリックしたことを検知できないのですが、ヘルプボタンの押下に限っては救済があります。

意味
OFN_SHOWHELP
0x00000010
ダイアログ ボックスに [ヘルプ] ボタンを表示します。hwndOwnerメンバーは、ユーザーが [ヘルプ] ボタンをクリックしたときにダイアログ ボックスが送信するHELPMSGSTRING登録メッセージを受信するウィンドウを指定する必要があります。ユーザーが [ヘルプ] ボタンを クリックすると、 Explorer スタイルのダイアログ ボックスがCDN_HELP通知メッセージをフック プロシージャに送信します。

ユーザーが [ヘルプ] ボタンをクリックしたときに、エクスプローラースタイルの [開く] または [名前を付けて保存] ダイアログ ボックスによって送信されます。
OFNHookProc フック プロシージャは、WM_NOTIFY メッセージの形式でこのメッセージを受信します。

これにより、OpenFileDialog と SaveFileDialog が備える helpRequest イベントは実装できます。多分、 GetDlgItem とかを駆使すれば、どのダイアログのヘルプボタンがクリックされたか突き止めることができるでしょう。

ただ、ファイルを選択するボタンを押下しても、CDN_FILEOK 通知メッセージをトラップすることができなかったので、どうやら fileOk イベントはこの方法では実装できないようです。

2つのイベントのうちヘルプボタンのクリックだけ対応しても中途半端なので、とりあえずエクスプローラスタイルのときはイベントハンドラが使えないことにしました。

条件付きではありますが、これで Vista スタイルのファイル選択ダイアログが使えるようになりました。

DFL のダウンロード

github.com

参考資料