需要.NET中Shell32的extractassiviaticon函数的工作示例
题
我需要一个在shell32.dll中的extracsAssivienticon函数的工作示例。我无法正常工作,我没有想法。我需要另一组关于以下代码的目光。当表单加载时,其图标应设置为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
.
解决方案
传递手柄肯定是错误的,第一个参数到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。如果您没有“索引”参数,请勿使用此代码。 ICON.ExtractAssocationIcon也将工作。
其他提示
为什么不简单地使用.NET本地 Icon.ExtractAssociatedIcon
方法,似乎有同样的事情?
Me.Icon = Icon.ExtractAssociatedIcon( _
"C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\devenv.exe")
PS:我尝试了您所描述的与您相同的错误结果的代码。上面的代码片段似乎有效。
尝试本机.NET方法Stakx提及 - 不过,我很高兴保存ICO文件(如果您保存为另一种格式,则说是位图,虽然它正常工作)
对于这样的钉子,应该有效:(警告,未测试)引用: http://social.msdn.microsoft.com/forums/en-us/csharpgeneral/thread/ecb6137c-8bda-4468-b5e0-359caeb202b102b1
[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);
}
不隶属于 StackOverflow