打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
利用Delphi编写Windows外壳扩展
  • 利用Delphi编写Windows外壳扩展
  • 利用Delphi编写Windows外壳扩展
        对于操作系统原理比较了解的朋友都会知道,一个完备的操作系统都会提供了一个外壳(Shell),以方便普通的用户
    使用操作系统提供的各种功能。Windows(在这里指的是Windows 95\Windows NT4.0以上版本的操作系统)的外壳不但提供
    了方便美观的GUI图形界面,而且还提供了强大的外壳扩展功能,大家可能在很多软件中看到这些外壳扩展了。例如在你的
    系统中安装了Winzip的话,当你在Windows Explore中鼠标右键点击文件夹或者文件后,在弹出菜单中就会出现Winzip的压
    缩菜单。又或者Bullet FTP中在Windows资源管理器中出现的FTP站点文件夹。
        Windows支持七种类型的外壳扩展(称为Handler),它们相应的作用简述如下:

      (1)Context menu handlers:向特定类型的文件对象增添上下文相关菜单;

      (2)Drag-and-drop handlers用来支持当用户对某种类型的文件对象进行拖放操作时的OLE数据传输;

      (3)Icon handlers用来向某个文件对象提供一个特有的图标,也可以给某一类文件对象指定图标;

      (4)Property sheet handlers给文件对象增添属性页(就是右键点击文件对象或文件夹对象后,在弹出菜单中选属性
        项后出现的对话框),属性页可以为同一类文件对象所共有,也可以给一个文件对象指定特有的属性页;

      (5)Copy-hook handlers在文件夹对象或者打印机对象被拷贝、移动、删除和重命名时,就会被系统调用,通过为Windows
        增加Copy-hook handlers,可以允许或者禁止其中的某些操作;

      (6)Drop target handlers在一个对象被拖放到另一个对象上时,就会被系统被调用;

      (7)Data object handlers在文件被拖放、拷贝或者粘贴时,就会被系统被调用。

      Windows的所有外壳扩展都是基于COM(Component Object Model) 组件模型的,外壳是通过接口(Interface)来访问对象的。
    外壳扩展被设计成32位的进程中服务器程序,并且都是以动态链接库的形式为操作系统提供服务的。因此,如果要对Windows
    的用户界面进行扩充的话,则具备写COM对象的一些知识是十分必要的。 由于篇幅所限,在这里就不介绍COM,读者可以参考
    微软的MSDN库或者相关的帮助文档,一个接口可以看做是一个特殊的类,它包含一组函数合过程可以用来操作一个对象。
        写好外壳扩展程序后,必须将它们注册才能生效。所有的外壳扩展都必须在Windows注册表的HKEY_CLASSES_ROOT\CLSID键
    之下进行注册。在该键下面可以找到许多名字像{0000002F-0000-0000-C000-000000000046}的键,这类键就是全局唯一类标识
    符(Guid)。每一个外壳扩展都必须有一个全局唯一类标识符,Windows正是通过此唯一类标识符来找到外壳扩展处理程序的。
    在类标识符之下的InProcServer32子键下记录着外壳扩展动态链接库在系统中的位置。与某种文件类型关联的外壳扩展注册在
    相应类型的shellex主键下。如果所处的Windows操作系统为Windows NT,则外壳扩展还必须在注册表中的
    HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\ShellExtensions\Approved主键下登记。
        编译完外壳扩展的DLL程序后就可以用Windows本身提供的regsvr32.exe来注册该DLL服务器程序了。如果使用Delphi,也可
    以在Run菜单中选择Register ActiveX Server来注册。

        下面首先介绍一个比较常用的外壳扩展应用:上下文相关菜单,在Windows中,用鼠标右键单击文件或者文件夹时弹出的那
    个菜单便称为上下文相关菜单。要动态地在上下文相关菜单中增添菜单项,可以通过写Context Menu Handler来实现。比如大家
    所熟悉的WinZip和UltraEdit等软件都是通过编写Context Menu Handler来动态地向菜单中增添菜单项的。如果系统中安装了
    WinZip,那么当用右键单击一个名为Windows的文件(夹)时,其上下文相关菜单就会有一个名为Add to Windows.zip的菜单项。
    本文要实现的Context Menu Handler与WinZip提供的上下文菜单相似。它将在任意类型的文件对象的上下文相关菜单中添加一个
    文件操作菜单项,当点击该项后,接口程序就会弹出一个文件操作窗口,执行文件拷贝、移动等操作。
         编写Context Menu Handler必须实现IShellExtInit、IContextMenu和TComObjectFactory三个接口。IShellExtInit实现
    接口的初始化,IContextMenu接口对象实现上下文相关菜单,IComObjectFactory接口实现对象的创建。
        下面来介绍具体的程序实现。首先在Delphi中点击菜单的 File|New 项,在New Item窗口中选择DLL建立一个DLL工程文件。
    然后点击菜单的 File|New 项,在New Item窗口中选择Unit建立一个Unit文件,点击点击菜单的 File|New 项,在New Item窗口
    中选择Form建立一个新的窗口。将将工程文件保存为Contextmenu.dpr ,将Unit1保存为Contextmenuhandle.pas,将Form保存为
    OpWindow.pas。
    Contextmenu.dpr的程序清单如下:
    library contextmenu;
        uses
      ComServ,
      contextmenuhandle in 'contextmenuhandle.pas',
      opwindow in 'opwindow.pas' {Form2};

    exports
       DllGetClassObject,
       DllCanUnloadNow,
       DllRegisterServer,
       DllUnregisterServer;

    {$R *.TLB}

    {$R *.RES}

    begin

    end.

        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;

  • 本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
    打开APP,阅读全文并永久保存 查看更多类似文章
    猜你喜欢
    类似文章
    【热】打开小程序,算一算2024你的财运
    Delphi编写windows外壳扩展
    上下文菜单创建
    Windows 7中提高工作效率的七个方法(2)
    PowerPoint中插入视频的三种方法
    一个超时上下文菜单的实现
    Windows GDI与GDI+
    更多类似文章 >>
    生活服务
    热点新闻
    分享 收藏 导长图 关注 下载文章
    绑定账号成功
    后续可登录账号畅享VIP特权!
    如果VIP功能使用有故障,
    可点击这里联系客服!

    联系客服