How does GDIP stay transparent when loading HICON?

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
arcticir
Posts: 693
Joined: 17 Nov 2013, 11:32

How does GDIP stay transparent when loading HICON?

15 Aug 2017, 16:53

Using GDIP to load the icon handle, it will lose transparency.
How to maintain transparency?

Image

This is the H2 code.

Code: Select all

GdiplusStartup(getvar(pToken:=0),(si:=Struct("UINT GdiplusVersion;PTR DebugEventCallback;BOOL SuppressBackgroundThread;BOOL SuppressExternalCodecs",{GdiplusVersion:1}))[])
HICON:=icon_getsys(".ttf")
GdipCreateBitmapFromHICON(HICON,getvar(pBitmap:=0))
gui_test(pBitmap,150,150)

gui_test(pBitmap,w:="",h:=""){
	static bit:="DWORD biSize;LONG biWidth;LONG biHeight;WORD biPlanes;WORD biBitCount;DWORD biCompression;DWORD biSizeImage;LONG biXPelsPerMeter;LONG biYPelsPerMeter;DWORD biClrUsed;DWORD biClrImportant;"
		,pt:=Struct("x,y",{x:0,y:0}),_w:=getvar(width:=0),_h:=getvar(height:=0)

	(gui:=GuiCreate()).OnEvent("Close","ExitApp")

	k:=GuiCreate("+E0x80000 0x10000000 +Parent" gui.hwnd)

	if !w or !h
		GdipGetImageDimension(pBitmap, _w, _h),w:=NumGet(_w,"Float"),h:=NumGet(_h,"Float")
	bi:=Struct(bit,{biSize:sizeof(bit),biWidth:w,biHeight:h,biPlanes:1,biBitCount:32})
	hbm := CreateDIBSection( hdc:=GetDC(), bi[]),ReleaseDC(0,hdc)
	hdc := CreateCompatibleDC(),obm := SelectObject(hdc, hbm)
	GdipCreateFromHDC(hdc,getvar(G:=0)),GdipSetInterpolationMode(G, 7)
	GdipDrawImageRectRectI(G,pBitmap,0,0,w,h,0,0,16,16,2)
	UpdateLayeredWindow(k.hwnd,0,pt[],getvar(temp1:=w|h<<32),hdc, getvar(temp2:=0),0,getvar(temp3:=255<<16|1<<24),2)
	gui.show("w" w+20 " h" h+20)
}

icon_getsys(Path){
	Static IID_IIL,SFI,cbSFI:=(VarSetCapacity(IID_IIL, 16, 0),DllCall("Ole32.dll\IIDFromString", "WStr", "{46EB5926-582E-4017-9FDF-E8998DAA0950}", "Ptr", &IID_IIL, "UInt"),VarSetCapacity(SFI, cbSFI:= A_PtrSize + 8 + (340 << !!A_IsUnicode), 0),cbSFI)
	Return (DllCall("Shell32.dll\SHGetFileInfoW", "Str", Path, "UInt", 0x80, "Ptr", &SFI, "UInt", cbSFI, "UInt", 0x04000 | 0x0010, "UPtr")
		,DllCall("Shell32.dll\SHGetImageList", "Int", 0x03, "Ptr", &IID_IIL, "PtrP", IIL, "UInt")
		,DllCall("Comctl32.dll\ImageList_GetIcon", "Ptr", IIL, "Int",  NumGet(SFI, A_PtrSize, "Int"), "UInt", 0x0020, "UPtr"))
}
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: How does GDIP stay transparent when loading HICON?

15 Aug 2017, 17:46

Hello. I do not have the answer. I have two questions.
1) Why not show the icon in the gui? "hIcon:" hIcon, see Image Handles.

Code: Select all

HICON:=icon_getsys(".ttf")
(gui:=GuiCreate()).OnEvent("Close","ExitApp")
Gui.Add("Picture", "w32 h32", "hIcon:" HICON)
gui.show("w100")
2) Are you on windows 10? I cannot run your code on win7, there is an error here: k:=GuiCreate("+E0x80000 0x10000000 +parent" gui.hwnd). (Same problem as I mentioned in your showGif() thread) If i remove +parent i see the gui, empty, and the icon is shown at screen (0,0), transparent.

Cheers.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: How does GDIP stay transparent when loading HICON?

16 Aug 2017, 08:00

SKAN said this, suggesting that images would lose transparency, unless I misinterpreted it.
Gdip: image binary data to hex string for OCR - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=35339
SKAN wrote:This is annoying as STM_SETIMAGE doesn't prefer pARGB and will convert it to 32bpp RGB.
So we have to remember to delete two bitmaps with STM_SETIMAGE.
One possibility is to create an image, the same colour as the background, and draw the icon onto that image.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
arcticir
Posts: 693
Joined: 17 Nov 2013, 11:32

Re: How does GDIP stay transparent when loading HICON?

16 Aug 2017, 08:30

Yes, I found some similar script, but still can not solve the problem of transparency

https://autohotkey.com/board/topic/4965 ... g-trouble/

Code: Select all

;Lexikos
TEST_GetBitmapFromDIB(hbm, method=3)
{
    ; Retrieve DIBSECTION from HBITMAP.
    VarSetCapacity(dib, 84)
    if !DllCall("GetObject", "UInt", hbm, "Int", 84, "UInt", &dib)
        return
    
    width  := NumGet(dib, 4)  ; BITMAP.bmWidth
    height := NumGet(dib, 8)  ; BITMAP.bmHeight
    stride := NumGet(dib,12)  ; BITMAP.bmWidthBytes
    bits   := NumGet(dib,20)  ; BITMAP.bmBits
    
    if Method = 1
    {
        ; Method #1: Create Bitmap from BITMAPINFO and raw bitmap data.
        DllCall("gdiplus\GdipCreateBitmapFromGdiDib", "UInt", &dib + 24, "UInt", bits, "UInt*", pBitmap)
        return pBitmap
    }
    
    ; The following methods will only work correctly if the source and destination
    ; pixel formats are equivalent.  If the stride (byte-length of each scan line)
    ; is out or the source bitmap is bottom-up, the result will be incorrect.
    if (stride != width*4)
        return

    if Method = 2
    {
        ; Method #2: Create Bitmap and copy in raw data using LockBits.
        pBitmap := Gdip_CreateBitmap(width, height)
        VarSetCapacity(rect, 16, 0), NumPut(height, NumPut(width, rect, 8))
        VarSetCapacity(bmd, 24) ; GDI+ BitmapData
        DllCall("gdiplus\GdipBitmapLockBits", "UInt", pBitmap, "UInt", &rect, "UInt", 3, "UInt", 0x26200A, "UInt", &bmd)
        DllCall("RtlMoveMemory", "UInt", NumGet(bmd,16), "UInt", bits, "UInt", width*height*4)
        DllCall("gdiplus\GdipBitmapUnlockBits", "UInt", pBitmap, "UInt", &bmd)
    }
    else
    {
        ; Method #3: Create Bitmap from raw bitmap data.
        DllCall("gdiplus\GdipCreateBitmapFromScan0", "Int", width, "Int", height, "Int", stride, "Int", 0x26200A, "UInt", bits, "UInt*", pBitmap)
    }

    return pBitmap
}
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: How does GDIP stay transparent when loading HICON?

16 Aug 2017, 08:48

@arcticir, I does this give you an error on ahk v1? It does for me, on win7.

Code: Select all

gui, new, +hwndMAIN
gui %MAIN%: show, w200 h150
gui, new, +hwndchild +E0x80000 0x10000000 +parent%MAIN%
gui %child%:show, x0 y0 w50 h50
It seems like there is an issue with the combination of +parent and those styles.
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: How does GDIP stay transparent when loading HICON?

16 Aug 2017, 09:46

OK, I have 3 approaches:

Code: Select all

;icon to image approach 1
hIcon := LoadPicture(A_AhkPath, "Icon2 w128 h128", vType)
Gui, New, +HwndhGui, MyWinTitle
Gui, Add, Picture,, % "HICON:" hIcon
Gui, Show
return

Code: Select all

;icon to image approach 2
hIcon := LoadPicture(A_AhkPath, "Icon2 w128 h128", vType)
Gui, New, +HwndhGui, MyWinTitle
Gui, Add, Picture, w128 h128
DetectHiddenWindows, On
;SS_ICON := 0x3
Control, Style, +0x3, % Static1, % "ahk_id " hGui
;IMAGE_BITMAP := 0 ;IMAGE_ICON := 1 ;IMAGE_CURSOR := 2
SendMessage, 0x172, 1, % hIcon, Static1, % "ahk_id " hGui ;STM_SETIMAGE := 0x172
Gui, Show
return

Code: Select all

;icon to image approach 3
pToken := Gdip_Startup()
hIcon := LoadPicture(A_AhkPath, "Icon2 w128 h128", vType)
pBitmap := Gdip_CreateBitmapFromHICON(hIcon)
;vPath = %A_Desktop%\z %A_Now%.png
;Gdip_SaveBitmapToFile(pBitmap, vPath)
Gdip_GetDimensions(pBitmap, vImgW, vImgH)
vNewW := 128, vNewH := 128
pBitmap2 := Gdip_CreateBitmap(vNewW, vNewH)
G := Gdip_GraphicsFromImage(pBitmap2)
pBrush := Gdip_BrushCreateSolid(0xfff0f0f0)
Gdip_FillRectangle(G, pBrush, 0, 0, vNewW, vNewH)
Gdip_DrawImage(G, pBitmap, 0, 0, vNewW, vNewH, 0, 0, vImgW, vImgH)
hBitmap := Gdip_CreateHBITMAPFromBitmap(pBitmap2)

Gui, New, +HwndhGui, MyWinTitle
Gui, Add, Picture, w128 h128
;IMAGE_BITMAP := 0 ;IMAGE_ICON := 1 ;IMAGE_CURSOR := 2
DetectHiddenWindows, On
;SS_BITMAP := 0xE
Control, Style, +0xE, % Static1, % "ahk_id " hGui
SendMessage, 0x172, 0, % hBitmap, Static1, % "ahk_id " hGui ;STM_SETIMAGE := 0x172
Gui, Show

DeleteObject(hBitmap)
Gdip_DeleteBrush(pBrush)
Gdip_DisposeImage(pBitmap)
Gdip_DeleteGraphics(G)
Gdip_DisposeImage(pBitmap2)
Gdip_Shutdown(pToken)
return
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
arcticir
Posts: 693
Joined: 17 Nov 2013, 11:32

Re: How does GDIP stay transparent when loading HICON?

16 Aug 2017, 11:36

Only the third program is closest, but still ineffective, Because GdipCreateBitmapFromHICON has lost the transparency,

Code: Select all

GdiplusStartup(getvar(pToken:=0),(si:=Struct("UINT GdiplusVersion;PTR DebugEventCallback;BOOL SuppressBackgroundThread;BOOL SuppressExternalCodecs",{GdiplusVersion:1}))[])
HICON:=icon_getsys(".ttf")
GdipCreateBitmapFromHICON(HICON,getvar(pBitmap:=0))
_w:=getvar(width:=0),_h:=getvar(height:=0)
GdipGetImageDimension(pBitmap, _w, _h),w:=NumGet(_w,"Float"),h:=NumGet(_h,"Float")
GdipCreateBitmapFromScan0(w*2,h*2,0,0x26200A,0,getvar(pBitmap2:=0))
GdipGetImageGraphicsContext(pBitmap2,getvar(G2:=0))
GdipCreateSolidFill(0xfff0f0f0,getvar(pBrush:=0))
GdipFillRectangle(G2,pBrush,0,0,W,H)
GdipDrawImageRectRectI(G2,pBitmap,0,0,w*2,h*2,0,0,w,h,2)
gui:=GuiCreate()
rr:=CreateWindowEx(0,"Static",0,0x5000010E|0x6, 0, 0, W*2, H*2, gui.hwnd, 0, 0, 0 )
GdipCreateHBITMAPFromBitmap(pBitmap2, getvar(hbitmap:=0), 4278190080)
SendMessage_(rr,0x172,0, hbitmap) 
gui.show("w222 h222")
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: How does GDIP stay transparent when loading HICON?

16 Aug 2017, 12:00

@arcticir. I'm not certain if this is relevant, but this script contians logic for hBitmap->hIcon, where you can choose which color is to be transparent.
I changed two lines, it should work for v2,

Code: Select all

class LoadPictureType {
	static IMAGE_BITMAP:=0, IMAGE_ICON:=1, IMAGE_CURSOR:=2
	doAutoFreeHandles:=false
	__new(Filename, options:="", ImageType:=0, bkColor:=0x000000, xHotspot:=0, yHotspot:=0,keepBITMAP:=false){
		this.keepBITMAP:=keepBITMAP
		bkColor:=this.rgbToBgr(bkColor)
		this.hImg:=this.LoadPicture(Filename,options)
		this.type:=ImageType
		if (ImageType==LoadPictureType.IMAGE_BITMAP)
			return this
		else if (ImageType==LoadPictureType.IMAGE_ICON)
			this.makeIcon(bkColor)
		else if (ImageType==LoadPictureType.IMAGE_CURSOR)
			this.makeCursor(bkColor,xHotspot, yHotspot)
		else{
			this.deleteObject(this.hImg)
			throw Exception("Invalid image type: " ImageType ".")
		}
	}
	getBitmap(){
		; The BITMAP contains data for the bitmap, see _getBitmap(.) method for more details.
		if (!this.BITMAP && this.type==IMAGE_BITMAP)
			this.BITMAP:=this._getBitmap(this.hImg)	; havn't tried this with an icon or cursor handle
		if this.BITMAP
			return this.BITMAP
	}
	setAutoFreeHandles(bool:=true){
		return this.doAutoFreeHandles:=bool
	}
	getHandle(){
		return this.hImg
	}
	freeHandle(){
		if !this.hImg
			return
		if (this.type==this.IMAGE_BITMAP)
			this.deleteObject(this.hImg)
		else if (this.type==this.IMAGE_ICON)
			this.destroyIcon(this.hImg)
		else if (this.type==this.IMAGE_CURSOR)
			this.destroyCursor(this.hImg)
		return this.hImg:=""
	}

	; Internal methods.
	__Delete(){
		if this.doAutoFreeHandles 
			this.freeHandle()
	}
	LoadPicture(Filename,options:=""){
		local hBitmap
		if !hBitmap:=LoadPicture(Filename,options)
			throw Exception("LoadPicture failed.")
		return hBitmap
	}
	
	makeIcon(bkColor){	
		local hIcon:=this.createIconIndirect(this.hImg, true, bkColor)
		this.deleteObject(this.hImg)
		this.hImg:=hIcon
		return
	}
	makeCursor(bkColor, xHotspot:=0, yHotspot:=0){
		local hCursor:=this.createIconIndirect(this.hImg, false, bkColor, xHotspot, yHotspot)
		this.deleteObject(this.hImg)
		this.hImg:=hCursor
		return
	}
	
	createIconIndirect(hBitmap, fIcon:=1, bkColor:=0x000000, xHotspot:=0, yHotspot:=0){
		/*
		ICONINFO:				sz				o
		BOOL    fIcon;			4				0
		DWORD   xHotspot;		4				4
		DWORD   yHotspot;		4				8
		pad						ps=4?0:4			
		HBITMAP hbmMask;		ps				ps=4?12:16
		HBITMAP hbmColor;		ps				ps=4?16:24
		
		total:					ps=4?20:32
		*/
		local bmps:=this.andXOrBitmap(hBitmap,bkColor)
		local ICONINFO
		VarSetCapacity(ICONINFO, A_PtrSize==4?20:32,0)
		
		NumPut(fIcon, 			ICONINFO, 				   0, "Int")
		NumPut(xHotspot, 		ICONINFO, 				   4, "Int")
		NumPut(yHotspot, 		ICONINFO, 				   8, "Int")
		NumPut(bmps.hbmMask, 	ICONINFO, A_PtrSize==4?12:16, "Ptr")
		NumPut(bmps.hbmColor, 	ICONINFO, A_PtrSize==4?16:24, "Ptr")
		
		local hIcon := DllCall("User32.dll\CreateIconIndirect", "Ptr", &ICONINFO, "Ptr")
		if !hIcon
			throw Exception("CreateIconIndirect failed, ErrorLevel: " ErrorLevel " Last error: " A_LastError ".")
		local k, obj
		for k, obj in bmps.disposableObjects
			this.deleteObject(obj)
		return hIcon
	}
	andXOrBitmap(hBitmap,bkColor){
		; Logic ported from:
		;	https://www.experts-exchange.com/questions/20259566/CreateIconIndirect.html#a6763928
		; Scope: this is the reference from __new()
		local r:=LoadPictureType ; For convenience - r - reference 
		local BITMAP:=r._getBitmap(hBitmap)
		if this.keepBITMAP
			this.BITMAP:=BITMAP
		local hClientDC:=r.getDc()
		local hDCCreate         	:=	r.createCompatibleDC(hClientDC)
		local hDCImage          	:=	r.createCompatibleDC(hClientDC)	
		local hDCAnd	            :=	r.createCompatibleDC(hClientDC)
		local hDCXOr    	        :=	r.createCompatibleDC(hClientDC)

		local hDDB          		:=	r.createCompatibleBitmap(hClientDC, BITMAP.w, BITMAP.h)
		local hXOrBitmap		    :=	r.createCompatibleBitmap(hClientDC, BITMAP.w, BITMAP.h)
		local hAndBitmap     		:=	r.createBitmap(BITMAP.w, BITMAP.h, BITMAP.widthBytes, 1, 0)
		
		local BITMAPINFO
		r.BITMAPtoStruct(BITMAP, BITMAPINFO) ; BITMAPINFO is byref
		r.setDIBits(hDCCreate, hDDB, 0, BITMAP.h, BITMAP.bits, &BITMAPINFO, 0)
		r.deleteDC(hDCCreate)
		
		; Create the AND Mask bitmap
		local hOldAndBitmap     := r.selectObject(hDCAnd, hAndBitmap)
		local hOldImageBitmap   := r.selectObject(hDCImage, hDDB)
		local hOldXorBitmap     := r.selectObject(hDCXOr, hXOrBitmap)
		; Create the monochrome mask bitmap from the source image using the background color
		local crOld := r.setBkColor(hDCImage, bkColor)
		static SRCCOPY:=0x00CC0020
		r.bitBlt(hDCAnd, 0, 0, BITMAP.w, BITMAP.h, hDCImage, 0, 0, SRCCOPY)
		r.setBkColor(hDCImage, crOld)
		
		; Create the XOR color bitmap
		r.bitBlt(hDCXOr, 0, 0, BITMAP.w, BITMAP.h, hDCImage, 0, 0, SRCCOPY)
		r.bitBlt(hDCXOr, 0, 0, BITMAP.w, BITMAP.h, hDCAnd, 0, 0, 0x220326)
		
		r.selectObject(hDCImage, hOldImageBitmap)
		r.selectObject(hDCAnd, hOldAndBitmap)
		r.selectObject(hDCXOr, hOldXorBitmap)

		r.deleteDC(hDCXOr)
		r.deleteDC(hDCImage)
		r.deleteDC(hDCAnd)

		r.releaseDC(0,hClientDC)		
		return {hbmMask:hAndBitmap, hbmColor:hXOrBitmap, disposableObjects:[hDDB,hAndBitmap,hXOrBitmap]}
	}
	BITMAPtoStruct(BITMAP, ByRef BITMAPINFO){
		; Create bitmap info struct
		VarSetCapacity(BITMAPINFO, 40, 0)
		/*
		DWORD biSize;					4
		LONG  biWidth;					4
		LONG  biHeight;					4	
		WORD  biPlanes;					2
		WORD  biBitCount;				2
		DWORD biCompression;			4
		DWORD biSizeImage;				4
		LONG  biXPelsPerMeter;			4
		LONG  biYPelsPerMeter;			4
		DWORD biClrUsed;				4
		DWORD biClrImportant;			4	
		Total:							40
		*/
		static BI_RGB:=0
		static biSize:=40
		NumPut(biSize, 				BITMAPINFO,  0, "Uint")			; biSize
		NumPut(BITMAP.w,			BITMAPINFO,  4, "Uint")			; biWidth
		NumPut(BITMAP.h, 			BITMAPINFO,  8, "Uint")			; biHeight;
		NumPut(BITMAP.planes,		BITMAPINFO, 12, "Ushort")       ; biPlanes;
		NumPut(BITMAP.bitsPixel,	BITMAPINFO, 14, "Ushort")       ; biBitCount;
		NumPut(BI_RGB, 				BITMAPINFO, 16, "Uint")     	; biCompression;
		return
	}
	getDC(hWnd:=0){
		local hDc
		if !(hDc:=DllCall("User32.dll\GetDC", "Ptr", hWnd, "Ptr"))
			throw Exception("Failed to get the device context, ErrorLevel: " ErrorLevel " Last error: " A_LastError ".",-1)
		return hDc
	}
	deleteDC(hDc){
		if !DllCall("Gdi32.dll\DeleteDC", "Ptr", hDc)
			throw Exception("Failed to delete the device context, ErrorLevel: " ErrorLevel " Last error: " A_LastError ".",-1)
		return true
	}
	createCompatibleDC(hDc){
		local hRet
		if !(hRet:=DllCall("Gdi32.dll\CreateCompatibleDC", "Ptr", hDc, "Ptr"))
			throw Exception("Failed to create a compatible device context, ErrorLevel: " ErrorLevel " Last error: " A_LastError ".",-1)
		return hRet
	}
	createCompatibleBitmap(hdc,w,h){
		local hBitmap
		if !(hBitmap:=DllCall("Gdi32.dll\CreateCompatibleBitmap", "Ptr", hdc, "Int", w, "Int", h, "Ptr"))
			throw Exception("Failed to create a compatible bitmap, ErrorLevel: " ErrorLevel " Last error: " A_LastError ".",-1)
		return hBitmap
	}
	setDIBits(hdc,hbmp,uStartScan,cScanLines,lpvBits,lpbmi,fuColorUse){
		static DIB_RGB_COLORS:=0
		local nLines
		if !(nLines:=DllCall("Gdi32.dll\SetDIBits", "Ptr", hdc, "Ptr", hbmp, "Uint", uStartScan, "Uint", cScanLines, "Ptr", lpvBits, "Ptr", lpbmi, "Uint", fuColorUse))
			throw Exception("Failed to set DIBbits, ErrorLevel: " ErrorLevel " Last error: " A_LastError ".",-1)
		return nLines
	}
	selectObject(hdc, hgdiobj){
		static HGDI_ERROR:=0xFFFFFFFF
		local hRet:=DllCall("Gdi32.dll\SelectObject", "Ptr", hDc, "Ptr", hgdiobj, "Ptr")
		if (hRet==HGDI_ERROR)
			throw Exception("Failed to select object, Error: " HGDI_ERROR ", ErrorLevel: " ErrorLevel " Last error: " A_LastError ".",-1)
		else if !hRet
			throw Exception("Failed to select object, Error: NULL,  ErrorLevel: " ErrorLevel " Last error: " A_LastError ".",-1)
		return hRet
		
	}
	setBkColor(hDc,bkColor){
		static CLR_INVALID:=0xFFFFFFFF
		local prevBkColor:=DllCall("Gdi32.dll\SetBkColor", "Ptr", hDc, "Uint", bkColor)
		if (prevBkColor==CLR_INVALID)
			throw Exception("Failed to select object, Error: CLR_INVALID =" CLR_INVALID "  ErrorLevel: " ErrorLevel " Last error: " A_LastError ".",-1)
		return prevBkColor
	}
	bitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, dwRop){
		if !DllCall("Gdi32.dll\BitBlt", "Ptr", hdcDest, "Int", nXDest, "Int", nYDest, "Int", nWidth, "Int",nHeight, "Ptr", hdcSrc, "Int",nXSrc, "Int", nYSrc, "UInt", dwRop)
			throw Exception("BitBlt failed,  ErrorLevel: " ErrorLevel " Last error: " A_LastError ".",-1)
		return true
	}
	releaseDC(hWnd,hDc){
		if !DllCall("User32.dll\ReleaseDC", "Ptr", hWnd, "Ptr", hDC)
			throw  Exception("Failed to release device context,  ErrorLevel: " ErrorLevel " Last error: " A_LastError ".",-1)
		return true
	}
	deleteObject(hObject){
		if !DllCall("Gdi32.dll\DeleteObject", "Ptr", hObject)
			throw Exception("Failed to delete object,  ErrorLevel: " ErrorLevel " Last error: " A_LastError ".",-1)
		return true
	}
	destroyCursor(hCursor){
		if !DllCall("User32.dll\DestroyCursor", "Ptr", hCursor)
			throw Exception("Failed to destroy cursor,  ErrorLevel: " ErrorLevel " Last error: " A_LastError ".",-1)
		return true
	}
	destroyIcon(hIcon){
		if !DllCall("User32.dll\DestroyIcon", "Ptr", hIcon)
			throw Exception("Failed to destroy icon,  ErrorLevel: " ErrorLevel " Last error: " A_LastError ".",-1)
		return true
	}
	_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
	}
	createBitmap(w,h,widthBytes,cBitsPerPel:=32, lpvBitsIsNull:=false){
		static cPlanes:=1
		local hBitmap, lpvBits,pBits
		if lpvBitsIsNull
			pBits:=0
		else
			VarSetCapacity(lpvBits, widthBytes*h*cBitsPerPel,0), pBits:=&lpvBits
		if !(hBitmap:=DllCall("Gdi32.dll\CreateBitmap", "Int", w, "Int", h, "Uint", cPlanes, "Uint", cBitsPerPel, "Ptr",  pBits, "Ptr"))
			throw Exception("Failed to create bitmap, ErrorLevel: " ErrorLevel " Last error: " A_LastError ".",-1)
		return hBitmap
	}
	rgbToBgr(rgb){
		return (rgb&0x0000ff)<<16 | ((rgb&0x00ff00)>>8)<<8 | (rgb>>16)
	}
}
Cheers.
arcticir
Posts: 693
Joined: 17 Nov 2013, 11:32

Re: How does GDIP stay transparent when loading HICON?

16 Aug 2017, 14:45

Thank you very much, I will find the exact code.
Helgef
Posts: 4709
Joined: 17 Jul 2016, 01:02
Contact:

Re: How does GDIP stay transparent when loading HICON?

30 Aug 2017, 11:34

arcticir wrote:I will find the exact code.
Hello. You might have noticed that my code didn't work well with 32 bit per pixel images, I have tried to fix that now, and added extended class specifically for hBitmap->hIcon. See LoadPictureType, it is now compatible with v2.

Cheers.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Rohwedder and 116 guests