Иллюстрированный самоучитель по Delphi 7 для профессионалов

Добавление пунктов в системное контекстное меню

Отдельно следует остановиться на описании параметра ipverb. Как уже говорилось, он может представлять из себя как идентификатор пункта меню, так и его текст – строку, заканчивающуюся нулем. Чтобы выяснить это, нужно проверить старшее слово этого 32-разрядного параметра на равенство нулю. В примере ContMenu вызов по тексту не предусмотрен:

if (HiWord(Integer(Ipici.IpVerb)) <> 0) then
begin
Exit;
end;

Для создания расширения контекстного меню мы должны породить объект, поддерживающий эти интерфейсы. К сожалению, мастера, предусмотренные в Delphi, не позволяют в автоматизированном режиме создавать объекты, реализующие уже существующие интерфейсы. Поэтому и описание, и реализацию методов придется делать "по старинке", вручную. В примере ContMenu описание объекта таково:

TContextMenu = class(TComObject, IShellExtlnit, IContextMenu) private
FFileName: array[0..MAX_PATHj of Char;
protected
(IShellExtlnit }
function IShellExtlnit.Initialize = SEIInitialize;
function SEIInitialize(pidlFolder: PItemlDList; Ipdobj: IDataObject;
hKeyProgID: HKEY): HResult; stdcall; { IContextMenu }
function QueryContextMenufMenu: HMENU;
indexMenu, idCmdFirst, idCmdLast,
uFlags: UINT): HResult;
stdcall;
function InvokeCommand(var Ipici: TCMInvokeCommandlnfo): HResult; stdcall;
function GetCommandString(idCmd, uType: UINT; pwReserved: POINT;
pszName: LPSTR; cchMax: UINT): HResult;
stdcall;
end;

Вас может насторожить конструкция, описывающая переименование метода initialize интерфейса ishellExtinit. На самом деле одноименный метод имеется у объекта TComObject, и приведенный синтаксис как раз и предназначен для выхода из подобных ситуаций.

Последняя часть работы – регистрация созданного обработчика. Самое подходящее место для этого – метод updateRegistry фабрики класса. Разработчики примера ContMenu породили класс TContextMenuFactory, который при регистрации СОМ-сервера регистрирует создаваемые фабрикой объекты:

Classic: = GUIDToString(Class_ContextMenu);
CreateRegKey('DelphiProjectXshellex', '', '')/'
CreateRegKey
('DelphiProject\shellex\ContextMenuHandlers', '', '');
CreateRegKey
('DelphiProject\shellex
\ContextMenuHandlers\ContMenu', '',
ClassID);

Пример ContMenu иллюстрирует "дельфийский" подход к созданию серверов СОМ через соответствующие объекты из иерархии объектов Delphi. Но в папке SHELLEXT вы найдете еще один пример создания расширения для контекстного меню, сделанный целиком и только с использованием интерфейсов и функций СОМ. Присмотритесь к этому примеру внимательнее, если хотите глубже понимать внутреннюю структуру СОМ-объектов.

Резюме

Несколько тем, затронутых в этой главе, могут дать лишь начальные представления о принципах работы с оболочкой Windows. Вы можете изучить составляющие ее объекты практически сколь угодно глубоко – были бы потребность да желание. Разумеется, чтобы не "наломать дров", перед этим надо отдать себе отчет в полном и правильном понимании механизмов СОМ.

Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.