F1 to write the bitmap to the map
F2 to rebuild (F2 only for test as it will dispose of the bitmap, it works correctly as long its the same script)
Code: Select all
;====== Test script 1 ======
FM := new FileMapping()
Return
F1::
pToken := Gdip_Startup()
WinGet, hWnd, Id, ahk_exe notepad.exe
pBitmap := Gdip_BitmapFromHWND(hWnd)
DllCall("gdiplus\GdipGetImageDimension", Ptr, pBitmap, "float*", width, "float*", height)
DllCall("gdiplus\GdipGetImagePixelFormat", "Ptr", pBitmap, "PtrP", pixelFormat)
Gdip_LockBits(pBitmap, 0, 0, width, height, stride, scan0, bitmapData,, pixelFormat)
size := stride * height
str := "testtest" ;CoCoJson.Dump(Object)
VarSetCapacity(data, dataSize := size + 16 + StrLen(str)*2 + 2, 0)
StrPut(str, &data + size + 16)
DllCall("RtlCopyMemory", "Ptr", &data + 16, "Ptr", scan0, "Ptr", size)
DllCall("Gdiplus\GdipBitmapUnlockBits", "UPtr", pBitmap, "UPtr", &BitmapData)
NumPut(pixelFormat, data)
NumPut(width, data, 4)
NumPut(height, data, 8)
NumPut(stride, data, 12, "UInt")
VarSetCapacity(COPYDATASTRUCT, A_PtrSize*3, 0)
NumPut(dataSize, COPYDATASTRUCT, A_PtrSize)
NumPut(&data, COPYDATASTRUCT, A_PtrSize*2)
FileAppend, size: %size%`n,*
FM.Write(©DATASTRUCT)
Return
F2:: FM.Read()
Esc::ExitApp
Class FileMapping {
__New(Name="Global\MyFileMappingObject", BufSize=10000) {
; Opens existing or creates new file mapping object
static INVALID_HANDLE_VALUE := -1, PAGE_READWRITE := 0x4, FILE_MAP_ALL_ACCESS := 0xF001F
hMapFile := DllCall("OpenFileMapping", "Ptr", FILE_MAP_ALL_ACCESS, "Int", 0, "Str", Name)
if ( hMapFile == 0 ) {
; OpenFileMapping Failed - file mapping object doesn't exist - that means we have to create it
hMapFile := DllCall("CreateFileMapping", "Ptr", INVALID_HANDLE_VALUE, "Ptr", 0, "Int", PAGE_READWRITE, "Int", 0, "Int", BufSize, "Str", Name)
if ( hMapFile == 0 ) ; CreateFileMapping Failed
return
}
pBuf := DllCall("MapViewOfFile", "Ptr", hMapFile, "Int", FILE_MAP_ALL_ACCESS, "Int", 0, "Int", 0, "Ptr", BufSize)
if ( pBuf == 0 ) ; MapViewOfFile Failed
return
this.Name := Name
this.hMapFile := hMapFile
this.pBuf := pBuf
this.BufSize := BufSize
}
Write(data:="") {
this.pBuf := data
}
Read() {
static flags := HEAP_ZERO_MEMORY := 0x00000008
, hHeap := DllCall("GetProcessHeap", "Ptr")
size := NumGet(this.pBuf + A_PtrSize, "UInt")
pData := NumGet(this.pBuf + A_PtrSize*2)
pHeap := DllCall("HeapAlloc", "Ptr", hHeap, "UInt", flags, "UPtr", size, "Ptr")
DllCall("RtlCopyMemory", "Ptr", pHeap, "Ptr", pData, "Ptr", size)
this.CreateBitmapFromData(hHeap, pHeap)
return
}
CreateBitmapFromData(hHeap, pImageData) {
pixelFormat := NumGet(pImageData+0, "UInt")
width := NumGet(pImageData+4, "UInt")
height := NumGet(pImageData+8, "UInt")
stride := NumGet(pImageData+12,"UInt")
str := StrGet(pImageData + 16 + stride*height)
DllCall("gdiplus\GdipCreateBitmapFromScan0", "Int", width, "Int", height, "Int", stride, "Int", pixelFormat, "Ptr", pImageData + 16, "PtrP", pBitmap)
DllCall("gdiplus\GdipCreateHBITMAPFromBitmap", "Ptr", pBitmap, "PtrP", hbm, "Int", 0xffffffff)
; Just for test
Gui, Add, Picture, x0 y0, % "HBITMAP:" hbm
Gui, Show
DllCall("HeapFree", "Ptr", hHeap, "UInt", 0, "Ptr", pImageData)
DllCall("gdiplus\GdipDisposeImage", "Ptr", pBitmap)
}
__Delete() {
DllCall("UnmapViewOfFile", "Ptr", this.pBuf), DllCall("CloseHandle", "Ptr", this.hMapFile)
}
}
however, when I start another script with the same code (you need to change F2 to another key, F3:: FM.Read())
and hit F3, the values inside of the function Read size and pdata are 0
Code: Select all
Read() {
static flags := HEAP_ZERO_MEMORY := 0x00000008
, hHeap := DllCall("GetProcessHeap", "Ptr")
size := NumGet(this.pBuf + A_PtrSize, "UInt")
pData := NumGet(this.pBuf + A_PtrSize*2)
pHeap := DllCall("HeapAlloc", "Ptr", hHeap, "UInt", flags, "UPtr", size, "Ptr")
DllCall("RtlCopyMemory", "Ptr", pHeap, "Ptr", pData, "Ptr", size)
this.CreateBitmapFromData(hHeap, pHeap)
return
}