我需要一个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
。
答案 0 :(得分:1)
为什么不简单地使用.NET本地Icon.ExtractAssociatedIcon
方法,这似乎做同样的事情?
Me.Icon = Icon.ExtractAssociatedIcon( _
"C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\devenv.exe")
P.S .: 我尝试了你的代码,你所描述的结果相同,错误。上面的代码片段似乎可以正常工作。
答案 1 :(得分:0)
尝试使用原生的.NET方法stakx提及 - 虽然保存了ICO文件,但我已经很幸运了(如果你保存为另一种格式,比如位图,它通常可以正常工作)
对于pinvoke,这样的某些东西应该有效:(警告,未经测试) 引用: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);
}
答案 2 :(得分:0)
传入句柄肯定是错误的,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
如果模块句柄为null,则不需要StringBuilder。如果不是“index”参数,请不要使用此代码。 Icon.ExtractAssocationIcon也可以正常工作。