![]() |
|
#1
|
|||
|
|||
![]() Возможно ли, и если да то как, превратить стандартный OpenDialog или SaveDialog в Select-диалог, который должен только выбирать место, куда будут сохранены ранее выбранные файлы (то есть такое окно, в котором я могу выбрать путь, куда экспортировать файлы и чтобы больше ничего нельзя было менять, то есть строки с названием файла вообще не должно быть).
|
#2
|
|||
|
|||
![]() Есть специальная функция Win32 API, показвающая диалог выбора папки. Называется SHBrowseForFolder. Возвращает идентификатор, который можно преобразовать в путь с помощью функции SHGetPathFromIDList.
Вот например, готовая функция, отображающая диалог выбора пути и возвращающая строку с терминальным нулем, в которой записывается путь к выбранной папке. Код:
function TFaceForm.ShowChooseDirDialog: PChar; const TitleName = 'Укажите папку назначения'; // это подсказка, которая будет выведена в диалоге var lpItemID: PItemIDList; BrowseInfo: TBrowseInfo; DisplayName: array[0..MAX_PATH] of Char; TempPath: array[0..MAX_PATH] of Char; begin Result := nil; FillChar(BrowseInfo, sizeof(TBrowseInfo), #0); BrowseInfo.hwndOwner := FaceForm.Handle; BrowseInfo.pszDisplayName := @DisplayName; BrowseInfo.lpszTitle := @TitleName[1]; BrowseInfo.ulFlags := BIF_RETURNONLYFSDIRS; lpItemID := SHBrowseForFolder(BrowseInfo); if lpItemID <> nil then begin SHGetPathFromIDList(lpItemID, TempPath); Result := TempPath; GlobalFreePtr(lpItemID); end; end; Не подойдет? |
#3
|
||||
|
||||
![]() Можно использовать стандартую функцию SelectDirectory из модуля FileCtrl , которая делает то же самое. Не приходиться писать то, что уже написано
![]() Велик и могуч наш Object Pascal ! ICQ: 357-591-887 |
#4
|
|||
|
|||
![]() Видимо у нас разные версии delphi (у меня 7), потому как не могу найти ни SHBrowseForFolder ни SelectDirectory.
|
#5
|
||||
|
||||
![]() У меня тоже 7 версия.
Добавить необходимые модули не забыл ? Для использования функции SelectDirectory нужен модуль FileCtrl Для SHBrowseForFolder - ShlObj Велик и могуч наш Object Pascal ! ICQ: 357-591-887 |
#6
|
|||
|
|||
![]() Это те которые лежат в ...\Borland\Delphi7\Source\Vcl\ ?
или в ...\Borland\Delphi7\Lib\Debug\ ? |
#7
|
||||
|
||||
![]() В начале кода можно увидеть такую строку(или что-то похожее):
Код:
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs; Если надо использовать функции из модуля, не указанного в этом списке, просто добавь его туда через запятую, например чтобы стало так: Код:
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, FileCtrl; Велик и могуч наш Object Pascal ! ICQ: 357-591-887 |
#8
|
|||
|
|||
![]() Теперь понял. Я просто перепутал слово "модуль" со словом "компонент"
|
#9
|
|||
|
|||
![]() Проверил оба варианта. По удобству для пользователя более приемлемым показался графический интерфейс, основанный на модуле ShlObj.pas (минимум лишней информации на экране, текст на кнопках на русском языке). Из недостатков — отсутствует кнопка создания новой директории. Если как-то добавить в окно диалога эту кнопку, то оно стало бы идеальным.
|
#10
|
||||
|
||||
![]() Есть два варианта процедуры SelectDirectory, в зависимости какой используешь, будут разные графические интерфейсы, да и код у них разный, можешь посмотреть исходник FileCtrl. Но вот кнопку создания новой папки туда не добавить. Поэтому процедуру вызова диалога надо писать самому, добавив необходимый флаг:
Код:
function ShowChooseDirDialog: String; const TitleName = 'Укажите папку назначения'; // это подсказка var lpItemID: PItemIDList; BrowseInfo: TBrowseInfo; DisplayName: array[0..MAX_PATH] of Char; TempPath: array[0..MAX_PATH] of Char; begin Result := ''; FillChar(BrowseInfo, sizeof(TBrowseInfo), 0); //Здесь нужно использовать именно Application.Handle BrowseInfo.hwndOwner := Application.Handle; BrowseInfo.pszDisplayName := @DisplayName; BrowseInfo.lpszTitle := @TitleName[1]; // NEWDIALOGSTYLE - будет добавлена кнопка "Создать папку" BrowseInfo.ulFlags := BIF_RETURNONLYFSDIRS or BIF_NEWDIALOGSTYLE; lpItemID := SHBrowseForFolder(BrowseInfo); if lpItemID <> nil then begin SHGetPathFromIDList(lpItemID, TempPath); Result := String(TempPath); GlobalFreePtr(lpItemID); end; end; Велик и могуч наш Object Pascal ! ICQ: 357-591-887 |
#11
|
|||
|
|||
![]() Rokuell, диалог стал таким как надо!
Но есть проблема: после того как я выполняю хотя бы один раз ShowChooseDirDialog приложение неправильно закрывается (то есть программа визуально закрывается, но в процессах виндов остается висеть EXE прграммы). Думаю это связано со строкой: BrowseInfo.hwndOwner := Application.Handle; |
#12
|
||||
|
||||
![]() Я думаю это связано с глюками в твоей программе, а не в функции:
Во-первых: Поле hwndOwner определяет окно-владельца данного диалога, и никак на закрытие программы оно не влияет. Во-вторых: Более корректно делать владельцем диалога всё приложение, а не одну форму ( можешь сравнить это, вызови диалог, сверни все окна, а потом попытайся развенуть твою прогу, если владельцем будет приложение, на экране появится окно программы, с вызванным диалогом, если же владельцем будет окно, появится только диалог, а окно программы останеться скрытым ). В-третьих: можешь создать новый проект и добавть туда только эту функцию, и убедишься, что всё работает нормально. В-четвёртых: Даже в исходниках Delphi ты можешь посмотреть, что владельцем делается именно всё приложение ( файл FileCtrl.pas строка 1998 ) Велик и могуч наш Object Pascal ! ICQ: 357-591-887 |
#13
|
|||
|
|||
![]() Сделал чистый проект с этой функцией, но та же проблема (после хотя бы одного запуска функции выбора пути, выход по кнопке "Exit" из главной формы уже не работает, точнее exe-файл программы остается в процессах виндов). Вот исходники тестового проекта:
test.rar |
#14
|
||||
|
||||
![]() Странно, у меня всё нормально работает. Попробуй проверить на другой винде (кстати, у тебя какая версия?).
Или изменить строки: Код:
procedure TForm2.Button2Click(Sender: TObject); begin Form1.Show; //Form2.Hide; Form2.Close; end; Велик и могуч наш Object Pascal ! ICQ: 357-591-887 |
#15
|
|||
|
|||
![]() Win XP Pro SP3, Delphi7. Изменил строки - тот же глюк. Другой винды не стоит.
Возможно проблема действительно в моем компе. Но все равно спасибо за коды и участие в теме. |