This code works fine when running 32-bit. But when I switch to 64-bit the GetObject method does not work and BITMAP struct is empty.
IntPtr hBmp = ObtainValidBitmapHandleFromSystem();
BITMAP bmpData = new BITMAP();
/* BITMAP consists of four 32bit ints,
* two 16 bit uints and one IntPtr */
* 4 + sizeof(UInt16) * 2 + IntPtr.Size;
int cbBuffer = sizeof(Int32) * 4 + sizeof(UInt16) * 2 + IntPtr.Size;
NativeMethods.GetObject(hBmp, cbBuffer, out bmpData);
Bitmap bmp = new Bitmap(bmpData.Width, bmpData.Height, PixelFormat.Format32bppPArgb);
The native method implementation:
private static class NativeMethods
{
[DllImport("gdi32", CharSet = CharSet.Auto)]
internal extern static int GetObject(
IntPtr hgdiobj, // handle to graphics object
int cbBuffer, // size of buffer for object information
out BITMAP lpvObject // Should be IntPtr, but we know we will use it only for BITMAP.
);
}
The BITMAP structure implementation (removed documentation to keep code compact):
[StructLayoutAttribute(LayoutKind.Sequential)]
private struct BITMAP
{
public Int32 Type;
public Int32 Width;
public Int32 Height;
public Int32 WidthBytes;
public UInt16 Planes;
public UInt16 BitsPixel;
public IntPtr Bits;
}
The idea behind this code is fully described in this question.
At first I thought that the issue is caused by different size of IntPtr resulting in different size of cbBuffer, but it seems that this is not the case as changing cbBuffer size did not help.
What is the correct way to use GDI's GetObject method on 64-bit system?