[UDF] _ScreenCaptureEx

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

[UDF] _ScreenCaptureEx

#1

Message par TommyDDR » lun. 29 févr. 2016 19:38

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