Skip to content

Instantly share code, notes, and snippets.

@maul-esel
Created January 23, 2012 19:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save maul-esel/1665138 to your computer and use it in GitHub Desktop.
Save maul-esel/1665138 to your computer and use it in GitHub Desktop.
SaveHImage2File - standalone version
#NoEnv
#SingleInstance ignore
#Include SaveHImage2File.ahk
hIcon := DllCall("LoadIcon", "UPtr", 0, "UInt", 32513, "UPtr") ; load a system icon
result := SaveHImage2File(hIcon, A_Desktop "\test.ico", "icon") ; save the icon to a file
MsgBox % "finished: " . (result ? "succeeded" : "failed") ; report to user
hbmp := DllCall("LoadBitmap", "UPtr", 0, "UInt", 32745, "UPtr")
result := SaveHImage2File(hbmp, A_Desktop "\test.bmp", "bitmap") ; save the bitmap to a file
MsgBox % "finished: " . (result ? "succeeded" : "failed") ; report to user
return
/*
Function: SaveHImage2File
saves a HICON or a HBITMAP to a *.ico or *.bmp file, respectively.
Parameters:
PTR handle - the HICON or HBITMAP handle
STR file - the file to save the handle to
STR type - the type, which is either "icon" or "bitmap"
Returns:
BOOL success - true on success, false otherwise
*/
SaveHImage2File(handle, file, type)
{
static IID_IPicture := "{7BF80980-BF32-101A-8BBB-00AA00300CAB}", PICTYPE_ICON := 3, PICTYPE_BITMAP := 1
; resolve type
if (type = "icon")
type := PICTYPE_ICON
else if (type = "bitmap")
type := PICTYPE_BITMAP
else
return false
; build PICTDESC struct
VarSetCapacity(pd, size := 8 + 2 * A_PtrSize, 00), NumPut(size, pd, 00, "UInt"), NumPut(type, pd, 04, "UInt"), NumPut(handle, pd, 08, "UPtr")
; create stream:
, DllCall("Ole32.dll\CreateStreamOnHGlobal", "UPtr", 0, "UInt", true, "UPtr*", pStrm)
; create picture:
VarSetCapacity(iid, 16, 00), DllCall("ole32\CLSIDFromString", "Str", IID_IPicture, "UPtr", &iid)
, DllCall("OleAut32.dll\OleCreatePictureIndirect", "UPtr", &pd, "UPtr", &iid, "UInt", false, "UPtr*", pPict)
; call pPict::SaveAsFile(pStrm)
, DllCall(NumGet(NumGet(pPict + 0)+15*A_PtrSize), "UPtr", pPict, "UPtr", pStrm, "UInt", true, "int*", cbSize)
; call pStrm:Seek(0)
, DllCall(NumGet(NumGet(pStrm + 0)+05*A_PtrSize), "UPtr", pStrm, "Int64", 0, "UInt", 0, "UInt64*", pos)
, hFile := FileOpen(file, "w")
if (hFile)
{
dwDone := 0, dwRead := 0, dwWritten := 0, VarSetCapacity(buf, 4096, 0)
while (dwDone < cbSize)
{
hr := DllCall(NumGet(NumGet(pStrm + 0)+03*A_PtrSize), "UPtr", pStrm, "UPtr", &buf, "UInt", 4096, "UInt*", dwRead)
if (hr >= 0x00)
{
dwWritten := hFile.RawWrite(&buf, dwRead)
if (dwWritten != dwRead)
break
dwDone += dwRead
}
else
break
}
hFile.Close()
, ObjRelease(pStrm)
, ObjRelease(pPict)
return dwDone == cbSize
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment