65.9K
CodeProject 正在变化。 阅读更多。
Home

关联图标图像控件

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.92/5 (9投票s)

2005年5月30日

5分钟阅读

viewsIcon

114954

downloadIcon

867

一个显示与给定文件或文件扩展名关联的图标的 Web 控件。

引言

此自定义服务器控件显示与给定文件扩展名当前关联的图标。文件图标关联由操作系统维护,只需一次 Win32 API 调用即可检索。

当您只需要显示一个众所周知的图标,或者当您想显示带有相应图标的文件列表时,可以使用此控件。

使用代码

文章下载包含一个 VS.NET 2003 项目,这是一个 ASP.NET 应用程序示例。该应用程序包含两个包含代码重要部分的文件。这些文件是 AssociatedIcon.csIconExtractor.cs

我建议您不要直接解压压缩文件中的整个项目,而是使用您自己的 Visual Studio .NET 安装创建一个名为 AssociatedIcons 的新 C# ASP.NET 项目。在您的应用程序中添加两个文件夹:ControlsIconStubs。删除默认的 Webform1.aspx 文件,并添加一个名为 TestPage 的新 WebForm。

为了节省大量打字时间,只需获取 IconExtractor.cs 文件并将其放入项目中的 Controls 文件夹。在同一个 Controls 文件夹中添加一个名为 AssociatedIcon 的新类。这个类将是我们的自定义控件。

完成所有这些之后,您的项目应该看起来像下面的图片

将以下代码添加到您刚刚创建的 AssociatedIcon.cs 文件中

using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;

namespace AssociatedIcons.Controls
{
    [ToolboxData("<{0}:AssociatedIcon 
        runat=server></{0}:AssociatedIcon>")]
    public class AssociatedIcon : Image
    {
        /*****
         * This control accepts a file name or file extension,
         * determines the associated icon, and displays it on the page
         * ***/

        /// <summary>
        /// Gets or sets a file name or extension (including the dot)
        /// to display the associated icon
        /// </summary>
        public string ExtensionOrFile
        {
            get
            {
                string s = (string)ViewState["ExtensionOrFile"];
                if(s == null) return "";
                return s;
            } 
            set{ ViewState["ExtensionOrFile"] = value; } 
        }

        /// <summary>
        /// Determines if the icon size will be 16x16 or 32x32 pixels
        /// </summary>
        public bool LargeIcon
        {
            get
            {
                object obj = ViewState["LargeIcon"];
                if(obj == null) return false;
                return (bool)obj;
            } 
            set
            {
                ViewState["LargeIcon"] = value;
            }
        }

        public override string ImageUrl
        {
            get{ return base.ImageUrl;}
            set{ throw new 
                 InvalidOperationException("The ImageUrl cannot be set.");}
        }

        protected override void OnLoad(EventArgs e)
        {
            if(!Page.IsPostBack)
                base.ImageUrl = 
                  IconExtractor.GetUrlToIcon(ExtensionOrFile, LargeIcon);
        }

    }
}

因为我们将在 IconStubs 文件夹中写入文件,所以您需要为 ASPNET 用户在该文件夹中授予*写*权限。如果您以前从未做过,这个过程很简单。在任何 Windows 资源管理器窗口中,找到 IconStubs 文件夹,右键单击它并选择*属性*。转到*安全*选项卡。如果选中了*允许继承的权限 [...]*复选框,请取消选中它。使用*添加*按钮将 ASPNET 用户添加到列表中(如果它尚未在列表中)。在列表中选择 ASPNET 用户,然后仅选择*允许写入*复选框。请参见下图。完成后,单击确定即可。

此控件的工作原理

正如您从上面的代码中可以看到的,我们的控件是 System.Web.UI.WebControls.Image 服务器控件的一个相当简单的扩展。我们添加了一个属性来保存所需的文件扩展名(或文件名),另一个属性来指定所需的图标是小(16 x 16 像素)还是大(32 x 32 像素)版本。我们还禁止直接设置 ImageUrl 属性,以免任何人无意中更改它。

您也可以注意到,这个控件的代码中并没有太多东西。实际的进程由 IconExtractor 类实现。

IconExtractor 类

图标提取过程的核心是调用 SHGetFileInfo Shell32 Windows API。此 API 除了其他功能外,还可以为给定文件提供关联图标(小或大)的句柄。之后,代码会将图标保存为具有透明背景的 PNG 图像,并存放在 IconStubs 文件夹中。下次请求相同的扩展名图标时,将返回已存在的图像文件的 URL,而无需创建新文件。一段时间后,您应该会发现您的 IconStubs 文件夹中充满了您使用的所有图标的图像,如下所示

注意:IE(至少我拥有的版本:6.0.2800.1106)在透明 PNG 渲染方面存在缺陷,导致透明区域渲染为灰色。代码中包含注释,可帮助您将实现从 PNG 更改为 GIF,但会丢失透明背景。

注意:在 .NET 中实现 GIF 图像的透明背景非常复杂,涉及*不安全*的代码块,因此为了简洁(如果您希望我诚实地说,也可以说是懒惰 :) ),我决定不将其包含在此示例中。

测试控件

要查看控件的工作原理,让我们在 TestPage.aspx 中添加一些内容。首先,让我们使用我们的 Controls 命名空间注册一个标签前缀。将以下内容添加到页面 ASPX 的顶部

<%@ Register Tagprefix="SP" 
    Namespace="AssociatedIcons.Controls" Assembly="AssociatedIcons" %>

现在,让我们在页面中添加一些我们的控件实例,如下所示

        <form id="TestPage" method="post" runat="server">
            <br>
            <SP:AssociatedIcon id="file1" runat="server" 
                ExtensionOrFile=".doc" largeIcon="True" />
            MyDocument.doc

            <br>
            <SP:AssociatedIcon id="file2" runat="server" 
                ExtensionOrFile="file.bmp" largeIcon="false" />
            MyIcon.bmp

            <br>
            <SP:AssociatedIcon id="Associatedicon1" runat="server" 
                ExtensionOrFile="file.jpg" largeIcon="true" />
            MyIcon.jpg

            <br>
            <SP:AssociatedIcon id="Associatedicon2" runat="server" 
                ExtensionOrFile="file.gif" largeIcon="false" />
            MyIcon.gif

            <br>
            <SP:AssociatedIcon id="Associatedicon3" runat="server" 
                ExtensionOrFile="file.mp3" largeIcon="true" />
            MyIcon.mp3

            <br>
            <asp:Button ID=test Runat=server  Text=test />
        </form>

当您保存、编译并运行此页面时,您应该会看到类似于下图的内容。图标可能会因您将哪些程序与文件扩展名关联而异。

增强建议

与任何示例一样,本文中的代码远非完美,并且充满了新功能或增强功能的可能性(可能还存在一些错误)。一些我想到的改进此代码的想法是

  • 使用配置值来确定图标图像文件的物理路径和虚拟路径。这样,您就可以在多个应用程序中使用此控件,并共享同一文件夹中的同一组图标。
  • 实现 GIF 的背景透明。将代码更改为生成 GIF 而不是 PNG(同时 IE 尚未修复透明 PNG 错误),并将背景颜色设为透明。这里有两个不错的参考资源可以帮助您:Eric Johnson 的使用 GDI+ 实现透明背景(新闻组帖子)和 Bob Powell 的GDI+ FAQ

参考文献

历史

  • 2005 年 5 月 29 日 - 代码已提交。
© . All rights reserved.