代码之家  ›  专栏  ›  技术社区  ›  AMissico

需要Shell32在.NET中的ExtractAssociatedIcon函数的工作示例

  •  0
  • AMissico  · 技术社区  · 16 年前

    我需要Shell32.dll中ExtractAssociatedIcon函数的一个工作示例。我不能让它发挥作用,我也没有想法。我需要在下面的代码上再看一眼。当窗体加载时,它的图标应该设置为Visual Studio图标,但我得到的只是默认的系统图标。

    Imports System.Runtime.InteropServices
    
    Public Class Form1
    
        Public Function ExtractIcon(ByVal path As String, ByVal handle As IntPtr) As Icon
            Dim oResult As Icon
            Dim hIcon As IntPtr
            Dim iIndex As Integer
            Dim oPath As New System.Text.StringBuilder(260, 260)
    
            oPath.Append(path)
    
            hIcon = ExtractAssociatedIcon(handle, oPath, iIndex)
    
            'hIcon = ExtractAssociatedIcon(handle, path, iIndex)
    
            Dim oIcon As Icon = Icon.FromHandle(hIcon)
    
            oResult = DirectCast(oIcon.Clone, Icon)
    
            DestroyIcon(hIcon)
    
            Return oResult
        End Function
    
        Public Declare Auto Function ExtractAssociatedIcon Lib "shell32" ( _
            ByVal hInst As IntPtr, _
            <MarshalAs(UnmanagedType.LPStr)> ByVal lpIconPath As System.Text.StringBuilder, _
            ByRef lpiIcon As Integer) As IntPtr
    
        'Public Declare Auto Function ExtractAssociatedIcon Lib "shell32" ( _
        '    ByVal hInst As IntPtr, _
        '    <MarshalAs(UnmanagedType.LPStr)> ByVal lpIconPath As String, _
        '    ByRef lpiIcon As Integer) As IntPtr
    
        Friend Declare Auto Function DestroyIcon Lib "user32" (<[In]()> ByVal hIcon As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
    
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    
            'ExtractAssociatedIcon uses ExtractAssociatedIcon that is in Shell32.dll.
            'This works, so why doesn't mine? What am I missing?
            'Me.Icon = System.Drawing.Icon.ExtractAssociatedIcon("C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\devenv.exe")
    
            Me.Icon = ExtractIcon("C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\devenv.exe", Me.Handle)
    
        End Sub
    
    End Class
    

    已更正

    <MarshalAs(UnmanagedType.LPStr)> 是问题所在。应该是 LPTStr 不是 LPStr .

    3 回复  |  直到 16 年前
        1
  •  0
  •   Hans Passant    16 年前

    传入句柄绝对是错误的,EAI的第一个参数是模块句柄,而不是图标句柄。这很有效:

    Imports System.Runtime.InteropServices
    Imports System.ComponentModel
    ...
      Public Shared Function ExtractIcon(ByVal path As String, Optional ByVal index As Integer = 0) As Icon
        Dim handle As IntPtr = ExtractAssociatedIcon(IntPtr.Zero, path, index)
        If handle = IntPtr.Zero Then Throw New Win32Exception(Marshal.GetLastWin32Error())
        Dim retval As Icon = Nothing
        using temp As Icon = Icon.FromHandle(handle)
          retval = CType(temp.Clone(), Icon)
          DestroyIcon(handle)
        end using
        Return retval      
      End Function
    
      Private Declare Auto Function ExtractAssociatedIcon Lib "shell32" ( _
          ByVal hInst As IntPtr, ByVal path As String, ByRef index As Integer) As IntPtr
      Private Declare Auto Function DestroyIcon Lib "user32" (ByVal hIcon As IntPtr) As Boolean
    

    如果模块句柄为空,则不需要使用StringBuilder。如果不使用“index”参数,则不要使用此代码。icon.extractAssoctionIcon也可以工作。

        2
  •  1
  •   stakx - no longer contributing Saravana Kumar    16 年前

    为什么不简单地使用.NET本机 Icon.ExtractAssociatedIcon 方法,哪一个似乎做同样的事情?

    Me.Icon = Icon.ExtractAssociatedIcon( _
        "C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\devenv.exe")
    

    附笔。: 我试过你的代码,结果和你描述的一样,是错误的。不过,上面的代码片段似乎可以工作。

        3
  •  0
  •   Chris B    16 年前

    尝试一下stakx提到的本地.NET方法-不过,我已经很幸运地保存了ico文件(如果您保存为另一种格式,比如位图,它通常会工作)。

    对于一个小矮人来说,这样的事情应该奏效:(警告,不要测试) 参考文献: http://social.msdn.microsoft.com/forums/en-US/csharpgeneral/thread/ecb6137c-8bda-4468-b5e0-359caeb202b1

    [DllImport("Shell32.dll")]
    private static extern int SHGetFileInfo( string pszPath, uint dwFileAttributes, out SHFILEINFO psfi, uint cbfileInfo, SHGFI uFlags );
    
    [StructLayout(LayoutKind.Sequential)]
    private struct SHFILEINFO
    {
        public SHFILEINFO(bool b)
        {
            hIcon = IntPtr.Zero; iIcon = 0; dwAttributes = 0; szDisplayName = ""; szTypeName = "";
        }
        public IntPtr hIcon;
        public int iIcon;
        public uint dwAttributes;
    
        [MarshalAs(UnmanagedType.LPStr, SizeConst = 260)]
        public string szDisplayName;
    
        [MarshalAs(UnmanagedType.LPStr, SizeConst = 80)]
        public string szTypeName;
    };
    
    private ExtractIcon()
    {
    }
    
    private enum SHGFI
    {
        SmallIcon = 0x00000001,
        LargeIcon = 0x00000000,
        Icon = 0x00000100,
        DisplayName = 0x00000200,
        Typename = 0x00000400,
        SysIconIndex = 0x00004000,
        UseFileAttributes = 0x00000010
    }
    
    public static Icon GetIcon(string strPath, bool bSmall)
    {
        SHFILEINFO info = new SHFILEINFO(true);
        int cbFileInfo = Marshal.SizeOf(info);
    
        SHGFI flags;
        if (bSmall)
        {
            flags = SHGFI.Icon | SHGFI.SmallIcon | SHGFI.UseFileAttributes;
        }
        else
        {
            flags = SHGFI.Icon | SHGFI.LargeIcon | SHGFI.UseFileAttributes;
        }
    
        SHGetFileInfo(strPath, 256, out info, (uint)cbFileInfo, flags);
    
        return Icon.FromHandle(info.hIcon);
    }
    
    推荐文章