Шаг 9.
Применение COM-объектов, входящих в Windows. Получение уведомлений от Windows Explorer (Проводника)

    На этом шаге мы рассмотрим получение уведомлений от Проводника.

    В данном разделе будет рассмотрен пример, позволяющий анализировать сообщения о манипуляциях каталогами в 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.
Текст этого приложения можно взять здесь (219 Кб).

    В данном проекте необходимо реализовать интерфейс 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 (Проводнике).




Предыдущий шаг Содержание Следующий шаг