Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.63/19: Рейтинг темы: голосов - 19, средняя оценка - 4.63
Evg
Эксперт CАвтор FAQ
21204 / 8220 / 633
Регистрация: 30.03.2009
Сообщений: 22,538
Записей в блоге: 30
1

Диалог для открытия каталога

26.09.2010, 18:40. Показов 3938. Ответов 10
Метки нет (Все метки)

Нужен диалог для открытия каталога (но не файла). TDialogOpen не подходит по той причине, что там можно открывать только файлы. Возможно, что можно и каталоги, но я сам что-то не разобрался и поиском ничего интересного не нашёл. Есть интерфейс SelectDirectory, но он откровенно ублюдочный в плане удобства использования. Есть ли ещё что-нибудь или можно ли как-то настроить TOpenDialog?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
26.09.2010, 18:40
Ответы с готовыми решениями:

Стандартный диалог для открытия файлов
Всем добрый вечер! Подскажите пожалуйста существует ли такой стандартный диалог, который выбирает...

Как внести в диалог открытия файлов Qt позицию для обзора сети?
"Родной диалог открытия файлов Windows имеет позицию "Сеть", выбор которой приводит к подключению...

Самый простой способ создать диалог для открытия файла с диска?
Добрый день! Подскажите, пожалуйста, самый не трудозатратный способ создать что-то вроде этого?...

Диалог открытия файла на winApi
Здратвуйте как вызвать диалог открытия/сохранения файла в winApi?

10
1336 / 987 / 119
Регистрация: 30.07.2010
Сообщений: 5,297
26.09.2010, 18:44 2
TOpenDirectory. На рутрекере вроде были сырцы.
1
Эксперт С++
3943 / 1798 / 184
Регистрация: 21.11.2009
Сообщений: 2,540
26.09.2010, 19:28 3
Evg, а как на счёт варианта со стандартным диалогом SHBrowseForFolder?

Перед всеми директивами include прописываем маркос:
C++
1
#define NO_WIN32_LEAN_AND_MEAN
Затем:
C++
1
#include "ShlObj.hpp"
И сам вызов с получением полного пути к директории и алиаса папки:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
::BROWSEINFO    info;
char szDir[MAX_PATH], szDisplayName[MAX_PATH];
LPITEMIDLIST  pidl;
LPMALLOC      pShellMalloc;
 
if(SHGetMalloc(&pShellMalloc) == NO_ERROR) {
  memset(&info, 0x00,sizeof(info));
  info.hwndOwner = Handle;                 // Owner window
  info.pidlRoot  = 0;                      // root folder
  info.pszDisplayName = szDisplayName;     // return display name
  info.lpszTitle = "Browse Title";         // label caption
  info.ulFlags   = BIF_RETURNONLYFSDIRS;   // config flags
  info.lpfn = 0;                           // callback function
 
  // Dialog calling...
  pidl = SHBrowseForFolder(&info);
 
  if(pidl) {
    if(SHGetPathFromIDList(pidl, szDir)) {
        ShowMessage(szDir);       // directory path
    }
 
    ShowMessage(info.pszDisplayName);    // display name
 
    pShellMalloc->Free(pidl);
  }
  pShellMalloc->Release();
}
2
Evg
Эксперт CАвтор FAQ
21204 / 8220 / 633
Регистрация: 30.03.2009
Сообщений: 22,538
Записей в блоге: 30
27.09.2010, 21:07  [ТС] 4
Цитата Сообщение от iama Посмотреть сообщение
TOpenDirectory. На рутрекере вроде были сырцы.
Не хочется корячиться с дополнительными компонентами

Цитата Сообщение от MikeSoft Посмотреть сообщение
Evg, а как на счёт варианта со стандартным диалогом SHBrowseForFolder?
Этот способ видел, но показалось излишне геморно. Ладно, будем пробовать его

Добавлено через 22 часа 23 минуты
Цитата Сообщение от MikeSoft Посмотреть сообщение
Evg, а как на счёт варианта со стандартным диалогом SHBrowseForFolder?
А можешь мне сказать хоть одно отличие от SelectDirectory? По-моему те же яйца и даже не в профиль, а в фас
0
Эксперт С++
3943 / 1798 / 184
Регистрация: 21.11.2009
Сообщений: 2,540
27.09.2010, 21:41 5
Цитата Сообщение от Evg Посмотреть сообщение
А можешь мне сказать хоть одно отличие от SelectDirectory?
1. SHBrowseForFolder - стандартная функция, не зависимая от производителя компилятора
2. SHBrowseForFolder предоставляет поддержку "Сетевого окружения".
3. SHBrowseForFolder генерирует стандартное диалоговое окно, которое спроектировано в ОС Windows, а не сделано на компонентах из вкладки Win 3.1 (которые использованы в диалоге, вызванном с помощью SelectDirectory)
0
1336 / 987 / 119
Регистрация: 30.07.2010
Сообщений: 5,297
27.09.2010, 21:47 6
MikeSoft, отличием есть только то, что описано в первом, остальное есть и в компоненте
0
Evg
Эксперт CАвтор FAQ
21204 / 8220 / 633
Регистрация: 30.03.2009
Сообщений: 22,538
Записей в блоге: 30
27.09.2010, 22:09  [ТС] 7
У меня тоже возникло подозрение, что SelectDirectory - это просто надстройка над стандартным SHBrowseForFolder (правда с меньшим количеством настроек). Хотел убедиться, так ли это. Прочёл два противоположных мнения.
0
1336 / 987 / 119
Регистрация: 30.07.2010
Сообщений: 5,297
27.09.2010, 22:45 8
Evg, не вижу противоречий. Понятия не имею, как писался этот TOpenDirectory, с использованием оной функции или без, но функционал у них плюс-минус один и тот же. Вам выбирать, пожертвовать переносимостю исходников или получить гемор в управлении SHBrowseForFolder
0
Evg
Эксперт CАвтор FAQ
21204 / 8220 / 633
Регистрация: 30.03.2009
Сообщений: 22,538
Записей в блоге: 30
27.09.2010, 23:30  [ТС] 9
Посмотрел повнимательнее - всё-таки это не одно и то же. В SelectDirectory если задать путь, который должен высвечиваться по умолчанию, то выделенный каталог подсвечивается серым (а не тёмно-синим, стандартным для выделения). К тому же скроллбар в момент открытия всегда находится наверху, и, если выделенный по умолчанию каталог, находится за пределами видимой области, то скроллбар надо крутить ручками, что есть неудобно. В случае же SHBrowseForFolder по этой части всё нормально (посмотрел в чужих инсталляторах), только я так и не понял, как задать путь до выделенного каталога в момент открытия

Добавлено через 1 минуту
Стороннюю компоненту TOpenDirectory я не рассматриваю в принципе, потому как вся жта идиотская концепция с компонентами мне не нравится. Чтобы мой исходник можно было скомпилять на чужом компе, надо сначала какие-то телодвиженя осуществить
0
Эксперт С++
3943 / 1798 / 184
Регистрация: 21.11.2009
Сообщений: 2,540
28.09.2010, 01:45 10
Цитата Сообщение от iama Посмотреть сообщение
MikeSoft, отличием есть только то, что описано в первом, остальное есть и в компоненте
В компоненте есть, но:
1.
Сравнение же требовалось с SelectDirectory
Цитата Сообщение от Evg Посмотреть сообщение
А можешь мне сказать хоть одно отличие от SelectDirectory?

2. Cама компонента, далеко не OpenSource... Платить 97 вечнозелёных за то, чтобы можно было легально пользоваться продуктом? Оно того не стоит, если есть достойные, синхронизированные с ОС, замены.

Цитата Сообщение от Evg Посмотреть сообщение
Прочёл два противоположных мнения.
Два противоположных? Каких?
Вроде всё однозначно: iama, упоминал о компоненте.

Цитата Сообщение от Evg Посмотреть сообщение
У меня тоже возникло подозрение, что SelectDirectory - это просто надстройка над стандартным SHBrowseForFolder
Это 100% не так. Убедится можно просмотрев имена классов.

Цитата Сообщение от Evg Посмотреть сообщение
только я так и не понял, как задать путь до выделенного каталога в момент открытия
Среди полей BROWSEINFO есть поле lpfn. Это указатель на сallback процедуру.

В коде, который я привёл выше, заменяем строку
C++
1
info.lpfn = 0;                           // callback function
на строку:
C++
1
info.lpfn = BrowseProc;                           // callback function
И соответственно, описываем саму функцию BrowseProc:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int __stdcall BrowseProc(HWND hwnd,UINT uMsg, LPARAM lParam, LPARAM lpData )
{
  char szDir[MAX_PATH];
 
  switch(uMsg) {
    case BFFM_INITIALIZED:
      SendMessage(hwnd, BFFM_SETSTATUSTEXT,0, (LPARAM)"Greetings");
      SendMessage(hwnd, BFFM_SETSELECTION, TRUE, (LPARAM)"C:\\");
      break;
    case BFFM_SELCHANGED:
      if(SHGetPathFromIDList((LPITEMIDLIST)lParam, szDir))
        ShowMessage(szDir);
      break;
  }
 
  return 0;
}
Соответственно, обзор будет начат с корня диска С:
1
Evg
Эксперт CАвтор FAQ
21204 / 8220 / 633
Регистрация: 30.03.2009
Сообщений: 22,538
Записей в блоге: 30
28.09.2010, 23:28  [ТС] 11
Цитата Сообщение от MikeSoft Посмотреть сообщение
Соответственно, обзор будет начат с корня диска С:
Обзор начинается. Но папка не выделена, а надо бы ей выделить (как если бы пользователь кликнул мышкой)

По поводу поля pidlRoot. Общий вопрос: как вообще что-то в pidlRoot засунуть, потому что во всех примерах туда записывают 0, но я так и не понял как преобразовать строковое значение пути в PIDL. И конкретный вопрос: что надо подсунуть в pidlRoot, чтобы в списке отображались только диски C, D, ..., но не было "Рабочий стол", "Компьютер" и прочая хрень.

Добавлено через 6 минут
И что делает BFFM_SETSTATUSTEXT? Судя по описанию - "Sets the status text", но что это такое? Потому что визуально я слова Greetings нигде не вижу

Добавлено через 9 минут
Цитата Сообщение от Evg Посмотреть сообщение
Посмотрел повнимательнее - всё-таки это не одно и то же
Однако я ошибся. Я сравнивал две разные вещи. Когда я работал через SelectDirectory, то добавлял опцию sdNewUI. Если в info.ulFlags добавить BIF_USENEWUI, то будет та же портянка с теми же косяками. А если не добавлять, то получится идиотское неудобное маленькое окно, которое нельзя растягивать. Можно это как-то разрулить?
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
28.09.2010, 23:28

Диалог выбора каталога
Добрый день! Процедура КнопкаВыполнитьНажатие(Кнопка) Режим =...

Как использовать диалог открытия файла
скажите само диалоговое окно открывается бкз каких либо параметров или параметры ,скажем размер...

Диалог открытия файла в bat/cmd
Добрый день! Подскажите решения JS вставки отображения (и функционирования) диалога открытия...

Создать свой диалог открытия файлов
Возник вопрос: а как вообще создать аналог opendialog?Есть допустим форма.Объект выбран.И что...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.