1 (изменено: Malcev, 2023-04-20 04:30:39)

Тема: AHK: Захват окна или монитора с помощью WindowsGraphicsCapture API

Работает на win10 build >= 19041, а также с окнами с аппаратным ускорением.
https://blogs.windows.com/windowsdevelo … n-capture/

window_handle := 0x290538
; captureCursor := true
; hideBorder := true   ; убирает рамку у захватываемого окна, только для winver >= 20348

f11::
DllCall("QueryPerformanceCounter", "int64*", StartTime)
a := a_tickcount
if !init
{
   setbatchlines -1
   DllCall("LoadLibrary","str","DXGI")
   DllCall("LoadLibrary","str","D3D11")
   DllCall("LoadLibrary","str","Dwmapi")
   DllCall("LoadLibrary", "str", "gdiplus")
   VarSetCapacity(si, A_PtrSize = 8 ? 24 : 16, 0), si := Chr(1)
   DllCall("gdiplus\GdiplusStartup", "ptr*", pToken, "ptr", &si, "ptr", 0)
   VarSetCapacity(rect, 16, 0)
   DllCall("Dwmapi.dll\DwmGetWindowAttribute", "ptr", window_handle, "uint", DWMWA_EXTENDED_FRAME_BOUNDS := 9, "ptr", &rect, "uint", 16)
   width := NumGet(rect, 8, "int") - NumGet(rect, 0, "int")
   height := NumGet(rect, 12, "int") - NumGet(rect, 4, "int")
   DllCall("D3D11\D3D11CreateDevice", "ptr", 0, "int", D3D_DRIVER_TYPE_HARDWARE := 1, "ptr", 0, "uint", D3D11_CREATE_DEVICE_BGRA_SUPPORT := 0x20, "ptr", 0, "uint", 0, "uint", D3D11_SDK_VERSION := 7, "ptr*", d3d_device, "ptr*", 0, "ptr*", d3d_context)
   dxgiDevice := ComObjQuery(d3d_device, IID_IDXGIDevice := "{54ec77fa-1377-44e6-8c32-88fd5f44c84c}")
   DllCall("D3D11\CreateDirect3D11DeviceFromDXGIDevice", "ptr", dxgiDevice, "ptr*", inspectable)
   device := ComObjQuery(inspectable, IDirect3DDevice := "{A37624AB-8D5F-4650-9D3E-9EAE3D9BC670}")
   CreateClass("Windows.Graphics.Capture.Direct3D11CaptureFramePool", IDirect3D11CaptureFramePoolStatics := "{7784056a-67aa-4d53-ae54-1088d5a8ca21}", Direct3D11CaptureFramePoolStatics)
   DllCall(NumGet(NumGet(Direct3D11CaptureFramePoolStatics+0)+6*A_PtrSize), "ptr", Direct3D11CaptureFramePoolStatics, "ptr", device, "int", B8G8R8A8UIntNormalized := 87, "int", numberOfBuffers := 2, "int64", (height << 32) | width, "ptr*", frame_pool)   ; Direct3D11CaptureFramePool.Create
   CreateClass("Windows.Graphics.Capture.GraphicsCaptureItem", IGraphicsCaptureItemStatics := "{A87EBEA5-457C-5788-AB47-0CF1D3637E74}", GraphicsCaptureItemStatics)
   interop_factory := ComObjQuery(GraphicsCaptureItemStatics, IGraphicsCaptureItemInterop := "{3628E81B-3CAC-4C60-B7F4-23CE0E0C3356}")
   VarSetCapacity(GUID, 16, 0)
   DllCall("ole32\CLSIDFromString", "wstr", IGraphicsCaptureItem := "{79c3f95b-31f7-4ec2-a464-632ef5d30760}", "ptr", &GUID)
   hr := DllCall(NumGet(NumGet(interop_factory+0)+3*A_PtrSize), "ptr", interop_factory, "ptr", window_handle, "ptr", &GUID, "ptr*", capture_item, "uint")   ; IGraphicsCaptureItemInterop::CreateForWindow
   if hr
   {
      msgbox Cannot capture such a window.`nError: %hr%
      ExitApp
   }
   DllCall(NumGet(NumGet(frame_pool+0)+10*A_PtrSize), "ptr", frame_pool, "ptr", capture_item, "ptr*", session)   ; Direct3D11CaptureFramePool.CreateCaptureSession
   if (captureCursor != 1)
   {
      session2 := ComObjQuery(session, IGraphicsCaptureSession2 := "{2c39ae40-7d2e-5044-804e-8b6799d4cf9e}")
      DllCall(NumGet(NumGet(session2+0)+7*A_PtrSize), "ptr", session2, "int", 0)   ; GraphicsCaptureSession.IsCursorCaptureEnabled put
   }
   if (hideBorder = 1) and (StrSplit(A_OSVersion, ".")[3] >= 20348)
   {
      session3 := ComObjQuery(session, IGraphicsCaptureSession3 := "{f2cdd966-22ae-5ea1-9596-3a289344c3be}")
      DllCall(NumGet(NumGet(session3+0)+7*A_PtrSize), "ptr", session3, "int", 0)   ; GraphicsCaptureSession.IsBorderRequired put
   }
   DllCall(NumGet(NumGet(session+0)+6*A_PtrSize), "ptr", session)   ; GraphicsCaptureSession.StartCapture
}
loop
{
   DllCall(NumGet(NumGet(frame_pool+0)+7*A_PtrSize), "ptr", frame_pool, "ptr*", frame)   ; Direct3D11CaptureFramePool.TryGetNextFrame
   if (frame != 0)
   {
      DllCall(NumGet(NumGet(frame+0)+7*A_PtrSize), "ptr", frame, "int64*", SystemRelativeTime)   ; Direct3D11CaptureFrame.SystemRelativeTime
      if !init or (SystemRelativeTime >= StartTime)
         break
      Close := ComObjQuery(frame, IClosable := "{30D5A829-7FA4-4026-83BB-D75BAE4EA99E}")
      DllCall(NumGet(NumGet(Close+0)+6*A_PtrSize), "ptr", Close)   ; Close
      ObjRelease(Close)
      ObjRelease(frame)
   }
}
if !init
{
   DllCall(NumGet(NumGet(frame+0)+6*A_PtrSize), "ptr", frame, "ptr*", surface)   ; Direct3D11CaptureFrame.Surface
   access := ComObjQuery(surface, IDirect3DDxgiInterfaceAccess := "{A9B3D012-3DF2-4EE3-B8D1-8695F457D3C1}")
   VarSetCapacity(GUID, 16, 0)
   DllCall("ole32\CLSIDFromString", "wstr", IID_ID3D11Texture2D := "{6f15aaf2-d208-4e89-9ab4-489535d34f9c}", "ptr", &GUID)
   DllCall(NumGet(NumGet(access+0)+3*A_PtrSize), "ptr", access, "ptr", &GUID, "ptr*", texture)   ; IDirect3DDxgiInterfaceAccess::GetInterface
   VarSetCapacity(captured_texture_desc, 44, 0)
   DllCall(NumGet(NumGet(texture+0)+10*A_PtrSize), "ptr", texture, "ptr", &captured_texture_desc)   ; ID3D11Texture2D::GetDesc
   NumPut(D3D11_USAGE_STAGING := 3, captured_texture_desc, 28, "uint")   ; Usage
   NumPut(0, captured_texture_desc, 32, "uint")   ; BindFlags
   NumPut(D3D11_CPU_ACCESS_READ := 0x20000, captured_texture_desc, 36, "uint")   ; CPUAccessFlags
   NumPut(0, captured_texture_desc, 40, "uint")   ; MiscFlags
   DllCall(NumGet(NumGet(d3d_device+0)+5*A_PtrSize), "ptr", d3d_device, "ptr", &captured_texture_desc, "ptr", 0, "ptr*", user_texture)   ; ID3D11Device::CreateTexture2D
   init := 1 
}
DllCall(NumGet(NumGet(d3d_context+0)+47*A_PtrSize), "ptr", d3d_context, "ptr", user_texture, "ptr", texture)   ; ID3D11DeviceContext::CopyResource
VarSetCapacity(D3D11_MAPPED_SUBRESOURCE, 8+A_PtrSize, 0)
DllCall(NumGet(NumGet(d3d_context+0)+14*A_PtrSize), "ptr", d3d_context, "ptr", user_texture, "uint", 0, "uint", D3D11_MAP_READ := 1, "uint", 0, "ptr", &D3D11_MAPPED_SUBRESOURCE)   ; ID3D11DeviceContext::Map
pBits := NumGet(D3D11_MAPPED_SUBRESOURCE, 0, "ptr")
pitch := NumGet(D3D11_MAPPED_SUBRESOURCE, A_PtrSize, "uint")
msgbox % a_tickcount - a
DllCall("gdiplus\GdipCreateBitmapFromScan0", "int", width, "int", height, "int", pitch, "int", PixelFormat32bppRGB := 0x22009, "ptr", pBits, "ptr*", pBitmap)
DllCall("gdiplus\GdipCreateHBITMAPFromBitmap", "ptr", pBitmap, "ptr*", hBitmap, "uint", 0xffffffff)
Gui, Destroy
Gui, Add, Picture, vpic, HBITMAP:%hBitmap%
Gui, Show
DllCall("gdiplus\GdipDisposeImage", "ptr", pBitmap)
DllCall("DeleteObject", "ptr", hBitmap)
DllCall(NumGet(NumGet(d3d_context+0)+15*A_PtrSize), "ptr", d3d_context, "ptr", user_texture, "uint", 0)   ; ID3D11DeviceContext::Unmap
Close := ComObjQuery(frame, IClosable := "{30D5A829-7FA4-4026-83BB-D75BAE4EA99E}")
DllCall(NumGet(NumGet(Close+0)+6*A_PtrSize), "ptr", Close)   ; Close
ObjRelease(Close)
ObjRelease(frame)
return



CreateClass(string, interface, ByRef Class)
{
   CreateHString(string, hString)
   VarSetCapacity(GUID, 16)
   DllCall("ole32\CLSIDFromString", "wstr", interface, "ptr", &GUID)
   result := DllCall("Combase.dll\RoGetActivationFactory", "ptr", hString, "ptr", &GUID, "ptr*", Class, "uint")
   if (result != 0)
   {
      if (result = 0x80004002)
         msgbox No such interface supported
      else if (result = 0x80040154)
         msgbox Class not registered
      else
         msgbox error: %result%
      ExitApp
   }
   DeleteHString(hString)
}

CreateHString(string, ByRef hString)
{
    DllCall("Combase.dll\WindowsCreateString", "wstr", string, "uint", StrLen(string), "ptr*", hString)
}

DeleteHString(hString)
{
   DllCall("Combase.dll\WindowsDeleteString", "ptr", hString)
}

Пример с захватом разных активных окон (медленно):

; captureCursor := true
; hideBorder := true   ; убирает рамку у захватываемого окна, только для winver >= 20348

f11::
if !init
{
   setbatchlines -1
   DllCall("LoadLibrary","str","DXGI")
   DllCall("LoadLibrary","str","D3D11")
   DllCall("LoadLibrary","str","Dwmapi")
   DllCall("LoadLibrary", "str", "gdiplus")
   VarSetCapacity(si, A_PtrSize = 8 ? 24 : 16, 0), si := Chr(1)
   DllCall("gdiplus\GdiplusStartup", "ptr*", pToken, "ptr", &si, "ptr", 0)
   DllCall("D3D11\D3D11CreateDevice", "ptr", 0, "int", D3D_DRIVER_TYPE_HARDWARE := 1, "ptr", 0, "uint", D3D11_CREATE_DEVICE_BGRA_SUPPORT := 0x20, "ptr", 0, "uint", 0, "uint", D3D11_SDK_VERSION := 7, "ptr*", d3d_device, "ptr*", 0, "ptr*", d3d_context)
   dxgiDevice := ComObjQuery(d3d_device, IID_IDXGIDevice := "{54ec77fa-1377-44e6-8c32-88fd5f44c84c}")
   DllCall("D3D11\CreateDirect3D11DeviceFromDXGIDevice", "ptr", dxgiDevice, "ptr*", inspectable)
   device := ComObjQuery(inspectable, IDirect3DDevice := "{A37624AB-8D5F-4650-9D3E-9EAE3D9BC670}")
   CreateClass("Windows.Graphics.Capture.Direct3D11CaptureFramePool", IDirect3D11CaptureFramePoolStatics := "{7784056a-67aa-4d53-ae54-1088d5a8ca21}", Direct3D11CaptureFramePoolStatics)
   CreateClass("Windows.Graphics.Capture.GraphicsCaptureItem", IGraphicsCaptureItemStatics := "{A87EBEA5-457C-5788-AB47-0CF1D3637E74}", GraphicsCaptureItemStatics)
   interop_factory := ComObjQuery(GraphicsCaptureItemStatics, IGraphicsCaptureItemInterop := "{3628E81B-3CAC-4C60-B7F4-23CE0E0C3356}")
   VarSetCapacity(GraphicsCaptureItemGUID, 16, 0)
   DllCall("ole32\CLSIDFromString", "wstr", IGraphicsCaptureItem := "{79c3f95b-31f7-4ec2-a464-632ef5d30760}", "ptr", &GraphicsCaptureItemGUID)
   VarSetCapacity(D3D11Texture2DGUID, 16, 0)
   DllCall("ole32\CLSIDFromString", "wstr", IID_ID3D11Texture2D := "{6f15aaf2-d208-4e89-9ab4-489535d34f9c}", "ptr", &D3D11Texture2DGUID)
   init := 1
}
window_handle := WinExist("A")
VarSetCapacity(rect, 16, 0)
DllCall("Dwmapi.dll\DwmGetWindowAttribute", "ptr", window_handle, "uint", DWMWA_EXTENDED_FRAME_BOUNDS := 9, "ptr", &rect, "uint", 16)
width := NumGet(rect, 8, "int") - NumGet(rect, 0, "int")
height := NumGet(rect, 12, "int") - NumGet(rect, 4, "int")
DllCall(NumGet(NumGet(Direct3D11CaptureFramePoolStatics+0)+6*A_PtrSize), "ptr", Direct3D11CaptureFramePoolStatics, "ptr", device, "int", B8G8R8A8UIntNormalized := 87, "int", numberOfBuffers := 2, "int64", (height << 32) | width, "ptr*", frame_pool)   ; Direct3D11CaptureFramePool.Create
hr := DllCall(NumGet(NumGet(interop_factory+0)+3*A_PtrSize), "ptr", interop_factory, "ptr", window_handle, "ptr", &GraphicsCaptureItemGUID, "ptr*", capture_item, "uint")   ; IGraphicsCaptureItemInterop::CreateForWindow
if hr
{
   msgbox Cannot capture such a window.`nError: %hr%
   ObjReleaseClose(frame_pool)
   return
}
DllCall(NumGet(NumGet(frame_pool+0)+10*A_PtrSize), "ptr", frame_pool, "ptr", capture_item, "ptr*", session)   ; Direct3D11CaptureFramePool.CreateCaptureSession
if (captureCursor != 1)
{
   session2 := ComObjQuery(session, IGraphicsCaptureSession2 := "{2c39ae40-7d2e-5044-804e-8b6799d4cf9e}")
   DllCall(NumGet(NumGet(session2+0)+7*A_PtrSize), "ptr", session2, "int", 0)   ; GraphicsCaptureSession.IsCursorCaptureEnabled put
}
if (hideBorder = 1) and (StrSplit(A_OSVersion, ".")[3] >= 20348)
{
   session3 := ComObjQuery(session, IGraphicsCaptureSession3 := "{f2cdd966-22ae-5ea1-9596-3a289344c3be}")
   DllCall(NumGet(NumGet(session3+0)+7*A_PtrSize), "ptr", session3, "int", 0)   ; GraphicsCaptureSession.IsBorderRequired put
}
DllCall(NumGet(NumGet(session+0)+6*A_PtrSize), "ptr", session)   ; GraphicsCaptureSession.StartCapture
loop
{
   DllCall(NumGet(NumGet(frame_pool+0)+7*A_PtrSize), "ptr", frame_pool, "ptr*", frame)   ; Direct3D11CaptureFramePool.TryGetNextFrame
   if (frame != 0)
      break
}
DllCall(NumGet(NumGet(frame+0)+6*A_PtrSize), "ptr", frame, "ptr*", surface)   ; Direct3D11CaptureFrame.Surface
access := ComObjQuery(surface, IDirect3DDxgiInterfaceAccess := "{A9B3D012-3DF2-4EE3-B8D1-8695F457D3C1}")
DllCall(NumGet(NumGet(access+0)+3*A_PtrSize), "ptr", access, "ptr", &D3D11Texture2DGUID, "ptr*", texture)   ; IDirect3DDxgiInterfaceAccess::GetInterface
VarSetCapacity(captured_texture_desc, 44, 0)
DllCall(NumGet(NumGet(texture+0)+10*A_PtrSize), "ptr", texture, "ptr", &captured_texture_desc)   ; ID3D11Texture2D::GetDesc
NumPut(D3D11_USAGE_STAGING := 3, captured_texture_desc, 28, "uint")   ; Usage
NumPut(0, captured_texture_desc, 32, "uint")   ; BindFlags
NumPut(D3D11_CPU_ACCESS_READ := 0x20000, captured_texture_desc, 36, "uint")   ; CPUAccessFlags
NumPut(0, captured_texture_desc, 40, "uint")   ; MiscFlags
DllCall(NumGet(NumGet(d3d_device+0)+5*A_PtrSize), "ptr", d3d_device, "ptr", &captured_texture_desc, "ptr", 0, "ptr*", user_texture)   ; ID3D11Device::CreateTexture2D
DllCall(NumGet(NumGet(d3d_context+0)+47*A_PtrSize), "ptr", d3d_context, "ptr", user_texture, "ptr", texture)   ; ID3D11DeviceContext::CopyResource
VarSetCapacity(D3D11_MAPPED_SUBRESOURCE, 8+A_PtrSize, 0)
DllCall(NumGet(NumGet(d3d_context+0)+14*A_PtrSize), "ptr", d3d_context, "ptr", user_texture, "uint", 0, "uint", D3D11_MAP_READ := 1, "uint", 0, "ptr", &D3D11_MAPPED_SUBRESOURCE)   ; ID3D11DeviceContext::Map
pBits := NumGet(D3D11_MAPPED_SUBRESOURCE, 0, "ptr")
pitch := NumGet(D3D11_MAPPED_SUBRESOURCE, A_PtrSize, "uint")
DllCall("gdiplus\GdipCreateBitmapFromScan0", "int", width, "int", height, "int", pitch, "int", PixelFormat32bppRGB := 0x22009, "ptr", pBits, "ptr*", pBitmap)
DllCall("gdiplus\GdipCreateHBITMAPFromBitmap", "ptr", pBitmap, "ptr*", hBitmap, "uint", 0xffffffff)
Gui, Destroy
Gui, Add, Picture, vpic, HBITMAP:%hBitmap%
Gui, Show
DllCall("gdiplus\GdipDisposeImage", "ptr", pBitmap)
DllCall("DeleteObject", "ptr", hBitmap)
DllCall(NumGet(NumGet(d3d_context+0)+15*A_PtrSize), "ptr", d3d_context, "ptr", user_texture, "uint", 0)   ; ID3D11DeviceContext::Unmap
ObjReleaseClose(frame_pool)
ObjRelease(capture_item)
ObjReleaseClose(session)
if session2
{
   ObjReleaseClose(session2)
   session2 := ""
}
if session3
{
   ObjReleaseClose(session3)
   session3 := ""
}
ObjReleaseClose(frame)
ObjReleaseClose(surface)
ObjReleaseClose(access)
ObjRelease(texture)
ObjRelease(user_texture)
return



CreateClass(string, interface, ByRef Class)
{
   CreateHString(string, hString)
   VarSetCapacity(GUID, 16)
   DllCall("ole32\CLSIDFromString", "wstr", interface, "ptr", &GUID)
   result := DllCall("Combase.dll\RoGetActivationFactory", "ptr", hString, "ptr", &GUID, "ptr*", Class, "uint")
   if (result != 0)
   {
      if (result = 0x80004002)
         msgbox No such interface supported
      else if (result = 0x80040154)
         msgbox Class not registered
      else
         msgbox error: %result%
      ExitApp
   }
   DeleteHString(hString)
}

CreateHString(string, ByRef hString)
{
    DllCall("Combase.dll\WindowsCreateString", "wstr", string, "uint", StrLen(string), "ptr*", hString)
}

DeleteHString(hString)
{
   DllCall("Combase.dll\WindowsDeleteString", "ptr", hString)
}

ObjReleaseClose(ByRef Object)
{
   Close := ComObjQuery(Object, IClosable := "{30D5A829-7FA4-4026-83BB-D75BAE4EA99E}")
   DllCall(NumGet(NumGet(Close+0)+6*A_PtrSize), "ptr", Close)   ; Close
   ObjRelease(Close)
   ObjRelease(Object)
   Object := ""
}

Пример сохранения монитора:

hMonitor := DllCall("MonitorFromPoint", "int64", 0, "uint", MONITOR_DEFAULTTOPRIMARY := 1, "ptr")
width := a_screenwidth
height := a_screenheight
extension := "jpg"
filename := "test"
; captureCursor := true
; hideBorder := true   ; убирает рамку у захватываемого окна, только для winver >= 20348
return

f11::
DllCall("QueryPerformanceCounter", "int64*", StartTime)
if !init
{
   setbatchlines -1
   DllCall("LoadLibrary","str","DXGI")
   DllCall("LoadLibrary","str","D3D11")
   DllCall("LoadLibrary", "str", "gdiplus")
   VarSetCapacity(si, A_PtrSize = 8 ? 24 : 16, 0), si := Chr(1)
   DllCall("gdiplus\GdiplusStartup", "ptr*", pToken, "ptr", &si, "ptr", 0)
   DllCall("gdiplus\GdipGetImageEncodersSize", "uint*", count:=0, "uint*", size:=0)
   VarSetCapacity(ci, size)
   DllCall("gdiplus\GdipGetImageEncoders", "uint", count, "uint", size, "ptr", &ci)
   if !(count && size)
      throw Exception("Could not get a list of image codec encoders on this system.")
   Loop % count
      EncoderExtensions := StrGet(NumGet(ci, (idx:=(48+7*A_PtrSize)*(A_Index-1))+32+3*A_PtrSize, "uptr"), "UTF-16")
         until InStr(EncoderExtensions, "*." extension)
   if !(pCodec := &ci + idx)
      throw Exception("Could not find a matching encoder for the specified file format.")

   DllCall("D3D11\D3D11CreateDevice", "ptr", 0, "int", D3D_DRIVER_TYPE_HARDWARE := 1, "ptr", 0, "uint", D3D11_CREATE_DEVICE_BGRA_SUPPORT := 0x20, "ptr", 0, "uint", 0, "uint", D3D11_SDK_VERSION := 7, "ptr*", d3d_device, "ptr*", 0, "ptr*", d3d_context)
   dxgiDevice := ComObjQuery(d3d_device, IID_IDXGIDevice := "{54ec77fa-1377-44e6-8c32-88fd5f44c84c}")
   DllCall("D3D11\CreateDirect3D11DeviceFromDXGIDevice", "ptr", dxgiDevice, "ptr*", inspectable)
   device := ComObjQuery(inspectable, IDirect3DDevice := "{A37624AB-8D5F-4650-9D3E-9EAE3D9BC670}")
   CreateClass("Windows.Graphics.Capture.Direct3D11CaptureFramePool", IDirect3D11CaptureFramePoolStatics := "{7784056a-67aa-4d53-ae54-1088d5a8ca21}", Direct3D11CaptureFramePoolStatics)
   DllCall(NumGet(NumGet(Direct3D11CaptureFramePoolStatics+0)+6*A_PtrSize), "ptr", Direct3D11CaptureFramePoolStatics, "ptr", device, "int", B8G8R8A8UIntNormalized := 87, "int", numberOfBuffers := 2, "int64", (height << 32) | width, "ptr*", frame_pool)   ; Direct3D11CaptureFramePool.Create
   CreateClass("Windows.Graphics.Capture.GraphicsCaptureItem", IGraphicsCaptureItemStatics := "{A87EBEA5-457C-5788-AB47-0CF1D3637E74}", GraphicsCaptureItemStatics)
   interop_factory := ComObjQuery(GraphicsCaptureItemStatics, IGraphicsCaptureItemInterop := "{3628E81B-3CAC-4C60-B7F4-23CE0E0C3356}")
   VarSetCapacity(GUID, 16, 0)
   DllCall("ole32\CLSIDFromString", "wstr", IGraphicsCaptureItem := "{79c3f95b-31f7-4ec2-a464-632ef5d30760}", "ptr", &GUID)
   DllCall(NumGet(NumGet(interop_factory+0)+4*A_PtrSize), "ptr", interop_factory, "ptr", hMonitor, "ptr", &GUID, "ptr*", capture_item)   ; IGraphicsCaptureItemInterop::CreateForMonitor
   DllCall(NumGet(NumGet(frame_pool+0)+10*A_PtrSize), "ptr", frame_pool, "ptr", capture_item, "ptr*", session)   ; Direct3D11CaptureFramePool.CreateCaptureSession
   if (captureCursor != 1)
   {
      session2 := ComObjQuery(session, IGraphicsCaptureSession2 := "{2c39ae40-7d2e-5044-804e-8b6799d4cf9e}")
      DllCall(NumGet(NumGet(session2+0)+7*A_PtrSize), "ptr", session2, "int", 0)   ; GraphicsCaptureSession.IsCursorCaptureEnabled put
   }
   if (hideBorder = 1) and (StrSplit(A_OSVersion, ".")[3] >= 20348)
   {
      session3 := ComObjQuery(session, IGraphicsCaptureSession3 := "{f2cdd966-22ae-5ea1-9596-3a289344c3be}")
      DllCall(NumGet(NumGet(session3+0)+7*A_PtrSize), "ptr", session3, "int", 0)   ; GraphicsCaptureSession.IsBorderRequired put
   }
   DllCall(NumGet(NumGet(session+0)+6*A_PtrSize), "ptr", session)   ; GraphicsCaptureSession.StartCapture
}
loop
{
   DllCall(NumGet(NumGet(frame_pool+0)+7*A_PtrSize), "ptr", frame_pool, "ptr*", frame)   ; Direct3D11CaptureFramePool.TryGetNextFrame
   if (frame != 0)
   {
      DllCall(NumGet(NumGet(frame+0)+7*A_PtrSize), "ptr", frame, "int64*", SystemRelativeTime)   ; Direct3D11CaptureFrame.SystemRelativeTime
      if !init or (SystemRelativeTime >= StartTime)
         break
      Close := ComObjQuery(frame, IClosable := "{30D5A829-7FA4-4026-83BB-D75BAE4EA99E}")
      DllCall(NumGet(NumGet(Close+0)+6*A_PtrSize), "ptr", Close)   ; Close
      ObjRelease(Close)
      ObjRelease(frame)
   }
}
if !init
{
   DllCall(NumGet(NumGet(frame+0)+6*A_PtrSize), "ptr", frame, "ptr*", surface)   ; Direct3D11CaptureFrame.Surface
   access := ComObjQuery(surface, IDirect3DDxgiInterfaceAccess := "{A9B3D012-3DF2-4EE3-B8D1-8695F457D3C1}")
   VarSetCapacity(GUID, 16, 0)
   DllCall("ole32\CLSIDFromString", "wstr", IID_ID3D11Texture2D := "{6f15aaf2-d208-4e89-9ab4-489535d34f9c}", "ptr", &GUID)
   DllCall(NumGet(NumGet(access+0)+3*A_PtrSize), "ptr", access, "ptr", &GUID, "ptr*", texture)   ; IDirect3DDxgiInterfaceAccess::GetInterface
   VarSetCapacity(captured_texture_desc, 44, 0)
   DllCall(NumGet(NumGet(texture+0)+10*A_PtrSize), "ptr", texture, "ptr", &captured_texture_desc)   ; ID3D11Texture2D::GetDesc
   NumPut(D3D11_USAGE_STAGING := 3, captured_texture_desc, 28, "uint")   ; Usage
   NumPut(0, captured_texture_desc, 32, "uint")   ; BindFlags
   NumPut(D3D11_CPU_ACCESS_READ := 0x20000, captured_texture_desc, 36, "uint")   ; CPUAccessFlags
   NumPut(0, captured_texture_desc, 40, "uint")   ; MiscFlags
   DllCall(NumGet(NumGet(d3d_device+0)+5*A_PtrSize), "ptr", d3d_device, "ptr", &captured_texture_desc, "ptr", 0, "ptr*", user_texture)   ; ID3D11Device::CreateTexture2D
   init := 1 
}
DllCall(NumGet(NumGet(d3d_context+0)+47*A_PtrSize), "ptr", d3d_context, "ptr", user_texture, "ptr", texture)   ; ID3D11DeviceContext::CopyResource
VarSetCapacity(D3D11_MAPPED_SUBRESOURCE, 8+A_PtrSize, 0)
DllCall(NumGet(NumGet(d3d_context+0)+14*A_PtrSize), "ptr", d3d_context, "ptr", user_texture, "uint", 0, "uint", D3D11_MAP_READ := 1, "uint", 0, "ptr", &D3D11_MAPPED_SUBRESOURCE)   ; ID3D11DeviceContext::Map
pBits := NumGet(D3D11_MAPPED_SUBRESOURCE, 0, "ptr")
pitch := NumGet(D3D11_MAPPED_SUBRESOURCE, A_PtrSize, "uint")
DllCall("gdiplus\GdipCreateBitmapFromScan0", "int", width, "int", height, "int", pitch, "int", PixelFormat32bppRGB := 0x22009, "ptr", pBits, "ptr*", pBitmap)
DllCall("gdiplus\GdipSaveImageToFile", "ptr", pBitmap, "wstr", filename "." extension, "ptr", pCodec, "uint", 0)
DllCall("gdiplus\GdipDisposeImage", "ptr", pBitmap)
DllCall(NumGet(NumGet(d3d_context+0)+15*A_PtrSize), "ptr", d3d_context, "ptr", user_texture, "uint", 0)   ; ID3D11DeviceContext::Unmap
Close := ComObjQuery(frame, IClosable := "{30D5A829-7FA4-4026-83BB-D75BAE4EA99E}")
DllCall(NumGet(NumGet(Close+0)+6*A_PtrSize), "ptr", Close)   ; Close
ObjRelease(Close)
ObjRelease(frame)
return



CreateClass(string, interface, ByRef Class)
{
   CreateHString(string, hString)
   VarSetCapacity(GUID, 16)
   DllCall("ole32\CLSIDFromString", "wstr", interface, "ptr", &GUID)
   result := DllCall("Combase.dll\RoGetActivationFactory", "ptr", hString, "ptr", &GUID, "ptr*", Class, "uint")
   if (result != 0)
   {
      if (result = 0x80004002)
         msgbox No such interface supported
      else if (result = 0x80040154)
         msgbox Class not registered
      else
         msgbox error: %result%
      ExitApp
   }
   DeleteHString(hString)
}

CreateHString(string, ByRef hString)
{
    DllCall("Combase.dll\WindowsCreateString", "wstr", string, "uint", StrLen(string), "ptr*", hString)
}

DeleteHString(hString)
{
   DllCall("Combase.dll\WindowsDeleteString", "ptr", hString)
}

Тема для обсуждения

2

Re: AHK: Захват окна или монитора с помощью WindowsGraphicsCapture API

Добавил пример с захватом монитора - может быть полезно когда используется лупа, а нужно захватить весь экран.