Пример добавления пункта в контекстное меню Windows Explorer
Как объявил недавно основатель Microsoft Билл Гейтс, его компания пожертвует 100 млн. долларов на прививки против менингита и заболеваний дыхательных путей детям в развивающихся странах. Стало также известно, что, в рамках этой благотворительной акции, на детей будет бесплатно установлен Internet Explorer 5.
// Откройте Delphi, выберите в меню New... Dynamic link library// Скопируйте нижеприведенный текст DLL// Скомпилируйте проект.// Теперь нужно зарегистрировать полученную библиотеку.// Наберите в командной строке regsvr32.exe sendtoweb.dll// После этого откройте Windows Explorer и вы увидите новый// пункт меню...unit Sendtoweb;
// Author C Pringle Cjpsoftware.com{ Реализация COM объекта расширения оболочки Windows Explorer. Этот
COM объект способен перенаправлять запросы компоненту TPopupMenu. Компонент
TPopupMenu должен находиться на форме MenuComponentForm.
Вы можете модернизировать код для большей гибкости.
Компонент TContextMenu регистрируется как глобальным обработчик
контекстного меню. Это достигается модификацией ключа реестра
HKEY_CLASSES_ROOT\*\ShellEx\ContextMenuHandlers.
jfl
}interfaceuses
Classes, ComServ, ComObj, ActiveX, Windows, ShlObj, Interfaces, Menus,
ShellAPI, SysUtils, registry;
type
TContextMenuFactory = class(TComObjectFactory)
publicprocedure UpdateRegistry(Register: Boolean); override;
end;
TContextMenu = class(TComObject, IShellExtInit, IContextMenu)
private
FFileName: string;
function BuildSubMenu(Menu: HMENU; IndexMenu: Integer;
var IDCmdFirst: Integer): HMENU;
protected
szFile: array[0..MAX_PATH] of Char;
// Необходимо для исключения предупреждения компилятора о неоднозначностиfunction IShellExtInit.Initialize = IShellExtInit_Initialize;
public{ IShellExtInit }function IShellExtInit_Initialize(pidlFolder: PItemIDList; lpdobj:
IDataObject;
hKeyProgID: HKEY): HResult; stdcall;
{ IContextMenu }function QueryContextMenu(Menu: HMENU;
indexMenu, idCmdFirst, idCmdLast, uFlags: UINT): HResult; stdcall;
function InvokeCommand(var lpici: TCMInvokeCommandInfo): HResult; stdcall;
function GetCommandString(idCmd, uType: UINT; pwReserved: PUINT;
pszName: LPSTR; cchMax: UINT): HResult; stdcall;
end;
var// Должен быть инициализирован перед регистрацией TContextMenu!
GFileExtensions: TStringList;
const
MenuCommandStrings: array[0..3] ofstring = (
'', '&STW Web Upload', '&STW FTPClient', '&STW Setup'
);
implementation{ TContextMenuFactory }{ Public }function ReadDefaultPAth: string;
var
path: string;
Reg: TRegistry;
begin
Reg := TRegistry.CReate;
trywith Reg dobegin
RootKey := HKEY_LOCAL_MACHINE;
Path := 'SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths';
if KeyExists(Path) thenbegin
OpenKey(Path + '\sendtoweb.exe', false);
Result := ReadString(#0);
closekey;
end;
// Ключ добавлен в реестр.end;
finally
Reg.CloseKey;
Reg.Free;
end;
end; // Код регистрацииprocedure TContextMenuFactory.UpdateRegistry(Register: Boolean);
begininherited UpdateRegistry(Register);
// Регистрация нашего обработчикаifRegisterthenbegin
CreateRegKey('*\ShellEx\ContextMenuHandlers\SendToWeb', '',
GUIDToString(Class_ContextMenu));
CreateRegKey('CLSID\' + GUIDToString(ClassID) + '\' +
ComServer.ServerKey, 'ThreadingModel', 'Apartment');
endelsebegin
DeleteRegKey('*\ShellEx\ContextMenuHandlers\SendToWeb');
end;
end;
{ TContextMenu }{ Private }{ Построение контекстного меню с использованием хэндла существующего меню.
Если Menu = nil, мы создаем новый хэндл меню и возвращаем его как результат
функции. Заметьте, что обработчик не поддерживаетвложенные (рекурсивные)
меню. }function TContextMenu.BuildSubMenu(Menu: HMENU; IndexMenu: Integer;
var IDCmdFirst: Integer): HMENU;
var
i: Integer;
menuItemInfo: TMenuItemInfo;
beginif Menu = 0 then
Result := CreateMenu
else
Result := Menu;
// Подготавливаем менюwith menuitemInfo dobegin
cbSize := SizeOf(TMenuItemInfo);
fMask := MIIM_CHECKMARKS or MIIM_DATA or MIIM_ID or
MIIM_STATE or MIIM_SUBMENU or MIIM_TYPE or MIIM_CHECKMARKS;
fType := MFT_STRING;
fState := MFS_ENABLED;
hSubMenu := 0;
hbmpChecked := 0;
hbmpUnchecked := 0;
end;
for i := 0 to High(MenuCommandStrings) dobeginif i = 0 then
menuitemInfo.fType := MFT_SEPARATOR
else
menuiteminfo.ftype := MFT_String;
if i = 1 then
menuitemInfo.fstate := MFS_ENABLED or MFS_DEFAULT
else
menuitemInfo.fstate := MFS_ENABLED;
menuitemInfo.dwTypeData := PChar(MenuCommandStrings[i]);
menuitemInfo.wID := IDCmdFirst;
InsertMenuItem(Result, IndexMenu + i, True, menuItemInfo);
Inc(IDCmdFirst);
end;
end;
{ IShellExtInit }function TContextMenu.IShellExtInit_Initialize(pidlFolder: PItemIDList;
lpdobj: IDataObject; hKeyProgID: HKEY): HResult;
var
medium: TStgMedium;
fe: TFormatEtc;
beginwith fe dobegin
cfFormat := CF_HDROP;
ptd := nil;
dwAspect := DVASPECT_CONTENT;
lindex := -1;
tymed := TYMED_HGLOBAL;
end;
// Ошибка, если lpdobj = Nil.if lpdobj = nilthenbegin
Result := E_FAIL;
Exit;
end;
Result := lpdobj.GetData(fe, medium);
if Failed(Result) then
Exit;
// Если выбран только один файл, получаем его имя и сохраняем в// szFile. иначе - ошибка.if DragQueryFile(medium.hGlobal, $FFFFFFFF, nil, 0) = 1 thenbegin
DragQueryFile(medium.hGlobal, 0, szFile, SizeOf(szFile));
Result := NOERROR;
endelse
Result := E_FAIL;
ReleaseStgMedium(medium);
end;
{ IContextMenu }function TContextMenu.QueryContextMenu(Menu: HMENU;
indexMenu, idCmdFirst, idCmdLast, uFlags: UINT): HResult;
var
extension: string;
I: Integer;
idLastCommand: Integer;
begin
Result := E_FAIL;
idLastCommand := idCmdFirst;
// Получаем расширение файла и определяем, есть ли для него// зарегистрированный обработчик// extension := UpperCase( ( FFileName ) );//for i := 0 to GFileExtensions.Count - 1 do// if Pos(Lowercase(GFileExtensions[ i ]),lowercase(extension))=0 then// begin
BuildSubMenu(Menu, indexMenu, idLastCommand);
// Return value is number of items added to context menu
Result := idLastCommand - idCmdFirst;
// Exit;// end;end;
function TContextMenu.InvokeCommand(var lpici:
TCMInvokeCommandInfo): HResult;
var
idCmd: UINT;
beginif HIWORD(Integer(lpici.lpVerb)) <> 0 then
Result := E_FAIL
elsebegin
idCmd := LOWORD(lpici.lpVerb);
Result := S_OK;
// Активизация диалога и подготовка к послке данных в Webcase idCmd of
1:
begin
ShellExecute(GetDesktopWindow, nil,
Pchar(ExtractFileName(ReadDefaultPath)),
Pchar('Direct' + '"' + szfile + '"'), nil, SW_SHOW);
end;
3:
begin
ShellExecute(GetDesktopWindow, nil,
Pchar(ExtractFileName(ReadDefaultPath)),
Pchar('Path'), nil, SW_SHOW);
end;
2:
ShellExecute(GetDesktopWindow, nil,
Pchar(ExtractFileName(ReadDefaultPath)),
PChar(''), nil, SW_SHOW);
else
Result := E_FAIL;
end;
end;
end;
function TContextMenu.GetCommandString(idCmd, uType: UINT;
pwReserved: PUINT; pszName: LPSTR; cchMax: UINT): HResult;
begin// StrCopy( pszName, 'Send To The Web') ;
Result := S_OK;
end;
initialization{ Заметьте, что в данном фрагменте мы создаем экземпляр TContextMenuFactory,
а не TComObjectFactory. }
TContextMenuFactory.Create(ComServer, TContextMenu, Class_ContextMenu,
'ContextMenu', 'Send To The Web', ciMultiInstance);
// Инициализируем список расширений
GFileExtensions := TStringList.Create;
// GFileExtensions.Add( 'setup msn' );finalization
GFileExtensions.Free;
end.
Это пример программирования на Delphi, демонстрирующий создание пользовательского контекстного меню для Windows Explorer с помощью технологии COM (Component Object Model).
Содержание кода:
Класс TContextMenuFactory отвечает за регистрацию и отмену регистрации компонента контекстного меню.
Класс TContextMenu реализует интерфейсы IShellExtInit и IContextMenu, используемые для инициализации и взаимодействия с контекстным меню.
Метод BuildSubMenu создает подменю для контекстного меню с помощью функции CreateMenu.
Метод QueryContextMenu вызывается, когда пользователь правый клик на элементе в Windows Explorer. Он возвращает handle к контекстному меню и заполняет его пунктами меню.
Метод InvokeCommand вызывается, когда пользователь выбирает команду из контекстного меню. Он выполняет действие в зависимости от выбранной команды (например, загрузка файлов на веб-сервер).
Метод GetCommandString возвращает строковое представление пункта меню.
Для использования этого кода вам нужно:
Создать новый проект Delphi и выбрать тип проекта "Dynamic Link Library".
Скопировать код в файл единицы (Sendtoweb.pas) и скомпилировать его.
Зарегистрировать DLL с помощью командной строки regsvr32 sendtoweb.dll.
Перезапустить Windows Explorer или выйти из системы и войти заново, чтобы увидеть новый пункт меню.
Обратите внимание, что это только пример кода, и вам нужно будет его модифицировать для соответствия вашим конкретным требованиям (например, изменение пунктов меню, реализация аутентификации и т.д.). Кроме того, код предполагает, что у вас есть настроенный веб-сервер.
Пример добавления пункта в контекстное меню Windows Explorer и создания COM-объекта для его реализации.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.