Стандартные диалоговые окна без ActiveX
Все, наверное, знают про стандартные окна открытия и сохранения файлов. Они есть в каждой программе под Windows. Но как их показать? Вы либо делали свои похожие формы или просто ставили на форму ActiveX компонент Common Dialog и вызывали окно всего одной строчкой (например MyDlg.ShowOpen). Но зато при этом Вам нужно носить вместе с программой этот .ocx файл, который занимает во много раз больше места, чем то, в какое увеличился бы Ваш .exe файл, в котором Вы сами написали на VB свой код вызова этого диалога. Так вот сейчас я расскажу как этот самый код написть.
Диалоговое окно для открытия и сохранения файлов вызывается
фуекцией GetOpenFileName и GetSaveFileName из comdlg32.dll
Вот синтаксис их объявления:
Declare Function GetOpenFileName Lib _
"comdlg32.dll" Alias "GetOpenFileNameA" _
(OpenFileName As OPENFILENAME) As Boolean
Declare Function GetSaveFileName Lib _
"comdlg32.dll" Alias "GetSaveFileNameA" _
(OpenFileName As OPENFILENAME) As Boolean
Параметер OpenFileName в той и другой функции - это переменная типа OPENFILENAME, в которой перечислены все свойства диалога. Вот объявление этого типа:
Type OPENFILENAME
StructSize As Long
Owner As Long
Instance As Long
Filter As String
CustomFilter As Long
MaxCustrFilter As Long
FilterIndex As Long
File As String
MaxFile As Long
FileTitle As String
MaxFileTitle As Long
InitialDir As String
Title As String
Flags As Long
FileOffset As Integer
FileExtension As Integer
DefExt As String
CustrData As Long
Hook As Long
TemplateName As Long
End Type
Теперь надо просто объявить какую-нибудь переменную этого типа, задать ей свойства и передать её в качестве параметра. Пример программы ниже.
'Переменная с полученным путём до файла
Dim File As String
'Фильтр файлов
Dim CommDlgF As String * 512
'Переменная для передачи API функции
Dim OpenFileName As OPENFILENAME
'Буфер для обработки строки
Dim Buf As Variant
CommDlgF = "Текстовые файлы|*.txt"
'Номер формы
OpenFileName.Owner = Me.hWnd
OpenFileName.Instance = 0
OpenFileName.CustomFilter = 0
OpenFileName.MaxCustrFilter = 0
OpenFileName.Hook = 0
OpenFileName.TemplateName = 0
OpenFileName.CustrData = 0
'Длина файла
OpenFileName.File = String$(512, 0)
OpenFileName.MaxFile = 511
Далее должны присвоить параметр фильтра переменной OpenFileName, но в отличие от фильтра в ActiveX компоненте, разделителем между названием типа и расширением файла служит не символ "|", а нулевой (vbNullChar). Поэтому это вызывает некоторые сложности при указании фильтра, но для тех, кто привык к "|" пишем следующий код.
If Len(CommDlgF) > 0 Then
For I = 1 To Len(CommDlgF)
If Mid(CommDlgF, I, 1) = "|" Then
Buf = Buf + vbNullChar
Else
Buf = Buf + Mid(CommDlgF, I, 1)
End If
Next I
CommDlgF = Buf
End If
Здесь всё просто. Если мы указали фильтр, то проходимся по всей строке и заменяемсимвол "|" на нулевой.
'Присваиваем фильтр
OPENFILENAME.Filter = CommDlgF
'Присваиваем заголовок окна
OPENFILENAME.Title = "Открытие файла"
'Каталог по умолчанию
OPENFILENAME.InitialDir = "c:\"
'Другие свойства диалога
OPENFILENAME.Flags = &H0
'Длина всей переменной
OPENFILENAME.StructSize = Len(OPENFILENAME)
If GetOpenFileName(OpenFileName) = True Then
Buf = InStr(1, OPENFILENAME.File, Chr(0))
MsgBox "Вы выбрали " & Left(OpenFileName.File, Buf - 1)
Else
MsgBox "Ошибка"
End If
Таблица с некоторыми значениями параметра Flags
&H2000 | Этот флаг устанавливает, что диалоговое окно сообщает пользователю об отсутствии файла и предлагает его создать ("Файл такой-то не существует. Создать его?"). |
&H1000 | Указывает, что пользователь может выбрать только существующий файл или увидит сообщение "Файл не существует. Проверьте правильность имени файла". |
&H10 | Показывает кнопку справки. |
&H4 | Прячет галочку "Только чтение". |
&H200000 | Использование длинных имён файлов. |
&H8 | Заставляет открыть диалог в том же каталоге, в котором он был открыть первый раз. |
&H40000 | Не использовать длинных имён файлов. |
&H100 | Можно использовать любые символы при указании имени файла. |
&H4000 | Игнорирует ошибки. |
Вот в принципе и всё. Исходник можно скачать здесь.
Автор: Павел Николаевич
E-mail: pasha_nik@mail.ru