уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.

Сегодня рассмотрим ещё один простой способ определения специальных папок Windows. К специальным относятся такие директории как, например:  «Мои документы», «Application Data», «Cookies» и т.д. В разное время развития операционной системы Windows, как и в разное время развития Delphi предлагалась масса различных способов определения путей к специальным директориям от самых простых — использование GetWindowsDirectory до таких «экзотических» как работа с интерфейсом ISHFolder и т.д.

Сегодня расмотрим более простой, на мой взгляд, способ получения всех без исключения системных папок. При этом мы воспользуемся всего одним заголовочным модулем Delphi — SHFolder.pas. Этот модуль содержит необходимы типы данных и константы для работы с библиотекой shfolder.dll, которая доступна во всех версиях Windows, начиная с Win95.

В начале немного теории. В модуле SHFolder.pas вы найдете всего одну функцию — SHGetFolderPath. Функция  получает путь к папке, определенной значением CSIDL. Следует отметить, что её не рекомендуется использовать в Windows Vista и выше, т.к. в бибилотеках ОС Win Vista и Windows 7 эта функция осталась только для обратной совместимости. Вместо этого рекоммендуется использовать функцию SHGetKnownFolderPath, которая, кстати сказать, по большому счёты не отличается от своей предшественницы. Т.к. я использую в работе только ОС Win XP, то для меня вполне хватит и обычной SHGetFolderPath.

Функция имеет следующее описание:

function(hwnd: HWND; csidl: Integer; hToken: THandle; dwFlags: DWord; pszPath: PAnsiChar): HRESULT;

Первый параметр hwnd — зарезервирован и не используется. При вызове функции достаточно присвоить ему значение 0.
csidl— определяет путь к какой директории мы хотим получить. Параметр может принимать следующие значения:

Константа Значение Путь к директории по умолчанию
CSIDL_PERSONAL $0005 C:\Documents and Settings\%User%\Мои
документы
CSIDL_APPDATA $001A C:\Documents and Settings\%User%\Application
Data
CSIDL_LOCAL_APPDATA $001C C:\Documents and Settings\%User%\Local
Settings\Application Data
CSIDL_MYMUSIC $000d C:\Documents and Settings\%User%\Мои
документы\Моя музыка
CSIDL_INTERNET_CACHE $0020 C:\Documents and Settings\%User%\Local
Settings\Temporary Internet Files
CSIDL_COOKIES $0021 C:\Documents and Settings\%User%\Cookies
CSIDL_HISTORY $0022 C:\Documents and Settings\%User%\Local
Settings\History
CSIDL_COMMON_APPDATA $0023 C:\Documents and Settings\All Users\Application Data
CSIDL_WINDOWS $0024 C:\WINDOWS
CSIDL_SYSTEM $0025 C:\WINDOWS\system32
CSIDL_PROGRAM_FILES $0026 C:\Program Files
CSIDL_MYPICTURES $0027 C:\Documents and Settings\%User%\Мои
документы\Мои рисунки
CSIDL_PROGRAM_FILES_COMMON $002b C:\Program Files\Common Files
CSIDL_COMMON_DOCUMENTS $002e C:\Documents and Settings\All Users\Документы
CSIDL_RESOURCES $0038 C:\WINDOWS\resources
CSIDL_RESOURCES_LOCALIZED $0039 C:\WINDOWS\resources\%LangID%
CSIDL_COMMON_ADMINTOOLS $002f C:\Documents and Settings\All Users\Главное меню\Программы\Администрирование
CSIDL_ADMINTOOLS $0030 C:\Documents and Settings\Главное меню\Программы\Администрирование

Параметр можно использовать совместно с флагом CSIDL_FLAG_CREATE (для версий Win 2k и выше). В этом случае, если заданная в параметре csidl директория не будет найдена, то функция автоматически её создаст и вернет путь по умолчанию.

  • hToken — маркер доступа. Для версий Windows 2000 и ниже всегда приравниваеся к NULL, для остальных версий может принимать ненудевое значение.
  • dwFlags — определяет какой путь будет возвращен функцией: по умолчанию или текущий. Соответственно, может принимать всего два значения: SHGFP_TYPE_DEFAULT и SHGFP_TYPE_CURRENT.
  • pszPath — указатель на строку WideChar.

Небольшой пример использования SHGetFolderPath. В первом случае мы попробуем получить путь к папке «Мои документы», а во втором — к папке с локализованными ресурсами. При этом, во втором случае, если путь не будет найден, то создадим необходимую директорию:
1. Как получить путь к папке «Мои документы»

var buf: array [1..MAX_PATH] of widechar;
begin
  Memo1.Lines.Clear;
  if Succeeded(SHGetFolderPath(0,CSIDL_PERSONAL,0,SHGFP_TYPE_CURRENT,@buf)) then
    Memo1.Lines.Add(buf);
end;

Результат выполнения функции:

C:\Documents and Settings\%User%\Мои документы

2. Как получить путь к папке с локализованными ресурсами или создать её, вернув путь по умолчанию

var buf: array [1..MAX_PATH] of widechar;
begin
  Memo1.Lines.Clear;
  if Succeeded(SHGetFolderPath(0,CSIDL_RESOURCES_LOCALIZED or  CSIDL_FLAG_CREATE,0,SHGFP_TYPE_CURRENT,@buf)) then
    Memo1.Lines.Add(buf);
end;

Результат выполнения функции:

C:\WINDOWS\resources\419

Аналогичным образом можно получать/создавать другие специальные директории Windows. По-моему рассмотреный выше вариант получения путей вполне приемлим для работы в ОС до Windows Vista. Ну, а если нужна поддержка более поздних версий, то тут уже надо использовать последние версии библиотеки и, вдимо, придётся использовать интерфейс ISHFolder.

5 1 голос
Рейтинг статьи
уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.
Подписаться
Уведомить о
4 Комментарий
Межтекстовые Отзывы
Посмотреть все комментарии
Alexo
Alexo
25/02/2010 22:35

Ну, а если нужна поддержка более поздних версий, то тут уже надо использовать последние версии библиотеки и, вдимо, придётся использовать интерфейс ISHFolder.
 
Чем это плохо то?

IL
IL
25/02/2010 22:56

Про параметр hToken в SHGetFolderPath есть в блоге Марко Кэнту http://blog.marcocantu.com/blog/SHGetFolderPath_Default_User.html

Алексей Тимохин

Я последнее время предпочитаю аналогичные функции из JCL — там как раз есть походяшие обёртки.