当右击任何类型的文件时,快捷菜单中弹出的选项除了操作系统默认的选项(例如打开,剪切,复制之类)外,还包括自己定义增加的选项。
大家都用过winzip,winrar这些压缩软件,在快捷菜单中就有‘压缩至...’等等选项,我想实现的功能就跟这些差不多。
请问,需要在注册表增加哪些项可以实现这样的功能。

解决方案 »

  1.   

    这个问题在Delphibbs曾经进行过大讨论,当时我给出的办法是写Shell Extenstion,不过后来有人给出更简单的方法,那就是直接更改注册表,具体讨论见:http://www.delphibbs.com/delphibbs/dispq.asp?lid=1248436
      

  2.   

    如果采用COM的编写方式,这里还有一个相关的帖子。http://www.delphibbs.com/delphibbs/dispq.asp?lid=1190116
      

  3.   

    这是一个Shell扩展菜单模板,非常不错的!利用她你能轻松地写出Shell Context Menu。
    unit ContextMenuHandler;interface
       uses Windows,ActiveX,ComObj,ShlObj,Classes, Registry;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;{全局唯一标识符(GUID)是一个16字节(128为)的值,它唯一地标识一个接口(interface)}
    var
       FileList:TStringList;
       Buffer:array[1..1024]of char;
       HasNoTextFile : boolean;implementationuses ComServ, SysUtils, ShellApi, GblImpl;//, UnitForm;function TContextMenu.SEIInitialize(pidlFolder: PItemIDList; lpdobj: IDataObject;
       hKeyProgID: HKEY): HResult;
    var
       StgMedium: TStgMedium;
       FormatEtc: TFormatEtc;
       FileNumber,i:Integer;
    begin
       //如果lpdobj等于Nil,则本调用失败
       if (lpdobj = nil) then begin
          Result := E_INVALIDARG;
          Exit;
       end;   //首先初始化并清空FileList以添加文件
       FileList:=TStringList.Create;
       FileList.Clear;
       //初始化剪贴版格式文件
       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;   //首先查询用户选中的文件的个数
       FileNumber := DragQueryFile(StgMedium.hGlobal,$FFFFFFFF,nil,0);
       //循环读取,将所有用户选中的文件保存到FileList中
       HasNoTextFile := False;
       for i:=0 to FileNumber-1 do begin
          DragQueryFile(StgMedium.hGlobal, i, FFileName, SizeOf(FFileName));
          if (LowerCase(ExtractFileExt(FFileName)) <> '.txt') and (LowerCase(ExtractFileExt(FFileName)) <> '.htm')
            and (LowerCase(ExtractFileExt(FFileName))<>'.html') then HasNoTextFile := True;
          FileList.Add(FFileName);
          Result := NOERROR;
       end;             
       ReleaseStgMedium(StgMedium);
    end;function TContextMenu.QueryContextMenu(Menu: HMENU; indexMenu, idCmdFirst,
       idCmdLast, uFlags: UINT): HResult;
    begin
       Result := 0;
       if HasNoTextFile then exit;
       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(InsertMenuCaption));
     // 返回增加菜单项的个数
       Result := 1;
       end;
    end;function TContextMenu.InvokeCommand(var lpici: TCMInvokeCommandInfo): HResult;
    var
    //   sFile:TFileStream;
       charSavePath:array[0..1023]of char;
       sSaveFile:String;
       i:Integer;
       F: TextFile;
       FirstLine: string;
       Reg : TRegIniFile;
       FileName : string;
    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;   //建立一个临时文件保存用户选中的文件名
       GetTempPath(1024,charSavePath);
       sSaveFile:=charSavePath+'gs_u2g_0001.tmp';   AssignFile(F,sSaveFile);   { next file in Files property }
       ReWrite(F);
       //将文件名保存到临时文件中
       for i:= 0 to FileList.Count -1 do begin
          FirstLine:=FileList.Strings[i];
          Writeln(F,FirstLine);    { Read the first line out of the file }
       end;
       CloseFile(F);
       //调用文件操作程序对用户选中的文件进行操作
       Reg := TRegIniFile.Create(RegStr);
       try
           FileName := Reg.ReadString(SectName, SectValuePath,'');
       finally
           Reg.Free;
       end;
       //ShellExecute(0,nil,'c:\FileOP.exe',PChar(sSaveFile),charSavePath,SW_NORMAL);
       ShellExecute(0,nil,PChar(FileName),PChar(sSaveFile),charSavePath,SW_NORMAL);   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);
          CreateRegKey('*\shellex', '', '');
          CreateRegKey('*\shellex\ContextMenuHandlers', '', '');
          CreateRegKey('*\shellex\ContextMenuHandlers\OpenWithWordPad', '', ClassID);    //如果操作系统为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');
          DeleteRegKey('*\shellex\ContextMenuHandlers');
    //      DeleteRegKey('*\shellex');
          inherited UpdateRegistry(Register);
       end;
    end;initialization
     TContextMenuFactory.Create(ComServer, TContextMenu, Class_ContextMenu,
       '', 'Context Menu Shell Extension', ciMultiInstance,tmApartment);
       HasNoTextFile := False;end.
      

  4.   

    转发:问题的标题是:如何在Win95弹出菜单中加入自己的内容和功能调用?(200分)
    ---------------------------------------------
    关于多种环境注册右键弹出事件的方法,请
    按照以下对应关系:
    \HKEY_CLASSES_ROOT\Folder\Shell          任意文件夹
    \HKEY_CLASSES_ROOT\Directory\Shell       任意目录
    \HKEY_CLASSES_ROOT\Drive\Shell           任意驱动器
    \HKEY_CLASSES_ROOT\*\Shell               任意文件
    新建一个主键,并在主键下添加一个特定主键(command),修改command的键值指到你的应用程序。例如:
    建立\HKEY_CLASSES_ROOT\Folder\Shell\AimTest,将在Folder上按下右键时出现"AimTest"菜单
    建立\HKEY_CLASSES_ROOT\Folder\Shell\AimTest,并设定该主键的缺省值为"我的测试菜单",则将在Folder上按下右键时出现"我的测试菜单"菜单钮。
    建立\HKEY_CLASSES_ROOT\Folder\Shell\AimTest\command,并设定command"缺省"键值为"c:\tools\pse.exe" "%1",则将以Folder名为第一参数启动pse.exe。
        * 注意command键值的双引号不可缺省另外:
    \HKEY_CLASSES_ROOT\Folder\Shellex
    \HKEY_CLASSES_ROOT\Directory\Shellex
    \HKEY_CLASSES_ROOT\Drive\Shellex
    \HKEY_CLASSES_ROOT\*\Shellex
    可以按应用程序在Registroy中的注册ID调用。这样可以调用.DLL和钩子函数。
    但建议按第一种方法调用应用程序,因为注册一个ID实在麻烦。如果你的应用程序支持DDE,你可以参考
    \HKEY_CLASSES_ROOT\Directory\Shell\Find键的设定来进行DDE设置。
      

  5.   

    to CoolSlob() :
      谢谢,不知可否详细说明。
    to BCB_FANS(四大名捕之追杀令) :
      很详细,谢谢。我尝试一下把它翻译为delphi版本的,如果遇到问题向你请教。
    to nne998(上上下下左右左右BABA) :
      谢谢!拜读中...
      

  6.   

    回复人: BCB_FANS(四大名捕之追杀令) (  ) 信誉:102  2002-09-16 15:43:00  得分:0  
     
     打不开,  这个问题在Delphibbs曾经进行过大讨论,当时我给出的办法是写Shell Extenstion,不过后来有人给出更简单的方法,那就是直接更改注册表,具体讨论见:http://www.delphibbs.com/delphibbs/dispq.asp?lid=1248436
     
     
      

  7.   

    to man8888(北京男人) :
       好!直接了当!
      

  8.   

    1. 如果你要在右键点击目录(文件夹)时,在弹出菜单中有"Browse with MyApp",用户点击后执行相关操作:
    [HKEY_CLASSES_ROOT\Directory\Shell]下“新建”项Browse with MyApp,在其下再“新建”项command;在右侧,双击command项的“(默认)”,填入你的程序路径和名字如C:\Program Files\MyApp\MyApp.exe "%1"。"%1"表示被选中的文件名,作为参数传给MyApp.exe
    2. 如果你要在右键单击某种扩展名的文件(如*.txt)时,在弹出的菜单中有"Open with MyApp",用户点击后执行相关操作:
    [HKEY_CLASSES_ROOT\.txt],看到其“(默认)”为txtfile,再到[HKEY_CLASSES_ROOT\txtfile\shell]下“新建”项Open with MyApp,在其下再“新建”项command;在右侧,双击command项的“(默认)”,填入你的程序路径和名字如C:\Program Files\MyApp\MyApp.exe "%1"。"%1"表示被选中的文件名,作为参数传给MyApp.exe
    3. 如果你要在右键单击所有扩展名的文件时,在弹出的菜单中有"Open with MyApp",用户点击后执行相关操作:
    [HKEY_CLASSES_ROOT\*]下如果没有shell项,自己新建一个。在shell下“新建”项Open with MyApp,在其下再“新建”项command;在右侧,双击command项的“(默认)”,填入你的程序路径和名字如C:\Program Files\MyApp\MyApp.exe "%1"。"%1"表示被选中的文件名,作为参数传给MyApp.exe
      

  9.   

    to BCB_FANS(四大名捕之追杀令) : 
    可否将
    http://www.csdn.net/expert/topic/906/906137.xml?temp=.5951349
    中所说的那个Shell程序源代码mail给我?谢谢!我尝试一下翻译为delphi.
    my email: [email protected] 
      

  10.   

    Sorry,回复完你的问题就关机了,所以没有及时看到你的回复。现在已经发送,请注意查收!不过我在Delphibbs上面有转载的Delphi例子,我想应该更有参考价值!
      

  11.   

    收到!
    谢谢!
    delphibbs上的那个例子已经收藏。