我正在从USB设备移植C ++ SDK以通过pinvoke在C#中使用而且到目前为止我已经取得了很好的进展,现在的问题是建立一个我可以用来附加的图像列表的功能使用SetImageList等函数的其他控件。
我想要做的是将此列表中的所有图像保存到磁盘并稍后使用。
还有其他函数返回此列表中的paraticular图像的索引,因此我可以传递此索引,然后将图像保存到磁盘。
答案 0 :(得分:2)
使用CImageList
class实例(通过调用Detach
method实例上的GetImageList
method上的CListCtrl
获得),您可以获得Detach method实例1}}通过调用Platform Invocation Services (P/Invoke) layer来处理。
从那里,您可以通过IntPtr
调用基础Windows API。
以下假设您在ImageList_GetImageCount
function中有HIMAGELIST
指针:
HIMAGELIST
首先,您需要在.NET中声明ImageList_GetImageInfo
:
IntPtr imageList = ...;
当然,将该调用的结果存储在变量中:
[DllImport("Comctl32.dll", SetLastError = true)]
static extern int ImageList_GetImageCount(IntPtr himl);
您还需要能够获取有关每张图片的详细信息,因此您需要拨打IMAGEINFO
structure:
int imageCount = ImageList_GetImageCount(imageList);
通过这些,您可以开始循环以获取有关图像的信息:
[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);
请注意,HBITMAP
中有一个字段,其中包含指向位图的指针(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();
字段)。
这是Bitmap
class句柄的句柄,在FromHbitmap
method中具有.NET中的等价句柄。您可以通过调用Image
class上的静态Save
method来翻译两者(是的,奇怪的是它不在hbmImage
类上):
Bitmap
获得 using (Bitmap bitmap = Image.FromHbitmap(imageInfo.hbmImage))
{
实例后,可以调用每个实例上的ImageList
class将其转储到磁盘:
Bitmap
请注意,.NET中有{{3}},但是无法将 bitmap.Save("<need to generate a filename>.<and extension>");
}
}
句柄传递给托管实现(这会使这更容易)。
答案 1 :(得分: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