[UDF] _ScreenCaptureEx
Posté : 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).
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.
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
#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
#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
#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