Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ОСиСП - методички / OS&SP_Lab_2.6(shell).doc
Скачиваний:
95
Добавлен:
18.05.2015
Размер:
1.12 Mб
Скачать

Извлечение методом 2

Метод 2 заключается в том, что наше расширение само извлекает иконки, игнорируя кэш иконок Проводника. При использовании этого метода функция IExtractIcon::Extract() всегда вызывается и именно она отвечает за загрузку иконок и возврат двух HICON Проводнику - для большой и для маленькой иконок. Достоинства этого метода заключаются в том, что вам не нужно волноваться об упорядочивании идентификаторов ресурсов ваших иконок. Оборотная сторона заключается в том, что не используется кэш иконок Проводника, что предположительно должно несколько замедлять загрузку списка файлов в окно Проводника, если вы зайдете в каталог со множеством текстовых файлов.

GetIconLocation() подобна реализованой в методе 1, но делает меньше работы, т.к. нужно только получить размер файла.

STDMETHODIMP CTxtIconShlExt::GetIconLocation (

UINT uFlags,

LPTSTR szIconFile,

UINT cchMax,

int* piIndex,

UINT* pwFlags )

{

DWORD dwFileSizeLo, dwFileSizeHi;

HANDLE hFile;

hFile = CreateFile ( m_szFilename, GENERIC_READ, FILE_SHARE_READ, NULL,

OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );

if ( INVALID_HANDLE_VALUE == hFile )

return S_FALSE; // Сообщаем оболочке, что нужно использовать иконку по умолчанию

dwFileSizeLo = GetFileSize ( hFile, &dwFileSizeHi );

CloseHandle ( hFile );

if ( (DWORD) -1 == dwFileSizeLo && GetLastError() != NO_ERROR )

return S_FALSE; // Сообщаем оболочке, что нужно использовать иконку по умолчанию

m_ldwFileSize = ((DWORDLONG) dwFileSizeHi)<<32 | dwFileSizeLo;

Как только мы сохраним размер файла, устанавливаем pwFlags в GIL_DONTCACHE, чтобы сообщить Проводнику, что ему не нужно проверять кэш иконок. Этот флаг необходим, т.к. мы не заполнили szIconFile/piIndex и нам нужно, чтобы Проводник их проигнорировал.

Флаг GIL_NOTFILENAME также устанавливается, хотя в текущих версиях оболочки он не имеет эффекта. Согласно документации его цель - сообщить Проводнику, что мы не заполнили пару szIconFile/piIndex, но т.к. использование этого флага является бессмысленным (мы не дали Проводнику других данных для извлечения), то похоже, что он не проверяется Проводником. Но, так или иначе, это хорошая идея - выставить этот флаг на случай, если будущие версии оболочки будут проверять его наличие.

*pwFlags = GIL_NOTFILENAME | GIL_DONTCACHE;

return S_OK;

}

Теперь посмотрим внимательнее на Extract(). Вот ее прототип:

HRESULT IExtractIcon::Extract (

LPCTSTR pszFile,

UINT nIconIndex,

HICON* phiconLarge,

HICON* phiconSmall,

UINT nIconSize );

Параметры:

  • pszFile/nIconIndex Имя файла и индекс, определяющие метонахождение иконки. Это те же самые значения, которые были возвращены из GetIconLocation().

  • phiconLarge, phiconSmall Указатели на HICON, которые Extract() должен установить на дескрипторы большой и маленькой иконок.

  • nIconSize Указывает требуемые размеры иконок. Старшее слово определяет размеры (высоту и ширину, т.к. они одинаковы) маленькой иконки, а младшее слово - размеры большой иконки. При нормальных обстоятельствах это будет 0x00100020 (старшее слово 16, младшее - 32), указывающее что требуется маленькая иконка 16х16 и большая 32х32.

В нашем расширении мы не заполняли пару имя/индекс в GetIconLocation(), так что можно проигнорировать pszFile и nIconIndex. Мы просто загружаем две иконки (какие - зависит от размера txt файла) и передаем их Проводнику.

STDMETHODIMP CTxtIconShlExt::Extract (

LPCTSTR pszFile,

UINT nIconIndex,

HICON* phiconLarge,

HICON* phiconSmall,

UINT nIconSize )

{

UINT uIconID;

// Определить используемую иконку, исходя из размера файла

if ( 0 == m_ldwFileSize )

uIconID = IDI_ZERO_BYTES;

else if ( m_ldwFileSize < 4096 )

uIconID = IDI_UNDER_4K;

else if ( m_ldwFileSize < 8192 )

uIconID = IDI_UNDER_8K;

else

uIconID = IDI_OVER_8K;

// Загружаем иконки

*phiconLarge = (HICON) LoadImage ( _Module.GetResourceInstance(),

MAKEINTRESOURCE(uIconID), IMAGE_ICON,

32, 32, LR_DEFAULTCOLOR );

*phiconSmall = (HICON) LoadImage ( _Module.GetResourceInstance(),

MAKEINTRESOURCE(uIconID), IMAGE_ICON,

16, 16, LR_DEFAULTCOLOR );

return S_OK;

}

И вот оно! Проводник показывает иконки, которые мы ему передали.

Еще одну вещь надо отметить при использовании метода 2 - установка флага GIL_SIMULATEDOC в GetIconLocation() не имеет никакого эффекта.

Соседние файлы в папке ОСиСП - методички