これは、文書化されていない関数のようです。
のドキュメントにphIcon
は次のように書かれています:
この関数が戻ると、アイコン ハンドルの配列へのポインターが含まれます。
ただし、パラメーターには typeHICON*
があるため、呼び出し元は配列を提供する必要があります。
のドキュメントpIconId
も間違っています。これも配列であることがわかります。
すべてのマーシャリングは、デフォルト設定を使用して実行できます。この API には ANSI バージョンがないため、完全な名前を付け、を UnicodeSHExtractIconsW
に設定します。Charset
ドキュメントに関する限り、呼び出されることについての言及はありません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;
}
}
}