Выделение буфера на GetOpenFileName

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Source
Постоялец
Постоялец
 
Сообщения: 351
Зарегистрирован: 04.09.2007 (Вт) 11:21

Выделение буфера на GetOpenFileName

Сообщение Source » 23.01.2008 (Ср) 7:11

Для выбора нескольких файлов(OFN_ALLOWMULTISELECT) использую GetOpenFileName. Какой размер буфера надо указывать в ofn.lpstrFile, ведь пользователь может выбрать сколь угодно много файлов! Или в диалоге выбора файлов есть ограничение на число выбираемых при мультивыборе?

Viper
Артефакт VBStreets
Артефакт VBStreets
Аватара пользователя
 
Сообщения: 4394
Зарегистрирован: 12.04.2005 (Вт) 17:50
Откуда: Н.Новгород

Сообщение Viper » 23.01.2008 (Ср) 8:28

Ограничения на количество фалов нет. Задавай размер буфера достаточный для нужд пользователя, хотя конечно всегда есть шанс, что пользователь выберет больше, чем поместится в буфер.
Весь мир матрица, а мы в нем потоки байтов!

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 23.01.2008 (Ср) 8:55

If the buffer is too small, the function returns FALSE and the CommDlgExtendedError function returns FNERR_BUFFERTOOSMALL. In this case, the first two bytes of the lpstrFile buffer contain the required size, in bytes or characters.
Lasciate ogni speranza, voi ch'entrate.

Source
Постоялец
Постоялец
 
Сообщения: 351
Зарегистрирован: 04.09.2007 (Вт) 11:21

Сообщение Source » 23.01.2008 (Ср) 15:09

first two bytes of the lpstrFile buffer contain the required size
т.е. размер буфера не м.б. больше 65536? Почему тогда nMaxFile имеет тип Long? Почему lpstrFile, я же там могу вообще указать нулевую строку :)

Source
Постоялец
Постоялец
 
Сообщения: 351
Зарегистрирован: 04.09.2007 (Вт) 11:21

Сообщение Source » 24.01.2008 (Чт) 0:37

Интересно, что диалог вызывается только при nMaxFile=len(lpstrFile)+1, при других значениях возвращается ноль (диалог не вызывается)! Глядя на название nMaxFile можно подумать, что эта величина задаёт максимальное число файлов при мультивыборе, тогда можно легко было бы рассчитать и размер буфера, выделив 255 байт на имена файлов + путь, тогда ofn.lpstrFile = Space$(nMaxFile+1)*255. Но на самом деле это размер буфера... И чем думали в том Microsofte? Короче, всё как всегда у них делается через одно место :D

Source
Постоялец
Постоялец
 
Сообщения: 351
Зарегистрирован: 04.09.2007 (Вт) 11:21

Сообщение Source » 24.01.2008 (Чт) 0:59

Странно вообще всё работает, в папке 3 237 файлов. После их выбора через Ctrl+A выдаёт после разрезки по именам 2329 файлов (с путём):
Код: Выделить всё
Dim sTemp() As String
sTemp = Split(Trim(ofn.lpstrFile), Chr(0))


? UBound(sTemp)
2329
? len(Trim(ofn.lpstrFile))
28143

Viper
Артефакт VBStreets
Артефакт VBStreets
Аватара пользователя
 
Сообщения: 4394
Зарегистрирован: 12.04.2005 (Вт) 17:50
Откуда: Н.Новгород

Сообщение Viper » 24.01.2008 (Чт) 8:16

Source писал(а):Интересно, что диалог вызывается только при nMaxFile=len(lpstrFile)+1, при других значениях возвращается ноль (диалог не вызывается)! Глядя на название nMaxFile можно подумать, что эта величина задаёт максимальное число файлов при мультивыборе, тогда можно легко было бы рассчитать и размер буфера, выделив 255 байт на имена файлов + путь, тогда ofn.lpstrFile = Space$(nMaxFile+1)*255. Но на самом деле это размер буфера... И чем думали в том Microsofte? Короче, всё как всегда у них делается через одно место :D

А MSDN то не судьба поглядеть? nMaxFile определяет размер буфера в символах, заданного в lpstrFile. Так что понятно, что при задании нуля ничего интересного не произойдет.

З.Ы. Год назад отправлял Гайдару статью про стандартные диалоги для книги, то ли не дошла, то ли одно из двух. Вот там все было подробно рзобрано про все стандартные диалоги.
Весь мир матрица, а мы в нем потоки байтов!

Source
Постоялец
Постоялец
 
Сообщения: 351
Зарегистрирован: 04.09.2007 (Вт) 11:21

Сообщение Source » 24.01.2008 (Чт) 10:12

А MSDN то не судьба поглядеть? nMaxFile определяет размер буфера в символах, заданного в lpstrFile. Так что понятно, что при задании нуля ничего интересного не произойдет.
Ну, если я укажу ofn.lpstrFile = Space$(300), я же могу указать nMaxFile=50 (меньше 300), но не сработает!

З.Ы. Год назад отправлял Гайдару статью про стандартные диалоги для книги, то ли не дошла, то ли одно из двух. Вот там все было подробно рзобрано про все стандартные диалоги.
Предлагаешь слетать в прошлое и перехватить? :)

Viper
Артефакт VBStreets
Артефакт VBStreets
Аватара пользователя
 
Сообщения: 4394
Зарегистрирован: 12.04.2005 (Вт) 17:50
Откуда: Н.Новгород

Сообщение Viper » 24.01.2008 (Чт) 10:32

Source писал(а):
А MSDN то не судьба поглядеть? nMaxFile определяет размер буфера в символах, заданного в lpstrFile. Так что понятно, что при задании нуля ничего интересного не произойдет.
Ну, если я укажу ofn.lpstrFile = Space$(300), я же могу указать nMaxFile=50 (меньше 300), но не сработает!

Сработает, если выбранный пользователем путь + файлы уместятся в 50 символов.

Source писал(а):
З.Ы. Год назад отправлял Гайдару статью про стандартные диалоги для книги, то ли не дошла, то ли одно из двух. Вот там все было подробно рзобрано про все стандартные диалоги.
Предлагаешь слетать в прошлое и перехватить? :)

Это намек Гайдару, если дошла статья, то может на сайте выложит, ежли таки нет, то могу послать еще раз.
Весь мир матрица, а мы в нем потоки байтов!

Source
Постоялец
Постоялец
 
Сообщения: 351
Зарегистрирован: 04.09.2007 (Вт) 11:21

Сообщение Source » 24.01.2008 (Чт) 19:58

Сработает, если выбранный пользователем путь + файлы уместятся в 50 символов.
Диалог вообще не покажется.

Это намек Гайдару, если дошла статья, то может на сайте выложит, ежли таки нет, то могу послать еще раз.
Не проще ли самому на сайте выложить и мне ссылку кинуть :)

Viper
Артефакт VBStreets
Артефакт VBStreets
Аватара пользователя
 
Сообщения: 4394
Зарегистрирован: 12.04.2005 (Вт) 17:50
Откуда: Н.Новгород

Сообщение Viper » 25.01.2008 (Пт) 8:21

Source писал(а):
Сработает, если выбранный пользователем путь + файлы уместятся в 50 символов.
Диалог вообще не покажется.

Обшибочка вышла, буфер должен иметь длину как минимум 256 символов согласно MSDN.

Source писал(а):
Это намек Гайдару, если дошла статья, то может на сайте выложит, ежли таки нет, то могу послать еще раз.
Не проще ли самому на сайте выложить и мне ссылку кинуть :)

Уговорил! На днях отправлю на основной сайт.
Весь мир матрица, а мы в нем потоки байтов!

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 25.01.2008 (Пт) 10:23

Viper, ты бы все-таки уточнил у gaidar-а.
Если статья ушла в книгу, возможно издательство будет против того, чтобы материалы книги размещались в интернете.
Lasciate ogni speranza, voi ch'entrate.

Viper
Артефакт VBStreets
Артефакт VBStreets
Аватара пользователя
 
Сообщения: 4394
Зарегистрирован: 12.04.2005 (Вт) 17:50
Откуда: Н.Новгород

Сообщение Viper » 25.01.2008 (Пт) 11:38

alibek писал(а):Viper, ты бы все-таки уточнил у gaidar-а.
Если статья ушла в книгу, возможно издательство будет против того, чтобы материалы книги размещались в интернете.

Как я понял в книге то ее нет, но в принципе да, уточнить бы надо.
Весь мир матрица, а мы в нем потоки байтов!

Source
Постоялец
Постоялец
 
Сообщения: 351
Зарегистрирован: 04.09.2007 (Вт) 11:21

Сообщение Source » 29.01.2008 (Вт) 4:37

Source писал(а):Странно вообще всё работает, в папке 3 237 файлов. После их выбора через Ctrl+A выдаёт после разрезки по именам 2329 файлов (с путём):
Код: Выделить всё
Dim sTemp() As String
sTemp = Split(Trim(ofn.lpstrFile), Chr(0))


? UBound(sTemp)
2329
? len(Trim(ofn.lpstrFile))
28143


значит, при множественном выборе файлов существует ограничение на число выбираемых файлов, которое визуально не подтверждается (пользователь видит выделенными все файлы в диалоге), но буфер не получает все файлы! Буфер был заказан 70000. Почему???

Source
Постоялец
Постоялец
 
Сообщения: 351
Зарегистрирован: 04.09.2007 (Вт) 11:21

Сообщение Source » 29.01.2008 (Вт) 5:27

сделал Batch Rename файлов через просмотрщик граф. файлов, чтобы исключить попадание файла с некорректными символами. Теперь выдаёт после нажатия кнопы диалога 'Открыть' сообщение "Файл 002048.j не найден. Проверьте правильность имени файла." Файл фактически именуется 002048.jpg и находится проводником. Отсюда делаю вывод, что у диалога существует ограниченный размер буфера под запись имён файлов, т.к. реальный файл был урезан. Получил в результате Debug.Print UBound(sTemp); Len(Trim(ofn.lpstrFile))
2049 28690
тогда 28690+len("002048.j")=28698 максимальный размер буфера у диалога. Весьма странное число...
Т.о. сам стандартный диалог работает некорректно, т.к. пользователь может выбирать больше файлов, чем может вернуть диалог, да к тому же ещё выдаёт сбивающее с толку сообщение о некорректности имени файла!

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 29.01.2008 (Вт) 8:48

А у тебя точно установлен флаг MULTISELECT?
Lasciate ogni speranza, voi ch'entrate.

Viper
Артефакт VBStreets
Артефакт VBStreets
Аватара пользователя
 
Сообщения: 4394
Зарегистрирован: 12.04.2005 (Вт) 17:50
Откуда: Н.Новгород

Сообщение Viper » 29.01.2008 (Вт) 11:47

Source, выложил бы ты код странно себя ведущий.
Весь мир матрица, а мы в нем потоки байтов!

Source
Постоялец
Постоялец
 
Сообщения: 351
Зарегистрирован: 04.09.2007 (Вт) 11:21

Сообщение Source » 29.01.2008 (Вт) 15:10

А у тебя точно установлен флаг MULTISELECT?
Да, иначе я бы не смог выбирать несколько файлов

Код: Выделить всё
Dim Ret As Long, ofn As OPENFILENAME, sTemp() As String, i As Long, sPathGet As String
'выбрать файл(ы)
    ofn.lStructSize = Len(ofn)
    ofn.hwndOwner = Me.hwnd
    ofn.hInstance = App.hInstance
    ofn.nMaxFile = 70000
    ofn.lpstrFile = Space$(ofn.nMaxFile - 1)
    ofn.nMaxFileTitle = 256 'для определении имени файла при выборе только 1 файла
    ofn.lpstrFileTitle = Space$(ofn.nMaxFileTitle - 1)
    ofn.lpstrInitialDir = CurDir
    ofn.lpstrTitle = "File Open"
    ofn.flags = OFN_EXPLORER Or OFN_FILEMUSTEXIST  Or OFN_ALLOWMULTISELECT
   
    Ret = GetOpenFileName(ofn)
    If Ret = 0 Then GoTo 100
    sTemp = Split(Trim(ofn.lpstrFile), Chr(0))
    If UBound(sTemp) <= 2 Then
'выбран 1 файл - полный путь, отделить путь от имени файла
     sPathGet = Mid(sTemp(0), 1, InStrRev(sTemp(0), "\"))
     sTemp(0) = Trim(ofn.lpstrFileTitle) 'взять имя файла
     sTemp(0) = Left$(sTemp(0), Len(sTemp(0)) - 1)  'Left$ убирает конец строки=0
    Else
     sPathGet = sTemp(0) & "\"
    End If
Debug.Print "UBound(sTemp)="; UBound(sTemp); Len(Trim(ofn.lpstrFile))

Source
Постоялец
Постоялец
 
Сообщения: 351
Зарегистрирован: 04.09.2007 (Вт) 11:21

Сообщение Source » 30.01.2008 (Ср) 6:19

1. вот мы и попали в тупик! :?
2. Интересно, что если не очистить ofn.lpstrFile перед повторным вызовом диалога, то диалог откроет родительскую папку CurDir, несмотря на ofn.lpstrInitialDir = CurDir!

Viper
Артефакт VBStreets
Артефакт VBStreets
Аватара пользователя
 
Сообщения: 4394
Зарегистрирован: 12.04.2005 (Вт) 17:50
Откуда: Н.Новгород

Сообщение Viper » 30.01.2008 (Ср) 8:30

Source писал(а):2. Интересно, что если не очистить ofn.lpstrFile перед повторным вызовом диалога, то диалог откроет родительскую папку CurDir, несмотря на ofn.lpstrInitialDir = CurDir!

и сделает он это в полном соответствии с описанием функции и структуры.
Насчет кода, вроде на первый взгляд все нормально, не считая странного выделения буфера на 1 меньше заданной длины.
Весь мир матрица, а мы в нем потоки байтов!

Source
Постоялец
Постоялец
 
Сообщения: 351
Зарегистрирован: 04.09.2007 (Вт) 11:21

Сообщение Source » 30.01.2008 (Ср) 9:05

Ладно, будем считать что я не знаю полного описания ф-и.
Без этого странного выделения ничего не будет работать. Наверное, это на байт-признак конца строки=0 :)


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: Yandex-бот и гости: 101

    TopList