ファイル選択ダイアログのフィルタパターンがダブって表示される事がある

※ C#向けに説明していますが、内部でWin32の GetOpenFileName / GetSaveFileName を使用しているプログラムが対象です。
　 フィルタの書式については、C++、その他各言語のスタイルに置き換えてお読み下さい。

---

ファイルを選択するダイアログを表示するとき、拡張子を絞り込むために

```csharp
OpenFileDialog.Filter = "音楽ファイル|*.mp3";
```

などと設定すると思いますが、Windows **ユーザー** の設定によっては、このフィルタパターンが表示される事があります。

違いをスクリーンショットで撮りました。OSは```Windows 7```です。
まずはPC購入時と同等の設定です。通常は次のように表示されます。
![P1]

そして、 **設定を変更した** 際の表示です。
![P2]

('ω')

じゃあ何の設定を変えたのかと言うと、これです。

![P3]

```登録されている拡張子は表示しない``` です。既定値は ```ON``` です。

この動作の違いを見て、「何の問題があるの？」という人と、
「えっじゃあアレやばくね」と思う人に分かれると思いますが、
今回の記事は後者の方々が対象になっています。前者の方は軽めに読んで下さい。

で、なにが「ヤバくね」なのかというと、

```csharp
OpenFileDialog.Filter = "音楽ファイル|*.mp3";
```

こうではなく、

```csharp
OpenFileDialog.Filter = "音楽ファイル (*.mp3)|*.mp3";
```

こういう風に書いているコードがありまして、
拡張子を常に表示させるようにするためのもので、自分も普通に使うようになってしまった書き方なのですが、
今回これが内部で上手く処理してくれているというのと、
あるパターンでダブって表示されてしまう事がわかりました。

何個かパターンを挙げてみましたので、自分のコードを確認しながらご覧下さい。

1. 拡張子でフィルタしている

    ```csharp
    OpenFileDialog.Filter = "実行ファイル (*.exe)|*.exe";
    ```
    ![P4]

    常に拡張子を表示させたい場合に使われるパターンです。
    ネット上でもよく見かけます。

2. ファイル名を限定している

    ```csharp
    OpenFileDialog.Filter = "特定実行ファイル (OnlyOne.exe)|OnlyOne.exe";
    ```
    ![P5]

    この記事を書くきっかけとなった、ファイル名を限定しているパターンです。ダブりました。

3. 拡張子が無い

    ```csharp
    OpenFileDialog.Filter = "MOTDファイル motd|motd";
    ```
    ![P6]

    これもダブりましたね。何気に括弧が外れていますが、
    付けても```(motd) (motd)```になるのは確認済みです。

4. フィルタはしていないが、選択するファイル名を表示している

    ```csharp
    OpenFileDialog.Filter = "特定実行ファイル (OnlyOne.exe)|*.exe";
    ```
    ![P7]

    特定と言いつつ、表示されるのは全てのEXEファイルというよくわからないパターン。
    実際には無いと思いますが、これはダブって表示されてしまいます。

5. フィルタはしているが、ユーザーには任意のファイルを選ばせるように表示している

    ```csharp
    OpenFileDialog.Filter = "特定実行ファイル (*.exe)|OnlyOne.exe";
    ```
    ![P8]

    ユーザーにはなんでも良いよと言いつつファイル名は限定するというパターン。何がしたいのか。
    実際には無いとは思いますが、これはダブりませんね。なんとなく動きが解ってきた気がします。

6. フィルタが間違っている

    ```csharp
    OpenFileDialog.Filter = "実行ファイル (*.exe)|*.txt";
    ```
    ![P9]

    フィルタと一致していないので表示されるかと思いましたが、表示側が優先されるようです。
    挙動を確認するために挙げましたが、ジョークソフト以外では見る機会は無さそうです。

---

表示文字列に拡張子が含まれていれば、フィルタパターンは表示されないようです。
上記に無い、複数の拡張子が含まれているケースですが、これも上の結果と同じのようです。

この前初めて知って衝撃を受けたのですが、幸い自作のソフトには問題ありませんでした。

パターンを細かく調べた訳では無いので、教えて頂ければ追記していきます。

[P1]: https://qiita-image-store.s3.amazonaws.com/0/12642/b3a30e3b-e7e8-ccb6-324f-94e89d6336ec.png ""音楽ファイル|*.mp3" (登録されている拡張子は表示しない - ON)"
[P2]: https://qiita-image-store.s3.amazonaws.com/0/12642/2e4d447f-8186-9576-aebd-57f29b367226.png ""音楽ファイル|*.mp3" (登録されている拡張子は表示しない - OFF)"
[P3]: https://qiita-image-store.s3.amazonaws.com/0/12642/62913844-d3c7-bccb-5259-7a59618eca7a.png "フォルダー オプション - 表示"
[P4]: https://qiita-image-store.s3.amazonaws.com/0/12642/3095bc4a-5e4e-7c91-d0f6-b0a699e41229.png ""実行ファイル (*.exe)|*.exe" (登録されている拡張子は表示しない - OFF)"
[P5]: https://qiita-image-store.s3.amazonaws.com/0/12642/35b62a04-ed6a-8f98-3765-10cc52ccdf2e.png ""特定実行ファイル (OnlyOne.exe)|OnlyOne.exe" (登録されている拡張子は表示しない - OFF)"
[P6]: https://qiita-image-store.s3.amazonaws.com/0/12642/c122e269-203f-a8d9-4194-90462eb304df.png ""MOTDファイル motd|motd" (登録されている拡張子は表示しない - OFF)"
[P7]: https://qiita-image-store.s3.amazonaws.com/0/12642/be8d89ea-64e1-8a07-bcff-fdda16ffdc8c.png ""特定実行ファイル (OnlyOne.exe)|*.exe" (登録されている拡張子は表示しない - OFF)" 
[P8]: https://qiita-image-store.s3.amazonaws.com/0/12642/ac141d56-06cb-13e7-c5e4-6132ccc19e14.png ""特定実行ファイル (*.exe)|OnlyOne.exe" (登録されている拡張子は表示しない - OFF)"
[P9]: https://qiita-image-store.s3.amazonaws.com/0/12642/1541c1ef-5474-5ec9-8adc-10a53c0e6b22.png ""実行ファイル (*.exe)|*.txt" (登録されている拡張子は表示しない - OFF)"