Есть ли способ выбрать, какие файлы будут отображаться пользователю через стандартные диалоги OPENFILE?
Vista представила интерфейс: IFileDialog::SetFilter, который позволяет мне установить фильтр, который будет вызываться для каждого потенциального имени файла, чтобы увидеть, должно ли оно быть показано пользователю.
Microsoft удалила это в Windows 7 и не поддержала в XP.
Я пытаюсь настроить наш диалог Открыть файл, чтобы я мог контролировать, какие файлы отображаются для конечного пользователя. Эти файлы внутренне помечены кодом продукта - в самом имени файла нет ничего для фильтрации (следовательно, фильтры расширения файлов здесь бесполезны -= Мне нужно фактически опросить каждый из них, чтобы увидеть, находится ли он в дополнительном фильтре параметры, которые указали наши пользователи).
Я предполагаю, что Microsoft удалила интерфейс SetFilter, потому что слишком часто он был слишком медленным. Я могу представить всевозможные идеи, схожие с этой, которые не очень хорошо подходят для сетей и облачных хранилищ и всего, что у вас есть.
Однако мне нужно знать, есть ли альтернативный интерфейс, который выполняет ту же цель, или я действительно ограничен только просмотром расширения файла для целей фильтрации в моих диалоговых окнах файлов?
Следовать за:
Посмотрев далее на CDN_INCLUDEITEM, для которого требуется предварительная версия OPENFILENAME, я обнаружил, что это самый бесполезный API из всех возможных. Он фильтрует только объекты не-файловой системы. Другими словами, вы не можете использовать его для фильтрации файлов. Или папки. Те самые вещи, которые можно отфильтровать в 99,99% времени для открытия или сохранения файла. Невероятно!
Существует очень старая статья Пола ДиЛаскиа, в которой предлагается техника удаления каждого оскорбительного имени файла из элемента управления представления списка при каждом обновлении представления списка.
Однако из горького опыта я знаю, что представление списка может со временем обновляться. Если вы просматриваете большую папку (много элементов) или соединение немного медленное (сильно загруженный сервер и / или большое количество файлов), то файлы добавляются в диалоговое окно по частям. Таким образом, придется неоднократно отфильтровывать оскорбительные имена файлов.
Фактически, наш текущий настраиваемый диалог открытия файлов использует таймер, чтобы периодически просматривать список имен файлов в представлении, чтобы увидеть, существуют ли какие-либо файлы данного шаблона, чтобы включить другой элемент управления. В противном случае можно проверить наличие этих файлов, не найти ни одного, но через мгновение представление обновляется, чтобы иметь больше имен файлов, и никакие события не отправляются в ваш диалог, чтобы указать, что представление было изменено. Фактически, мой опыт с необходимостью писать и поддерживать код для диалоговых файлов с общими элементами управления на протяжении многих лет заключался в том, что Microsoft не очень понимает, как написать такую вещь. События являются неполными, отправляются в ненужные моменты времени, повторяются, когда в этом нет необходимости, и целых классов полезных уведомлений не существует.
К сожалению, я думаю, что мне, возможно, придется отказаться от этой идеи. Если кто-то не задумывается о том, как я мог бы успевать за спонтанно меняющимся видом, пока пользователь пытается с ним взаимодействовать (то есть было бы неловко удалять записи из представления списка и изменять визуальную позицию пользователя). или выделенные файлы, или положение прокрутки и т. д.)
2 ответа
Вам нужно инициализировать обратные вызовы для вашего CFileDialog. Затем вам нужно обработать код уведомления CDN_INCLUDEITEM, чтобы включить или исключить элементы.
Вы также можете проверить эту замечательную статью. Автор использует некоторые другие подходы в дополнение к обратным вызовам
Как вы уже обнаружили, начиная с Windows 7 больше невозможно отфильтровать файлы от отображения по содержимому, только по расширению файла. Однако вы можете проверить, что выбранные пользователем файлы приемлемы для вас, прежде чем разрешить закрытие диалогового окна, и, если это не так, отобразить окно сообщения для пользователя и оставить диалоговое окно открытым. Это лучшее, что вы сможете сделать, если не создадите свой собственный диалог.