Hello.
Disclaimer: I know very little about
gdi(+).
does a pBitmap actually point to data?
It depends, I'd say. According to
msdn, the BITMAP structure looks like this,
Code: Select all
typedef struct tagBITMAP {
LONG bmType;
LONG bmWidth;
LONG bmHeight;
LONG bmWidthBytes;
WORD bmPlanes;
WORD bmBitsPixel;
LPVOID bmBits;
} BITMAP, *PBITMAP;
So I would expect a
PBITMAP to point to such a stucture. Now, in AHK code, we don't need (can't rather) specify the type of the variables we use, so if you see
pBitmap in AHK, don't count on it being a pointer to such a struct
. For example, from your code,
Code: Select all
DllCall( "gdiplus\GdipCreateBitmapFromStream", UInt,pStream, UIntP,pBitmap ) ; Maybe use "Ptr" and "PtrP" instead
Here,
pBitmap is not a pointer to the above struct. Instead, it is a pointer to a
Bitmap class object. It might have been more appropriate to implement a gdi+ wrapper in an object oriented way, then there might have been less confusion.
nnnik has at least started work on it, we'll see what happens.
Note: When I try to read/write bytes to the variablespace HBITMAP points to after using LoadPicture, AHK crashes. Am I doing it wrong or is it pointing to memory space I'm not allowed to access this way?
A
HBITMAP is to be consider an
opaque pointer, you can't use so freely, you need to use its associated functions/methods. To get the image's bit array from a
hBitmap from
loadPicture, I have used this function,
Code: Select all
_getBitmap(hBitmap){
; Url:
; - https://msdn.microsoft.com/en-us/library/windows/desktop/dd144904%28v=vs.85%29.aspx (GetObject function)
; - https://msdn.microsoft.com/en-us/library/windows/desktop/dd183371(v=vs.85).aspx (BITMAP structure)
/*
typedef struct tagBITMAP {
LONG bmType;
LONG bmWidth;
LONG bmHeight;
LONG bmWidthBytes;
WORD bmPlanes;
WORD bmBitsPixel;
LPVOID bmBits;
} BITMAP, *PBITMAP;
*/
static pBits:=A_PtrSize==4?20:24
local BITMAP,cbBuffer,nBytes
if !(cbBuffer:=DllCall("Gdi32.dll\GetObject", "Ptr", hBitmap, "Int", cbBuffer, "Ptr",0)) ; Get the requiered size of the buffer (BITMAP)
throw Exception("Failed to get the requiered buffer size, ErrorLevel: " ErrorLevel " Last error: " A_LastError ".",-1)
VarSetCapacity(BITMAP,cbBuffer,0)
if !(nBytes:=DllCall("Gdi32.dll\GetObject", "Ptr", hBitmap, "Int", cbBuffer, "Ptr", &BITMAP) == cbBuffer) ; Get the BITMAP
throw Exception("Failed to get the bitmap object, ErrorLevel: " ErrorLevel " Last error: " A_LastError ".",-1)
BITMAP := {type: NumGet(&BITMAP, 0, "Int") ; bmType
,w: NumGet(&BITMAP, 4, "Int") ; bmWidth
,h: NumGet(&BITMAP, 8, "Int") ; bmHeight
,widthBytes: NumGet(&BITMAP, 12, "Int") ; bmWidthBytes
,planes: NumGet(&BITMAP, 16, "UShort") ; bmPlanes
,bitsPixel: NumGet(&BITMAP, 18, "UShort") ; bmBitsPixel
,bits: NumGet(&BITMAP, pBits, "Ptr")} ; bmBits
return BITMAP
}
Source: github and AHK forum. The pointer to the bits is in
BITMAP.bits.
Please remember the above disclaimer, I'd be happy to have my statments and my understanding corrected.
Cheers