Delphi World - это проект, являющийся сборником статей и малодокументированных возможностей  по программированию в среде Delphi. Здесь вы найдёте работы по следующим категориям: delphi, delfi, borland, bds, дельфи, делфи, дэльфи, дэлфи, programming, example, программирование, исходные коды, code, исходники, source, sources, сорцы, сорсы, soft, programs, программы, and, how, delphiworld, базы данных, графика, игры, интернет, сети, компоненты, классы, мультимедиа, ос, железо, программа, интерфейс, рабочий стол, синтаксис, технологии, файловая система...
Расширения оболочки Windows - Всплывающие подсказки

С каждой новой версией Windows, её оболочка (shell) приобретает всё больше и больше различных возможностей. Обычно эти возможности добавляются через расширения оболочки, которые позволяют разработчикам добавлять различные возможности в существующую оболочку Windows. Вот некоторые примеры расширений оболочки: Context Menus (меню, зависящее от объекта, на котором кликнули правой кнопкой мыши), Property Sheet Handlers (страницы в виде закладок, которые появляются в случае выбора пункта контексного меню Properties), Folder Customization, и т.д.

На сайте Microsoft доступно большое количество информации о расширениях оболочки, но эта информация мало полезна Delphi аудитории. Итак давайте рассмотрим расширение оболочки под названием "Всплывающие подсказки" (InfoTip), которые появляются в эксплорере, при наведении мышкой на файл.

Расширения оболочки – Краткий обзор

Расширения оболочки существуют в виде In Process COM серверов. В ответ на определённые события оболочки проводник вызывает соответствующее расширение. Проводник очень специфически реагирует на различные функции в пределах оболочки. Первое, что делает Проводник - это проверяет модули, которые были зарегистрированы для определённого события и, если таковой существует, то загружает данный модуль.

Чтобы быть расширением оболочки, COM сервер должен включать в себя интерфейс, который определяет специфическое поведение для данного расширения, а так же он должен включать в себя интефейс инициализации. Наконец, чтобы быть расширением оболочки, COM сервер должен следовать определённым в системе методам регистрации.

Следующая таблица представляет собой список всех существующих на сегодняшний день расширений оболочки, а так же их минимальных версий, учавствующих интерфейсов и их описаний:

Тип Добавлено в Версия Используемые интерфейсы Описание
Context Menu File class and shell’s object Windows 95+ IContextMenu, IContextMenu2, или IContextMenu3 Позволяет добавлять новые пункты в контекстное меню объекта оболочки.
Right Drag and Drop File class and shell’s object Windows 95+ IContextMenu, IContextMenu2, или IContextMenu3 Позволяет добавлять новые пункты в контекстное меню, при перетаскивании правой кнопкой мыши и отпускании файлов.
Drawing Shell Icons File class and shell’s object Windows 95+ IExtractIcon Позволяет решить в данный момент, какая будет отображаться иконка для данного файла.
Property Sheet File class and shell’s object Windows 95+ IShellPropSheetExt Позволяет добавлять дополнительные страницы property sheet в диалог свойств файла. Так же это работает для Панели управления.
Left Drag and Drop File class and shell’s object Windows 95+ IDropTarget Позволяет решать - что делать с перетаскиваемым объектом (используя левую кнопку мыши) на другой объект в оболочке.
Clipboard File class and shell’s object Windows 95+ IDataObject Позволяет Вам определить, как объект скопирован и извлечён из буфера обмена.
File Hook   Windows 95+ ICopyHook Позволяет контролировать некоторые файловые операции, которые происходят черех оболочку. Вы можете разрешить или запретить их, но Вы не сможете получать уведомление об успешности операции или об ошибке.
Program Execution Explorer Desktop Update IShellExecuteHook Позволяет перехватывать некоторые выполнения программ, которые происходят через оболочку.
Infotip File class and shell’s object Desktop Update IQueryInfo Позволяет отображать короткие текстовые сообщения, когда курсор мышки находится на определённом файле.
Column Folders Windows 2000 IColumnProvider Позволяет добавлять новую колонку в режиме отображения Details в Проводнике.
Icon Overlay Explorer Windows 2000 IShellIconOverlay Позволяет определить собственные изображения, которые будут использоваться как иконки.
Search Explorer Windows 2000 IContextMenu Позволяет добавить новую ячейку в меню "Найти" (в меню, открывающемся при нажатии на "Пуск").
Cleanup Cleanup Manager Windows 2000 IEmptyVolumeCache2 Позволяет добавить новую ячейку в Менеджер Очистки для восстановления дискового пространства.
         

Всплывающие подсказки – Введение и обзор

Infotip-ы это всплывающие окна подсказки, которые появляются в случае, если курсор мышки находится над любым файлом. Если расширения для файла не было зарегистрировано, то будет высвечиваться окошко с подсказкой по умолчанию, однако Вы можете создать своё собственно расширение для отображения информации об определённом типе файла. Например, Office 2000 инсталирует обработчики для MS Word и MS Excel, которые отображают Имя, Автора и заголовок из свойств документа. Расширения Infotip отличаются от других расширений оболочки по регистрации. Об этом мы поговорим позже, когда перейдём к регистрации нашего расширения Infotip.

Implementing Infotip Extensions

Расширение Infotip является In-Process (Inproc) COM Server. Это значит, что Infotip является обыкновенной Windows DLL, которая экспортирует необходимые методы, чтобы быть как обыкновенным элементом управления ActiveX. Расширение Infotip так же включает IQueryInfo и IPersistFile и должна самостоятельно регистрировать себя в реестре. В виду того, что IQueryInfo и IPersistFile являются интерфейсами, то они не содержат исходного кода своих методов. Поэтому наш объект включает в себя каждый метод, определённый в обоих интерфейсах; однако, некоторые из методов не являются необходимыми для нашего расширения Infotip, поэтому мы просто возвращаем E_NOTIMPL, чтобы показать, что они не осуществимы.

IQueryInfo обеспечивает отображение текста во всплывающем окошке и содержит два метода: GetInfoFlags – Получает информационные флаги. На текущий момент это метод не используется, поэтому возвращаем E_NOTIMPL. GetInfoTip – Получает текст Infotip-а.

GetInfoTip определена следующим образом:


function GetInfoTip(dwFlags: DWORD; var ppwszTip: PWideChar): HResult; stdcall;

dwFlags
в данный момент не используется
ppwszTip
Адрес указателя на строку Unicode, кото string pointer that receives the tip string pointer.

Важное замечание

Параметр ppwszTip метода GetInfoTip - это указатель на строковый буфер Unicode, который содержит текст, отображаемый в всплывающем информационном поле. Этот буфер должен быть распределен, используя стандартную программу распределения памяти оболочки, потому что буфер распределен нашим приложением, но освобожден оболочкой. Чтобы быть уверенным, что всё пройдёт успешно, используйте SHGetMalloc для получения указателя на программу распределения памяти оболочки - объект IMalloc. Затем используйте метод Alloc из IMalloc-а для распределения необходимой памяти для буфера содержащего Unicode представление текста Infotip.

Исходник содержит стандартный код, который Вы можете использовать для всех расширений Infotip, которые Вы создадите.

IPersistFile это то, при помощи чего оболочка обеспечивает расширение информацией о файле, на котором находится курсор. В интерфейсе определены пять методов:

IsDirty
проверяет объект на предмет изменений, сделанных в текущем файле. Наше расширение не требует данного метода, поэтому возвращаем E_NOTIMPL.
Load
открывает указанный файл и инициализирует объект из содержимого файла. Мы будем использовать этот метод для получения имени файла, на котором находится курсор.
Save
сохраняет объект в указанном файле. Мы его не используем и возвращаем E_NOTIMPL.
SaveCompleted
уведомляет объект, о том, что он может быть переведён из режима NoScribble в режим Normal. Не используем, поэтому возвращаем E_NOTIMPL.
GetCurFile
получает текущее имя файла, связанного с объектом. Тоже возвращаем E_NOTIMPL.

Load определена следующим образом:


function Load(pszFileName: PoleStr; dwMode: LongInt): HResult; stdcall;

pszFileName
указатель на строку, содержащую абсолютный путь открываемого файла. Строка должна завершаться нулём.
dwMode
содержит набор атрибутов для открытия файла.

Чтобы получить имя файла и его путь, мы будем использовать только IPersistFile; фактически мы не используем интерфейс для доступа к файлу, поэтому игнорируем флаги. Стандартная реализация метода Load сохраняет содержимое pszFileName в приватную переменную, которая будет использоваться в IQueryInfo::GetInfoTip для расположения файла.

Регистрация расширения Infotip

Регистрация происходит в два этапа:

  1. При помощи regsvr32.exe регистрируется COM DLL (Пуск (Start)..Выполнить(Run))


    regsvr32 "C:\...\DPRInfoTip.dll"
    

  2. Добавление ссылки на расширение (.dpr) в ключ реестра HKEY_CLASSES_ROOT.

По умолчанию значение для нового ключа должно быть CLSID объекта COM, который содержит расширение оболочки. Данное значение можно получить из файла Type Library, который был сгенерирован Delphi (имя файла оканчивается на "_TLB.pas"). Для нашего примера расширения CLSID назван CLASS_DPRInfoTip и содержит значение "{B20433A8-D083-11D4-993A-00D00912C440}".

Самый простой способ внести изменения в реестр - это сделать копию файла .REG, содержащуюся в исходниках проекта. Просто измените CLSID и расширение файла на необходимые значения.

Одно важное замечание:

Если Вы регистрируете расширение оболочки в Windows NT или 2000, то необходимо войти в систему с правами администратора.

Проект Delphi World © Выпуск 2002 - 2004
Автор проекта: ___Nikolay