Алекс Jenter - Программирование на Visual C++. Архив рассылки
- Название:Программирование на Visual C++. Архив рассылки
- Автор:
- Жанр:
- Издательство:неизвестно
- Год:неизвестен
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Алекс Jenter - Программирование на Visual C++. Архив рассылки краткое содержание
РАССЫЛКА ЯВЛЯЕТСЯ ЧАСТЬЮ ПРОЕКТА RSDN, НА САЙТЕ КОТОРОГО ВСЕГДА МОЖНО НАЙТИ ВСЮ НЕОБХОДИМУЮ РАЗРАБОТЧИКУ ИНФОРМАЦИЮ, СТАТЬИ, ФОРУМЫ, РЕСУРСЫ, ПОЛНЫЙ АРХИВ ПРЕДЫДУЩИХ ВЫПУСКОВ РАССЫЛКИ И МНОГОЕ ДРУГОЕ.
Программирование на Visual C++. Архив рассылки - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Приложение оперирует понятием указателя на список идентификаторов(pointer to an identifier list), который кратко именуют как PIDL-указатель. Все глобальные методы (утилиты) оболочки, принимающие в качестве одного из параметров PIDL-указатель, ожидают его в абсолютном формате. В то же время все методы интерфейса IShellFolder, принимающие в качестве одного из параметров pidl-указатель, ожидают его в относительном формате (если только в описании метода не указано иначе).
Ниже представлена функция, позволяющая получить указатель на следующий элемент в списке идентификаторов. В случае неудачи возвращается пустой указатель.
#include
LPITEMIDLIST GetNextItemID(const LPITEMIDLIST pidl) {
size_t cb = pidl->mkid.cb;
if (cb == 0) {
return NULL;
}
pidl = (LPITEMIDLIST)(((LPBYTE)pidl) + cb);
if (pidl->mkid.cb == 0) {
return NULL;
}
return pidl;
}
За размещение списков идентификаторов отвечает распределитель памяти оболочки(Shell's allocator), предоставляющий интерфейс IMalloc. Указатель на данный интерфейс распределителя памяти оболочки можно получить через метод SHGetMalloc.
Таким образом, если Ваше приложение получает от оболочки PIDL-указатель, то оно становится ответственным за обязательное в дальнейшем освобождение этого списка с помощью распределителя памяти оболочки.
Ниже представлен пример копирования списка идентификаторов:
#include
size_t GetItemIDListSize(const LPITEMIDLIST pidl) {
size_t size = 0;
LPBYTE p = LPBYTE(pidl);
while (p != NULL) {
if (static_cast(p + size)->mkid.cb == 0) {
size += sizeof(USHORT); // size of terminator;
break;
}
size += static_cast(p + size)->mkid.cb;
}
return size;
}
LPITEMIDLIST CopyItemIDList(const LPITEMIDLIST pidl) {
LPMALLOC pMalloc;
LPITEMIDLIST pidlResult;
if (pidl == NULL) {
return NULL;
}
if (!SUCCEEDED(SHGetMalloc(&pMalloc)) {
return NULL;
}
size_t size = GetItemIDListSize(pidl);
pidlResult = pMalloc->Alloc(size);
if (pidlResult!= NULL) {
CopyMemory(pidlResult, pidl, size);
}
pMalloc->Release();
return pidlResult;
}
Для увеличения эффективности работы Ваших приложений рекомендуется брать ссылку на распределитель памяти оболочки при запуске приложения, и освобождать эту ссылку при выходе из приложения.
Интерфейс IShellFolderпредоставляет метод CompareIDsдля определения расположения двух идентификаторов относительно друг друга (выше, ниже или равны) в данной папке. При этом параметр lParam определяет критерий упорядочивания, но заранее определённым для всех объектов-папок является только сортировка по имени (значение 0). Если вызов этого метода завершён успешно, то поле CODE возвращаемого значения содержит ноль при равенстве объектов, отрицательно, если первое меньше второго, и положительно в обратном случае.
hr = ppsf->CompareIDs(0, pidlA, pidlB);
if (SUCCEEDED(hr)) {
iComparisonResult = short(HRESULT_CODE(hr))
}
Некоторые папки имеют особое значение для оболочки. Для нахождения этих специальных папок, а также для того, чтобы пользователь мог сам искать необходимые ему папки, оболочка предоставляет специализированный набор функций:
SHGetDesktopFolder | Возвращает интерфейс IShellFolderобъекта-папки "Рабочий стол" (Desktop); |
SHGetSpecialFolderLocation | Возвращает указатель на список идентификаторов специального объекта-папки. |
SHBrowseForFolder | Проводит диалог с пользователем и возвращает указатель на список идентификаторов выбранного пользователем объекта-папки; |
SHGetSpecialFolderPath | Версия 4.71. Возвращает путь файловой системы для специального объекта-папки. Функция предназначена для работы со специальнымипапками, а не для работы с виртуальными. |
При отсутствии нужной папки может, по требованию приложения, её создавать.
Каждый объект-папка прдоставляет Вам возможность перебора всех объектов, которыми данный объект владеет. Для этого Вам предоставляется метод EnumObjectsинтерфейса IShellFolder, который возвращает интерфейс-итератор IEnumIDList. При этом Вы можете ограничить список (включать папки, не папки, скрытые и системные объекты).
Описание методов интерфейса IEnumIDList:
Clone | Создаёт новый объект-итератор, идентичный данному; |
Next | Восстанавливает указанное количество идентификаторов элементов, находящихся в папке; |
Reset | Возвращает итератор к началу последовательности; |
Skip | Пропускает указанное количество элементов; |
Таким образом Вы сможете получить набор указателей на списки идентификаторов, причём эти списки будут относительнымипо отношению к папке-владельцу.
Чтобы получить интерфейс IShellFolderдля любого из этих объектов, Вам потребуется осуществить привязку, вызвав метод BindToObjectинтерфейса IShellFolderпапки-владельца.
Чтобы узнать атрибуты данного объекта или нескольких объектов, необходимо вызвать метод GetAttributesOfинтерфейса IShellFolderпапки-владельца. При этом перед вызовом этого метода необходимо установить те атрибуты, значения которых Вы бы хотели выяснить. Если запрошены атрибуты нескольких элементов, то метод вернёт только те значения атрибутов, которые совпадают у всех переданных элементов. В частности, Вы сможете взять интерфейс IShellFolderтолько от тех объектов, которые имеют атрибут SFGAO_FOLDER. Вы можете обновить информацию об элементах, входящих в папку, использовав флаг SFGAO_VALIDATE.
Прежде всего, Ваше приложение всегда можете получить строку с именем объекта, представленном в удобном для Вас формате. Для этого интерфейс IShellFolderпредоставляет метод GetDisplayNameOf.
Вы можете указать один из следующих требующихся форматов:
SHGDN_NORMAL | Обычный формат представления; |
SHGDN_INFOLDER | Формат представления относительно данной папки; |
SHGDN_INCLUDE_NONFILESYS | Приложение заинтересовано в именах элементов всех типов. Если этот флаг не установлен, то приложение заинтересовано лишь в тех элементах, которые представляют часть файловой системы. Если этот флаг не установлен, и элемент не представляет собой часть файловой системы, то этот метод может быть выполнен неудачно; |
SHGDN_FORADDRESSBAR | Имя будет использовано для показа в адресном комбобоксе; |
SHGDN_FORPARSING | Формат представления, используемый для дальнейшего разбора имени; |
Имя элемента, полученное с установленным флагом SHGDN_FORPARSING, имеет особое значение. Вы можете использовать такое имя как командную строку для запуска приложения. Говоря точнее – такое имя эквивалентно понятию пути файловой системы.
Читать дальшеИнтервал:
Закладка: