Скрыть расширения в Vista / Windows 7 WPF FileDialog.Filter - PullRequest
6 голосов
/ 20 апреля 2011

Я использую WPF OpenFileDialog и SaveFileDialog в моем приложении .NET 4 WPF.Я использую свойство Filter, чтобы позволить пользователю устанавливать различные фильтры файлов.В .NET 4 для этого используются собственные диалоговые окна файлов, представленные в Windows Vista (если это возможно).

Однако в этих диалоговых окнах показаны расширения, составляющие фильтры файлов.Поскольку некоторые из них используют довольно много расширений, это довольно уродливо.

Например, у меня есть фильтр Image files|*.bmp;*.dib;*.jpg;*.jpeg;*.jpe;*.jfif;*.gif;*.tif;*.tiff;*.png;*.ico|All files|*.*, который отображается в диалоге как Image files (*.bmp;*.dib;*.jpg;*.jpeg;*.jpe;*.jfif;*.gif;*.tif;*.tiff;*.png;*.ico).Все в скобках добавляется автоматически, т.е. в соответствии со строкой фильтра должно отображаться Image files.Но где-то материал в скобках добавляется.Я попытался просмотреть код с помощью Reflector, чтобы увидеть, выполняется ли он где-нибудь, но быстро сдался, поскольку он довольно запутанный.

При запуске Paint, например, я вижу, что можно использовать эти диалоговые окна файловбез содержимого в скобках, т.е. он показывает Image files.

Кто-нибудь знает обходной путь для этой "функции"?

Ответы [ 3 ]

5 голосов
/ 21 апреля 2011

Вы на правильном пути.Существует два способа отображения диалога открытия файла.Более новый метод использует IFileOpenDialog (который расширяет IFileDialog ).С помощью этого метода описания фильтров и спецификации файлов определяются с использованием структуры COMDLG_FILTERSPEC .Это позволяет разделить их на собственные поля, что является более естественным.

Если вы хотите удалить спецификации файла из поля со списком, используя этот метод, то вам придется либо добавить свой собственный элемент управления, либо манипулироватьполе со списком управления в диалоговом окне.Это может привести к путанице, но должно быть выполнимо.

В старом школьном методе используются GetOpenFileName и структура OPENFILENAME .Уловка с этим, то, что это может показать диалоговое окно со старым взглядом или новым взглядом.Внешний вид определяется настройками в структуре OPENFILENAME, как описано здесь .

Проблема с WinForms OpenFileDialog заключается в том, что они либо используют IFileOpenDialog, когда, например, AutoUpgradeEnabled имеет значение true, а GetOpenFileName с параметромболее старый взгляд, когда AutoUpgradeEnabled имеет значение false.

Версия WPF не дает вам выбора, но по-прежнему использует ту же логику, что и WinForms, но выполняет ее автоматически по мере необходимости.Это верно для WPF в .NET 4, в предыдущих версиях он просто использовал GetOpenFileName со старым внешним видом.

Paint, скорее всего, использует GetOpenFileName с новым внешним видом.Вот пример C #:

private delegate IntPtr WndProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);

private const int OFN_ALLOWMULTISELECT = 0x00000200;
private const int OFN_CREATEPROMPT = 0x00002000;
private const int OFN_DONTADDTORECENT = 0x02000000;
private const int OFN_ENABLEHOOK = 0x00000020;
private const int OFN_ENABLEINCLUDENOTIFY = 0x00400000;
private const int OFN_ENABLESIZING = 0x00800000;
private const int OFN_ENABLETEMPLATE = 0x00000040;
private const int OFN_ENABLETEMPLATEHANDLE = 0x00000080;
private const int OFN_EXPLORER = 0x00080000;
private const int OFN_EXTENSIONDIFFERENT = 0x00000400;
private const int OFN_FILEMUSTEXIST = 0x00001000;
private const int OFN_FORCESHOWHIDDEN = 0x10000000;
private const int OFN_HIDEREADONLY = 0x00000004;
private const int OFN_LONGNAMES = 0x00200000;
private const int OFN_NOCHANGEDIR = 0x00000008;
private const int OFN_NODEREFERENCELINKS = 0x00100000;
private const int OFN_NOLONGNAMES = 0x00040000;
private const int OFN_NONETWORKBUTTON = 0x00020000;
private const int OFN_NOREADONLYRETURN = 0x00008000;
private const int OFN_NOTESTFILECREATE = 0x00010000;
private const int OFN_NOVALIDATE = 0x00000100;
private const int OFN_OVERWRITEPROMPT = 0x00000002;
private const int OFN_PATHMUSTEXIST = 0x00000800;
private const int OFN_READONLY = 0x00000001;
private const int OFN_SHAREAWARE = 0x00004000;
private const int OFN_SHOWHELP = 0x00000010;

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public class OPENFILENAME_I {
    public int lStructSize;
    public IntPtr hwndOwner;
    public IntPtr hInstance;
    public string lpstrFilter;
    public IntPtr lpstrCustomFilter;
    public int nMaxCustFilter;
    public int nFilterIndex;
    public IntPtr lpstrFile;
    public int nMaxFile = 260;
    public IntPtr lpstrFileTitle;
    public int nMaxFileTitle = 260;
    public string lpstrInitialDir;
    public string lpstrTitle;
    public int Flags;
    public short nFileOffset;
    public short nFileExtension;
    public string lpstrDefExt;
    public IntPtr lCustData;
    public WndProc lpfnHook;
    public string lpTemplateName;
    public IntPtr pvReserved;
    public int dwReserved;
    public int FlagsEx;
}

[DllImport("comdlg32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern bool GetOpenFileName([In, Out] OPENFILENAME_I ofn);

private void ShowOpenFileDialog() {
    OPENFILENAME_I ofn = new OPENFILENAME_I();
    ofn.lStructSize = Marshal.SizeOf(typeof(OPENFILENAME_I));
    ofn.lpstrFilter = "Text Files (*.txt)\0*.txt\0All Files\0*.*\0\0";
    ofn.nFilterIndex = 0;
    //ofn.Flags = OFN_EXPLORER | OFN_ENABLEHOOK | OFN_ENABLESIZING | OFN_NODEREFERENCELINKS | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
    ofn.Flags = OFN_ENABLESIZING | OFN_NODEREFERENCELINKS | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
    GetOpenFileName(ofn);
}

Вы можете попробовать добавить обратно флаги OFN_EXPLORER и / или OFN_ENABLEHOOK, и он вернется к старому виду.Но, как есть, приведенный выше код будет отображать диалог открытия файла с All Files, не показывающий его спецификацию файла.

1 голос
/ 03 мая 2011

Возможно, вы захотите отправиться сюда ...

Скрыть расширения

1 голос
/ 21 апреля 2011

После нескольких испытаний я получил следующий результат: FileDialog в WPF вызывает собственный метод IFileDialog :: SetFileTypes со строками, определенными фильтром.В зависимости от опции Windows, чтобы скрыть расширение для известных типов файлов (в настройках папки Windows Explorer), расширения добавляются автоматически или нет.

Теперь остается только вопрос, как Paint может не отображатьрасширения для «файлов изображений» в диалоге открытия файла.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...