zoukankan      html  css  js  c++  java
  • (C#)Windows Shell 外壳编程系列2 解释,从“桌面”开始展开

    接上一篇:(C#)Windows Shell 外壳编程系列1 - 基础,浏览一个文件夹

    让我们详细解释一下 Shell 编程中最基本的一些函数、结构体和枚举。

    SHGetDesktopFolder
    获取桌面的 IShellFolder 接口

    [DllImport("shell32.dll")]
            
    public static extern Int32 SHGetDesktopFolder(out IntPtr ppshf);

    要使用这个函数,必须先定义一个 IntPtr 指针。然后通过指针,使用 GetObjectForIUnknown 返回通过指向 COM 对象的 IShellFolder 接口的指针实例。于是需要编写以下函数:

    public static IShellFolder GetDesktopFolder(out IntPtr ppshf)
            
    {
                SHGetDesktopFolder(
    out ppshf);
                Object obj 
    = Marshal.GetObjectForIUnknown(ppshf);
                
    return (IShellFolder)obj;
            }

    ParseDisplayName
    获得对象的PIDL,即便对象在目录树中处于当前目录下一层或更多层。例如,对于文件对象来说,它的解析名就是它的路径,我们用文件系统对象的完全路径名来调用桌面的IshellFolder接口的 ParseDisplayName 方法,它会返回这个对象的完全PIDL。定义:
    void ParseDisplayName(
                IntPtr hwnd,
                IntPtr pbc,
                [MarshalAs(UnmanagedType.LPWStr)] 
    string pszDisplayName,
                
    out uint pchEaten,
                
    out IntPtr ppidl,
                
    ref uint pdwAttributes);

    里面最重要的参数就是 out IntPtr ppidl 了,它返回 pszDisplayName 指定路径对应的 PIDL。然而仅仅是 PIDL 并不能让你做更多的事情。这时候还需要调用 BindToObject 来返回 IShellFolder 接口。

    BindToObject
    根据 PIDL 创建和初始化 IShellFolder 对象。定义:

    void BindToObject(
                IntPtr pidl,
                IntPtr pbc,
                [In()] 
    ref Guid riid,
                
    out IShellFolder ppv);

    里面有一个 [In()] ref Guid riid 参数,表示接口的接口标识符 (IID)。GUID其实就是一个唯一的标识符。世界上的任何两台计算机都不会生成重复的 GUID 值。GUID 主要用于在拥有多个节点、多台计算机的网络或系统中,分配必须具有唯一性的标识符。我们这里使用 IID_IShellFolder 表示它获取的是一个 IShellFolder 接口。

    public static Guid IID_IShellFolder = new Guid("{000214E6-0000-0000-C000-000000000046}");

    另外介绍 IEnumIDList 接口。IEnumIDList 接口使资源管理器获得文件夹包含的全部对象的PIDL,PIDL然后可以用来获得这些对象的信息。

    因此,我们使用 EnumObjects 函数返回的将是 IEnumIDList 的指针:

    int EnumObjects(IntPtr hWnd, SHCONTF flags, out IntPtr enumIDList);

    其中 flags 是 SHCONTF 枚举类型,它决定了枚举的内容:

    SHCONTF

    因此,我们可以通过 flags 的不同来分别列举子文件和子目录。这里会遇到一个问题,怎么获取 PIDL 对象的名称呢。这里编写了2个函数,可以通过 PIDL 或者 IShellFolder 返回对象的名称(详细解释留到下一节):

    获取名称

    例子二,从“桌面”开始展开

    这个例子将使你深入理解之前的内容。它是这样的一个例子,允许你从“桌面”开始,一直展开到最深层的对象。

    例2

    照例,附图片和源代码:



    源代码:/Files/lemony/WinShell2.rar

    下一节将讲述 Shell 编程中的 IContextMenu ,也就是上下文菜单,将使你的应用程序列举 Shell 对象的同时,还能在右键操控它们的菜单。
  • 相关阅读:
    【WindowsAPI之MoveWindow】 C#调整目标窗体的位置、大小
    Visual Studio 2022 community 社区版本离线安装
    MS SQL SERVER 创建表、索引、添加字段等常用脚本
    支付宝支付jemter 插件,导入到高版本jmeter 中使用
    ASP.NET Core定时之Quartz.NET使用
    PB通过OLE方式调用C#.NET DLL时,DLL获取自身根目录
    C#.NET 操作Windows服务(安装、卸载)
    数据库的基本概念
    TCP 与 UDP的区别
    静静地想
  • 原文地址:https://www.cnblogs.com/luluping/p/1809848.html
Copyright © 2011-2022 走看看