TStrings - ShellListView - ShellTreeView.
Модераторы: Duncon, Naeel Maqsudov, Игорь Акопян, Хыиуду
Здравствуйте, уважаемые программеры! Такой вопрос. Пользователь с помощью стандартных диалогов выбирает файлы и папки, которые со всем содержимым добавляются в TStrings. А задача заключается в том, чтобы в каком-нибудь визуальном компоненте отобразить структуру TStrings, т.е. в корневом каталоге будут все файлы и папки, которые были добавлены непосредственно, при щелчке на папке, показывается ее содержимое. У меня есть только вариант, когда все выбранные объекты копируются в отдельную папку на диске, а потом эта папка отображается в ShellTreeView. Но хочется все сделать виртуально.
- Romeo
- Сообщения: 3126
- Зарегистрирован: 02 мар 2004, 17:25
- Откуда: Крым, Севастополь
- Контактная информация:
Предлагаю использовать обычный TreeView. Иконки для элементов можно получать через SHGetFileInfo. Контекстное меню тоже можно выдрать из системы, но это уже немного потруднее. Могу кинуть готовый код как это делается, если понадобится.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Да, если можно, то кинь.
- Romeo
- Сообщения: 3126
- Зарегистрирован: 02 мар 2004, 17:25
- Откуда: Крым, Севастополь
- Контактная информация:
Код: Выделить всё
#include <shlobj.h>
#include <atlbase.h>
...
void ShowContextMenu(HWND hWnd, LPCTSTR pszPath, int x, int y)
{
USES_CONVERSION;
// Строим полное имя файла/каталога
TCHAR tchFullPath[MAX_PATH];
GetFullPathName(pszPath, sizeof(tchFullPath)/sizeof(TCHAR), tchFullPath, NULL);
// Получаем интерфейс IShellFolder рабочего стола
IShellFolder *pDesktopFolder;
SHGetDesktopFolder(&pDesktopFolder);
// Преобразуем заданный путь в LPITEMIDLIST
LPITEMIDLIST pidl;
pDesktopFolder->ParseDisplayName(hWnd, NULL, T2OLE(tchFullPath), NULL, &pidl, NULL);
// Ищем последний идентификатор в полученном списке pidl
LPITEMIDLIST pLastId = pidl;
USHORT temp;
while(1)
{
int offset = pLastId->mkid.cb;
temp = *(USHORT*)((BYTE*)pLastId + offset);
if(temp == 0)
break;
pLastId = (LPITEMIDLIST)((BYTE*)pLastId + offset);
}
// Получаем интерфейс IShellFolder родительского объекта для заданного файла/каталога
// Примечание: родительский каталог идентифицируется списком pidl за вычетом последнего
// элемента, поэтому мы временно зануляем pLastId->mkid.cb, отрезая его от списка
temp = pLastId->mkid.cb;
pLastId->mkid.cb = 0;
IShellFolder *pFolder;
pDesktopFolder->BindToObject(pidl, NULL, IID_IShellFolder, (void**)&pFolder);
// Получаем интерфейс IContextMenu для заданного файла/каталога
// Примечание: относительно родительского объекта заданный файл/каталог идентифицируется
// единственным элементом pLastId
pLastId->mkid.cb = temp;
IContextMenu *pContextMenu;
pFolder->GetUIObjectOf(
hWnd, 1, (LPCITEMIDLIST *)&pLastId, IID_IContextMenu, NULL, (void**)&pContextMenu);
// Создаём меню
HMENU hPopupMenu = CreatePopupMenu();
// Заполняем меню
pContextMenu->QueryContextMenu(hPopupMenu, 0, 1, 0x7FFF, 0);
// Отображаем меню
UINT nCmd = TrackPopupMenu(hPopupMenu,
TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_RIGHTBUTTON|TPM_RETURNCMD, x, y, 0, hWnd, 0);
// Выполняем команду (если она была выбрана)
if(nCmd)
{
CMINVOKECOMMANDINFO ici;
ZeroMemory(&ici, sizeof(CMINVOKECOMMANDINFO));
ici.cbSize = sizeof(CMINVOKECOMMANDINFO);
ici.hwnd = hWnd;
ici.lpVerb = MAKEINTRESOURCE(nCmd-1);
ici.nShow = SW_SHOWNORMAL;
pContextMenu->InvokeCommand(&ici);
}
// Получаем интерфейс IMalloc
IMalloc *pMalloc;
SHGetMalloc(&pMalloc);
// Освобождаем память, выделенную для pidl
pMalloc->Free(pidl);
// Освобождаем все полученные интерфейсы
pDesktopFolder->Release();
pFolder->Release();
pContextMenu->Release();
pMalloc->Release();
return;
}
http://www.rsdn.ru/article/qna/winshell/filemenu.xml
Там также есть очень краткие коментарии, хотя, думаю, и так всё понятно.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.