is there an alternative imagesearch solution on gdip lib ?

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
takayo97
Posts: 63
Joined: 09 Jun 2018, 16:30

is there an alternative imagesearch solution on gdip lib ?

30 Sep 2019, 08:36

For some reasons, imagesearch is not able to use on my situation, where capture an area of screen and search for providing image file within this area.
A helper program which provide more game info overlay on game screen banned api which imagesearch are using, not allow user for screen capture the overlay.

i ve tested with the gdip lib which can still able to capture game screen (without the overlay )that what i want to.
User avatar
RaptorX
Posts: 371
Joined: 06 Dec 2014, 14:27
Contact:

Re: is there an alternative imagesearch solution on gdip lib ?

30 Sep 2019, 08:50

You can try with sc.ahk, a library for making screen captures that if i remember correctly uses gdi.

I will link to it later as i am on mobile right now.
Projects:
AHK-ToolKit
takayo97
Posts: 63
Joined: 09 Jun 2018, 16:30

Re: is there an alternative imagesearch solution on gdip lib ?

30 Sep 2019, 09:05

I just found imagesearch functionality of gdip version
https://www.autohotkey.com/boards/viewtopic.php?t=28871

But is it provide imagesearch similar fucntion which can provide variant
User avatar
RaptorX
Posts: 371
Joined: 06 Dec 2014, 14:27
Contact:

Re: is there an alternative imagesearch solution on gdip lib ?

30 Sep 2019, 14:44

Here is the library I was talking about

Uses gidp to create the images. But you dont need any aditional files for it to work.

You can download it by clicking here:
sc.ahk
Screen Capture
(9.16 KiB) Downloaded 147 times
Here is the intro to the tool.

Code: Select all

/*
CaptureScreen(aRect, sFileTo, bCursor, nQuality)
1) If the optional parameter bCursor is True, captures the cursor too.
2) If the optional parameter sFileTo is 0, set the image to Clipboard.
   If it is omitted or "", saves to screen.bmp in the script folder,
   otherwise to sFileTo which can be BMP/JPG/PNG/GIF/TIF.
3) The optional parameter nQuality is applicable only when sFileTo is JPG. Set it to the desired quality level of the resulting JPG, an integer between 0 - 100.
4) If aRect is 0/1/2/3, captures the entire desktop/active window/active client area/active monitor.
5) aRect can be comma delimited sequence of coordinates, e.g., "Left, Top, Right, Bottom" or "Left, Top, Right, Bottom, Width_Zoomed, Height_Zoomed".
   In this case, only that portion of the rectangle will be captured. Additionally, in the latter case, zoomed to the new width/height, Width_Zoomed/Height_Zoomed.

Example:
CaptureScreen(0)
CaptureScreen(1)
CaptureScreen(2)
CaptureScreen(3)
CaptureScreen("100, 100, 200, 200")
CaptureScreen("100, 100, 200, 200, 400, 400")   ; Zoomed
*/

/* 
Convert(sFileFr, sFileTo, nQuality)
Convert("C:\image.bmp", "C:\image.jpg")
Convert("C:\image.bmp", "C:\image.jpg", 95)
Convert(0, "C:\clip.png")   ; Save the bitmap in the clipboard to sFileTo if sFileFr is "" or 0.
*/
Very easy to use.
Projects:
AHK-ToolKit
User avatar
gwarble
Posts: 524
Joined: 30 Sep 2013, 15:01

Re: is there an alternative imagesearch solution on gdip lib ?

30 Sep 2019, 18:36

i believe that version only works with A32, try this thanks to LinearSpoon:

Code: Select all

/* CaptureScreen(aRect, bCursor, sFileTo, nQuality)
1) If the optional parameter bCursor is True, captures the cursor too.
2) If the optional parameter sFileTo is 0, set the image to Clipboard.
   If it is omitted or "", saves to screen.bmp in the script folder,
   otherwise to sFileTo which can be BMP/JPG/PNG/GIF/TIF.
3) The optional parameter nQuality is applicable only when sFileTo is JPG. Set it to the desired quality level of the resulting JPG, an integer between 0 - 100.
4) If aRect is 0/1/2/3, captures the entire desktop/active window/active client area/active monitor.
5) aRect can be comma delimited sequence of coordinates, e.g., "Left, Top, Right, Bottom" or "Left, Top, Right, Bottom, Width_Zoomed, Height_Zoomed".
   In this case, only that portion of the rectangle will be captured. Additionally, in the latter case, zoomed to the new width/height, Width_Zoomed/Height_Zoomed.

Example:
CaptureScreen(0)
CaptureScreen(1)
CaptureScreen(2)
CaptureScreen(3)
CaptureScreen("100, 100, 200, 200")
CaptureScreen("100, 100, 200, 200, 400, 400")   ; Zoomed
*/

/* Convert(sFileFr, sFileTo, nQuality)
Convert("C:\image.bmp", "C:\image.jpg")
Convert("C:\image.bmp", "C:\image.jpg", 95)
Convert(0, "C:\clip.png")   ; Save the bitmap in the clipboard to sFileTo if sFileFr is "" or 0.
*/


CaptureScreen(aRect = 0, bCursor = False, sFile = "", nQuality = "")
{
	If !aRect
	{
		SysGet, nL, 76  ; virtual screen left & top
		SysGet, nT, 77
		SysGet, nW, 78	; virtual screen width and height
		SysGet, nH, 79
	}
	Else If aRect = 1
		WinGetPos, nL, nT, nW, nH, A
	Else If aRect = 2
	{
		WinGet, hWnd, ID, A
		VarSetCapacity(rt, 16, 0)
		DllCall("GetClientRect" , "ptr", hWnd, "ptr", &rt)
		DllCall("ClientToScreen", "ptr", hWnd, "ptr", &rt)
		nL := NumGet(rt, 0, "int")
		nT := NumGet(rt, 4, "int")
		nW := NumGet(rt, 8)
		nH := NumGet(rt,12)
	}
	Else If aRect = 3
	{
		VarSetCapacity(mi, 40, 0)
		DllCall("GetCursorPos", "int64P", pt), NumPut(40,mi,0,"uint")
		DllCall("GetMonitorInfo", "ptr", DllCall("MonitorFromPoint", "int64", pt, "Uint", 2, "ptr"), "ptr", &mi)
		nL := NumGet(mi, 4, "int")
		nT := NumGet(mi, 8, "int")
		nW := NumGet(mi,12, "int") - nL
		nH := NumGet(mi,16, "int") - nT
	}
	Else
	{
		StringSplit, rt, aRect, `,, %A_Space%%A_Tab%
		nL := rt1	; convert the Left,top, right, bottom into left, top, width, height
		nT := rt2
		nW := rt3 - rt1
		nH := rt4 - rt2
		znW := rt5
		znH := rt6
	}

	mDC := DllCall("CreateCompatibleDC", "ptr", 0, "ptr")
	hBM := CreateDIBSection(mDC, nW, nH)
	oBM := DllCall("SelectObject", "ptr", mDC, "ptr", hBM, "ptr")
	hDC := DllCall("GetDC", "ptr", 0, "ptr")
	DllCall("BitBlt", "ptr", mDC, "int", 0, "int", 0, "int", nW, "int", nH, "ptr", hDC, "int", nL, "int", nT, "Uint", 0x40CC0020)
	DllCall("ReleaseDC", "ptr", 0, "ptr", hDC)
	If bCursor
		CaptureCursor(mDC, nL, nT)
	DllCall("SelectObject", "ptr", mDC, "ptr", oBM)
	DllCall("DeleteDC", "ptr", mDC)
	If znW && znH
		hBM := Zoomer(hBM, nW, nH, znW, znH)
	If sFile = 0
		SetClipboardData(hBM)
	Else Convert(hBM, sFile, nQuality), DllCall("DeleteObject", "ptr", hBM)
}

CaptureCursor(hDC, nL, nT)
{
	VarSetCapacity(mi, 32, 0), Numput(16+A_PtrSize, mi, 0, "uint")
	DllCall("GetCursorInfo", "ptr", &mi)
	bShow   := NumGet(mi, 4, "uint")
	hCursor := NumGet(mi, 8)
	xCursor := NumGet(mi,8+A_PtrSize, "int")
	yCursor := NumGet(mi,12+A_PtrSize, "int")

	DllCall("GetIconInfo", "ptr", hCursor, "ptr", &mi)
	xHotspot := NumGet(mi, 4, "uint")
	yHotspot := NumGet(mi, 8, "uint")
	hBMMask  := NumGet(mi,8+A_PtrSize)
	hBMColor := NumGet(mi,16+A_PtrSize)

	If bShow
		DllCall("DrawIcon", "ptr", hDC, "int", xCursor - xHotspot - nL, "int", yCursor - yHotspot - nT, "ptr", hCursor)
	If hBMMask
		DllCall("DeleteObject", "ptr", hBMMask)
	If hBMColor
		DllCall("DeleteObject", "ptr", hBMColor)
}

Zoomer(hBM, nW, nH, znW, znH)
{
	mDC1 := DllCall("CreateCompatibleDC", "ptr", 0, "ptr")
	mDC2 := DllCall("CreateCompatibleDC", "ptr", 0, "ptr")
	zhBM := CreateDIBSection(mDC2, znW, znH)
	oBM1 := DllCall("SelectObject", "ptr", mDC1, "ptr",  hBM, "ptr")
	oBM2 := DllCall("SelectObject", "ptr", mDC2, "ptr", zhBM, "ptr")
	DllCall("SetStretchBltMode", "ptr", mDC2, "int", 4)
	DllCall("StretchBlt", "ptr", mDC2, "int", 0, "int", 0, "int", znW, "int", znH, "ptr", mDC1, "int", 0, "int", 0, "int", nW, "int", nH, "Uint", 0x00CC0020)
	DllCall("SelectObject", "ptr", mDC1, "ptr", oBM1)
	DllCall("SelectObject", "ptr", mDC2, "ptr", oBM2)
	DllCall("DeleteDC", "ptr", mDC1)
	DllCall("DeleteDC", "ptr", mDC2)
	DllCall("DeleteObject", "ptr", hBM)
	Return zhBM
}

Convert(sFileFr = "", sFileTo = "", nQuality = "")
{
	If (sFileTo = "")
		sFileTo := A_ScriptDir . "\screen.bmp"
	SplitPath, sFileTo, , sDirTo, sExtTo, sNameTo
	
	If Not hGdiPlus := DllCall("LoadLibrary", "str", "gdiplus.dll", "ptr")
		Return	sFileFr+0 ? SaveHBITMAPToFile(sFileFr, sDirTo (sDirTo = "" ? "" : "\") sNameTo ".bmp") : ""
	VarSetCapacity(si, 16, 0), si := Chr(1)
	DllCall("gdiplus\GdiplusStartup", "UintP", pToken, "ptr", &si, "ptr", 0)

	If !sFileFr
	{
		DllCall("OpenClipboard", "ptr", 0)
		If	(DllCall("IsClipboardFormatAvailable", "Uint", 2) && (hBM:=DllCall("GetClipboardData", "Uint", 2, "ptr")))
			DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", "ptr", hBM, "ptr", 0, "ptr*", pImage)
		DllCall("CloseClipboard")
	}
	Else If	sFileFr Is Integer
		DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", "ptr", sFileFr, "ptr", 0, "ptr*", pImage)
	Else	DllCall("gdiplus\GdipLoadImageFromFile", "wstr", sFileFr, "ptr*", pImage)
	DllCall("gdiplus\GdipGetImageEncodersSize", "UintP", nCount, "UintP", nSize)
	VarSetCapacity(ci,nSize,0)
	DllCall("gdiplus\GdipGetImageEncoders", "Uint", nCount, "Uint", nSize, "ptr", &ci)
	struct_size := 48+7*A_PtrSize, offset := 32 + 3*A_PtrSize, pCodec := &ci - struct_size
	Loop, %	nCount
		If InStr(StrGet(Numget(offset + (pCodec+=struct_size)), "utf-16") , "." . sExtTo)
			break

	If (InStr(".JPG.JPEG.JPE.JFIF", "." . sExtTo) && nQuality<>"" && pImage && pCodec < &ci + nSize)
	{
		DllCall("gdiplus\GdipGetEncoderParameterListSize", "ptr", pImage, "ptr", pCodec, "UintP", nCount)
		VarSetCapacity(pi,nCount,0), struct_size := 24 + A_PtrSize
		DllCall("gdiplus\GdipGetEncoderParameterList", "ptr", pImage, "ptr", pCodec, "Uint", nCount, "ptr", &pi)
		Loop, %	NumGet(pi,0,"uint")
			If (NumGet(pi,struct_size*(A_Index-1)+16+A_PtrSize,"uint")=1 && NumGet(pi,struct_size*(A_Index-1)+20+A_PtrSize,"uint")=6)
			{
				pParam := &pi+struct_size*(A_Index-1)
				NumPut(nQuality,NumGet(NumPut(4,NumPut(1,pParam+0,"uint")+16+A_PtrSize,"uint")),"uint")
				Break
			}
	}

	If pImage
		pCodec < &ci + nSize	? DllCall("gdiplus\GdipSaveImageToFile", "ptr", pImage, "wstr", sFileTo, "ptr", pCodec, "ptr", pParam) : DllCall("gdiplus\GdipCreateHBITMAPFromBitmap", "ptr", pImage, "ptr*", hBitmap, "Uint", 0) . SetClipboardData(hBitmap), DllCall("gdiplus\GdipDisposeImage", "ptr", pImage)

	DllCall("gdiplus\GdiplusShutdown" , "Uint", pToken)
	DllCall("FreeLibrary", "ptr", hGdiPlus)
}


CreateDIBSection(hDC, nW, nH, bpp = 32, ByRef pBits = "")
{
	VarSetCapacity(bi, 40, 0)
	NumPut(40, bi, "uint")
	NumPut(nW, bi, 4, "int")
	NumPut(nH, bi, 8, "int")
	NumPut(bpp, NumPut(1, bi, 12, "UShort"), 0, "Ushort")
	Return DllCall("gdi32\CreateDIBSection", "ptr", hDC, "ptr", &bi, "Uint", 0, "UintP", pBits, "ptr", 0, "Uint", 0, "ptr")
}

SaveHBITMAPToFile(hBitmap, sFile)
{
	VarSetCapacity(oi,104,0)
	DllCall("GetObject", "ptr", hBitmap, "int", 64+5*A_PtrSize, "ptr", &oi)
	fObj := FileOpen(sFile, "w")
	fObj.WriteShort(0x4D42)
	fObj.WriteInt(54+NumGet(oi,36+2*A_PtrSize,"uint"))
	fObj.WriteInt64(54<<32)
	fObj.RawWrite(&oi + 16 + 2*A_PtrSize, 40)
	fObj.RawWrite(NumGet(oi, 16+A_PtrSize), NumGet(oi,36+2*A_PtrSize,"uint"))
	fObj.Close()
}

SetClipboardData(hBitmap)
{
	VarSetCapacity(oi,104,0)
	DllCall("GetObject", "ptr", hBitmap, "int", 64+5*A_PtrSize, "ptr", &oi)
	sz := NumGet(oi,36+2*A_PtrSize,"uint")
	hDIB :=	DllCall("GlobalAlloc", "Uint", 2, "Uptr", 40+sz, "ptr")
	pDIB := DllCall("GlobalLock", "ptr", hDIB, "ptr")
	DllCall("RtlMoveMemory", "ptr", pDIB, "ptr", &oi + 16 + 2*A_PtrSize, "Uptr", 40)
	DllCall("RtlMoveMemory", "ptr", pDIB+40, "ptr", NumGet(oi, 16+A_PtrSize), "Uptr", sz)
	DllCall("GlobalUnlock", "ptr", hDIB)
	DllCall("DeleteObject", "ptr", hBitmap)
	DllCall("OpenClipboard", "ptr", 0)
	DllCall("EmptyClipboard")
	DllCall("SetClipboardData", "Uint", 8, "ptr", hDIB)
	DllCall("CloseClipboard")
}
EitherMouse - Multiple mice, individual settings . . . . www.EitherMouse.com . . . . forum . . . .
User avatar
RaptorX
Posts: 371
Joined: 06 Dec 2014, 14:27
Contact:

Re: is there an alternative imagesearch solution on gdip lib ?

01 Oct 2019, 00:09

Yes, it is a very old script that i dug out of my library.

I will update it with this version. Thanks for sharing!
Projects:
AHK-ToolKit
malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: is there an alternative imagesearch solution on gdip lib ?

07 Oct 2019, 14:15

You can try to capture with directx::.
It is much faster than through gdi.
For example for win 8, win 10 with DirectX DXGI Desktop Duplication API:
captures 100 screenshots and the last saves with WIC.

Code: Select all

file := "file.png"

setbatchlines -1
IDXGIFactory := CreateDXGIFactory()
if !IDXGIFactory
{
   MsgBox, 16, Error, Create IDXGIFactory failed.
   ExitApp
}
loop
{
   IDXGIFactory_EnumAdapters(IDXGIFactory, A_Index-1, IDXGIAdapter)
   loop
   {
      hr := IDXGIAdapter_EnumOutputs(IDXGIAdapter, A_Index-1, IDXGIOutput)
      if (hr = "DXGI_ERROR_NOT_FOUND")
         break
      VarSetCapacity(DXGI_OUTPUT_DESC, 88+A_PtrSize, 0)
      IDXGIOutput_GetDesc(IDXGIOutput, &DXGI_OUTPUT_DESC)
      Width := NumGet(DXGI_OUTPUT_DESC, 72, "int")
      Height := NumGet(DXGI_OUTPUT_DESC, 76, "int")
      AttachedToDesktop := NumGet(DXGI_OUTPUT_DESC, 80, "int")
      if (AttachedToDesktop = 1)
         break 2         
      ObjRelease(IDXGIOutput)
   }
   ObjRelease(IDXGIAdapter)
}
if (AttachedToDesktop != 1)
{
   MsgBox, 16, Error, No adapter attached to desktop
   ExitApp
}
D3D11CreateDevice(IDXGIAdapter, D3D_DRIVER_TYPE_UNKNOWN := 0, 0, 0, 0, 0, D3D11_SDK_VERSION := 7, d3d_device, 0, d3d_context)
IDXGIOutput1 := IDXGIOutput1_Query(IDXGIOutput)
IDXGIOutput1_DuplicateOutput(IDXGIOutput1, d3d_device, Duplication)
VarSetCapacity(DXGI_OUTDUPL_DESC, 36, 0)
IDXGIOutputDuplication_GetDesc(Duplication, &DXGI_OUTDUPL_DESC)
DesktopImageInSystemMemory := NumGet(DXGI_OUTDUPL_DESC, 32, "uint")
if (DesktopImageInSystemMemory = 1)
   msgbox Image is in system memory, will be used DesktopSurface
else
   msgbox Image not in system memory, will be used CopyResource
sleep 50   ; As I understand - need some sleep for successful connecting to IDXGIOutputDuplication interface

VarSetCapacity(D3D11_TEXTURE2D_DESC, 44, 0)
NumPut(width, D3D11_TEXTURE2D_DESC, 0, "uint")   ; Width
NumPut(height, D3D11_TEXTURE2D_DESC, 4, "uint")   ; Height
NumPut(1, D3D11_TEXTURE2D_DESC, 8, "uint")   ; MipLevels
NumPut(1, D3D11_TEXTURE2D_DESC, 12, "uint")   ; ArraySize
NumPut(DXGI_FORMAT_B8G8R8A8_UNORM := 87, D3D11_TEXTURE2D_DESC, 16, "uint")   ; Format
NumPut(1, D3D11_TEXTURE2D_DESC, 20, "uint")   ; SampleDescCount
NumPut(0, D3D11_TEXTURE2D_DESC, 24, "uint")   ; SampleDescQuality
NumPut(D3D11_USAGE_STAGING := 3, D3D11_TEXTURE2D_DESC, 28, "uint")   ; Usage
NumPut(0, D3D11_TEXTURE2D_DESC, 32, "uint")   ; BindFlags
NumPut(D3D11_CPU_ACCESS_READ := 0x20000, D3D11_TEXTURE2D_DESC, 36, "uint")   ; CPUAccessFlags
NumPut(0, D3D11_TEXTURE2D_DESC, 40, "uint")   ; MiscFlags
ID3D11Device_CreateTexture2D(d3d_device, &D3D11_TEXTURE2D_DESC, 0, staging_tex)
a := a_tickcount
loop 100
{
   tooltip % A_Index
   VarSetCapacity(DXGI_OUTDUPL_FRAME_INFO, 48, 0)
   hr := IDXGIOutputDuplication_AcquireNextFrame(Duplication, 1000, &DXGI_OUTDUPL_FRAME_INFO, desktop_resource)
   if (hr = "DXGI_ERROR_WAIT_TIMEOUT")
   {
      msgbox timeout
      Continue
   }
   tex := ID3D11Texture2D_Query(desktop_resource)
   VarSetCapacity(DXGI_MAPPED_RECT, A_PtrSize*2, 0)
   hr := IDXGIOutputDuplication_MapDesktopSurface(Duplication, &DXGI_MAPPED_RECT)
   if (hr != "DXGI_ERROR_UNSUPPORTED")
   {
      pitch := NumGet(DXGI_MAPPED_RECT, 0, "int")
      pBits := NumGet(DXGI_MAPPED_RECT, A_PtrSize, "ptr")
      IDXGIOutputDuplication_UnMapDesktopSurface(Duplication)
  }
   else
   {
     ; VarSetCapacity(D3D11_BOX, 24, 0)
     ; NumPut(0, D3D11_BOX, 0, "uint")   ; left
     ; NumPut(0, D3D11_BOX, 4, "uint")   ; top
     ; NumPut(0, D3D11_BOX, 8, "uint")   ; front
     ; NumPut(500, D3D11_BOX, 12, "uint")   ; right
     ; NumPut(500, D3D11_BOX, 16, "uint")   ; bottom
     ; NumPut(1, D3D11_BOX, 20, "uint")   ; back
     ; ID3D11DeviceContext_CopySubresourceRegion(d3d_context, staging_tex, 0, 0, 0, 0, tex, 0, &D3D11_BOX)   ; set region
      ID3D11DeviceContext_CopyResource(d3d_context, staging_tex, tex)
      VarSetCapacity(D3D11_MAPPED_SUBRESOURCE, 8+A_PtrSize, 0)
      ID3D11DeviceContext_Map(d3d_context, staging_tex, 0, D3D11_MAP_READ := 1, 0, &D3D11_MAPPED_SUBRESOURCE)
      pBits := NumGet(D3D11_MAPPED_SUBRESOURCE, 0, "ptr")
      pitch := NumGet(D3D11_MAPPED_SUBRESOURCE, A_PtrSize, "uint")
      ID3D11DeviceContext_Unmap(d3d_context, staging_tex, 0)
   }
   ObjRelease(tex)
   Release(desktop_resource)
   tex := desktop_resource := ""
   IDXGIOutputDuplication_ReleaseFrame(duplication)
}
msgbox % a_tickcount - a
SavePixelsToFile32bppPBGRA(width, height, pitch, pBits, file, "GUID_ContainerFormatPng")
Release(staging_tex)
Release(d3d_device)
Release(d3d_context)
Release(duplication)
Release(IDXGIAdapter)
Release(IDXGIOutput)
ObjRelease(IDXGIOutput1)
Release(IDXGIFactory)
staging_tex := d3d_device := d3d_context := duplication := IDXGIAdapter := IDXGIOutput := IDXGIOutput1 := IDXGIFactory := ""
ExitApp




CreateDXGIFactory()
{
   if !DllCall("GetModuleHandle","str","DXGI")
      DllCall("LoadLibrary","str","DXGI")
   if !DllCall("GetModuleHandle","str","D3D11")
      DllCall("LoadLibrary","str","D3D11")
   GUID(riid, "{7b7166ec-21c7-44ae-b21a-c9ae321ae369}")
   hr := DllCall("DXGI\CreateDXGIFactory1", "ptr", &riid, "ptr*", ppFactory)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
   return ppFactory
}

IDXGIFactory_EnumAdapters(this, Adapter, ByRef ppAdapter)
{
   hr := DllCall(NumGet(NumGet(this+0)+7*A_PtrSize), "ptr", this, "uint", Adapter, "ptr*", ppAdapter)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IDXGIAdapter_EnumOutputs(this, Output, ByRef ppOutput)
{
   hr := DllCall(NumGet(NumGet(this+0)+7*A_PtrSize), "ptr", this, "uint", Output, "ptr*", ppOutput)
   if hr or ErrorLevel
   {
      if (hr&=0xFFFFFFFF) = 0x887A0002   ; DXGI_ERROR_NOT_FOUND
         return "DXGI_ERROR_NOT_FOUND"
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
   }
}

IDXGIAdapter_GetDesc(this, pDesc)
{
   hr := DllCall(NumGet(NumGet(this+0)+8*A_PtrSize), "ptr", this, "ptr", pDesc)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IDXGIOutput_GetDesc(this, pDesc)
{
   hr := DllCall(NumGet(NumGet(this+0)+7*A_PtrSize), "ptr", this, "ptr", pDesc)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IDXGIOutputDuplication_GetDesc(this, pDesc)
{
   DllCall(NumGet(NumGet(this+0)+7*A_PtrSize), "ptr", this, "ptr", pDesc)
   if ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IDXGIOutputDuplication_AcquireNextFrame(this, TimeoutInMilliseconds, pFrameInfo, ByRef ppDesktopResource)
{
   hr := DllCall(NumGet(NumGet(this+0)+8*A_PtrSize), "ptr", this, "uint", TimeoutInMilliseconds, "ptr", pFrameInfo, "ptr*", ppDesktopResource)
   if hr or ErrorLevel
   {
      if (hr&=0xFFFFFFFF) = 0x887A0027   ; DXGI_ERROR_WAIT_TIMEOUT
         return "DXGI_ERROR_WAIT_TIMEOUT"
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
   }
}

D3D11CreateDevice(pAdapter, DriverType, Software, Flags, pFeatureLevels, FeatureLevels, SDKVersion, ByRef ppDevice, ByRef pFeatureLevel, ByRef ppImmediateContext)
{
   hr := DllCall("D3D11\D3D11CreateDevice", "ptr", pAdapter, "int", DriverType, "ptr", Software, "uint", Flags, "ptr", pFeatureLevels, "uint", FeatureLevels, "uint", SDKVersion, "ptr*", ppDevice, "ptr*", pFeatureLevel, "ptr*", ppImmediateContext)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

ID3D11Device_CreateTexture2D(this, pDesc, pInitialData, ByRef ppTexture2D)
{
   hr := DllCall(NumGet(NumGet(this+0)+5*A_PtrSize), "ptr", this, "ptr", pDesc, "ptr", pInitialData, "ptr*", ppTexture2D)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IDXGIOutputDuplication_MapDesktopSurface(this, pLockedRect)
{
   hr := DllCall(NumGet(NumGet(this+0)+12*A_PtrSize), "ptr", this, "ptr", pLockedRect)
   if hr or ErrorLevel
   {
      if (hr&=0xFFFFFFFF) = 0x887A0004   ; DXGI_ERROR_UNSUPPORTED
         return "DXGI_ERROR_UNSUPPORTED"
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
   }
}

IDXGIOutputDuplication_UnMapDesktopSurface(this)
{
   hr := DllCall(NumGet(NumGet(this+0)+13*A_PtrSize), "ptr", this)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IDXGIOutputDuplication_ReleaseFrame(this)
{
   hr := DllCall(NumGet(NumGet(this+0)+14*A_PtrSize), "ptr", this)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IDXGIOutput1_DuplicateOutput(this, pDevice, ByRef ppOutputDuplication)
{
   hr := DllCall(NumGet(NumGet(this+0)+22*A_PtrSize), "ptr", this, "ptr", pDevice, "ptr*", ppOutputDuplication)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IDXGIOutput1_Query(IDXGIOutput)
{ 
   hr := ComObjQuery(IDXGIOutput, "{00cddea8-939b-4b83-a340-a685226666cc}")
   if !hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
   return hr
}

ID3D11Texture2D_Query(desktop_resource)
{ 
   hr := ComObjQuery(desktop_resource, "{6f15aaf2-d208-4e89-9ab4-489535d34f9c}")
   if !hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
   return hr
}

ID3D11DeviceContext_CopyResource(this, pDstResource, pSrcResource)
{
   hr := DllCall(NumGet(NumGet(this+0)+47*A_PtrSize), "ptr", this, "ptr", pDstResource, "ptr", pSrcResource)
   if ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

ID3D11DeviceContext_CopySubresourceRegion(this, pDstResource, DstSubresource, DstX, DstY, DstZ, pSrcResource, SrcSubresource, pSrcBox)
{
   hr := DllCall(NumGet(NumGet(this+0)+46*A_PtrSize), "ptr", this, "ptr", pDstResource, "uint", DstSubresource, "uint", DstX, "uint", DstY, "uint", DstZ, "ptr", pSrcResource, "uint", SrcSubresource, "ptr", pSrcBox)
   if ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

ID3D11DeviceContext_Map(this, pResource, Subresource, MapType, MapFlags, pMappedResource)
{
   hr := DllCall(NumGet(NumGet(this+0)+14*A_PtrSize), "ptr", this, "ptr", pResource, "uint", Subresource, "uint", MapType, "uint", MapFlags, "ptr", pMappedResource)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

ID3D11DeviceContext_Unmap(this, pResource, Subresource)
{
   hr := DllCall(NumGet(NumGet(this+0)+15*A_PtrSize), "ptr", this, "ptr", pResource, "uint", Subresource)
   if ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

Release(this)
{
   DllCall(NumGet(NumGet(this+0)+2*A_PtrSize), "ptr", this)
   if ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

GUID(ByRef GUID, sGUID)
{
    VarSetCapacity(GUID, 16, 0)
    return DllCall("ole32\CLSIDFromString", "WStr", sGUID, "Ptr", &GUID) >= 0 ? &GUID : ""
}

_Error(val)
{
   msgbox % val
   ExitApp
}

SavePixelsToFile32bppPBGRA(width, height, stride, pixels, filePath, GUID)
{
   wic := IWICCreate()
   IWICImagingFactory_CreateStream(wic, stream)
   IWICStream_InitializeFromFilename(stream, filePath, GENERIC_WRITE := 0x40000000)
   IWICImagingFactory_CreateEncoder(wic, GUID, 0, encoder)
   IWICBitmapEncoder_Initialize(encoder, stream, WICBitmapEncoderNoCache := 0x2)
   IWICBitmapEncoder_CreateNewFrame(encoder, frame)
   IWICBitmapFrameEncode_Initialize(frame)
   IWICBitmapFrameEncode_SetSize(frame, width, height)
   IWICBitmapFrameEncode_SetPixelFormat(frame, "GUID_WICPixelFormat32bppPBGRA")
   IWICBitmapFrameEncode_WritePixels(frame, height, stride, stride * height, pixels)
   IWICBitmapFrameEncode_Commit(frame)
   IWICBitmapEncoder_Commit(encoder)
   Release(stream)
   Release(frame)
   Release(encoder)
   ObjRelease(wic)
   return
}

IWICCreate()
{
   return ComObjCreate("{cacaf262-9370-4615-a13b-9f5539da4c0a}", "{ec5ec8a9-c395-4314-9c77-54d7a935ff70}")
}

IWICImagingFactory_CreateStream(this, ByRef ppIWICStream)
{
   hr := DllCall(NumGet(NumGet(this+0)+14*A_PtrSize), "ptr", this, "ptr*", ppIWICStream)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IWICImagingFactory_CreateEncoder(this, guidContainerFormat, pguidVendor, ByRef ppIEncoder)
{
   hr := DllCall(NumGet(NumGet(this+0)+8*A_PtrSize), "ptr", this, "ptr", WIC_GUID(GUID1, guidContainerFormat), "ptr", WIC_GUID(GUID2, pguidVendor), "ptr*", ppIEncoder)
   if hr
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IWICStream_InitializeFromFilename(this, wzFileName, dwDesiredAccess)
{
   hr := DllCall(NumGet(NumGet(this+0)+15*A_PtrSize), "ptr", this, "str", wzFileName, "uint", dwDesiredAccess)
   if hr
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IWICBitmapEncoder_Initialize(this, pIStream, cacheOption)
{
   hr := DllCall(NumGet(NumGet(this+0)+3*A_PtrSize), "ptr", this, "ptr", pIStream, "int", cacheOption)
   if hr
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IWICBitmapEncoder_CreateNewFrame(this, ByRef ppIFrameEncode, ppIEncoderOptions := 0)
{
   hr := DllCall(NumGet(NumGet(this+0)+10*A_PtrSize), "ptr", this, "ptr*", ppIFrameEncode, "ptr*", ppIEncoderOptions)
   if hr
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IWICBitmapEncoder_Commit(this)
{
   hr := DllCall(NumGet(NumGet(this+0)+11*A_PtrSize), "ptr", this)
   if hr
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IWICBitmapFrameEncode_Initialize(this, pIEncoderOptions := 0)
{
   hr := DllCall(NumGet(NumGet(this+0)+3*A_PtrSize), "ptr", this, "ptr", pIEncoderOptions)
   if hr
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IWICBitmapFrameEncode_SetSize(this, uiWidth, uiHeight)
{
   hr := DllCall(NumGet(NumGet(this+0)+4*A_PtrSize), "ptr", this, "uint", uiWidth, "uint", uiHeight)
   if hr
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IWICBitmapFrameEncode_SetPixelFormat(this, pPixelFormat)
{
   hr := DllCall(NumGet(NumGet(this+0)+6*A_PtrSize), "ptr", this, "ptr", WIC_GUID(GUID, pPixelFormat))
   if hr
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IWICBitmapFrameEncode_WritePixels(this, lineCount, cbStride, cbBufferSize, pbPixels)
{
   hr := DllCall(NumGet(NumGet(this+0)+10*A_PtrSize), "ptr", this, "uint", lineCount, "uint", cbStride, "uint", cbBufferSize, "ptr", pbPixels)
   if hr
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IWICBitmapFrameEncode_Commit(this)
{
   hr := DllCall(NumGet(NumGet(this+0)+12*A_PtrSize), "ptr", this)
   if hr
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

WIC_GUID(ByRef GUID,name){
	static init:=1,_:={}
	if init {
	init:=0
	; Decoders
	 _.CLSID_WICBmpDecoder:=[0x6b462062, 0x7cbf, 0x400d, 0x9f, 0xdb, 0x81, 0x3d, 0xd1, 0xf, 0x27, 0x78]
	,_.CLSID_WICPngDecoder:=[0x389ea17b, 0x5078, 0x4cde, 0xb6, 0xef, 0x25, 0xc1, 0x51, 0x75, 0xc7, 0x51]
	,_.CLSID_WICIcoDecoder:=[0xc61bfcdf, 0x2e0f, 0x4aad, 0xa8, 0xd7, 0xe0, 0x6b, 0xaf, 0xeb, 0xcd, 0xfe]
	,_.CLSID_WICJpegDecoder:=[0x9456a480, 0xe88b, 0x43ea, 0x9e, 0x73, 0xb, 0x2d, 0x9b, 0x71, 0xb1, 0xca]
	,_.CLSID_WICGifDecoder:=[0x381dda3c, 0x9ce9, 0x4834, 0xa2, 0x3e, 0x1f, 0x98, 0xf8, 0xfc, 0x52, 0xbe]
	,_.CLSID_WICTiffDecoder:=[0xb54e85d9, 0xfe23, 0x499f, 0x8b, 0x88, 0x6a, 0xce, 0xa7, 0x13, 0x75, 0x2b]
	,_.CLSID_WICWmpDecoder:=[0xa26cec36, 0x234c, 0x4950, 0xae, 0x16, 0xe3, 0x4a, 0xac, 0xe7, 0x1d, 0x0d]
	; Encoders
	 _.CLSID_WICBmpEncoder:=[0x69be8bb4, 0xd66d, 0x47c8, 0x86, 0x5a, 0xed, 0x15, 0x89, 0x43, 0x37, 0x82]
	,_.CLSID_WICPngEncoder:=[0x27949969, 0x876a, 0x41d7, 0x94, 0x47, 0x56, 0x8f, 0x6a, 0x35, 0xa4, 0xdc]
	,_.CLSID_WICJpegEncoder:=[0x1a34f5c1, 0x4a5a, 0x46dc, 0xb6, 0x44, 0x1f, 0x45, 0x67, 0xe7, 0xa6, 0x76]
	,_.CLSID_WICGifEncoder:=[0x114f5598, 0xb22, 0x40a0, 0x86, 0xa1, 0xc8, 0x3e, 0xa4, 0x95, 0xad, 0xbd]
	,_.CLSID_WICTiffEncoder:=[0x0131be10, 0x2001, 0x4c5f, 0xa9, 0xb0, 0xcc, 0x88, 0xfa, 0xb6, 0x4c, 0xe8]
	,_.CLSID_WICWmpEncoder:=[0xac4ce3cb, 0xe1c1, 0x44cd, 0x82, 0x15, 0x5a, 0x16, 0x65, 0x50, 0x9e, 0xc2]
	; Container Formats
	 _.GUID_ContainerFormatBmp:=[0xaf1d87e, 0xfcfe, 0x4188, 0xbd, 0xeb, 0xa7, 0x90, 0x64, 0x71, 0xcb, 0xe3]
	,_.GUID_ContainerFormatPng:=[0x1b7cfaf4, 0x713f, 0x473c, 0xbb, 0xcd, 0x61, 0x37, 0x42, 0x5f, 0xae, 0xaf]
	,_.GUID_ContainerFormatIco:=[0xa3a860c4, 0x338f, 0x4c17, 0x91, 0x9a, 0xfb, 0xa4, 0xb5, 0x62, 0x8f, 0x21]
	,_.GUID_ContainerFormatJpeg:=[0x19e4a5aa, 0x5662, 0x4fc5, 0xa0, 0xc0, 0x17, 0x58, 0x2, 0x8e, 0x10, 0x57]
	,_.GUID_ContainerFormatTiff:=[0x163bcc30, 0xe2e9, 0x4f0b, 0x96, 0x1d, 0xa3, 0xe9, 0xfd, 0xb7, 0x88, 0xa3]
	,_.GUID_ContainerFormatGif:=[0x1f8a5601, 0x7d4d, 0x4cbd, 0x9c, 0x82, 0x1b, 0xc8, 0xd4, 0xee, 0xb9, 0xa5]
	,_.GUID_ContainerFormatWmp:=[0x57a37caa, 0x367a, 0x4540, 0x91, 0x6b, 0xf1, 0x83, 0xc5, 0x09, 0x3a, 0x4b]
	; Component Identifiers
	 _.CLSID_WICImagingCategories:=[0xfae3d380, 0xfea4, 0x4623, 0x8c, 0x75, 0xc6, 0xb6, 0x11, 0x10, 0xb6, 0x81]
	,_.CATID_WICBitmapDecoders:=[0x7ed96837, 0x96f0, 0x4812, 0xb2, 0x11, 0xf1, 0x3c, 0x24, 0x11, 0x7e, 0xd3]
	,_.CATID_WICBitmapEncoders:=[0xac757296, 0x3522, 0x4e11, 0x98, 0x62, 0xc1, 0x7b, 0xe5, 0xa1, 0x76, 0x7e]
	,_.CATID_WICPixelFormats:=[0x2b46e70f, 0xcda7, 0x473e, 0x89, 0xf6, 0xdc, 0x96, 0x30, 0xa2, 0x39, 0x0b]
	,_.CATID_WICFormatConverters:=[0x7835eae8, 0xbf14, 0x49d1, 0x93, 0xce, 0x53, 0x3a, 0x40, 0x7b, 0x22, 0x48]
	,_.CATID_WICMetadataReader:=[0x05af94d8, 0x7174, 0x4cd2, 0xbe, 0x4a, 0x41, 0x24, 0xb8, 0x0e, 0xe4, 0xb8]
	,_.CATID_WICMetadataWriter:=[0xabe3b9a4, 0x257d, 0x4b97, 0xbd, 0x1a, 0x29, 0x4a, 0xf4, 0x96, 0x22, 0x2e]
	; Format Converters
	 _.CLSID_WICDefaultFormatConverter:=[0x1a3f11dc, 0xb514, 0x4b17, 0x8c, 0x5f, 0x21, 0x54, 0x51, 0x38, 0x52, 0xf1]
	,_.CLSID_WICFormatConverterHighColor:=[0xac75d454, 0x9f37, 0x48f8, 0xb9, 0x72, 0x4e, 0x19, 0xbc, 0x85, 0x60, 0x11]
	,_.CLSID_WICFormatConverterNChannel:=[0xc17cabb2, 0xd4a3, 0x47d7, 0xa5, 0x57, 0x33, 0x9b, 0x2e, 0xfb, 0xd4, 0xf1]
	,_.CLSID_WICFormatConverterWMPhoto:=[0x9cb5172b, 0xd600, 0x46ba, 0xab, 0x77, 0x77, 0xbb, 0x7e, 0x3a, 0x00, 0xd9]
	; Metadata Handlers
	 _.GUID_MetadataFormatUnknown:=[0xA45E592F, 0x9078, 0x4A7C, 0xAD, 0xB5, 0x4E, 0xDC, 0x4F, 0xD6, 0x1B, 0x1F]
	,_.GUID_MetadataFormatIfd:=[0x537396C6, 0x2D8A, 0x4BB6, 0x9B, 0xF8, 0x2F, 0x0A, 0x8E, 0x2A, 0x3A, 0xDF]
	,_.GUID_MetadataFormatSubIfd:=[0x58A2E128, 0x2DB9, 0x4E57, 0xBB, 0x14, 0x51, 0x77, 0x89, 0x1E, 0xD3, 0x31]
	,_.GUID_MetadataFormatExif:=[0x1C3C4F9D, 0xB84A, 0x467D, 0x94, 0x93, 0x36, 0xCF, 0xBD, 0x59, 0xEA, 0x57]
	,_.GUID_MetadataFormatGps:=[0x7134AB8A, 0x9351, 0x44AD, 0xAF, 0x62, 0x44, 0x8D, 0xB6, 0xB5, 0x02, 0xEC]
	,_.GUID_MetadataFormatInterop:=[0xED686F8E, 0x681F, 0x4C8B, 0xBD, 0x41, 0xA8, 0xAD, 0xDB, 0xF6, 0xB3, 0xFC]
	,_.GUID_MetadataFormatApp0:=[0x79007028, 0x268D, 0x45d6, 0xA3, 0xC2, 0x35, 0x4E, 0x6A, 0x50, 0x4B, 0xC9]
	,_.GUID_MetadataFormatApp1:=[0x8FD3DFC3, 0xF951, 0x492B, 0x81, 0x7F, 0x69, 0xC2, 0xE6, 0xD9, 0xA5, 0xB0]
	,_.GUID_MetadataFormatApp13:=[0x326556A2, 0xF502, 0x4354, 0x9C, 0xC0, 0x8E, 0x3F, 0x48, 0xEA, 0xF6, 0xB5]
	,_.GUID_MetadataFormatIPTC:=[0x4FAB0914, 0xE129, 0x4087, 0xA1, 0xD1, 0xBC, 0x81, 0x2D, 0x45, 0xA7, 0xB5]
	,_.GUID_MetadataFormatIRB:=[0x16100D66, 0x8570, 0x4BB9, 0xB9, 0x2D, 0xFD, 0xA4, 0xB2, 0x3E, 0xCE, 0x67]
	,_.GUID_MetadataFormat8BIMIPTC:=[0x0010568c, 0x0852, 0x4e6a, 0xb1, 0x91, 0x5c, 0x33, 0xac, 0x5b, 0x04, 0x30]
	,_.GUID_MetadataFormat8BIMResolutionInfo:=[0x739F305D, 0x81DB, 0x43CB, 0xAC, 0x5E, 0x55, 0x01, 0x3E, 0xF9, 0xF0, 0x03]
	 _.GUID_MetadataFormat8BIMIPTCDigest:=[0x1CA32285, 0x9CCD, 0x4786, 0x8B, 0xD8, 0x79, 0x53, 0x9D, 0xB6, 0xA0, 0x06]
	,_.GUID_MetadataFormatXMP:=[0xBB5ACC38, 0xF216, 0x4CEC, 0xA6, 0xC5, 0x5F, 0x6E, 0x73, 0x97, 0x63, 0xA9]
	,_.GUID_MetadataFormatThumbnail:=[0x243dcee9, 0x8703, 0x40ee, 0x8e, 0xf0, 0x22, 0xa6, 0x0, 0xb8, 0x5, 0x8c]
	,_.GUID_MetadataFormatChunktEXt:=[0x568d8936, 0xc0a9, 0x4923, 0x90, 0x5d, 0xdf, 0x2b, 0x38, 0x23, 0x8f, 0xbc]
	,_.GUID_MetadataFormatXMPStruct:=[0x22383CF1, 0xED17, 0x4E2E, 0xAF, 0x17, 0xD8, 0x5B, 0x8F, 0x6B, 0x30, 0xD0]
	,_.GUID_MetadataFormatXMPBag:=[0x833CCA5F, 0xDCB7, 0x4516, 0x80, 0x6F, 0x65, 0x96, 0xAB, 0x26, 0xDC, 0xE4]
	,_.GUID_MetadataFormatXMPSeq:=[0x63E8DF02, 0xEB6C,0x456C, 0xA2, 0x24, 0xB2, 0x5E, 0x79, 0x4F, 0xD6, 0x48]
	,_.GUID_MetadataFormatXMPAlt:=[0x7B08A675, 0x91AA, 0x481B, 0xA7, 0x98, 0x4D, 0xA9, 0x49, 0x08, 0x61, 0x3B]
	,_.GUID_MetadataFormatLSD:=[0xE256031E, 0x6299, 0x4929, 0xB9, 0x8D, 0x5A, 0xC8, 0x84, 0xAF, 0xBA, 0x92]
	,_.GUID_MetadataFormatIMD:=[0xBD2BB086, 0x4D52, 0x48DD, 0x96, 0x77, 0xDB, 0x48, 0x3E, 0x85, 0xAE, 0x8F]
	,_.GUID_MetadataFormatGCE:=[0x2A25CAD8, 0xDEEB, 0x4C69, 0xA7, 0x88, 0xE, 0xC2, 0x26, 0x6D, 0xCA, 0xFD]
	,_.GUID_MetadataFormatAPE:=[0x2E043DC2, 0xC967, 0x4E05, 0x87, 0x5E, 0x61, 0x8B, 0xF6, 0x7E, 0x85, 0xC3]
	 _.GUID_MetadataFormatJpegChrominance:=[0xF73D0DCF, 0xCEC6, 0x4F85, 0x9B, 0x0E, 0x1C, 0x39, 0x56, 0xB1, 0xBE, 0xF7]
	,_.GUID_MetadataFormatJpegLuminance:=[0x86908007, 0xEDFC, 0x4860, 0x8D, 0x4B, 0x4E, 0xE6, 0xE8, 0x3E, 0x60, 0x58]
	,_.GUID_MetadataFormatJpegComment:=[0x220E5F33, 0xAFD3, 0x474E, 0x9D, 0x31, 0x7D, 0x4F, 0xE7, 0x30, 0xF5, 0x57]
	,_.GUID_MetadataFormatGifComment:=[0xC4B6E0E0, 0xCFB4, 0x4AD3, 0xAB, 0x33, 0x9A, 0xAD, 0x23, 0x55, 0xA3, 0x4A]
	,_.GUID_MetadataFormatChunkgAMA:=[0xF00935A5, 0x1D5D, 0x4CD1, 0x81, 0xB2, 0x93, 0x24, 0xD7, 0xEC, 0xA7, 0x81]
	,_.GUID_MetadataFormatChunkbKGD:=[0xE14D3571, 0x6B47, 0x4DEA, 0xB6, 0xA, 0x87, 0xCE, 0xA, 0x78, 0xDF, 0xB7]
	,_.GUID_MetadataFormatChunkiTXt:=[0xC2BEC729, 0xB68, 0x4B77, 0xAA, 0xE, 0x62, 0x95, 0xA6, 0xAC, 0x18, 0x14]
	,_.GUID_MetadataFormatChunkcHRM:=[0x9DB3655B, 0x2842, 0x44B3, 0x80, 0x67, 0x12, 0xE9, 0xB3, 0x75, 0x55, 0x6A]
	,_.GUID_MetadataFormatChunkhIST:=[0xC59A82DA, 0xDB74, 0x48A4, 0xBD, 0x6A, 0xB6, 0x9C, 0x49, 0x31, 0xEF, 0x95]
	,_.GUID_MetadataFormatChunkiCCP:=[0xEB4349AB, 0xB685, 0x450F, 0x91, 0xB5, 0xE8, 0x2, 0xE8, 0x92, 0x53, 0x6C]
	,_.GUID_MetadataFormatChunksRGB:=[0xC115FD36, 0xCC6F, 0x4E3F, 0x83, 0x63, 0x52, 0x4B, 0x87, 0xC6, 0xB0, 0xD9]
	,_.GUID_MetadataFormatChunktIME:=[0x6B00AE2D, 0xE24B, 0x460A, 0x98, 0xB6, 0x87, 0x8B, 0xD0, 0x30, 0x72, 0xFD]
	; Vendor Identification
	 _.GUID_VendorMicrosoft:=[0x69fd0fdc, 0xa866, 0x4108, 0xb3, 0xb2, 0x98, 0x44, 0x7f, 0xa9, 0xed, 0xd4]
	,_.GUID_VendorMicrosoftBuiltIn:=[0x257a30fd, 0x6b6, 0x462b, 0xae, 0xa4, 0x63, 0xf7, 0xb, 0x86, 0xe5, 0x33]
	; WICBitmapPaletteType
	 _.GUID_WICPixelFormatDontCare:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x00]
	,_.GUID_WICPixelFormat1bppIndexed:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x01]
	,_.GUID_WICPixelFormat2bppIndexed:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x02]
	,_.GUID_WICPixelFormat4bppIndexed:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x03]
	,_.GUID_WICPixelFormat8bppIndexed:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x04]
	,_.GUID_WICPixelFormatBlackWhite:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x05]
	,_.GUID_WICPixelFormat2bppGray:=[  0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x06]
	,_.GUID_WICPixelFormat4bppGray:=[  0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x07]
	,_.GUID_WICPixelFormat8bppGray:=[  0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x08]
	,_.GUID_WICPixelFormat8bppAlpha:=[0xe6cd0116, 0xeeba, 0x4161, 0xaa, 0x85, 0x27, 0xdd, 0x9f, 0xb3, 0xa8, 0x95]
	,_.GUID_WICPixelFormat16bppBGR555:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x09]
	,_.GUID_WICPixelFormat16bppBGR565:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0a]
	,_.GUID_WICPixelFormat16bppBGRA5551:=[0x05ec7c2b, 0xf1e6, 0x4961, 0xad, 0x46, 0xe1, 0xcc, 0x81, 0x0a, 0x87, 0xd2]
	 _.GUID_WICPixelFormat16bppGray:=[  0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0b]
	,_.GUID_WICPixelFormat24bppBGR:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0c]
	,_.GUID_WICPixelFormat24bppRGB:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0d]
	,_.GUID_WICPixelFormat32bppBGR:=[  0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0e]
	,_.GUID_WICPixelFormat32bppBGRA:=[ 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0f]
	,_.GUID_WICPixelFormat32bppPBGRA:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x10]
	,_.GUID_WICPixelFormat32bppGrayFloat:=[ 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x11]
	,_.GUID_WICPixelFormat32bppRGBA:=[0xf5c7ad2d, 0x6a8d, 0x43dd, 0xa7, 0xa8, 0xa2, 0x99, 0x35, 0x26, 0x1a, 0xe9]
	,_.GUID_WICPixelFormat32bppPRGBA:=[0x3cc4a650, 0xa527, 0x4d37, 0xa9, 0x16, 0x31, 0x42, 0xc7, 0xeb, 0xed, 0xba]
	,_.GUID_WICPixelFormat48bppRGB:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x15]
	,_.GUID_WICPixelFormat48bppBGR:=[0xe605a384, 0xb468, 0x46ce, 0xbb, 0x2e, 0x36, 0xf1, 0x80, 0xe6, 0x43, 0x13]
	,_.GUID_WICPixelFormat64bppRGBA:=[ 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x16]
	,_.GUID_WICPixelFormat64bppBGRA:=[ 0x1562ff7c, 0xd352, 0x46f9, 0x97, 0x9e, 0x42, 0x97, 0x6b, 0x79, 0x22, 0x46]
	 _.GUID_WICPixelFormat64bppPRGBA:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x17]
	,_.GUID_WICPixelFormat64bppPBGRA:=[0x8c518e8e, 0xa4ec, 0x468b, 0xae, 0x70, 0xc9, 0xa3, 0x5a, 0x9c, 0x55, 0x30]
	,_.GUID_WICPixelFormat16bppGrayFixedPoint:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x13]
	,_.GUID_WICPixelFormat32bppBGR101010:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x14]
	,_.GUID_WICPixelFormat48bppRGBFixedPoint:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x12]
	,_.GUID_WICPixelFormat48bppBGRFixedPoint:=[0x49ca140e, 0xcab6, 0x493b, 0x9d, 0xdf, 0x60, 0x18, 0x7c, 0x37, 0x53, 0x2a]
	,_.GUID_WICPixelFormat96bppRGBFixedPoint:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x18]
	,_.GUID_WICPixelFormat128bppRGBAFloat:=[ 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x19]
	,_.GUID_WICPixelFormat128bppPRGBAFloat:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x1a]
	,_.GUID_WICPixelFormat128bppRGBFloat:=[  0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x1b]
	,_.GUID_WICPixelFormat32bppCMYK:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x1c]
	,_.GUID_WICPixelFormat64bppRGBAFixedPoint:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x1d]
	,_.GUID_WICPixelFormat64bppBGRAFixedPoint:=[0x356de33c, 0x54d2, 0x4a23, 0xbb, 0x4, 0x9b, 0x7b, 0xf9, 0xb1, 0xd4, 0x2d]
	 _.GUID_WICPixelFormat64bppRGBFixedPoint:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x40]
	,_.GUID_WICPixelFormat128bppRGBAFixedPoint:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x1e]
	,_.GUID_WICPixelFormat128bppRGBFixedPoint:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x41]
	,_.GUID_WICPixelFormat64bppRGBAHalf:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x3a]
	,_.GUID_WICPixelFormat64bppRGBHalf:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x42]
	,_.GUID_WICPixelFormat48bppRGBHalf:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x3b]
	,_.GUID_WICPixelFormat32bppRGBE:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x3d]
	,_.GUID_WICPixelFormat16bppGrayHalf:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x3e]
	,_.GUID_WICPixelFormat32bppGrayFixedPoint:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x3f]
	,_.GUID_WICPixelFormat32bppRGBA1010102:=[0x25238D72, 0xFCF9, 0x4522, 0xb5, 0x14, 0x55, 0x78, 0xe5, 0xad, 0x55, 0xe0]
	,_.GUID_WICPixelFormat32bppRGBA1010102XR:=[0x00DE6B9A, 0xC101, 0x434b, 0xb5, 0x02, 0xd0, 0x16, 0x5e, 0xe1, 0x12, 0x2c]
	,_.GUID_WICPixelFormat64bppCMYK:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x1f]
	,_.GUID_WICPixelFormat24bpp3Channels:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x20]
	 _.GUID_WICPixelFormat32bpp4Channels:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x21]
	,_.GUID_WICPixelFormat40bpp5Channels:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x22]
	,_.GUID_WICPixelFormat48bpp6Channels:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x23]
	,_.GUID_WICPixelFormat56bpp7Channels:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x24]
	,_.GUID_WICPixelFormat64bpp8Channels:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x25]
	,_.GUID_WICPixelFormat48bpp3Channels:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x26]
	,_.GUID_WICPixelFormat64bpp4Channels:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x27]
	,_.GUID_WICPixelFormat80bpp5Channels:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x28]
	,_.GUID_WICPixelFormat96bpp6Channels:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x29]
	,_.GUID_WICPixelFormat112bpp7Channels:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x2a]
	,_.GUID_WICPixelFormat128bpp8Channels:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x2b]
	,_.GUID_WICPixelFormat40bppCMYKAlpha:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x2c]
	,_.GUID_WICPixelFormat80bppCMYKAlpha:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x2d]
	,_.GUID_WICPixelFormat32bpp3ChannelsAlpha:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x2e]
	 _.GUID_WICPixelFormat40bpp4ChannelsAlpha:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x2f]
	,_.GUID_WICPixelFormat48bpp5ChannelsAlpha:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x30]
	,_.GUID_WICPixelFormat56bpp6ChannelsAlpha:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x31]
	,_.GUID_WICPixelFormat64bpp7ChannelsAlpha:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x32]
	,_.GUID_WICPixelFormat72bpp8ChannelsAlpha:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x33]
	,_.GUID_WICPixelFormat64bpp3ChannelsAlpha:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x34]
	,_.GUID_WICPixelFormat80bpp4ChannelsAlpha:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x35]
	,_.GUID_WICPixelFormat96bpp5ChannelsAlpha:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x36]
	,_.GUID_WICPixelFormat112bpp6ChannelsAlpha:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x37]
	,_.GUID_WICPixelFormat128bpp7ChannelsAlpha:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x38]
	,_.GUID_WICPixelFormat144bpp8ChannelsAlpha:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x39]

	}
	if _.haskey(name){
		p:=_[name]
		VarSetCapacity(GUID,16)
		,NumPut(p.1+(p.2<<32)+(p.3<<48),GUID,0,"int64")
		,NumPut(p.4+(p.5<<8)+(p.6<<16)+(p.7<<24)+(p.8<<32)+(p.9<<40)+(p.10<<48)+(p.11<<56),GUID,8,"int64")
		return &GUID
	}else return name
}
For win7 with directx 9

Code: Select all

;
; Script Requirements:
;
;   DirectX - March 2008 or later. (d3dx9_37.dll)
;     DirectX End-User Runtime Web Installer (March 2008):
;     http://www.microsoft.com/downloads/details.aspx?FamilyId=2DA43D38-DB71-4C1B-BC6A-9B6652CD92A3&displaylang=en
;
file := "test.png"
setbatchlines -1

; init D3D and get screen size
d3d := Direct3DCreate9(D3D_SDK_VERSION := 32) 
if !d3d
{
    MsgBox, 16, Error, Direct3DCreate9 failed.
    ExitApp
}
VarSetCapacity(D3DDISPLAYMODE, 16, 0)
IDirect3D9_GetAdapterDisplayMode(d3d, D3DADAPTER_DEFAULT := 0, &D3DDISPLAYMODE)
Windowed := true
BackBufferCount := 1
BackBufferHeight := NumGet(D3DDISPLAYMODE, 4, "uint")
BackBufferWidth := NumGet(D3DDISPLAYMODE, 0, "uint")
SwapEffect := 1   ; D3DSWAPEFFECT_DISCARD
hDeviceWindow := 0

; create device & capture surface
VarSetCapacity(D3DPRESENT_PARAMETERS, 48+2*A_PtrSize, 0) 
NumPut(BackBufferWidth, D3DPRESENT_PARAMETERS, 0)
NumPut(BackBufferHeight, D3DPRESENT_PARAMETERS, 4)
NumPut(BackBufferCount, D3DPRESENT_PARAMETERS, 12)
NumPut(SwapEffect, D3DPRESENT_PARAMETERS, 24)
NumPut(hDeviceWindow, D3DPRESENT_PARAMETERS, 24+A_PtrSize)
NumPut(Windowed, D3DPRESENT_PARAMETERS, 24+2*A_PtrSize)
IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT := 0, D3DDEVTYPE_HAL := 1, 0, D3DCREATE_SOFTWARE_VERTEXPROCESSING := 0x00000020, &D3DPRESENT_PARAMETERS, device)
IDirect3DDevice9_CreateOffscreenPlainSurface(device, BackBufferWidth, BackBufferHeight, D3DFMT_A8R8G8B8 := 21, D3DPOOL_SYSTEMMEM := 2, surface, 0)

a := a_tickcount
loop 100
{
   ; get the data
   IDirect3DDevice9_GetFrontBufferData(device, 0, surface)

   ; copy it into our buffers
   VarSetCapacity(D3DLOCKED_RECT, A_PtrSize*2, 0)
   IDirect3DSurface9_LockRect(surface, &D3DLOCKED_RECT, 0, 0)
   pitch := NumGet(D3DLOCKED_RECT, 0, "int")
   pBits := NumGet(D3DLOCKED_RECT, A_PtrSize, "ptr")
   IDirect3DSurface9_UnlockRect(surface)
}
msgbox % a_tickcount - a

SavePixelsToFile32bppPBGRA(BackBufferWidth, BackBufferHeight, pitch, pBits, file, "GUID_ContainerFormatPng")

Release(surface)
Release(device)
Release(d3d)
msgbox done
return



Direct3DCreate9(SDKVersion) {
    if !DllCall("GetModuleHandle","str","d3d9")
        DllCall("LoadLibrary","str","d3d9")
    return DllCall("d3d9\Direct3DCreate9", "uint", SDKVersion)
}

IDirect3D9_GetAdapterDisplayMode(this,Adapter,pMode)
{
   hr := DllCall(NumGet(NumGet(this+0)+8*A_PtrSize),"ptr",this,"uint",Adapter,"ptr",pMode)
   if hr
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IDirect3D9_CreateDevice(this,Adapter,DeviceType,hFocusWindow,BehaviorFlags,pPresentationParameters,ByRef ppReturnedDeviceInterface)
{
   hr := DllCall(NumGet(NumGet(this+0)+16*A_PtrSize),"ptr",this,"uint",Adapter,"uint",DeviceType,"ptr",hFocusWindow,"uint",BehaviorFlags,"ptr",pPresentationParameters,"ptr*",ppReturnedDeviceInterface)
   if hr
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IDirect3DDevice9_GetFrontBufferData(this,iSwapChain,pDestSurface)
{
   hr := DllCall(NumGet(NumGet(this+0)+33*A_PtrSize),"ptr",this,"uint",iSwapChain,"ptr",pDestSurface)
   if hr
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IDirect3DDevice9_CreateOffscreenPlainSurface(this,Width,Height,Format,Pool,ByRef ppSurface,pSharedHandle)
{
   hr := DllCall(NumGet(NumGet(this+0)+36*A_PtrSize),"ptr",this,"uint",Width,"uint",Height,"uint",Format,"uint",Pool,"ptr*",ppSurface,"ptr",pSharedHandle)
   if hr
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IDirect3DSurface9_LockRect(this,pLockedRect,pRect,Flags)
{
   hr := DllCall(NumGet(NumGet(this+0)+13*A_PtrSize),"ptr",this,"ptr",pLockedRect,"ptr",pRect,"uint",Flags)
   if hr
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IDirect3DSurface9_UnlockRect(this)
{
   hr := DllCall(NumGet(NumGet(this+0)+14*A_PtrSize),"ptr",this)
   if hr
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

Release(this) { ; COM_Release. So far the only required COM_* function...
    return DllCall(NumGet(NumGet(this+0)+2*A_PtrSize), "ptr", this)
}

_Error(val)
{
   msgbox % val
   ExitApp
}

SavePixelsToFile32bppPBGRA(width, height, stride, pixels, filePath, GUID)
{
   wic := IWICCreate()
   IWICImagingFactory_CreateStream(wic, stream)
   IWICStream_InitializeFromFilename(stream, filePath, GENERIC_WRITE := 0x40000000)
   IWICImagingFactory_CreateEncoder(wic, GUID, 0, encoder)
   IWICBitmapEncoder_Initialize(encoder, stream, WICBitmapEncoderNoCache := 0x2)
   IWICBitmapEncoder_CreateNewFrame(encoder, frame)
   IWICBitmapFrameEncode_Initialize(frame)
   IWICBitmapFrameEncode_SetSize(frame, width, height)
   IWICBitmapFrameEncode_SetPixelFormat(frame, "GUID_WICPixelFormat32bppPBGRA")
   IWICBitmapFrameEncode_WritePixels(frame, height, stride, stride * height, pixels)
   IWICBitmapFrameEncode_Commit(frame)
   IWICBitmapEncoder_Commit(encoder)
   Release(stream)
   Release(frame)
   Release(encoder)
   Release(factory)
   ObjRelease(wic)
   return
}

IWICCreate()
{
   return ComObjCreate("{cacaf262-9370-4615-a13b-9f5539da4c0a}", "{ec5ec8a9-c395-4314-9c77-54d7a935ff70}")
}

IWICImagingFactory_CreateStream(this, ByRef ppIWICStream)
{
   hr := DllCall(NumGet(NumGet(this+0)+14*A_PtrSize), "ptr", this, "ptr*", ppIWICStream)
   if hr or ErrorLevel
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IWICImagingFactory_CreateEncoder(this, guidContainerFormat, pguidVendor, ByRef ppIEncoder)
{
   hr := DllCall(NumGet(NumGet(this+0)+8*A_PtrSize), "ptr", this, "ptr", WIC_GUID(GUID1, guidContainerFormat), "ptr", WIC_GUID(GUID2, pguidVendor), "ptr*", ppIEncoder)
   if hr
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IWICStream_InitializeFromFilename(this, wzFileName, dwDesiredAccess)
{
   hr := DllCall(NumGet(NumGet(this+0)+15*A_PtrSize), "ptr", this, "str", wzFileName, "uint", dwDesiredAccess)
   if hr
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IWICBitmapEncoder_Initialize(this, pIStream, cacheOption)
{
   hr := DllCall(NumGet(NumGet(this+0)+3*A_PtrSize), "ptr", this, "ptr", pIStream, "int", cacheOption)
   if hr
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IWICBitmapEncoder_CreateNewFrame(this, ByRef ppIFrameEncode, ppIEncoderOptions := 0)
{
   hr := DllCall(NumGet(NumGet(this+0)+10*A_PtrSize), "ptr", this, "ptr*", ppIFrameEncode, "ptr*", ppIEncoderOptions)
   if hr
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IWICBitmapEncoder_Commit(this)
{
   hr := DllCall(NumGet(NumGet(this+0)+11*A_PtrSize), "ptr", this)
   if hr
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IWICBitmapFrameEncode_Initialize(this, pIEncoderOptions := 0)
{
   hr := DllCall(NumGet(NumGet(this+0)+3*A_PtrSize), "ptr", this, "ptr", pIEncoderOptions)
   if hr
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IWICBitmapFrameEncode_SetSize(this, uiWidth, uiHeight)
{
   hr := DllCall(NumGet(NumGet(this+0)+4*A_PtrSize), "ptr", this, "uint", uiWidth, "uint", uiHeight)
   if hr
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IWICBitmapFrameEncode_SetPixelFormat(this, pPixelFormat)
{
   hr := DllCall(NumGet(NumGet(this+0)+6*A_PtrSize), "ptr", this, "ptr", WIC_GUID(GUID, pPixelFormat))
   if hr
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IWICBitmapFrameEncode_WritePixels(this, lineCount, cbStride, cbBufferSize, pbPixels)
{
   hr := DllCall(NumGet(NumGet(this+0)+10*A_PtrSize), "ptr", this, "uint", lineCount, "uint", cbStride, "uint", cbBufferSize, "ptr", pbPixels)
   if hr
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

IWICBitmapFrameEncode_Commit(this)
{
   hr := DllCall(NumGet(NumGet(this+0)+12*A_PtrSize), "ptr", this)
   if hr
      _Error(A_ThisFunc " error: " hr "`nErrorLevel: " ErrorLevel)
}

WIC_GUID(ByRef GUID,name){
	static init:=1,_:={}
	if init {
	init:=0
	; Decoders
	 _.CLSID_WICBmpDecoder:=[0x6b462062, 0x7cbf, 0x400d, 0x9f, 0xdb, 0x81, 0x3d, 0xd1, 0xf, 0x27, 0x78]
	,_.CLSID_WICPngDecoder:=[0x389ea17b, 0x5078, 0x4cde, 0xb6, 0xef, 0x25, 0xc1, 0x51, 0x75, 0xc7, 0x51]
	,_.CLSID_WICIcoDecoder:=[0xc61bfcdf, 0x2e0f, 0x4aad, 0xa8, 0xd7, 0xe0, 0x6b, 0xaf, 0xeb, 0xcd, 0xfe]
	,_.CLSID_WICJpegDecoder:=[0x9456a480, 0xe88b, 0x43ea, 0x9e, 0x73, 0xb, 0x2d, 0x9b, 0x71, 0xb1, 0xca]
	,_.CLSID_WICGifDecoder:=[0x381dda3c, 0x9ce9, 0x4834, 0xa2, 0x3e, 0x1f, 0x98, 0xf8, 0xfc, 0x52, 0xbe]
	,_.CLSID_WICTiffDecoder:=[0xb54e85d9, 0xfe23, 0x499f, 0x8b, 0x88, 0x6a, 0xce, 0xa7, 0x13, 0x75, 0x2b]
	,_.CLSID_WICWmpDecoder:=[0xa26cec36, 0x234c, 0x4950, 0xae, 0x16, 0xe3, 0x4a, 0xac, 0xe7, 0x1d, 0x0d]
	; Encoders
	 _.CLSID_WICBmpEncoder:=[0x69be8bb4, 0xd66d, 0x47c8, 0x86, 0x5a, 0xed, 0x15, 0x89, 0x43, 0x37, 0x82]
	,_.CLSID_WICPngEncoder:=[0x27949969, 0x876a, 0x41d7, 0x94, 0x47, 0x56, 0x8f, 0x6a, 0x35, 0xa4, 0xdc]
	,_.CLSID_WICJpegEncoder:=[0x1a34f5c1, 0x4a5a, 0x46dc, 0xb6, 0x44, 0x1f, 0x45, 0x67, 0xe7, 0xa6, 0x76]
	,_.CLSID_WICGifEncoder:=[0x114f5598, 0xb22, 0x40a0, 0x86, 0xa1, 0xc8, 0x3e, 0xa4, 0x95, 0xad, 0xbd]
	,_.CLSID_WICTiffEncoder:=[0x0131be10, 0x2001, 0x4c5f, 0xa9, 0xb0, 0xcc, 0x88, 0xfa, 0xb6, 0x4c, 0xe8]
	,_.CLSID_WICWmpEncoder:=[0xac4ce3cb, 0xe1c1, 0x44cd, 0x82, 0x15, 0x5a, 0x16, 0x65, 0x50, 0x9e, 0xc2]
	; Container Formats
	 _.GUID_ContainerFormatBmp:=[0xaf1d87e, 0xfcfe, 0x4188, 0xbd, 0xeb, 0xa7, 0x90, 0x64, 0x71, 0xcb, 0xe3]
	,_.GUID_ContainerFormatPng:=[0x1b7cfaf4, 0x713f, 0x473c, 0xbb, 0xcd, 0x61, 0x37, 0x42, 0x5f, 0xae, 0xaf]
	,_.GUID_ContainerFormatIco:=[0xa3a860c4, 0x338f, 0x4c17, 0x91, 0x9a, 0xfb, 0xa4, 0xb5, 0x62, 0x8f, 0x21]
	,_.GUID_ContainerFormatJpeg:=[0x19e4a5aa, 0x5662, 0x4fc5, 0xa0, 0xc0, 0x17, 0x58, 0x2, 0x8e, 0x10, 0x57]
	,_.GUID_ContainerFormatTiff:=[0x163bcc30, 0xe2e9, 0x4f0b, 0x96, 0x1d, 0xa3, 0xe9, 0xfd, 0xb7, 0x88, 0xa3]
	,_.GUID_ContainerFormatGif:=[0x1f8a5601, 0x7d4d, 0x4cbd, 0x9c, 0x82, 0x1b, 0xc8, 0xd4, 0xee, 0xb9, 0xa5]
	,_.GUID_ContainerFormatWmp:=[0x57a37caa, 0x367a, 0x4540, 0x91, 0x6b, 0xf1, 0x83, 0xc5, 0x09, 0x3a, 0x4b]
	; Component Identifiers
	 _.CLSID_WICImagingCategories:=[0xfae3d380, 0xfea4, 0x4623, 0x8c, 0x75, 0xc6, 0xb6, 0x11, 0x10, 0xb6, 0x81]
	,_.CATID_WICBitmapDecoders:=[0x7ed96837, 0x96f0, 0x4812, 0xb2, 0x11, 0xf1, 0x3c, 0x24, 0x11, 0x7e, 0xd3]
	,_.CATID_WICBitmapEncoders:=[0xac757296, 0x3522, 0x4e11, 0x98, 0x62, 0xc1, 0x7b, 0xe5, 0xa1, 0x76, 0x7e]
	,_.CATID_WICPixelFormats:=[0x2b46e70f, 0xcda7, 0x473e, 0x89, 0xf6, 0xdc, 0x96, 0x30, 0xa2, 0x39, 0x0b]
	,_.CATID_WICFormatConverters:=[0x7835eae8, 0xbf14, 0x49d1, 0x93, 0xce, 0x53, 0x3a, 0x40, 0x7b, 0x22, 0x48]
	,_.CATID_WICMetadataReader:=[0x05af94d8, 0x7174, 0x4cd2, 0xbe, 0x4a, 0x41, 0x24, 0xb8, 0x0e, 0xe4, 0xb8]
	,_.CATID_WICMetadataWriter:=[0xabe3b9a4, 0x257d, 0x4b97, 0xbd, 0x1a, 0x29, 0x4a, 0xf4, 0x96, 0x22, 0x2e]
	; Format Converters
	 _.CLSID_WICDefaultFormatConverter:=[0x1a3f11dc, 0xb514, 0x4b17, 0x8c, 0x5f, 0x21, 0x54, 0x51, 0x38, 0x52, 0xf1]
	,_.CLSID_WICFormatConverterHighColor:=[0xac75d454, 0x9f37, 0x48f8, 0xb9, 0x72, 0x4e, 0x19, 0xbc, 0x85, 0x60, 0x11]
	,_.CLSID_WICFormatConverterNChannel:=[0xc17cabb2, 0xd4a3, 0x47d7, 0xa5, 0x57, 0x33, 0x9b, 0x2e, 0xfb, 0xd4, 0xf1]
	,_.CLSID_WICFormatConverterWMPhoto:=[0x9cb5172b, 0xd600, 0x46ba, 0xab, 0x77, 0x77, 0xbb, 0x7e, 0x3a, 0x00, 0xd9]
	; Metadata Handlers
	 _.GUID_MetadataFormatUnknown:=[0xA45E592F, 0x9078, 0x4A7C, 0xAD, 0xB5, 0x4E, 0xDC, 0x4F, 0xD6, 0x1B, 0x1F]
	,_.GUID_MetadataFormatIfd:=[0x537396C6, 0x2D8A, 0x4BB6, 0x9B, 0xF8, 0x2F, 0x0A, 0x8E, 0x2A, 0x3A, 0xDF]
	,_.GUID_MetadataFormatSubIfd:=[0x58A2E128, 0x2DB9, 0x4E57, 0xBB, 0x14, 0x51, 0x77, 0x89, 0x1E, 0xD3, 0x31]
	,_.GUID_MetadataFormatExif:=[0x1C3C4F9D, 0xB84A, 0x467D, 0x94, 0x93, 0x36, 0xCF, 0xBD, 0x59, 0xEA, 0x57]
	,_.GUID_MetadataFormatGps:=[0x7134AB8A, 0x9351, 0x44AD, 0xAF, 0x62, 0x44, 0x8D, 0xB6, 0xB5, 0x02, 0xEC]
	,_.GUID_MetadataFormatInterop:=[0xED686F8E, 0x681F, 0x4C8B, 0xBD, 0x41, 0xA8, 0xAD, 0xDB, 0xF6, 0xB3, 0xFC]
	,_.GUID_MetadataFormatApp0:=[0x79007028, 0x268D, 0x45d6, 0xA3, 0xC2, 0x35, 0x4E, 0x6A, 0x50, 0x4B, 0xC9]
	,_.GUID_MetadataFormatApp1:=[0x8FD3DFC3, 0xF951, 0x492B, 0x81, 0x7F, 0x69, 0xC2, 0xE6, 0xD9, 0xA5, 0xB0]
	,_.GUID_MetadataFormatApp13:=[0x326556A2, 0xF502, 0x4354, 0x9C, 0xC0, 0x8E, 0x3F, 0x48, 0xEA, 0xF6, 0xB5]
	,_.GUID_MetadataFormatIPTC:=[0x4FAB0914, 0xE129, 0x4087, 0xA1, 0xD1, 0xBC, 0x81, 0x2D, 0x45, 0xA7, 0xB5]
	,_.GUID_MetadataFormatIRB:=[0x16100D66, 0x8570, 0x4BB9, 0xB9, 0x2D, 0xFD, 0xA4, 0xB2, 0x3E, 0xCE, 0x67]
	,_.GUID_MetadataFormat8BIMIPTC:=[0x0010568c, 0x0852, 0x4e6a, 0xb1, 0x91, 0x5c, 0x33, 0xac, 0x5b, 0x04, 0x30]
	,_.GUID_MetadataFormat8BIMResolutionInfo:=[0x739F305D, 0x81DB, 0x43CB, 0xAC, 0x5E, 0x55, 0x01, 0x3E, 0xF9, 0xF0, 0x03]
	 _.GUID_MetadataFormat8BIMIPTCDigest:=[0x1CA32285, 0x9CCD, 0x4786, 0x8B, 0xD8, 0x79, 0x53, 0x9D, 0xB6, 0xA0, 0x06]
	,_.GUID_MetadataFormatXMP:=[0xBB5ACC38, 0xF216, 0x4CEC, 0xA6, 0xC5, 0x5F, 0x6E, 0x73, 0x97, 0x63, 0xA9]
	,_.GUID_MetadataFormatThumbnail:=[0x243dcee9, 0x8703, 0x40ee, 0x8e, 0xf0, 0x22, 0xa6, 0x0, 0xb8, 0x5, 0x8c]
	,_.GUID_MetadataFormatChunktEXt:=[0x568d8936, 0xc0a9, 0x4923, 0x90, 0x5d, 0xdf, 0x2b, 0x38, 0x23, 0x8f, 0xbc]
	,_.GUID_MetadataFormatXMPStruct:=[0x22383CF1, 0xED17, 0x4E2E, 0xAF, 0x17, 0xD8, 0x5B, 0x8F, 0x6B, 0x30, 0xD0]
	,_.GUID_MetadataFormatXMPBag:=[0x833CCA5F, 0xDCB7, 0x4516, 0x80, 0x6F, 0x65, 0x96, 0xAB, 0x26, 0xDC, 0xE4]
	,_.GUID_MetadataFormatXMPSeq:=[0x63E8DF02, 0xEB6C,0x456C, 0xA2, 0x24, 0xB2, 0x5E, 0x79, 0x4F, 0xD6, 0x48]
	,_.GUID_MetadataFormatXMPAlt:=[0x7B08A675, 0x91AA, 0x481B, 0xA7, 0x98, 0x4D, 0xA9, 0x49, 0x08, 0x61, 0x3B]
	,_.GUID_MetadataFormatLSD:=[0xE256031E, 0x6299, 0x4929, 0xB9, 0x8D, 0x5A, 0xC8, 0x84, 0xAF, 0xBA, 0x92]
	,_.GUID_MetadataFormatIMD:=[0xBD2BB086, 0x4D52, 0x48DD, 0x96, 0x77, 0xDB, 0x48, 0x3E, 0x85, 0xAE, 0x8F]
	,_.GUID_MetadataFormatGCE:=[0x2A25CAD8, 0xDEEB, 0x4C69, 0xA7, 0x88, 0xE, 0xC2, 0x26, 0x6D, 0xCA, 0xFD]
	,_.GUID_MetadataFormatAPE:=[0x2E043DC2, 0xC967, 0x4E05, 0x87, 0x5E, 0x61, 0x8B, 0xF6, 0x7E, 0x85, 0xC3]
	 _.GUID_MetadataFormatJpegChrominance:=[0xF73D0DCF, 0xCEC6, 0x4F85, 0x9B, 0x0E, 0x1C, 0x39, 0x56, 0xB1, 0xBE, 0xF7]
	,_.GUID_MetadataFormatJpegLuminance:=[0x86908007, 0xEDFC, 0x4860, 0x8D, 0x4B, 0x4E, 0xE6, 0xE8, 0x3E, 0x60, 0x58]
	,_.GUID_MetadataFormatJpegComment:=[0x220E5F33, 0xAFD3, 0x474E, 0x9D, 0x31, 0x7D, 0x4F, 0xE7, 0x30, 0xF5, 0x57]
	,_.GUID_MetadataFormatGifComment:=[0xC4B6E0E0, 0xCFB4, 0x4AD3, 0xAB, 0x33, 0x9A, 0xAD, 0x23, 0x55, 0xA3, 0x4A]
	,_.GUID_MetadataFormatChunkgAMA:=[0xF00935A5, 0x1D5D, 0x4CD1, 0x81, 0xB2, 0x93, 0x24, 0xD7, 0xEC, 0xA7, 0x81]
	,_.GUID_MetadataFormatChunkbKGD:=[0xE14D3571, 0x6B47, 0x4DEA, 0xB6, 0xA, 0x87, 0xCE, 0xA, 0x78, 0xDF, 0xB7]
	,_.GUID_MetadataFormatChunkiTXt:=[0xC2BEC729, 0xB68, 0x4B77, 0xAA, 0xE, 0x62, 0x95, 0xA6, 0xAC, 0x18, 0x14]
	,_.GUID_MetadataFormatChunkcHRM:=[0x9DB3655B, 0x2842, 0x44B3, 0x80, 0x67, 0x12, 0xE9, 0xB3, 0x75, 0x55, 0x6A]
	,_.GUID_MetadataFormatChunkhIST:=[0xC59A82DA, 0xDB74, 0x48A4, 0xBD, 0x6A, 0xB6, 0x9C, 0x49, 0x31, 0xEF, 0x95]
	,_.GUID_MetadataFormatChunkiCCP:=[0xEB4349AB, 0xB685, 0x450F, 0x91, 0xB5, 0xE8, 0x2, 0xE8, 0x92, 0x53, 0x6C]
	,_.GUID_MetadataFormatChunksRGB:=[0xC115FD36, 0xCC6F, 0x4E3F, 0x83, 0x63, 0x52, 0x4B, 0x87, 0xC6, 0xB0, 0xD9]
	,_.GUID_MetadataFormatChunktIME:=[0x6B00AE2D, 0xE24B, 0x460A, 0x98, 0xB6, 0x87, 0x8B, 0xD0, 0x30, 0x72, 0xFD]
	; Vendor Identification
	 _.GUID_VendorMicrosoft:=[0x69fd0fdc, 0xa866, 0x4108, 0xb3, 0xb2, 0x98, 0x44, 0x7f, 0xa9, 0xed, 0xd4]
	,_.GUID_VendorMicrosoftBuiltIn:=[0x257a30fd, 0x6b6, 0x462b, 0xae, 0xa4, 0x63, 0xf7, 0xb, 0x86, 0xe5, 0x33]
	; WICBitmapPaletteType
	 _.GUID_WICPixelFormatDontCare:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x00]
	,_.GUID_WICPixelFormat1bppIndexed:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x01]
	,_.GUID_WICPixelFormat2bppIndexed:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x02]
	,_.GUID_WICPixelFormat4bppIndexed:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x03]
	,_.GUID_WICPixelFormat8bppIndexed:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x04]
	,_.GUID_WICPixelFormatBlackWhite:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x05]
	,_.GUID_WICPixelFormat2bppGray:=[  0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x06]
	,_.GUID_WICPixelFormat4bppGray:=[  0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x07]
	,_.GUID_WICPixelFormat8bppGray:=[  0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x08]
	,_.GUID_WICPixelFormat8bppAlpha:=[0xe6cd0116, 0xeeba, 0x4161, 0xaa, 0x85, 0x27, 0xdd, 0x9f, 0xb3, 0xa8, 0x95]
	,_.GUID_WICPixelFormat16bppBGR555:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x09]
	,_.GUID_WICPixelFormat16bppBGR565:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0a]
	,_.GUID_WICPixelFormat16bppBGRA5551:=[0x05ec7c2b, 0xf1e6, 0x4961, 0xad, 0x46, 0xe1, 0xcc, 0x81, 0x0a, 0x87, 0xd2]
	 _.GUID_WICPixelFormat16bppGray:=[  0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0b]
	,_.GUID_WICPixelFormat24bppBGR:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0c]
	,_.GUID_WICPixelFormat24bppRGB:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0d]
	,_.GUID_WICPixelFormat32bppBGR:=[  0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0e]
	,_.GUID_WICPixelFormat32bppBGRA:=[ 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x0f]
	,_.GUID_WICPixelFormat32bppPBGRA:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x10]
	,_.GUID_WICPixelFormat32bppGrayFloat:=[ 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x11]
	,_.GUID_WICPixelFormat32bppRGBA:=[0xf5c7ad2d, 0x6a8d, 0x43dd, 0xa7, 0xa8, 0xa2, 0x99, 0x35, 0x26, 0x1a, 0xe9]
	,_.GUID_WICPixelFormat32bppPRGBA:=[0x3cc4a650, 0xa527, 0x4d37, 0xa9, 0x16, 0x31, 0x42, 0xc7, 0xeb, 0xed, 0xba]
	,_.GUID_WICPixelFormat48bppRGB:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x15]
	,_.GUID_WICPixelFormat48bppBGR:=[0xe605a384, 0xb468, 0x46ce, 0xbb, 0x2e, 0x36, 0xf1, 0x80, 0xe6, 0x43, 0x13]
	,_.GUID_WICPixelFormat64bppRGBA:=[ 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x16]
	,_.GUID_WICPixelFormat64bppBGRA:=[ 0x1562ff7c, 0xd352, 0x46f9, 0x97, 0x9e, 0x42, 0x97, 0x6b, 0x79, 0x22, 0x46]
	 _.GUID_WICPixelFormat64bppPRGBA:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x17]
	,_.GUID_WICPixelFormat64bppPBGRA:=[0x8c518e8e, 0xa4ec, 0x468b, 0xae, 0x70, 0xc9, 0xa3, 0x5a, 0x9c, 0x55, 0x30]
	,_.GUID_WICPixelFormat16bppGrayFixedPoint:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x13]
	,_.GUID_WICPixelFormat32bppBGR101010:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x14]
	,_.GUID_WICPixelFormat48bppRGBFixedPoint:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x12]
	,_.GUID_WICPixelFormat48bppBGRFixedPoint:=[0x49ca140e, 0xcab6, 0x493b, 0x9d, 0xdf, 0x60, 0x18, 0x7c, 0x37, 0x53, 0x2a]
	,_.GUID_WICPixelFormat96bppRGBFixedPoint:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x18]
	,_.GUID_WICPixelFormat128bppRGBAFloat:=[ 0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x19]
	,_.GUID_WICPixelFormat128bppPRGBAFloat:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x1a]
	,_.GUID_WICPixelFormat128bppRGBFloat:=[  0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x1b]
	,_.GUID_WICPixelFormat32bppCMYK:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x1c]
	,_.GUID_WICPixelFormat64bppRGBAFixedPoint:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x1d]
	,_.GUID_WICPixelFormat64bppBGRAFixedPoint:=[0x356de33c, 0x54d2, 0x4a23, 0xbb, 0x4, 0x9b, 0x7b, 0xf9, 0xb1, 0xd4, 0x2d]
	 _.GUID_WICPixelFormat64bppRGBFixedPoint:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x40]
	,_.GUID_WICPixelFormat128bppRGBAFixedPoint:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x1e]
	,_.GUID_WICPixelFormat128bppRGBFixedPoint:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x41]
	,_.GUID_WICPixelFormat64bppRGBAHalf:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x3a]
	,_.GUID_WICPixelFormat64bppRGBHalf:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x42]
	,_.GUID_WICPixelFormat48bppRGBHalf:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x3b]
	,_.GUID_WICPixelFormat32bppRGBE:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x3d]
	,_.GUID_WICPixelFormat16bppGrayHalf:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x3e]
	,_.GUID_WICPixelFormat32bppGrayFixedPoint:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x3f]
	,_.GUID_WICPixelFormat32bppRGBA1010102:=[0x25238D72, 0xFCF9, 0x4522, 0xb5, 0x14, 0x55, 0x78, 0xe5, 0xad, 0x55, 0xe0]
	,_.GUID_WICPixelFormat32bppRGBA1010102XR:=[0x00DE6B9A, 0xC101, 0x434b, 0xb5, 0x02, 0xd0, 0x16, 0x5e, 0xe1, 0x12, 0x2c]
	,_.GUID_WICPixelFormat64bppCMYK:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x1f]
	,_.GUID_WICPixelFormat24bpp3Channels:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x20]
	 _.GUID_WICPixelFormat32bpp4Channels:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x21]
	,_.GUID_WICPixelFormat40bpp5Channels:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x22]
	,_.GUID_WICPixelFormat48bpp6Channels:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x23]
	,_.GUID_WICPixelFormat56bpp7Channels:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x24]
	,_.GUID_WICPixelFormat64bpp8Channels:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x25]
	,_.GUID_WICPixelFormat48bpp3Channels:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x26]
	,_.GUID_WICPixelFormat64bpp4Channels:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x27]
	,_.GUID_WICPixelFormat80bpp5Channels:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x28]
	,_.GUID_WICPixelFormat96bpp6Channels:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x29]
	,_.GUID_WICPixelFormat112bpp7Channels:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x2a]
	,_.GUID_WICPixelFormat128bpp8Channels:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x2b]
	,_.GUID_WICPixelFormat40bppCMYKAlpha:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x2c]
	,_.GUID_WICPixelFormat80bppCMYKAlpha:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x2d]
	,_.GUID_WICPixelFormat32bpp3ChannelsAlpha:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x2e]
	 _.GUID_WICPixelFormat40bpp4ChannelsAlpha:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x2f]
	,_.GUID_WICPixelFormat48bpp5ChannelsAlpha:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x30]
	,_.GUID_WICPixelFormat56bpp6ChannelsAlpha:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x31]
	,_.GUID_WICPixelFormat64bpp7ChannelsAlpha:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x32]
	,_.GUID_WICPixelFormat72bpp8ChannelsAlpha:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x33]
	,_.GUID_WICPixelFormat64bpp3ChannelsAlpha:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x34]
	,_.GUID_WICPixelFormat80bpp4ChannelsAlpha:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x35]
	,_.GUID_WICPixelFormat96bpp5ChannelsAlpha:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x36]
	,_.GUID_WICPixelFormat112bpp6ChannelsAlpha:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x37]
	,_.GUID_WICPixelFormat128bpp7ChannelsAlpha:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x38]
	,_.GUID_WICPixelFormat144bpp8ChannelsAlpha:=[0x6fddc324, 0x4e03, 0x4bfe, 0xb1, 0x85, 0x3d, 0x77, 0x76, 0x8d, 0xc9, 0x39]

	}
	if _.haskey(name){
		p:=_[name]
		VarSetCapacity(GUID,16)
		,NumPut(p.1+(p.2<<32)+(p.3<<48),GUID,0,"int64")
		,NumPut(p.4+(p.5<<8)+(p.6<<16)+(p.7<<24)+(p.8<<32)+(p.9<<40)+(p.10<<48)+(p.11<<56),GUID,8,"int64")
		return &GUID
	}else return name
}
Last edited by malcev on 13 May 2023, 12:29, edited 3 times in total.
ssjkakaroto
Posts: 5
Joined: 09 Mar 2019, 07:56

Re: is there an alternative imagesearch solution on gdip lib ?

03 Nov 2019, 11:12

Thanks @malcev.
Is it possible to use this method to capture a specific hwnd instead of the whole screen? Can just a small portion of the window/screen be captured? Instead of SavePixelsToFile32bppPBGRA, what should I use to keep the image as a bitmap in memory for use with Gdip_ImageSearch?
Last edited by ssjkakaroto on 03 Nov 2019, 12:50, edited 1 time in total.
guest3456
Posts: 3454
Joined: 09 Oct 2013, 10:31

Re: is there an alternative imagesearch solution on gdip lib ?

03 Nov 2019, 12:19

@malcev excellent, but i'm guessing this will only work fullscreen, and we'd still need to use GDI to capture and/or imagesearch for windows that are obscured behind others

malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: is there an alternative imagesearch solution on gdip lib ?

04 Nov 2019, 03:19

guest3456, I also think that We cannot capture windows that are obscured behind others with direct3d or dxgi help, but if target process uses directx we can hook it and capture directly from back buffer.
I know 3 ways to capture windows that are obscured behind others:
1) gdi
2) dwm
3) magnification api
But I did not test their speed.

ssjkakaroto, I did not test it, but I think that this part

Code: Select all

pitch := NumGet(DXGI_MAPPED_RECT, 0, "int")
pBits := NumGet(DXGI_MAPPED_RECT, A_PtrSize, "ptr")
is the same as Stride and Scan that we recieve with GdipBitmapLockBits.
And You can capture small portion of the window using ID3D11DeviceContext::CopySubresourceRegion method instead of ID3D11DeviceContext::CopyResource method
https://docs.microsoft.com/en-us/windows/win32/api/d3d11/nf-d3d11-id3d11devicecontext-copysubresourceregion

Code: Select all

 VarSetCapacity(D3D11_BOX, 24, 0)
 NumPut(0, D3D11_BOX, 0, "uint")   ; left
 NumPut(0, D3D11_BOX, 4, "uint")   ; top
 NumPut(0, D3D11_BOX, 8, "uint")   ; front
 NumPut(500, D3D11_BOX, 12, "uint")   ; right
 NumPut(500, D3D11_BOX, 16, "uint")   ; bottom
 NumPut(1, D3D11_BOX, 20, "uint")   ; back
 ID3D11DeviceContext_CopySubresourceRegion(d3d_context, staging_tex, 0, 0, 0, 0, tex, 0, &D3D11_BOX)   ; set region
guest3456
Posts: 3454
Joined: 09 Oct 2013, 10:31

Re: is there an alternative imagesearch solution on gdip lib ?

04 Nov 2019, 05:34

malcev wrote:
04 Nov 2019, 03:19
guest3456, I also think that We cannot capture windows that are obscured behind others with direct3d or dxgi help, but if target process uses directx we can hook it and capture directly from back buffer.
I know 3 ways to capture windows that are obscured behind others:
1) gdi
2) dwm
3) magnification api
But I did not test their speed.
can you elaborate or give examples on those 3?

gdi i guess you mean PrintWindow (Gdip_BitmapFromHWND) and/or BitBlt (Gdip_BitmapfromScreen("hwnd:" hwnd))? that's what i typically use.

what do you use for Dwm and for Magnification api?

a quick google looks like magnification api cannot capture obscured windows. this api call looks like it just wants full desktop coordinates:
https://docs.microsoft.com/en-us/windows/win32/api/magnification/nf-magnification-magsetwindowsource

malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: is there an alternative imagesearch solution on gdip lib ?

04 Nov 2019, 22:20

I do not have examples of this approaches on ahk.
But if You are interested You can look here:
https://www.codeproject.com/Articles/607288/Screenshot-using-the-Magnification-library
serzh82saratov wrote code that captures all windows except notepad++.

Code: Select all

#NoEnv
#Persistent
#SingleInstance Force 
SetBatchLines -1
OnExit, Uninitialize 
CoordMode, Mouse, Screen
Gui, +HWNDhGui
Global hPic

rWidth :=  320
rHeight := 240

HWNDarr := [WinExist("ahk_class Notepad++"), hGui]

Ptr := A_PtrSize ? "UPtr" : "UInt"
if !DllCall("GetModuleHandle", "str", "gdiplus", Ptr)
	DllCall("LoadLibrary", "str", "gdiplus")
VarSetCapacity(GdiplusStartupInput, A_PtrSize = 8 ? 24 : 16, 0), GdiplusStartupInput := Chr(1)
DllCall("gdiplus\GdiplusStartup", A_PtrSize = 8 ? "UPtr*" : "UInt*", pToken, Ptr, &GdiplusStartupInput, Ptr, 0)

Gui, -Caption +AlwaysOnTop +E0x02000000 +E0x00080000  ;  WS_EX_COMPOSITED := E0x02000000  WS_EX_LAYERED := E0x00080000
Gui, Margin, 0,0  
Gui, Add, text, w%rWidth% h%rHeight% 0xE hwndhPic ; SS_BITMAP = 0xE
Gui, Show, x100 NA, MagnifierCloneWindowAHK

Gui, Magnifier: +AlwaysOnTop -Caption +ToolWindow +HWNDhMagnifier
Gui, Magnifier: Show, w%rWidth% h%rHeight% NA Hide, MagnifierWindowAHK
	
DllCall("LoadLibrary", "str", "magnification.dll")
DllCall("magnification.dll\MagInitialize")

WS_CHILD := 0x40000000, WS_VISIBLE := 0x10000000, MS_SHOWMAGNIFIEDCURSOR := 0x1 
	
hChildMagnifier := DllCall("CreateWindowEx"
	, "UInt", 0
	, "Str", "Magnifier"
	, "Str", "MagnifierWindow"
	, "UInt", MS_SHOWMAGNIFIEDCURSOR | WS_CHILD | WS_VISIBLE
	, "Int", 0
	, "Int", 0
	, "Int", rWidth
	, "Int", rHeight
	, Ptr, hMagnifier
	, "UInt", 0
	, Ptr, DllCall("GetWindowLong", Ptr, hMagnifier, "UInt", GWL_HINSTANCE := -6)
	, "UInt", 0)

VarSetCapacity(HWNDstruct, HWNDarr.Count() * A_PtrSize, 0)
Loop % HWNDarr.Count()
	NumPut(HWNDarr[A_Index], HWNDstruct, (A_Index - 1) * A_PtrSize, "UPtr")
DllCall("magnification.dll\MagSetWindowFilterList", Ptr, hChildMagnifier, "Int", MW_FILTERMODE_EXCLUDE := 0, "Int", HWNDarr.Count(), Ptr, &HWNDstruct)

Matrix := "1|0|0|"
        . "0|1|0|"
        . "0|0|1"  
VarSetCapacity(MAGTRANSFORM, 36, 0)
Loop, Parse, Matrix, |  
	NumPut(A_LoopField, MAGTRANSFORM, (A_Index - 1) * 4, "Float")
DllCall("magnification.dll\MagSetWindowTransform", Ptr, hChildMagnifier, Ptr, &MAGTRANSFORM)

DllCall("magnification.dll\MagSetImageScalingCallback", Ptr, hChildMagnifier, "Int", RegisterCallback("MagImageScalingCallback", "Fast"))

VarSetCapacity(RECT, 16, 0)

; 1::
Loop
{
	MouseGetPos, MXS, MYS
	NumPut(MXS - rWidth/2, RECT, 0, "Int")
	NumPut(MYS - rHeight/2, RECT, 4, "Int")
	NumPut(rWidth, RECT, 8, "Int")
	NumPut(rHeight, RECT, 12, "Int")
	DllCall("magnification.dll\MagSetWindowSource", Ptr, hChildMagnifier, Ptr, &RECT)
}
Return 

MagImageScalingCallback(hwnd, srcdata, srcheader, destdata, destheader, unclipped, clipped, dirty) {
	Static BI_RGB := 0, CBM_INIT := 6, DIB_RGB_COLORS := 0
		, Ptr := A_PtrSize = 8 ? "UPtr" : "UInt"
		, STM_SETIMAGE := 0x172, IMAGE_BITMAP := 0x0
		, _ := VarSetCapacity(BITMAPV5HEADER, 124, 0)
		, __ := VarSetCapacity(BITMAPINFO, 44, 0)
	
	bV5Width := NumGet(srcheader + 0, 0, "UInt")
	bV5Height := NumGet(srcheader + 0, 4, "UInt") 
	
	NumPut(124, BITMAPV5HEADER, 0, "UInt")  		;	DWORD		bV5Size;
	NumPut(bV5Width, BITMAPV5HEADER, 4, "UInt")		;	LONG		bV5Width;
	NumPut(bV5Height, BITMAPV5HEADER, 8, "UInt")	;	LONG		bV5Height;
	NumPut(1, BITMAPV5HEADER, 12, "Short")			;	WORD		bV5Planes;
	NumPut(32, BITMAPV5HEADER, 14, "Short")			;	WORD		bV5BitCount;
	NumPut(BI_RGB, BITMAPV5HEADER, 16, "UInt")		;	DWORD		bV5Compression; 
	
	NumPut(44, BITMAPINFO, 0, "UInt")  				;	DWORD biSize;
	NumPut(bV5Width, BITMAPINFO, 4, "UInt")  		;	LONG  biWidth;
	NumPut(bV5Height, BITMAPINFO, 8, "UInt")  		;	LONG  biHeight;
	NumPut(1, BITMAPINFO, 12, "Short")  			;	WORD  biPlanes;
	NumPut(32, BITMAPINFO, 14, "Short")  			;	WORD  biBitCount;
	NumPut(BI_RGB, BITMAPINFO, 16, "UInt")  		;	DWORD biCompression;
 
	hDC := DllCall("GetDC", Ptr, hwnd)
	
	hBMP := DllCall("CreateDIBitmap"
		, Ptr, hDC
		, Ptr, &BITMAPV5HEADER
		, "UInt", CBM_INIT
		, Ptr,  srcdata
		, Ptr, &BITMAPINFO
		, "UInt", DIB_RGB_COLORS) 
	
	DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", Ptr, hBMP, Ptr, 0, A_PtrSize = 8 ? "UPtr*" : "UInt*", pBitmap)
	DllCall("gdiplus\GdipImageRotateFlip", Ptr, pBitmap, "Int", 6)   ;	Rotate180FlipX
	DllCall("gdiplus\GdipCreateHBITMAPFromBitmap", Ptr, pBitmap, A_PtrSize = 8 ? "UPtr*" : "UInt*", hBitmap, "Int", 0xffffffff)
	
	SendMessage, STM_SETIMAGE, IMAGE_BITMAP, hBitmap,, ahk_id %hPic% 
	
	DllCall("DeleteObject", Ptr, ErrorLevel)
	DllCall("gdiplus\GdipDisposeImage", Ptr, pBitmap)
	DllCall("DeleteDC", Ptr, hDC)
	DllCall("DeleteObject", Ptr, hBMP)
	DllCall("DeleteObject", Ptr, hBitmap)
	Return 1
}

Escape:: 
Uninitialize: 	
	DllCall("magnification.dll\MagUninitialize")
	DllCall("gdiplus\GdiplusShutdown", Ptr, pToken)
	if hModule := DllCall("GetModuleHandle", "Str", "gdiplus", Ptr)
		DllCall("FreeLibrary", Ptr, hModule)
	ExitApp
I think that it is enough info to write screen capture with magnification api by Yourself.
As for dwm You can see different approaches here:
https://github.com/mika-sandbox/dotnet-window-capture
Also if You are interested in hooking directx 11 there are some examples here:
https://www.autohotkey.com/boards/viewtopic.php?p=294758#p294758
And example of image search using OpenCV:
https://www.autohotkey.com/boards/viewtopic.php?f=76&p=299604#p299604
guest3456
Posts: 3454
Joined: 09 Oct 2013, 10:31

Re: is there an alternative imagesearch solution on gdip lib ?

05 Nov 2019, 00:42

@malcev thank you very much for your links, i will investigate
as for this:
malcev wrote:
04 Nov 2019, 22:20
serzh82saratov wrote code that captures all windows except notepad++.

Code: Select all

#NoEnv
#Persistent
#SingleInstance Force 
SetBatchLines -1
OnExit, Uninitialize 
CoordMode, Mouse, Screen
Gui, +HWNDhGui
Global hPic

rWidth :=  320
rHeight := 240

HWNDarr := [WinExist("ahk_class Notepad++"), hGui]

Ptr := A_PtrSize ? "UPtr" : "UInt"
if !DllCall("GetModuleHandle", "str", "gdiplus", Ptr)
	DllCall("LoadLibrary", "str", "gdiplus")
VarSetCapacity(GdiplusStartupInput, A_PtrSize = 8 ? 24 : 16, 0), GdiplusStartupInput := Chr(1)
DllCall("gdiplus\GdiplusStartup", A_PtrSize = 8 ? "UPtr*" : "UInt*", pToken, Ptr, &GdiplusStartupInput, Ptr, 0)

Gui, -Caption +AlwaysOnTop +E0x02000000 +E0x00080000  ;  WS_EX_COMPOSITED := E0x02000000  WS_EX_LAYERED := E0x00080000
Gui, Margin, 0,0  
Gui, Add, text, w%rWidth% h%rHeight% 0xE hwndhPic ; SS_BITMAP = 0xE
Gui, Show, x100 NA, MagnifierCloneWindowAHK

Gui, Magnifier: +AlwaysOnTop -Caption +ToolWindow +HWNDhMagnifier
Gui, Magnifier: Show, w%rWidth% h%rHeight% NA Hide, MagnifierWindowAHK
	
DllCall("LoadLibrary", "str", "magnification.dll")
DllCall("magnification.dll\MagInitialize")

WS_CHILD := 0x40000000, WS_VISIBLE := 0x10000000, MS_SHOWMAGNIFIEDCURSOR := 0x1 
	
hChildMagnifier := DllCall("CreateWindowEx"
	, "UInt", 0
	, "Str", "Magnifier"
	, "Str", "MagnifierWindow"
	, "UInt", MS_SHOWMAGNIFIEDCURSOR | WS_CHILD | WS_VISIBLE
	, "Int", 0
	, "Int", 0
	, "Int", rWidth
	, "Int", rHeight
	, Ptr, hMagnifier
	, "UInt", 0
	, Ptr, DllCall("GetWindowLong", Ptr, hMagnifier, "UInt", GWL_HINSTANCE := -6)
	, "UInt", 0)

VarSetCapacity(HWNDstruct, HWNDarr.Count() * A_PtrSize, 0)
Loop % HWNDarr.Count()
	NumPut(HWNDarr[A_Index], HWNDstruct, (A_Index - 1) * A_PtrSize, "UPtr")
DllCall("magnification.dll\MagSetWindowFilterList", Ptr, hChildMagnifier, "Int", MW_FILTERMODE_EXCLUDE := 0, "Int", HWNDarr.Count(), Ptr, &HWNDstruct)

Matrix := "1|0|0|"
        . "0|1|0|"
        . "0|0|1"  
VarSetCapacity(MAGTRANSFORM, 36, 0)
Loop, Parse, Matrix, |  
	NumPut(A_LoopField, MAGTRANSFORM, (A_Index - 1) * 4, "Float")
DllCall("magnification.dll\MagSetWindowTransform", Ptr, hChildMagnifier, Ptr, &MAGTRANSFORM)

DllCall("magnification.dll\MagSetImageScalingCallback", Ptr, hChildMagnifier, "Int", RegisterCallback("MagImageScalingCallback", "Fast"))

VarSetCapacity(RECT, 16, 0)

; 1::
Loop
{
	MouseGetPos, MXS, MYS
	NumPut(MXS - rWidth/2, RECT, 0, "Int")
	NumPut(MYS - rHeight/2, RECT, 4, "Int")
	NumPut(rWidth, RECT, 8, "Int")
	NumPut(rHeight, RECT, 12, "Int")
	DllCall("magnification.dll\MagSetWindowSource", Ptr, hChildMagnifier, Ptr, &RECT)
}
Return 

MagImageScalingCallback(hwnd, srcdata, srcheader, destdata, destheader, unclipped, clipped, dirty) {
	Static BI_RGB := 0, CBM_INIT := 6, DIB_RGB_COLORS := 0
		, Ptr := A_PtrSize = 8 ? "UPtr" : "UInt"
		, STM_SETIMAGE := 0x172, IMAGE_BITMAP := 0x0
		, _ := VarSetCapacity(BITMAPV5HEADER, 124, 0)
		, __ := VarSetCapacity(BITMAPINFO, 44, 0)
	
	bV5Width := NumGet(srcheader + 0, 0, "UInt")
	bV5Height := NumGet(srcheader + 0, 4, "UInt") 
	
	NumPut(124, BITMAPV5HEADER, 0, "UInt")  		;	DWORD		bV5Size;
	NumPut(bV5Width, BITMAPV5HEADER, 4, "UInt")		;	LONG		bV5Width;
	NumPut(bV5Height, BITMAPV5HEADER, 8, "UInt")	;	LONG		bV5Height;
	NumPut(1, BITMAPV5HEADER, 12, "Short")			;	WORD		bV5Planes;
	NumPut(32, BITMAPV5HEADER, 14, "Short")			;	WORD		bV5BitCount;
	NumPut(BI_RGB, BITMAPV5HEADER, 16, "UInt")		;	DWORD		bV5Compression; 
	
	NumPut(44, BITMAPINFO, 0, "UInt")  				;	DWORD biSize;
	NumPut(bV5Width, BITMAPINFO, 4, "UInt")  		;	LONG  biWidth;
	NumPut(bV5Height, BITMAPINFO, 8, "UInt")  		;	LONG  biHeight;
	NumPut(1, BITMAPINFO, 12, "Short")  			;	WORD  biPlanes;
	NumPut(32, BITMAPINFO, 14, "Short")  			;	WORD  biBitCount;
	NumPut(BI_RGB, BITMAPINFO, 16, "UInt")  		;	DWORD biCompression;
 
	hDC := DllCall("GetDC", Ptr, hwnd)
	
	hBMP := DllCall("CreateDIBitmap"
		, Ptr, hDC
		, Ptr, &BITMAPV5HEADER
		, "UInt", CBM_INIT
		, Ptr,  srcdata
		, Ptr, &BITMAPINFO
		, "UInt", DIB_RGB_COLORS) 
	
	DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", Ptr, hBMP, Ptr, 0, A_PtrSize = 8 ? "UPtr*" : "UInt*", pBitmap)
	DllCall("gdiplus\GdipImageRotateFlip", Ptr, pBitmap, "Int", 6)   ;	Rotate180FlipX
	DllCall("gdiplus\GdipCreateHBITMAPFromBitmap", Ptr, pBitmap, A_PtrSize = 8 ? "UPtr*" : "UInt*", hBitmap, "Int", 0xffffffff)
	
	SendMessage, STM_SETIMAGE, IMAGE_BITMAP, hBitmap,, ahk_id %hPic% 
	
	DllCall("DeleteObject", Ptr, ErrorLevel)
	DllCall("gdiplus\GdipDisposeImage", Ptr, pBitmap)
	DllCall("DeleteDC", Ptr, hDC)
	DllCall("DeleteObject", Ptr, hBMP)
	DllCall("DeleteObject", Ptr, hBitmap)
	Return 1
}

Escape:: 
Uninitialize: 	
	DllCall("magnification.dll\MagUninitialize")
	DllCall("gdiplus\GdiplusShutdown", Ptr, pToken)
	if hModule := DllCall("GetModuleHandle", "Str", "gdiplus", Ptr)
		DllCall("FreeLibrary", Ptr, hModule)
	ExitApp
I think that it is enough info to write screen capture with magnification api by Yourself.
does this code work for you? when i run it, i just get a blank gray gui on win10 ahk 1.1.31
Last edited by guest3456 on 05 Nov 2019, 00:46, edited 2 times in total.

malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: is there an alternative imagesearch solution on gdip lib ?

05 Nov 2019, 00:45

The bitness of autohotkey should be the same as the bitness of Windows.
guest3456
Posts: 3454
Joined: 09 Oct 2013, 10:31

Re: is there an alternative imagesearch solution on gdip lib ?

05 Nov 2019, 00:47

malcev wrote:
05 Nov 2019, 00:45
The bitness of autohotkey should be the same as the bitness of Windows.
edit:
ok it works if i use x64 version of AHK. but it doesn't exclude notepad++. and it also isn't capturing any windows that are obscured behind other windows

edit2:
ok i had to have notepad++ open first before starting the script... now it does ignore notepad++ and does capture a window behind. interesting.

guest3456
Posts: 3454
Joined: 09 Oct 2013, 10:31

Re: is there an alternative imagesearch solution on gdip lib ?

05 Nov 2019, 10:43

malcev wrote:
05 Nov 2019, 00:45
The bitness of autohotkey should be the same as the bitness of Windows.
is there a way to get that Magnification example to work on 32bit AHK? or is 64bit required? i see a bunch of A_PtrSize = 8 ternary checks throughout the code, so i thought it should be compatible with both

malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: is there an alternative imagesearch solution on gdip lib ?

05 Nov 2019, 12:00

The Magnification API is not supported under WOW64; that is, a 32-bit magnifier application will not run correctly on 64-bit Windows.
https://docs.microsoft.com/en-us/previous-versions/windows/desktop/magapi/entry-magapi-sdk
guest3456
Posts: 3454
Joined: 09 Oct 2013, 10:31

Re: is there an alternative imagesearch solution on gdip lib ?

07 Nov 2019, 11:03

malcev wrote:
05 Nov 2019, 12:00
The Magnification API is not supported under WOW64; that is, a 32-bit magnifier application will not run correctly on 64-bit Windows.
https://docs.microsoft.com/en-us/previous-versions/windows/desktop/magapi/entry-magapi-sdk
not exactly correct

solved

here are the fixes to serzh82saratov's code, i found on your russian forum and from this thread, so it also works on with 32bit ahk on 64bit windows:

Code: Select all

        left := MXS - rWidth/2
        top  := MYS - rHeight/2
        if (A_PtrSize = 8)
        {
           NumPut(left, RECT, 0, "Int")
           NumPut(top, RECT, 4, "Int")
           NumPut(rWidth, RECT, 8, "Int")
           NumPut(rHeight, RECT, 12, "Int")
           DllCall("magnification.dll\MagSetWindowSource", Ptr, hChildMagnifier, Ptr, &RECT)
        }
        else
           DllCall("magnification.dll\MagSetWindowSource", Ptr, hChildMagnifier, "Int", left, "Int", top, "Int", rWidth, "Int", rHeight)
;...
;...
;...
        if (A_PtrSize = 8)
        {
           bV5Width := NumGet(srcheader + 0, 0, "UInt")
           bV5Height := NumGet(srcheader + 0, 4, "UInt") 
         }
         else
         {
            bV5Width := srcheader
            bV5Height := destdata
         }

unfortunately, the MW_FILTERMODE_INCLUDE option doesn't work for the filtering. if i want to magnify ONLY notepad++ it fails:

Code: Select all

;works
DllCall("magnification.dll\MagSetWindowFilterList", Ptr, hChildMagnifier, "Int", MW_FILTERMODE_EXCLUDE := 0, "Int", HWNDarr.Count(), Ptr, &HWNDstruct)

;doesn't work
; DllCall("magnification.dll\MagSetWindowFilterList", Ptr, hChildMagnifier, "Int", MW_FILTERMODE_INCLUDE := 1, "Int", HWNDarr.Count(), Ptr, &HWNDstruct)
msdn says its not supported on win7/8, but i'm on win10 and it doesn't work

malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: is there an alternative imagesearch solution on gdip lib ?

07 Nov 2019, 13:35

I think, that MW_FILTERMODE_INCLUDE worked only on Vista.
But we can get all windows that overlap our window and exclude them.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: imstupidpleshelp, JoeWinograd, ositoMalvado, Rohwedder, usser and 171 guests