Пространство имен |
Общие замечанияНачиная с Windows 95, система поддерживает так называемое пространство имен (shell namespace), в котором каждый объект (файл или папка) однозначно идентифицируется структурой типа ITEMIDLIST. Функции работы с пространством имен принимают в качестве одного из параметров указатель на такую структуру (или массив таких структур). В документации такие указатели обычно носят название PIDL. Подобный механизм позволяет операционной системе поддерживать так называемые виртуальные папки, которым не соответствуют никакие объекты в реальной файловой системе. Существует некоторое количество системных папок, доступ к которым можно получить с помощью функции HRESULT SHGetSpecialFolderLocation( HWND hWnd, int nFolder, ITEMIDLIST** ppidl ); Через параметр hWnd передается дескриптор окна, поверх которого при необходимости будут выводиться диалоговые окна или окна сообщений. В качестве параметра nFolder необходимо указать идентификатор системной папки, PIDL которой функция должна записать в переменную по адресу ppidl. Освобождение памяти, которую функция выделяет под PIDL, должно выполняться приложением-клиентом при помощи метода Free интерфейса IMalloc. Ниже перечислены возможные значения параметра nFolder.
Функция возвращает значение NOERROR при успешном выполнении или код ошибки OLE — в противном случае. Заметим, что создаваемый этой функцией PIDL идентифицирует указанную папку относительно вершины пространства имен (то есть виртуальной папки Desktop). Для создания в папке Documents ярлыка на заданный документ используется функция void SHAddToRecentDocs( UINT fuFlags, const void* pvDoc Значение параметра fuFlags определяет, как функция будет интерпретировать параметр pvDoc: при fuFlags равном SHARD_PATH по адресу pvDoc должна находиться завершающаяся двоичным нулем строка с полным именем файла, на который должен ссылаться создаваемый ярлык; а при fuFlags равном SHARD_PIDL через pvDoc необходимо передать PIDL этого файла. Для работы с объектами пространства имен предназначены интерфейсы IShellFolder и IEnumIDList. Интерфейс IShellFolder
Ниже перечислены методы этого интерфейса, позволяющие получать информацию об объекте пространства имен, если известен PIDL этого объекта. HRESULT GetDisplayNameOf( ITEMIDLIST* pidl, DWORD fdwFlags, STRRET* pNameStr ); Метод записывает текстовое имя объекта с идентификатором pidl в переменную по адресу pNameStr. Параметр fdwFlags определяет вид этого имени и может быть комбинацией следующих флагов:
Заметим, что первые два флага являются взаимоисключающими; если не один из них не указан явно, то используется флаг SHGDN_NORMAL. Опыт показывает, что для получения имени объекта в «привычном» виде необходимо использовать флаг SHGDN_FORPARSING. Структура STRRET объявлена следующим образом: typedef struct _STRRET { UINT uType; union { LPWSTR pOleStr; LPSTR pStr; UINT uOffset; char cStr[MAX_PATH]; }; } STRRET; В поле uType метод записывает тип возвращенного значения, который может быть одним из следующих:
Заметим, что поле pStr структуры STRRET вообще не используется. Метод возвращает значение NOERROR при успешном выполнении или код ошибки OLE — в противном случае. HRESULT GetAttributesOf( UINT cItems, ITEMIDLIST** apidl, ULONG* pfuFlags ); Этот метод предназначен для получения атрибутов одного или нескольких объектов пространства имен. Через параметр apidl передается адрес массива, каждый элемент которого содержит PIDL объекта, а через параметр cItems — количество элементов в этом массиве. В переменную по адресу pfuFlags перед вызовом метода необходимо записать комбинацию битовых флагов, соответствующую проверяемым атрибутам; после выполнения метода по этому адресу будет записана комбинация флагов, соответствующая общим для всех объектов атрибутам. Допустимы следующие флаги:
Метод возвращает значение NOERROR при успешном выполнении или код ошибки OLE — в противном случае. Получить указатель на интерфейс IShellFolder, связанный с виртуальной папкой Desktop, можно с помощью функции HRESULT SHGetDesktopFolder( IShellFolder** ppDest ); которая записывает требуемый указатель в переменную по адресу ppDest и возвращает значение NOERROR при успешном выполнении или код ошибки OLE — в противном случае. Просмотр пространства именДля просмотра содержимого пространства имен необходимо вначале получить указатель на интерфейс IEnumIDList. Это можно сделать с помощью метода интерфейса IShellFolder HRESULT EnumObjects( HWND hWnd, DWORD fdwFlags, IEnumIDList** ppDest ); Через параметр hWnd передается дескриптор окна, поверх которого система будет выводить диалоговые окна, если потребуется ввод пользователя. Этот параметр можно задать равным NULL, но если при этом ввод пользователя все-таки потребуется, то метод завершится с ошибкой. Параметр fdwFlags определяет, объекты каких типов необходимо просмотреть, и может быть комбинацией следующих флагов:
Дополнительно может быть указан флаг SHCONTF_INIT_ON_FIRST_NEXT; в этом случае созданный экземпляр интерфейса IEnumIDList будет сразу же инициализирован PIDL'ом первого найденного объекта, соответствующего заданным условиям. Через параметр ppDest необходимо передать адрес переменной, в которую будет записан полученный указатель. Метод возвращает значение NOERROR при успешном выполнении или код ошибки OLE — в противном случае. После получения указателя на интерфейс IEnumIDList необходимо циклически вызывать его метод HRESULT Next( ULONG cItems, ITEMIDLIST** apidl, ULONG* pcFetched ); до тех пор, пока он не вернет значение S_FALSE. Через параметр apidl необходимо передавать адрес массива, в который метод будет записывать PIDL'ы найденных объектов, а через параметр cItems — емкость этого массива. В переменную по адресу pcFetched метод будет записывать количество PIDL'ов, скопированных в массив по адресу apidl. Если этот массив будет состоять из одного элемента, то параметр pcFetched можно задать равным NULL. Метод возвращает значение NOERROR при успешном выполнении или код ошибки OLE — в противном случае; еще раз отметим, что значение S_FALSE соответствует успешному окончанию перебора объектов. Стандартное окно выбора папкиДля создания стандартного окна выбора папки используется функция ITEMIDLIST* SHBrowseForFolder( BROWSEINFO* pbi ); Через параметр pbi передается указатель на структуру, определяющую внешний вид и поведение создаваемого диалогового окна. Функция возвращает PIDL выбранного пользователем объекта или NULL, если пользователь отказался от выбора. Ниже перечислены поля структуры BROWSEINFO:
Для формирования значения поля ulFlags могут использоваться следующие флаги:
Функция, адресуемая полем lpfn, должна иметь следующий прототип: int CALLBACK имя_функции( HWND hDlg, UINT uMsg, LONG lParam, LONG lData ); Через параметр hDlg в нее будет передаваться дескриптор диалогового окна, а через параметр uMsg — один из следующих идентификаторов извещений:
В каждом из этих случаев через параметр lData в функцию передается значение, указанное в поле lParam структуры BROWSEINFO. При обработке перечисленных извещений можно использовать функцию SendMessage для отправки диалоговому окну одного из следующих управляющих сообщений:
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||