1 (изменено: Malcev, 2023-03-18 22:33:59)

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

https://learn.microsoft.com/en-us/previ … magapi-sdk
Алгоритм кода был сделан ранее serzh82saratov с небольшой моей помощью.
Я немного модифицировал его для сохранения рабочего стола в jpg.
Это может быть полезно для сохранения реального рабочего стола при использовании оверлеев с аппаратным ускорением, таких как виндовская лупа.

; global captureCursor := true   ; раскомментировать если нужен захват курсора.
; global hwndExclude := [0x1111, 0x2222]   ; массив hwnd окон, исключенных из захвата
OnExit, Uninitialize
setbatchlines -1
return

f11::
savedesktop("temp")
return

savedesktop(name)
{
   static hChildMagnifier, RECT, this
   varsetcapacity(this, StrLen(name)+1, 0)
   StrPut(name, &this, "utf-8")
   if !hChildMagnifier
   {
      Gui, Magnifier: +HWNDhMagnifier +toolwindow -Caption +E0x00080000 +E0x20 ; WS_EX_LAYERED := E0x00080000 WS_EX_TRANSPARENT := E0x20
      DllCall("LoadLibrary", "str", "magnification.dll")
      DllCall("magnification.dll\MagInitialize")
      if (captureCursor = "")
         captureCursor := 0
      hChildMagnifier := DllCall("CreateWindowEx", "uint", 0, "str", "Magnifier", "str", "MagnifierWindow", "uint", (WS_CHILD := 0x40000000)|captureCursor, "int", 0, "int", 0, "int", A_ScreenWidth, "int", A_ScreenHeight, "uptr", hMagnifier, "uint", 0, "ptr", DllCall("GetWindowLong" (A_PtrSize=8 ? "Ptr" : ""), "uptr", hMagnifier, "int", GWL_HINSTANCE := -6 , "ptr"), "uint", 0, "ptr")
      if hwndExclude
      {
         VarSetCapacity(HWNDlist, hwndExclude.Count() * A_PtrSize, 0)
         loop % hwndExclude.Count()
            NumPut(hwndExclude[A_Index], HWNDlist, (A_Index - 1) * A_PtrSize, "ptr")
         DllCall("magnification.dll\MagSetWindowFilterList", "uptr", hChildMagnifier, "int", MW_FILTERMODE_EXCLUDE := 0, "int", hwndExclude.Count(), "ptr", &HWNDlist)
      }
      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", "uptr", hChildMagnifier, "ptr", &MAGTRANSFORM)
      DllCall("magnification.dll\MagSetImageScalingCallback", "uptr", hChildMagnifier, "ptr", RegisterCallback("MagImageScalingCallback", "Fast",, &this))
      if (A_PtrSize = 8)
      {
         VarSetCapacity(RECT, 16, 0)
         NumPut(0, RECT, 0, "int")
         NumPut(0, RECT, 4, "int")
         NumPut(A_ScreenWidth, RECT, 8, "int")
         NumPut(A_ScreenHeight, RECT, 12, "int")
      }
   }
   if (A_PtrSize = 8)
      DllCall("magnification.dll\MagSetWindowSource", "uptr", hChildMagnifier, "ptr", &RECT)
   else
      DllCall("magnification.dll\MagSetWindowSource", "uptr", hChildMagnifier, "int", 0, "int", 0, "int", A_ScreenWidth, "int", A_ScreenHeight)
   return
}

MagImageScalingCallback(hwnd, srcdata, srcheader, destdata, destheader, unclipped, clipped, dirty)
{
   static hDC, BITMAPV5HEADER, BITMAPINFO, pCodec, extension := "jpg"
   if !hDC
   {  
      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.")
      VarSetCapacity(BITMAPV5HEADER, 124, 0)
      NumPut(124, BITMAPV5HEADER, 0, "uint")   ; bV5Size
      NumPut(A_ScreenWidth, BITMAPV5HEADER, 4, "uint")   ; bV5Width
      NumPut(-A_ScreenHeight, BITMAPV5HEADER, 8, "uint")   ; bV5Height
      NumPut(1, BITMAPV5HEADER, 12, "short")   ; bV5Planes
      NumPut(32, BITMAPV5HEADER, 14, "short")   ; bV5BitCount
      VarSetCapacity(BITMAPINFO, 44, 0)
      NumPut(44, BITMAPINFO, 0, "uint")   ; biSize
      NumPut(A_ScreenWidth, BITMAPINFO, 4, "uint")   ; biWidth
      NumPut(-A_ScreenHeight, BITMAPINFO, 8, "UInt")   ; biHeight
      NumPut(1, BITMAPINFO, 12, "short")   ; biPlanes
      NumPut(32, BITMAPINFO, 14, "short")   ; biBitCount
      hDC := DllCall("GetDC", "uptr", hwnd)
   }
   hBitmap := DllCall("CreateDIBitmap", "ptr", hDC, "ptr", &BITMAPV5HEADER, "uint", CBM_INIT := 6, "ptr", srcdata, "ptr", &BITMAPINFO, "uint", DIB_RGB_COLORS := 0, "ptr")
   DllCall("gdiplus\GdipCreateBitmapFromHBITMAP", "ptr", hBitmap, "ptr", 0, "ptr*", pBitmap)
   DllCall("gdiplus\GdipSaveImageToFile", "ptr", pBitmap, "wstr", strget(A_EventInfo, "utf-8") "." extension, "ptr", pCodec, "uint", 0)
   DllCall("gdiplus\GdipDisposeImage", "ptr", pBitmap)
   DllCall("DeleteObject", "ptr", hBitmap)
   return
}

Uninitialize: 	
DllCall("magnification.dll\MagUninitialize")
ExitApp

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