На этом шаге мы рассмотрим получение уведомлений от Проводника.
В данном разделе будет рассмотрен пример, позволяющий анализировать сообщения о манипуляциях каталогами в Windows Explorer (Проводнике) и обрабатывать их, дав возможность пользователю разрешить или запретить копирование (перемещение, удаление, изменение имени) каталога. Проекты такого типа используют интерфейс ICopyHook, определенный в модуле ShlObj.
Создание проекта должно начинаться с команды File | New | Other... | ActiveX | ActiveX library (Файл | Создать | Другие... | ActiveX | Библиотека ActiveX). Далее требуется вызвать команду File | New Unit (Файл | Создать Модуль) и создать новый модуль, в который поместить следующий текст:
unit UHook; interface uses ShlObj, ComObj, Windows; const CLSID_WEHook:TGUID='{9C123760-65F8-11D2-AEF9-444553540000}'; type TWEHook=class(TComObject,ICopyHook) public function CopyCallback(Wnd: HWND; wFunc, wFlags: UINT; pszSrcFile: PAnsiChar; dwSrcAttribs: DWORD; pszDestFile: PAnsiChar; dwDestAttribs: DWORD): UINT; stdcall; end; implementation uses Dialogs, Forms, ShellAPI, SysUtils, ComServ; type TWEHookFactory=class(TComObjectFactory) public procedure UpdateRegistry(Register: Boolean); override; end; function TWEHook.CopyCallback(Wnd: HWND; wFunc, wFlags: UINT; pszSrcFile: PAnsiChar; dwSrcAttribs: DWORD; pszDestFile: PAnsiChar; dwDestAttribs: DWORD): UINT; var Msg:string; begin Application.Handle:=Wnd; Msg:=''; case WFunc of FO_COPY: Msg:=Format('Действительно ли Вы хотите копировать директорию %s в %s?', [pszSrcFile,pszDestFile]); FO_DELETE: Msg:=Format('Действительно ли Вы хотите удалить директорию %s?', [pszSrcFile]); FO_MOVE: Msg:=Format('Действительно ли Вы хотите переместить директорию %s в %s?', [pszSrcFile,pszDestFile]); FO_RENAME: Msg:=Format('Действительно ли Вы хотите назвать директорию %s именем %s?', [pszSrcFile,pszDestFile]); end; if length(Msg)>0 then Result:=MessageDlg(Msg,mtConfirmation,[mbYes,mbNo, mbCancel],0) else Result:=id_Yes; end; procedure TWEHookFactory.UpdateRegistry(Register: Boolean); begin if Register then begin CreateRegKey('Directory\shellex\CopyHookHandlers\WEHook','', GUIDToString(CLSID_WEHook)); CreateRegKey('CLSID\'+GUIDToString(CLSID_WEHook)+ '\InprocServer32', 'ThreadingModel','Apartment'); inherited UpdateRegistry(Register); end else begin DeleteRegKey('Directory\shellex\CopyHookHandlers\WEHook'); inherited UpdateRegistry(Register); end; end; initialization TWEHookFactory.Create(ComServer,TWEHook,CLSID_WEHook,'WEHook', 'WEFolder Test Hook',ciMultiInstance); end.
В данном проекте необходимо реализовать интерфейс ICopyHook, в котором определен один метод - CopyCallback с соответствующим списком параметров. Для его реализации используется класс TComObject. Параметр WFunc содержит информацию об изменениях, которые пользователь осуществляет с данным каталогом; параметры pszSrcFile и pszDestFile - старое и новое имена данного каталога (содержащие полный путь). Возвращаемый результат содержит информацию о том, согласен ли пользователь с проведением данной операции.
При регистрации сервера, перехватывающего сообщения от Windows Explorer (Проводника), необходимо внести записи в реестр Windows в секции Directory | ShellEx. Внесение такой записи не предусмотрено стандартной процедурой регистрации TComObjectFactory, поэтому необходимо переписать ее метод UpdateRegistry. Вносимая запись представляет собой ссылку на CLSID интерфейса. Кроме того, в реестре необходимо указать, что данный сервер работает в многопоточном режиме и подчиняется протоколу Apartment.
После компиляции данного проекта и регистрации сервера с помощью выбора пункта меню Run | Register ActiveX server (Выполнить | Зарегистрировать Сервер ActiveX) необходимо перезагрузить компьютер (однако в некоторых случаях сервер может начать работу и без перезагрузки).
Для тестирования приложения необходимо в Windows Explorer (Проводнике) создать каталог и попытаться изменить его название, скопировать его в другой каталог или удалить. В результате этих действий будут возникать сообщения, подобные приведенному на рис.1.
Рис.1. Уведомление в Windows Explorer (Проводнике)
Получение подобных уведомлений от Windows Explorer (Проводника) можно использовать в приложениях, которые нуждаются в информации об изменении имен своих каталогов.
На следующем шаге мы рассмотрим процесс создания собственных окон просмотра данных в Windows Explorer (Проводнике).