Шаг 140 - Cтруктура OPENFILENAME

Для вызова стандартных диалогов открытия и сохранения файла в MFC есть класс CFileDialog. В WinAPI существуют соответствующие функции вызова этих диалогов.

Вызов стандартного диалога для открытия файла осуществляется с помощью функции GetOpenFileName

BOOL GetOpenFileName(

    LPOPENFILENAME lpofn 
		// адрес структуры с данными 
		//для инициализации диалога 
   );
Вызов стандартного диалога для сохранения файла осуществляется с помощью функции GetSaveFileName
BOOL GetSaveFileName(

    LPOPENFILENAME lpofn
		// адрес структуры с данными для инициализации диалога
   );
где:

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

Если пользователь указал какое-либо имя файла(несколько имен) и нажал кнопку OK, то возвращается ненулевое значение. При этом, выбранные имена, путь и т.д. и т.п. можно почерпнуть из все той же структуры типа OPENFILENAME.

Если же пользователь жмет на кнопку "Отмена", закрывает окно или происходит какая-то ошибка в ходе выполнения функции, то возвращаемое значение будет 0. Для получения дополнительной информации об ошибках в процессе выполнения функции используется функция CommDlgExtendedError

А теперь, пожалуй, самое интересное и важное - сама структура OPENFILENAME:

typedef struct tagOFN { // ofn  
    DWORD         lStructSize; 
    HWND          hwndOwner; 
    HINSTANCE     hInstance; 
    LPCTSTR       lpstrFilter; 
    LPTSTR        lpstrCustomFilter; 
    DWORD         nMaxCustFilter; 
    DWORD         nFilterIndex; 
    LPTSTR        lpstrFile; 
    DWORD         nMaxFile; 
    LPTSTR        lpstrFileTitle; 
    DWORD         nMaxFileTitle; 
    LPCTSTR       lpstrInitialDir; 
    LPCTSTR       lpstrTitle; 
    DWORD         Flags; 

    WORD          nFileOffset; 
    WORD          nFileExtension; 
    LPCTSTR       lpstrDefExt; 
    DWORD         lCustData; 
    LPOFNHOOKPROC lpfnHook; 
    LPCTSTR       lpTemplateName; 
} OPENFILENAME;
Рассмотрим составляющие этой структуры по отдельности (приводится частичное описание параметров):

lStructSize - определяет длину структуры в байтах.

hwndOwner - идентифицирует окно, которое является "владельцем". Это может быть как указатель на окно, так и NULL значение (если нет владельца).

hInstance - принимается во внимание только если установлены флаги OFN_ENABLETEMPLATEHANDLE или OFN_ENABLETEMPLATE и идентифицирует модуль, в котором находится шаблон формы диалога. Имя шаблона указывается в параметре lpTemplateName структуры.

lpstrFilter - указатель на буфер, в котором находятся пары нуль-терминированных (null-terminated) строк для фильтра. Последняя строка в этом буфере должна заканчиваться двумя NULL символами. Первая строка пары содержит описание фильтра (например, "Text Files"), а вторая - сам шаблон фильтра (например, "*.TXT"). Можно указать несколько шаблонов для одного фильтра. Для отделения одного шаблона от другого (для одного и того же фильтра) используется знак ";"(точка с запятой), например, "*.TXT;*.DOC;*.BAK". Шаблон должен состоять из комбинации разрешенных символов и знака (*) звездочки. В шаблоне не используются пробелы.

Операционная среда не меняет порядок фильтров, а показывает их в том порядке, в котором шаблоны были заданы в lpstrFilter. Если lpstrFilter имеет значение NULL, то диалог не показывает фильтров.

Пример строки для этого параметра из MFC (3 шаблона):

"Bitmap files(*.bmp)\0*.bmp\0JPEG files(*.jpg)\0*.jpg\0All files(*.*)\0*.*\0\0"

lpstrCustomFilter - указатель на статический буфер, в котором находится пара ноль-терминированных(null-terminated) строк для определения шаблона пользователя. Первая строка описывает шаблон, вторая - сам шаблон. Первый раз, когда Ваше приложение создает диалоговое окно, вы определяет первую строку(не должна быть пустой). Когда пользователь выбирает файл, диалог копирует текущий шаблон фильтра во вторую строку. Этот шаблон может быть как одним из шаблонов, определенных в буфере lpstrFilter, так и может быть введен пользователем. Система использует эти строки для определения шаблона, указанного пользователем, в следующий раз, когда диалог будет вызван. Если параметр nFilterIndex равен нулю, то диалог использует пользовательский шаблон. Если этот параметр имеет значение NULL, то диалог не поддерживает использование пользовательского шаблона. Если значение этого параметра не равно NULL, то параметр nMaxCustFilter должен указывать размер буфера lpstrCustomFilter: для ANSI в байтах, а для Unicode - в символах.

nMaxCustFilter - определяет размер, в байтах, буфера, описанного в lpstrCustomFilter. Этот буфер должен быть длиной как минимум в 40 символов. Этот параметр игнорируется, если lpstrCustomFilter имеет значение NULL или указывает на строку со значением NULL.

nFilterIndex - определяет выбранный в настоящий момент фильтр для поля "Тип файлов" диалога. Параметр указывает на пару строк, которые определены в параметре lpstrFilter. Первая пара строк параметра lpstrFilter имеет индекс 1, вторая - 2 и т.д. Индекс 0 указывает на то, что выбран фильтр, определенный в lpstrCustomFilter. Можно указать необходимый индекс фильтра при вызове диалога. Когда пользователь выбирает файл, nFilterIndex возвращает индекс текущего фильтра. Если nFilterIndex равен 0 и lpstrCustomFilter имеет значение NULL, то система использует первый фильтр из буфера lpstrFilter. Если все три параметра равны 0 или NULL, то система не использует никаких фильтров и не показывает никаких файлов в списке файлов диалога.

lpstrFile - указатель на буфер, в котором находится имя для инициализации поля "Имя файла" диалога. Если инициализация не нужна, то первый символ буфера должен быть NULL. Если функции GetOpenFileName или GetSaveFileName успешно выполнены, то буфер содержит полный путь, имя и разрешение выбранного файла(ов).

Если флаг OFN_ALLOWMULTISELECT установлен и пользователь выбирает несколько файлов, то буфер содержит текущую папку и затем следуют имена выбранных файлов. Для "Explorer-style" диалога, папка и имена файлов разделены символом NULL. После последнего имени файла добавляется еще один символ NULL. В диалогах старого типа строки разделены пробелами и функции используют короткие имена для файлов с пробелами в имени. Функция FindFirstFile может быть использована для преобразования длинных имен в короткие. Если буфер слишком мал, то функция (GetOpenFileName или GetSaveFileName) вернет FALSE и функция CommDlgExtendedError вернет значение FNERR_BUFFERTOOSMALL. В этом случае первые два байта параметра lpstrFile будут содержать требуемый размер (в байтах или символах).

nMaxFile - определяет размер буфера, на который указывает параметр lpstrFile, в байтах (ANSI) или в символах (Unicode). Функции GetOpenFileName и GetSaveFileName вернут значение FALSE если буфер будет слишком маленьким, чтобы вместить информацию о файлах. Буфер должен быть как минимум длиной в 256 символов.

lpstrFileTitle - указатель на буфер, в котором находятся имя и расширение(без пути) выбранного файла. Параметр может иметь значение NULL.

nMaxFileTitle - определяет размер буфера, на который указывает параметр lpstrFileTitle, в байтах (ANSIUnicode). Этот параметр игнорируется, если lpstrFileTitle имеет значение NULL.

lpstrInitialDir - указатель на строку, в которой определяется стартовая папка при открытии диалога. Если параметр имеет значение NULL, то система использует текущую папку как стартовую для этого диалога.

lpstrTitle - указатель на строку, которая будет помещена в заголовке окна диалога. Если этот параметр имеет значение NULL, то система использует стандартные заголовки (соответственно, "Сохранить как" или "Открыть")

Flags (флаги)

Набор флагов используется при инициализации диалога. Они определяют то, как будет происходить и результат взаимодействия пользователя и системы. Этот параметр может быть представлен как комбинация флагов (например, OFN_ALLOWMULTISELECT + OFN_EXPLORER): Флаги и их расшифровки:

OFN_ALLOWMULTISELECT - Разрешает выбирать несколько файлов сразу (с помощью клавиш Shift и Ctrl) в открывшемся диалоге. Если при этом указан флаг OFN_EXPLORER, то диалог будет использовать Explorer-style интерфейс диалога; иначе будет использован старый стиль диалога. Если пользователь вибирает более, чем один файл, то параметр lpstrFile возвращает путь к текущему каталогу, а за ним следуют имена выбранных файлов. Параметр nFileOffset указывает сдвиг(смещение) первого имени файла, а параметр nFileExtension вообще не используется. В диалогах типа Explorer-style путь к файлам и имена файлов разделены нулевым (NULL) символом с дополнительным нулевым символом после последнего имени файла. Использование нулевых символов для разделение пути и имен файлов позволяют возвращать диалогу типа Explorer-style имена файлов с пробелами. В диалогах старого образца путь и имена файлов разделены пробелами и функции используют короткие (8.3) имена для файлов с пробелами в имени. Для преобразования длинных имен в короткие можно использовать функцию FindFirstFile.

OFN_CREATEPROMPT - Если пользователь указал файл, которого не существует, то диалог запросит разрешение создать новый файл с указанным именем. Если пользователь выберет создание нового файл, то диалог закроется и вернет указанное имя, в противном случае диалог останется открытым.

OFN_ENABLEHOOK - Разрешает применение перехватывающей процедуры, определенной в параметре lpfnHook.

OFN_ENABLETEMPLATE - показывает, что параметр lpTemplateName указывает на ресурс шаблона диалога в модуле, который указан в параметре hInstance.

OFN_ENABLETEMPLATEHANDLE - показывает, что параметр hInstance определяет блок данных, который является пред-загружаемым шаблоном.

OFN_EXTENSIONDIFFERENT - показывает, что пользователь ввел расширение, которое отличается от расширения, используемого в параметре lpstrDefExt. Этот флаг не используется, если флаг lpstrDefExt имеет значение NULL.

OFN_FILEMUSTEXIST - определяет, что пользователь может ввести только имена существующих файлов в поле ввода "Имя файла" диалога. Если указан этот флаг и пользователь ввел некорректное имя файла, то выдается предупреждающее сообщение. Если указан этот параметр, то также используется флаг OFN_PATHMUSTEXIST.

OFN_HIDEREADONLY - скрывает поле "Только для чтения" диалога.

OFN_LONGNAMES - Для диалогов старого образца. Этот флаг определяет использование длинных имен файлов. Если этот флаг не установлен или OFN_ALLOWMULTISELECT флаг также выбран, диалоговый окна старого образца используют формат коротких имен (8.3) для файлов с пробелами. Explorer-style диалоги игнорируют этот флаг и всегда показывают длинные имена.

OFN_NOCHANGEDIR - устанавливает текущей папкой первоначальное значение в случае, если пользователь переходит из одной папки в другую при поиске фалов.

OFN_NODEREFERENCELINKS - указывает диалогу возвращать путь и имя файла ярлыка (.LNK). Если этот флаг не установлен, то диалог возвращает путь и имя файла, на которые указывает ярлык.

OFN_NOLONGNAMES - для диалогов старого типа. Этот флаг приводит к тому, что в диалоге используются короткие имена (формат 8.3). Explorer-style диалог игнорирует этот диалог и всегда показывает длинные имена.

OFN_NONETWORKBUTTON - убирает и выключает кнопку "Сеть" диалога.

OFN_NOREADONLYRETURN - определяет, что диалог не содержит выбранным поле "Только для чтения" и возвращаемый файл не находится защищенной от копирования папке.

OFN_NOTESTFILECREATE - определяет, что файл не создается до тех пора, когда диалог не будет закрыт. Этот флаг должен быть определен, если приложение сохраняет файл при наличии прав "создать но не модифицировать" в сети (create-nonmodify network sharepoint). При использрвании этого флага не производится проверки на наличие защиты от записи, полный диск, не вставлен диск или защиты от сетевого доступа. При этом, приложение должно очень осторожно должно использовать эту операцию для открытия файла, т.к. файл не может быть открыт заново, если он был закрыт.

OFN_NOVALIDATE - позволяет использовать некорректные символы при вводе имени файла. Обычно, перехватывающая(hook) процедура вызывающего приложения проверяет корректность имени файла используя вызов FILEOKSTRING. Если поле ввода имени файла диалог пусто или заполнено пробелами, то список файлов и папок обновляется. Если поле ввода содержит что-то другое, то значения параметров nFileOffset и nFileExtension устанавливаются путем грамматического разбора текста. При этом к тексту не добавляются ни расширение по умолчанию, ни текстовый буфер, определенный в параметре lpstrFileTitle. Если значение параметра nFileOffset меньше 0, то имя файла некорректно. В противном случае имя считается корректным, nFileExtension и nFileOffset используются как будто не был указан флаг OFN_NOVALIDATE (т.е. как обычно).

OFN_OVERWRITEPROMPT - определяет, что диалог "Сохранить как" выдаст предупреждающее сообщение, если файл уже существует. Пользователь должен подтвердить перезапись файла.

OFN_PATHMUSTEXIST - определяет, что пользователь может указать только существующий путь и имена файлов. Если пользователь ввел неправильное имя файла или путь, то появится предупреждающее окно.

OFN_READONLY - использование этого флага ведет к тому, что "Только для чтения" поле для выбора диалога будет выбрано при создании диалога. Когда диалог закрыт, этот флаг говорит о состоянии поля "Только для чтения" диалога.

OFN_SHAREAWARE - определяет, что если вызов функции OpenFile потерпел неудачу из-за отсутствия сетевого доступа, то эта ошибка будет проигнорирована и диалог вернет имя выбранного файла. Если этот флаг не установлен, диалог сообщит перехватывающей(hook) процедуре, о произошедшей ошибке доступа к сетевым ресурсам(файлу).

OFN_SHOWHELP - выводит в окне диалога кнопку "Справка". Параметр hwndOwner должен определять окно, которому получит сообщение HELPMSGSTRING, посылаемое диалогом, когда пользователь нажимает на кнопку "Справка".

nFileOffset - определяет сдвиг (основанный на нуле) от начала пути на имени файла в строке, на которую указывает параметр lpstrFile. К примеру, если lpstrFile указывает на следующую строку, "c:\dir1\dir2\file.ext", то этот параметр равен 13, что обозначает сдвиг строки "file.ext" от начала параметра lpstrFile.

nFileExtension - определяет сдвиг(основанный на нуле) начиная с первого символа пути до расширения файла, на который указывает параметр lpstrFile. Например, если lpstrFile указывает на строку "c:\dir1\dir2\file.ext", то этот параметр равен 18. Если пользователь не указал расширение и lpstrDefExt имеет значение NULL, то этот параметр указывает сдвиг до последнего(терминирующего) символа. Если в имени файла пользователь указал последним символом ".", то этот параметр равен 0.

lpstrDefExt - указатель на буфер, в котором находится расширение по умолчанию. Если пользователь не указал расширение файла, то это расширение будет добавлено к имени файла. Строка может быть любой длины, но присоединяются только 3 первых символа. Строка не должна содержать точки (.). Если этот параметр имеет значение NULL, то, при отсутствии расширения, ничего к имени файла не добавляется.

lCustData - В этом параметре хранятся данные, которые передаются перехватывающей процедуре, указанной в параметре lpfnHook.

lpfnHook - указатель на перехватыватывающую процедуру. Этот параметр игнорируется, если не установлен флаг OFN_ENABLEHOOK.

lpTemplateName - указатель на нуль-терминированную строку, в которой описаны имена(указатели) ресурсов, определенные в параметре hInstance.

Вызов других стандартных диалогов (выбор цвета, поиск и т.д.) возможен как через соответствующие классы MFC, так и с помощью соответствующих функций WinAPI.

Прислал Valeri Khromov.


Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Каев Артем - 10.03.2000