- •Методические указания для выполнения лабораторной работы №2.6 по курсу «Операционные системы и системное программирование»
- •Цель работы
- •Теоретические сведения
- •Пример 1 «Добавление пунктов в контекстное меню для отдельных расширений файлов»
- •Использование AppWizard.
- •Интерфейс инициализации
- •Интерфейс взаимодействия с контекстным меню
- •Модификация контекстного меню
- •Отображение подсказки в строке состояния
- •Выполнение выбора пользователя
- •Регистрация расширения оболочки
- •Отладка расширения оболочки
- •Результат
- •Пример 2 «Добавление пунктов в контекстное меню для всех файлов не зависимо от расширения»
- •Дополнительные функции расширения, добавляющего пункты к контекстному меню оболочки.
- •Использование AppWizard
- •Интерфейс инициализации
- •Добавление пунктов к меню
- •Подсказка в строке состояния и "действие"
- •Выполнение выбора пользователя
- •Регистрация расширения
- •Результат
- •Другие способы регистрации расширения
- •Пример 3 «Использование разделяемой с оболочкой памяти»
- •Расширение QueryInfo
- •Использование AppWizard
- •Интерфейс инициализации
- •Создание текста для тултипа
- •Регистрация расширения оболочки
- •Пример 4 «Обработчик перетаскивания контекстного меню»
- •Обработчик перетаскивания
- •Интерфейс инициализации
- •Модификация контекстного меню
- •Создание связи
- •Обеспечение подсказки в строке состояния
- •Создание связи
- •Регистрация расширения
- •Пример 5 «Добавления новых страниц в набор свойств файлов»
- •Обработчик набора свойств
- •Использование AppWizard
- •Интерфейс инициализации
- •Добавление страниц свойств
- •Неприятная ситуация с периодом жизни объектов
- •Функции обратного вызова страницы свойств
- •Обработчики сообщений страницы свойств
- •Регистрация расширения
- •Пример 6 «Обработчик сбрасывания в меню Send To»
- •Обработчик сбрасывания
- •Использование AppWizard
- •Интерфейс инициализации
- •Участвуем в операции drag and drop
- •DragEnter()
- •DragLeave()
- •Регистрация расширения
- •Пример 7 «Owner-drawn меню в расширениях контекстных меню и по созданию расширения контекстного меню, которое отзывается на правый щелчок на фоне окна каталога» Расширение 1 - Пункты меню owner-drawn.
- •Использование AppWizard
- •Интерфейс инициализации.
- •Взаимодействие с контекстным меню
- •Модифицирование контекстного меню.
- •Отображение всплывающей подсказки в строке состояния.
- •Выполнение выбора пользователя.
- •Рисование пункта меню.
- •Обработка wm_measureitem
- •Обработка wm_drawitem
- •Регистрация расширения оболочки
- •Расширение 2 - Обработка щелчка правой кнопкой мыши на фоне окна каталога.
- •Отличия в iShellExtInit::Initialize()
- •Отличия в регистрации.
- •Пример 8 «Добавление колонки в окно детального просмотра Проводника» Детальный просмотр в Windows 2000
- •Использование AppWizard
- •Интерфейс расширения
- •Инициализация
- •Перечисление новых столбцов
- •Отображение данных в столбцах
- •Небольшое отступление - обработка тэгов id3
- •Как это все выглядит?
- •Регистрация расширения оболочки
- •Еще одна полезная штучка - InfoTips
- •Пример 9 «Настройка иконок, отображаемых для файлов заданного типа» Файловые иконки в Проводнике
- •Использование AppWizard
- •Интерфейс расширения
- •Интерфейс инициализации
- •Интерфейс iExtractIcon
- •Извлечение методом 1
- •Извлечение методом 2
- •Регистрация расширения
- •Пример 10 «Расширение оболочки для изменения иконок у dll в зависимости от их типа»
- •Как установить
- •Подробности реализации
- •Задания для лабораторных работ
- •Содержание отчета
Извлечение методом 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() не имеет никакого эффекта.
