1

USBデバイスからC++SDKを移植してpinvokeを介してC#で使用していますが、これまでのところ順調に進んでいます。問題は、他のコントロールに接続するために使用できる画像リストを作成する関数にあります。SetImageListなどの関数を使用します。

私がやりたいのは、このリストのすべての画像をディスクに保存し、後で使用することです。

このリスト内に特定の画像のインデックスを返す関数は他にもあるので、このインデックスを渡してから画像をディスクに保存することができます。

4

2 に答える 2

2

CImageListクラスインスタンス (所有しているインスタンスのメソッドのメソッドを呼び出して取得)Detach使用すると、 Detach メソッドを呼び出すことでハンドルを取得できます。GetImageListCListCtrlHIMAGELIST

そこから、プラットフォーム呼び出しサービス (P/Invoke) レイヤーを介して、基になる Windows API を呼び出すことができます。

HIMAGELIST以下は、このポインターが にあると仮定していますIntPtr

IntPtr imageList = ...;

まず、 .NETでImageList_GetImageCount関数を宣言する必要があります。

[DllImport("Comctl32.dll", SetLastError = true)]
static extern int ImageList_GetImageCount(IntPtr himl);

そしてもちろん、その呼び出しの結果を変数に格納します。

int imageCount = ImageList_GetImageCount(imageList);

また、各画像の詳細を取得できる必要があるため、次の呼び出しが必要になりますImageList_GetImageInfo

[StructLayout(LayoutKind.Sequential)]
struct RECT
{
    public int left, top, right, bottom;
}

[StructLayout(LayoutKind.Sequential)]
struct IMAGEINFO
{
    public IntPtr hbmImage;
    public IntPtr hbmMask;
    public int Unused1;
    public int Unused2;
    public RECT rcImage;
}

[DllImport("Comctl32.dll", SetLastError = true)]
static extern bool ImageList_GetImageInfo(IntPtr himl, int i,
    ref IMAGEINFO pImageInfo);

これらを使用して、ループを開始して画像に関する情報を取得できます。

for (int i = 0; i < imageCount; ++i)
{
    // The image info.
    var imageInfo = new IMAGEINFO();

    // Get the call to ImageList_GetImageInfo.
    if (!ImageList_GetImageInfo(imageList, i, ref imageInfo)
        throw new System.ComponentModel.Win32Exception();

IMAGEINFO構造体には、ビットマップへのポインターを含むフィールド (フィールド) があることに注意してくださいhbmImage

これはハンドルへのハンドルであり、クラスHBITMAP.NET に同等のものがあります。クラスで静的メソッドを呼び出すことにより、2 つの間で変換できます (はい、クラスにないのは奇妙です)。BitmapFromHbitmapImageBitmap

    using (Bitmap bitmap = Image.FromHbitmap(imageInfo.hbmImage))
    {

インスタンスを取得したら、各インスタンスでメソッドBitmapを呼び出してディスクにダンプできます。Save

        bitmap.Save("<need to generate a filename>.<and extension>");
    }
}

.NET にはImageListクラスがありますが、マネージ実装にハンドルを渡す方法がないことに注意してくださいHIMAGELIST(これにより、はるかに簡単になります)。

于 2012-10-24T19:43:40.593 に答える
0

実際、HIMAGELIST ハンドルからマネージ ImageList を作成することは可能です。この2分間をテストしました。前に:

Public Shared Function ImageList_FromHIMAGELIST(cxcy As Integer, uFlags As UInteger, initSize As Integer, growSize As Integer, _
                                         hicons() As IntPtr) As ImageList

    Dim himl = ImageList_Create(cxcy, cxcy, uFlags, initSize, growSize)
    If Not IsNothing(hicons) AndAlso hicons.Length > 0 Then
        For Each HIcon As IntPtr In hicons
            ImageList_ReplaceIcon(himl, -1, HIcon)
        Next
    End If
    Dim NativeILType As Type = _
        GetType(Button).Assembly.GetType("System.Windows.Forms.ImageList+NativeImageList", False, True)
    If IsNothing(NativeILType) Then
        Return Nothing
    Else
        Dim natObj As Object = _
            Activator.CreateInstance( _
                NativeILType, BindingFlags.Instance Or BindingFlags.NonPublic, Nothing, {himl}, Nothing)


        If Not IsNothing(natObj) Then
            Dim iml As New ImageList With {.ImageSize = New Size(cxcy, cxcy)}
            iml.GetType.InvokeMember("nativeImageList", _
                                     BindingFlags.NonPublic Or BindingFlags.Instance Or BindingFlags.SetField, _
                                      Nothing, iml, {natObj})
            Return iml
        End If
    End If
    Return Nothing
End Function
于 2013-01-02T20:14:17.767 に答える