- •Методические указания для выполнения лабораторной работы №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 в зависимости от их типа»
- •Как установить
- •Подробности реализации
- •Задания для лабораторных работ
- •Содержание отчета
Использование AppWizard
Запустите AppWizard и создайте новый ATL COM проект. Назовем его FileTime. Сохраните все начальные установки AppWizard и щелкните Finish. Чтобы добавить COM объект к DLL, перейдите в дерево просмотра классов, ClassView, щелкните правой кнопкой на пункте FileTime classes и укажите New ATL Object.
В мастере ATL объектов, на первой панели уже указан Simple Object, поэтому просто щелкните Next. Во второй панели, в поле редактирования Short Name введите краткое имя FileTimeShlExt и щелкните OK. (Остальные поля заполняются автоматически.) Мы создали класс CFileTimeShlExt, который содержит основной код для реализации объекта COM. Добавим свой код к этому классу.
Интерфейс инициализации
Поскольку обработчик набора свойств оперирует всеми выделенными файлами сразу, в качестве интерфейса инициализации используется IShellExtInit. Нам необходимо добавить IShellExtInit к списку интерфейсов, которые реализует CFileTimeShlExt. Инструкция, как это сделать, содержится в части IV. Классу также необходим список строк, в котором будут храниться имена выделенных файлов.
|
typedef std::list<std::basic_string<TCHAR> > string_list;
protected: // IFileTimeShlExt string_list m_lsFiles; |
Метод Initialize() делает тоже, что и в части II - читает имена выделенных файлов и сохраняет их в списке строк. Вот начало функции:
|
HRESULT CFileTimeShlExt::Initialize ( LPCITEMIDLIST pidlFolder, LPDATAOBJECT pDataObj, HKEY hProgID ) { TCHAR szFile [MAX_PATH]; UINT uNumFiles; HDROP hdrop; FORMATETC etc = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; STGMEDIUM stg; INITCOMMONCONTROLSEX iccex = { sizeof(INITCOMMONCONTROLSEX), ICC_DATE_CLASSES };
// Инициализация общих элементов управления InitCommonControlsEx ( &iccex ); |
Мы инициализируем общие элементы управления, потому что наша вкладка будет использовать элемент управления для выбора даты и времени (date/time picker (DTP)). Далее мы выполняем всю черновую работу с помощью интерфейса IDataObject и получаем дескриптор HDROP для перечисления выделенных файлов.
|
// Читаем список пунктов из объекта данных. Они сохранены в форме HDROP, // поэтому, просто получаем HDROP и используем drag 'n' drop API if ( FAILED( pDataObj->GetData ( &etc, &stg ))) return E_INVALIDARG;
// Получаем HDROP hdrop = (HDROP) GlobalLock ( stg.hGlobal );
if ( NULL == hdrop ) { ReleaseStgMedium ( &stg ); return E_INVALIDARG; }
// Определяем, сколько файлов участвует в операции uNumFiles = DragQueryFile ( hdrop, 0xFFFFFFFF, NULL, 0 ); |
Далее следует цикл, который перечисляет выделенные файлы. Расширение оперирует только файлами, любые директории, которые нам попадаются мы игнорируем.
|
for ( UINT uFile = 0; uFile < uNumFiles; uFile++ ) { // Получаем следующее имя файла if ( 0 == DragQueryFile ( hdrop, uFile, szFile, MAX_PATH )) continue;
// Пропускаем каталоги. Мы могли бы использовать дескрипторы каталогов, т.к. у них // есть время и дата создания, но в этом примере я предпочитаю этого не делать if ( PathIsDirectory ( szFile )) continue;
// Добавляем имя файла к нашему списку m_lsFiles.push_back ( szFile ); } // end for // Освобождаем ресурсы GlobalUnlock ( stg.hGlobal ); ReleaseStgMedium ( &stg ); |
Вот что здесь нового: существует предел числа страниц, которые может иметь набор свойств. Он определен как константа MAXPROPPAGES в prsht.h. Каждый файл получает свою собственную страницу, и, если наш список содержит больше файлов, чем MAXPROPPAGES, остальные придется исключить, так как MAXPROPPAGES это предел. (Хотя, если MAXPROPPAGES=100, то набор свойств все равно не сможет показать все множество вкладок, максимум - 34).
|
// Проверим, сколько файлов было отмечено, если больше чем // MAXPROPPAGES, укоротим список if ( m_lsFiles.size() > MAXPROPPAGES ) { m_lsFiles.resize ( MAXPROPPAGES ); }
// Если мы нашли какие-нибудь файлы, пригодные для работы, вернем S_OK. // В противном случае вернем E_FAIL return ( m_lsFiles.size() > 0 ) ? S_OK : E_FAIL; } |
