Войти

Показать полную графическую версию : Диалог OpenFile


Sir Z
18-03-2006, 21:26
В VCL есть несколько стандартных диалогов - среди них - диалог OpenDialog. Подскажите, как унаследовать от него (или какой-то другой способ) другой диалог, который может передавать в программу сразу несколько имен файлов для открытия, а не один

DillerInc
18-03-2006, 23:54
Sir Z
Так у этого диалога есть же свойство ofAllowMultiSelect, разрешающее множественный выбор файлов...

XPEHOMETP
19-03-2006, 21:53
А вот меня этот вопрос тоже интересует. Сделал я этот MultiSelect, как я понял, по умолчанию выдается диалог устаревшего образца. И даже удалось это побороть. Только я не смог разобраться, в каком формате выдается путь к каталогу и имена файлов. Или я туплю, или у меня где-то это дело режется раньше времени по какому-то нолику-разделителю. Где бы посмотреть подробные разъяснения?

DillerInc
20-03-2006, 19:37
Sir Z
Если что,то я объясняю на основе WinAPI,а не VCL.
И даже удалось это побороть
...с помощью флага OFN_EXPLORER .
Итак,мы выставляем в структуре OPENFILENAME флаг OFN_ALLOWMULTISELECT.
При выборе нескольких файлов в принимающем буфере путь директории отделяется от файловой части нулевым байтом.В свою очередь названия файлов также разделяются между собою нулевыми байтами,и всё это дело,в конце концов,завершается двумя нулевыми байтами.
Если же был выбран только один файл,то принимающий буфер не содержит нулевого байта между директорией и файловой частью.
В структуре OPENFILENAME есть поле nFileOffset,которое является смещением относительно начала принимающего буфера до файловой части.Мы его будем использовать.
Теперь код:

var
OpenDlgBox : TOpenFileName;
s : String;
cf : PChar;
pathFile : array[0..4096] of Char = ' ';
begin
// типа заполняем структуру OPENFILENAME
OpenDlgBox.lStructSize := SizeOf(OpenDlgBox);
OpenDlgBox.hWndOwner := Handle;
OpenDlgBox.lpstrFilter := 'Text Files'#0'*.txt'#0#0;
OpenDlgBox.lpstrFile := pathFile;
OpenDlgBox.nMaxFile := SizeOf(pathFile);
OpenDlgBox.Flags := OFN_FILEMUSTEXIST or OFN_PATHMUSTEXIST or
OFN_ALLOWMULTISELECT or OFN_EXPLORER;

if Length(OpenDlgBox.lpstrFile) < OpenDlgBox.nFileOffset then
{ Если выбрано несколько файлов,
т.к. в данном случае функция Length читает длину строки до ближайшего нулевого байта,а у нас он будет стоять
сразу за названием директории,и значение поля nFileOffset,которое характеризует байт начала
файловой части,будет лежать после этого нулевого байта,т.е. значение поля nFileOffset будет больше длины,
возвращаемой функцией Length в конкретном случае }
begin
cf := pathFile;
inc(cf, OpenDlgBox.nFileOffset);
s := 'Выбрано несколько файлов в директории: '+pathFile+#13#10;

repeat
s := s+cf+#13#10;
inc(cf, Length(cf) + 1);
until Length(cf) = 0; // а тут мы упрёмся во второй нулевой байт той пары,которая стоит в конце буфера

end else
begin
s := 'Выбран только один файл: '+pathFile;
end;
SendMessage(hMemo, WM_SETTEXT, 0, lParam(s));

XPEHOMETP
20-03-2006, 21:03
Спасибо, попробую применить!

XPEHOMETP
21-03-2006, 09:28
Да, нашел свою ошибку: не использовал nFileOffset, в результате получал только папку, до первого нулевого байта. Спасибо!




© OSzone.net 2001-2012