这似乎是一个记录得很差的函数。
的文档phIcon
说:
当此函数返回时,包含一个指向图标句柄数组的指针。
但由于参数具有 type HICON*
,调用者必须提供数组。
的文档pIconId
也是错误的。原来它也是一个数组。
所有编组都可以使用默认设置完成。由于此 API 没有 ANSI 版本,因此请为其提供全名,SHExtractIconsW
并将其设置Charset
为 Unicode。
就文档而言,没有提到SetLastError
被调用。
[DllImport("Shell32.dll", CharSet=CharSet.Unicode, ExactSpelling=true)]
static extern uint SHExtractIconsW(
string pszFileName,
int nIconIndex,
int cxIcon,
int cyIcon,
IntPtr[] phIcon,
uint[] pIconId,
uint nIcons,
uint flags
);
要调用它,您需要像这样分配数组:
IntPtr[] Icons = new IntPtr[nIcons];
uint[] IconIDs = new uint[nIcons];
最后,我回应@Cody 的评论。由于此 API 的文档记录明显不正确,因此我会尝试使用已正确记录且您将来可以依赖的替代 API。
由于您似乎很难让这一切正常工作,这里有一个有趣的程序,它从shell32.dll
. 我没有尝试进行任何错误检查,也没有DestroyIcon
在图标上调用等等。
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication12
{
public partial class Form1 : Form
{
[DllImport("Shell32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)]
static extern uint SHExtractIconsW(
string pszFileName,
int nIconIndex,
int cxIcon,
int cyIcon,
IntPtr[] phIcon,
uint[] pIconId,
uint nIcons,
uint flags
);
public Form1()
{
InitializeComponent();
}
private IntPtr[] Icons;
private int currentIcon = 0;
uint iconsExtracted;
private void Form1_Load(object sender, EventArgs e)
{
uint nIcons = 1000;
Icons = new IntPtr[nIcons];
uint[] IconIDs = new uint[nIcons];
iconsExtracted = SHExtractIconsW(
@"C:\Windows\System32\shell32.dll",
0,
256, 256,
Icons,
IconIDs,
nIcons,
0
);
if (iconsExtracted == 0)
;//handle error
Text = string.Format("Icon count: {0:d}", iconsExtracted);
}
private void timer1_Tick(object sender, EventArgs e)
{
pictureBox1.Image = Bitmap.FromHicon(Icons[currentIcon]);
currentIcon = (currentIcon + 1) % (int)iconsExtracted;
}
}
}