ファイルを開くときや保存するとき、標準のファイルダイアログを使います。
Windows APIならGetOpenFileNameとGetSaveFileName、.NET FrameworkならOpenFileDialogとSaveFileDialog。
OpenFileDialogとSaveFileDialogはFileDialogのサブクラスであり、ほとんどの機能はこのFileDialogに実装されています。
そこで、まずは、FileDialogにある機能と、サブクラスで実装されている機能についてまとめてみましょう。
なお、メソッドは大したことがないので、ここではpublicプロパティのみに着目します。
FileDialogのプロパティ
名前 |
意味 |
AddExtension |
ユーザが拡張子を入力しなかったとき、デフォルトの拡張子を付加する。 |
CheckFileExists |
存在しないファイル名を入力すると警告を表示する。 |
CheckPathExists |
存在しないディレクトリ名を入力すると警告を表示する。 |
DefaultExt |
ユーザが拡張子を入力しなかったときに付加するデフォルトの拡張子。 |
DereferenceLinks |
ショートカットが選択されたとき、リンク先の実体を選択したことにする。 |
FileName |
選択したファイル名。複数選択した場合は最初のファイル名。 |
FileNames |
選択したすべてのファイル名。 |
Filter |
表示するファイルフィルタ。 |
FilterIndex |
初期状態で選択しておく、または、ユーザが選択したフィルタのインデックス。 |
InitialDirectory |
初期状態で表示しておくディレクトリ。 |
RestoreDirectory |
ダイアログを閉じたとき、カレントディレクトリを復元する。 |
ShowHelp |
ダイアログにヘルプボタンを表示する。 |
SupportMultiDottedExtensions |
ドットを複数含む拡張子をサポートする。 |
Title |
ダイアログのタイトル。 |
ValidateNames |
無効なファイル名を入力すると警告を表示する。 |
OpenFileDialogのプロパティ
名前 |
意味 |
MultiSelect |
ファイルの複数選択を許可する。 |
ReadOnlyChecked |
読み取り専用がチェックされている。 |
ShowReadOnly |
読み取り専用チェックボックスを表示する。 |
SaveFileDialogのプロパティ
名前 |
意味 |
CreatePrompt |
存在しないファイル名を入力すると、新しいファイルを作成するかどうか問い合わせる。 |
OverWritePrompt |
既に存在するファイル名を入力すると、上書きするかどうか問い合わせる。 |
さて、これらのプロパティはほとんどが、GetOpenFileNameとGetSaveFileNameで使用するOPENFILENAME構造体のメンバに対応しています。
ここでは特に、OPENFILENAME構造体のFlagsメンバに着目してみましょう。
OpenFileDialogとSaveFileDialogのプロパティに対応するものがないフラグは省略しています。中には、フラグの意味が反転しているものがあるので要注意です。
OPENFILENAME構造体のFlagsの意味(一部抜粋)
名前 |
意味 |
対応するプロパティ |
OFN_ALLOWMULTISELECT |
ファイルの複数選択を許可する。 |
MultiSelect |
OFN_CREATEPROMPT |
存在しないファイル名を入力すると、新しいファイルを作成するかどうか問い合わせる。 |
CreatePrompt? |
OFN_FILEMUSTEXIST |
存在しないファイル名を入力すると警告を表示する。 |
CheckFileExists? |
OFN_HIDEREADONLY |
読み取り専用チェックボックスを表示しない。 |
ShowReadOnly |
OFN_NOCHANGEDIR |
ダイアログを閉じたとき、カレントディレクトリを復元する。 |
RestoreDirectory |
OFN_NODEREFERENCELINKS |
ショートカットが選択されたとき、リンク先の実体を選択したことにしない。 |
DereferenceLinks |
OFN_NOVALIDATE |
無効なファイル名を入力したとき、警告を表示しない。 |
ValidateNames |
OFN_OVERWRITEPROMPT |
既に存在するファイル名を入力すると、上書きするかどうか問い合わせる。 |
OverWritePrompt? |
OFN_PATHMUSTEXIST |
存在しないディレクトリ名を入力すると警告を表示する。 |
CheckPathExists |
OFN_READONLY |
読み取り専用がチェックされている。 |
ReadOnlyChecked |
OFN_SHOWHELP |
ダイアログにヘルプボタンを表示する。 |
ShowHelp |
対応するプロパティの欄に?がついているものがあるのにお気づきでしょうか。
これは、一見してそのプロパティに対応するように見えるけれども、実はそうではないものです。Windows APIを知っている場合は注意が必要ですね。
順番に見て行きましょう。
- OFN_CREATEPROMPT
- CreatePrompt
- これは、Windows APIではGetOpenFileNameとともに使うフラグです。GetSaveFileNameとともに使っても何も起きません。
しかし、.NET Frameworkでは何故か、SaveFileDialogだけのプロパティになっています。
そもそも、存在しないファイルを新しく作るのがGetSaveFileNameやSaveFileDialogの主目的なので、こんなこと確認するまでもないと思うのですが、どうしてこうなっているのかは謎です。
ちなみに、OpenFileDialogでは、CheckFileExistsがfalseならば、存在しないファイル名を入力しても、何も警告は表示されません。
- OFN_FILEMUSTEXIST
- CheckFileExists
- これもやはり、Windows APIではGetOpenFileName専用のフラグです。存在するファイルしか開かせないというのは、きわめて自然な欲求です。
NET Frameworkでは、スーパークラスであるFileDialogのプロパティになっていることからもわかるように、OpenFileDialogでもSaveFileDialogでも有効です。
SaveFileDialogに使うと、既存のファイルを上書きすることしかできなくなります。それはそれで使い道はありそうに思えますが、ファイルリストの背景部分を右クリックして新規作成を選択すると、新しい空のファイルを作ることができるので、これに上書きすれば、新規作成と同じ効果が得られてしまいます。実装者は馬鹿ですね。
- OFN_OVERWRITEPROMPT
- OverWritePrompt
- 上書き確認という機能から、言うまでもなく、GetSaveFileName専用のフラグです。
このフラグをOFN_NOVALIDATEやValidateNamesと併用するときは注意が必要です。
Windows APIでは、OFN_NOVALIDATEフラグが立っていても、上書き確認は行われますが、.NET Frameworkでは、ValidateNamesがfalseだと行われません。
これにはハマりました。
この3つのフラグは、どうしてこのような仕様になっているのか、理解に苦しみます。どなたかご存知の方はいらっしゃいませんか?