[UDF] _ScreenCaptureEx

Partagez des fonctions et des UDF AutoIt.
Règles du forum
.
Répondre
Avatar du membre
TommyDDR
Modérateur
Modérateur
Messages : 1869
Enregistré le : mar. 22 juil. 2008 21:55
Localisation : Nantes
Status : Hors ligne

[UDF] _ScreenCaptureEx

#1

Message par TommyDDR »

Bonjour,

Suite à une demande récente, je vous partage cet UDF qui permet de prendre une impression écran d'une fenêtre se trouvant en dehors de l'écran (Ne fonctionne pas avec les fenêtre réduites).
#include-once
#include <GDIPlus.au3>
#include <Misc.au3>
#include <WinAPI.au3>

Global $ScreenCapture_Hwnd = ""
Global $ScreenCapture_hDDC = ""
Global $ScreenCapture_hCDC = ""
Global $ScreenCapture_hBMP = ""
Global $ScreenCapture_width = ""
Global $ScreenCapture_height = ""
Global $ScreenCapture_bords[2] = [-1, -1]

_GDIPlus_Startup()
OnAutoItExitRegister("exit_screenCaptureEx")

Func _ScreenCapture_CaptureWndNoBlackInitHwnd($Hwnd)
   If($Hwnd <> $ScreenCapture_Hwnd) Then
      If($ScreenCapture_Hwnd <> "") Then
         _ScreenCapture_CaptureWndNoBlackDisposeHwnd()
      EndIf
      $ScreenCapture_Hwnd     = $Hwnd
      $ScreenCapture_width = _WinAPI_GetWindowWidth($ScreenCapture_Hwnd)
      $ScreenCapture_height   = _WinAPI_GetWindowHeight($ScreenCapture_Hwnd)
      $ScreenCapture_hDDC     = _WinAPI_GetDC($ScreenCapture_Hwnd)
      $ScreenCapture_hCDC     = _WinAPI_CreateCompatibleDC($ScreenCapture_hDDC)
      $ScreenCapture_hBMP     = _WinAPI_CreateCompatibleBitmap($ScreenCapture_hDDC, $ScreenCapture_width, $ScreenCapture_height)
                          _WinAPI_SelectObject($ScreenCapture_hCDC, $ScreenCapture_hBMP)
      $ScreenCapture_bords = WinGetSideSize($ScreenCapture_Hwnd)
   EndIf
EndFunc

Func _ScreenCapture_CaptureWndNoBlackDisposeHwnd()
   _WinAPI_ReleaseDC($ScreenCapture_Hwnd, $ScreenCapture_hDDC)
   _WinAPI_DeleteDC($ScreenCapture_hCDC)
   _WinAPI_DeleteObject($ScreenCapture_hBMP)
   $ScreenCapture_Hwnd = ""
   $ScreenCapture_hDDC = ""
   $ScreenCapture_hCDC = ""
   $ScreenCapture_hBMP = ""
   $ScreenCapture_width = ""
   $ScreenCapture_height = ""
   $ScreenCapture_bords[0] = -1
   $ScreenCapture_bords[1] = -1
EndFunc

Func _ScreenCapture_SaveCaptureWndNoBlack($Hwnd, $fileName, $bords = True, $x = -1, $y = -1, $w = -1, $h = -1, $fCursor = False, $xCur = 0, $yCur = 0)
   Local $bitmap = _ScreenCapture_CaptureWndNoBlack($Hwnd, $bords, true, $x, $y, $w, $h, $fCursor, $xCur, $yCur)
   _GDIPlus_ImageSaveToFile($bitmap, $fileName)
   _GDIPlus_ImageDispose($bitmap)
EndFunc

Func _ScreenCapture_CaptureWndNoBlack($Hwnd, $bords = True, $bitmap = True, $x = -1, $y = -1, $w = -1, $h = -1, $fCursor = False, $xCur = 0, $yCur = 0)
   _ScreenCapture_CaptureWndNoBlackInitHwnd($Hwnd)
   If(WinExists($ScreenCapture_Hwnd)) Then
      $x = ($x = -1) ? 0 : $x
      $y = ($y = -1) ? 0 : $y
      $w = ($w = -1) ? $ScreenCapture_width : $w
      $h = ($h = -1) ? $ScreenCapture_height : $h
      Local $Supplements[2] = [0, 0]
      If(Not($bords)) Then
         $Supplements[0] = $ScreenCapture_bords[0]
         $Supplements[1] = $ScreenCapture_bords[1]
         $x += $Supplements[0]
         $y += $Supplements[1]
      EndIf
      $x = ($x < $Supplements[0]) ? $Supplements[0] : $x
      $y = ($y < $Supplements[1]) ? $Supplements[1] : $y
      $w = (($x+$w > $ScreenCapture_width Or $w < 0)) ? $ScreenCapture_width-$x-$Supplements[0] : $w
      $h = (($y+$h > $ScreenCapture_height Or $h < 0)) ? $ScreenCapture_height-$y-$Supplements[0] : $h
      DllCall("User32.dll", "int", "PrintWindow", "hwnd", $ScreenCapture_Hwnd, "hwnd", $ScreenCapture_hCDC, "int", 0)
      If $fCursor Then
         Local $pos = WinGetPos($Hwnd)
         $xCur -= $pos[0]
         $yCur -= $pos[1]
         _DrawCursor($ScreenCapture_hCDC, $xCur, $yCur)
      EndIf
      Local $BMP = _GDIPlus_BitmapCreateFromHBITMAP($ScreenCapture_hBMP)
      Local $Image = _GDIPlus_BitmapCloneArea($BMP, $x, $y, $w, $h)
      _GDIPlus_BitmapDispose($BMP)
   Else
      Return SetError(1, 0, 0)
   EndIf
   Local $retour
   If($bitmap) Then
      $retour = $Image
   Else
      $retour = _GDIPlus_BitmapCreateHBITMAPFromBitmap($Image)
      _GDIPlus_BitmapDispose($Image)
   EndIf
   Return $retour
EndFunc

Func _DrawCursor($hCDC, $x, $y)
   Local $aCursor = _WinAPI_GetCursorInfo()
   If(Not(@error) And $aCursor[1]) Then
      Local $hIcon = _WinAPI_CopyIcon($aCursor[2])
      Local $aIcon = _WinAPI_GetIconInfo($hIcon)
      _WinAPI_DeleteObject($aIcon[4]) ; delete bitmap mask return by _WinAPI_GetIconInfo()
      If $aIcon[5] <> 0 Then _WinAPI_DeleteObject($aIcon[5]); delete bitmap hbmColor return by _WinAPI_GetIconInfo()
      Local $mPos[2] = [$aCursor[3] - $aIcon[2] + $x, $aCursor[4] - $aIcon[3] + $y]
      _WinAPI_DrawIcon($hCDC, $mPos[0], $mPos[1], $hIcon)
      _WinAPI_DestroyIcon($hIcon)
   EndIf
EndFunc

Func WinGetSideSize($hWnd, $dim = -1)
   Local $clientSize = WinGetClientSize($hWnd)
   Local $winSize = WinGetPos($hWnd)
   Local $size[2]
   $size[0] = Round(($winSize[2]-$clientSize[0])/2)
   $size[1] = $winSize[3]-$clientSize[1]-$size[0]
   Switch $dim
      Case 0
         $size = $size[0]
      Case 1
         $size = $size[1]
   EndSwitch
   Return $size
EndFunc

Func exit_screenCaptureEx()
   _GDIPlus_Shutdown()
EndFunc
Lancez le script, déplacez la fenêtre sur un bord de l'écran et appuyez sur "²" pour lancer une série d'impression écran avec différentes options.
#include "_ScreenCaptureEx.au3"
#include <GUIConstantsEx.au3>

HotKeySet("²", impr)

Opt("GUIOnEventMode", 1)
Opt("MustDeclareVars", 1)

Global $gui
Global $label
Global $taille[2] = [300, 100]
Global $bordure = 10

$gui = GUICreate("", $taille[0], $taille[1])
GUISetBkColor(0x008000)
$label = GUICtrlCreateLabel("", $bordure, $bordure, $taille[0]-2*$bordure, $taille[1]-2*$bordure)
GUICtrlSetFont($label, 40)
GUISetOnEvent($GUI_EVENT_CLOSE, "quit", $gui)
GUISetState(@SW_SHOW, $gui)

While(True)
   MAJ_Label()
   Sleep(10)
WEnd

Func impr()
   Local Static $count = 0
   $count += 1
   Local $prefix = @ScriptDir & "\impr_" & $count & "_"
   Local $suffix = ".png"
   _ScreenCapture_SaveCaptureWndNoBlack($gui, $prefix & "bordure" & $suffix)
   _ScreenCapture_SaveCaptureWndNoBlack($gui, $prefix & "sans_bordure" & $suffix, false)
   _ScreenCapture_SaveCaptureWndNoBlack($gui, $prefix & "x_y" & $suffix, false, 20, 20, 100, 80, True)
   _ScreenCapture_SaveCaptureWndNoBlack($gui, $prefix & "cursor" & $suffix, true, -1, -1, -1, -1, true)
EndFunc

Func MAJ_Label()
   Local $pos = WinGetPos($gui)
   Local $txt = $pos[0] & ", " & $pos[1]
   _GUICtrlSetData($label, $txt)
EndFunc

Func _GUICtrlSetData($label, $txt)
   If(GUICtrlRead($label) <> $txt) Then
      GUICtrlSetData($label, $txt)
   EndIf
EndFunc

Func quit()
   Exit
EndFunc
3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679

Répondre