contextmenuhandle的程序清單如下:
unit ContextMenuHandle; interface uses Windows,ActiveX,ComObj,ShlObj,Classes; type TContextMenu = class(TComObject,IShellExtInit,IContextMenu) private FFileName: array[0..MAX_PATH] of Char; protected function IShellExtInit.Initialize = SEIInitialize; // Avoid compiler warning function SEIInitialize(pidlFolder: PItemIDList; lpdobj: IDataObject; hKeyProgID: HKEY): HResult; stdcall; 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; const Class_ContextMenu: TGUID = '{19741013-C829-11D1-8233-0020AF3E97A0}'; {全局唯一標識符(GUID)是一個16字節(128為)的值,它唯一地標識一個接口(interface)} var FileList:TStringList; implementation uses ComServ, SysUtils, ShellApi, Registry,UnitForm; function TContextMenu.SEIInitialize(pidlFolder: PItemIDList; lpdobj: IDataObject; hKeyProgID: HKEY): HResult; var StgMedium: TStgMedium; FormatEtc: TFormatEtc; FileNumber,i:Integer; begin file://如果lpdobj等於Nil,則本調用失敗 if (lpdobj = nil) then begin Result := E_INVALIDARG; Exit; end; file://首先初始化並清空FileList以添加文件 FileList:=TStringList.Create; FileList.Clear; file://初始化剪貼版格式文件 with FormatEtc do begin cfFormat := CF_HDROP; ptd := nil; dwAspect := DVASPECT_CONTENT; lindex := -1; tymed := TYMED_HGLOBAL; end; Result := lpdobj.GetData(FormatEtc, StgMedium); if Failed(Result) then Exit; file://首先查詢用戶選中的文件的個數 FileNumber := DragQueryFile(StgMedium.hGlobal,$FFFFFFFF,nil,0); file://循環讀取,將所有用戶選中的文件保存到FileList中 for i:=0 to FileNumber-1 do begin DragQueryFile(StgMedium.hGlobal, i, FFileName, SizeOf(FFileName)); FileList.Add(FFileName); Result := NOERROR; end; ReleaseStgMedium(StgMedium); end; function TContextMenu.QueryContextMenu(Menu: HMENU; indexMenu, idCmdFirst, idCmdLast, uFlags: UINT): HResult; begin Result := 0; if ((uFlags and $0000000F) = CMF_NORMAL) or ((uFlags and CMF_EXPLORE) <> 0) then begin // 往Context Menu中加入一個菜單項 ,菜單項的標題為察看位圖文件 InsertMenu(Menu, indexMenu, MF_STRING or MF_BYPOSITION, idCmdFirst, PChar('文件操作')); // 返回增加菜單項的個數 Result := 1; end; end; function TContextMenu.InvokeCommand(var lpici: TCMInvokeCommandInfo): HResult; var frmOP:TForm1; begin // 首先確定該過程是被系統而不是被一個程序所調用 if (HiWord(Integer(lpici.lpVerb)) <> 0) then begin Result := E_FAIL; Exit; end; // 確定傳遞的參數的有效性 if (LoWord(lpici.lpVerb) <> 0) then begin Result := E_INVALIDARG; Exit; end; file://建立文件操作窗口 frmOP:=TForm1.Create(nil); file://將所有的文件列表添加到文件操作窗口的列表中 frmOP.ListBox1.Items := FileList; Result := NOERROR; end; function TContextMenu.GetCommandString(idCmd, uType: UINT; pwReserved: PUINT; pszName: LPSTR; cchMax: UINT): HRESULT; begin if (idCmd = 0) then begin if (uType = GCS_HELPTEXT) then {返回該菜單項的幫助信息,此幫助信息將在用戶把鼠標 移動到該菜單項時出現在狀態條上。} StrCopy(pszName, PChar('點擊該菜單項將執行文件操作')); Result := NOERROR; end else Result := E_INVALIDARG; end; type TContextMenuFactory = class(TComObjectFactory) public procedure UpdateRegistry(Register: Boolean); override; end; procedure TContextMenuFactory.UpdateRegistry(Register: Boolean); var ClassID: string; begin if Register then begin inherited UpdateRegistry(Register); ClassID := GUIDToString(Class_ContextMenu); file://當注冊擴展庫文件時,添加庫到注冊表中 CreateRegKey('*\shellex', '', ''); CreateRegKey('*\shellex\ContextMenuHandlers', '', ''); CreateRegKey('*\shellex\ContextMenuHandlers\FileOpreation', '', ClassID); file://如果操作系統為Windows NT的話 if (Win32Platform = VER_PLATFORM_WIN32_NT) then with TRegistry.Create do try RootKey := HKEY_LOCAL_MacHINE; OpenKey('SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions', True); OpenKey('Approved', True); WriteString(ClassID, 'Context Menu Shell Extension'); finally Free; end; end else begin DeleteRegKey('*\shellex\ContextMenuHandlers\FileOpreation'); inherited UpdateRegistry(Register); end; end; initialization TContextMenuFactory.Create(ComServer, TContextMenu, Class_ContextMenu, '', 'Context Menu Shell Extension', ciMultiInstance,tmApartment); end.