Um mal zu zeigen, wie man mit der _ScreenCapture-UDF ein kleines Capture-Programm in AutoIt schreiben kann, habe ich hier mal die wichtigsten Funktionen in einem Programm zusammengefasst:
Edit 11.09.2021:
- Die "Ganzer Bildschirm"-Funktion funktioniert jetzt auch mit mehreren Monitoren korrekt.
- Außerdem kann man jetzt auswählen, ob der Mauszeiger mit aufgenommen werden soll oder nicht.
Edit 13.09.2021:
- Die Capture-Funktion umgeschrieben, weil die Funktionen "_ScreenCapture_Capture" und "_ScreenCapture_CaptureWnd" nicht korrekt mit negativen Screenkoordinaten umgehen ("-1" als Defaultwert).
Edit 14.09.2021:
- Der Anwender kann jetzt den Hotkey selbst im Programm registrieren (Tasten begrenzt). Die Tastenkombination wird in der Registry gespeichert.
- Die Capture-Funktion noch etwas umgeschrieben.
- Statuszeile hinzugefügt.
- Icon für das Fenster hinzugefügt.
Edit 15.09.2021:
- Hotkey-Funktion nochmal überarbeitet, damit bereits registrierte Hotkeys erkannt werden.
- Icon (rotes X / grüner Haken) für (nicht) registrierten Hotkey hinzugefügt.
#include <APIGdiConstants.au3>
#include <APISysConstants.au3>
#include <ComboConstants.au3>
#include <FileConstants.au3>
#include <GDIPlus.au3>
#include <GDIPlusConstants.au3>
#include <GuiComboBox.au3>
#include <GUIConstantsEx.au3>
#include <GuiStatusBar.au3>
#include <ScreenCapture.au3>
#include <SendMessage.au3>
#include <StaticConstants.au3>
#include <StructureConstants.au3>
#include <WinAPIGdi.au3>
#include <WinAPIGdiDC.au3>
#include <WinAPIGdiInternals.au3>
#include <WinAPIHObj.au3>
#include <WinAPIIcons.au3>
#include <WinAPIInternals.au3>
#include <WinAPIMisc.au3>
#include <WinAPIRes.au3>
#include <WinAPISysInternals.au3>
#include <WinAPISysWin.au3>
#include <WindowsConstants.au3>
Opt('TrayMenuMode', 1)
Opt('TrayIconHide', 1)
_GDIPlus_Startup()
Global $aIconNr[6] = [117, 296, 221, 244, 8, 10], $ahIcon[UBound($aIconNr)]
For $i = 0 To UBound($aIconNr) - 1
If $i < 4 Then
$ahIcon[$i] = _WinAPI_ExtractIcon('shell32.dll', $aIconNr[$i])
Else
$ahIcon[$i] = _WinAPI_ExtractIcon('comres.dll', $aIconNr[$i])
EndIf
Next
Global $iGuiWidth = 1024, $iGuiHeight = 600
Global $iImgWidth = $iGuiWidth - 180, $iImgHeight = $iGuiHeight - 36
Global $hCapture = 0
OnAutoItExitRegister('_Exit')
Global $hGui = GUICreate('AutoIt-ScreenCapture v2.1', $iGuiWidth, $iGuiHeight)
GUISetBkColor(0xC0C0C0)
GUISetFont(10, 400, 0, 'Verdana')
GUICtrlCreateGroup('Capture-Auswahl', 10, 10, 160, 130)
Global $idSelectScreen = GUICtrlCreateRadio('Ganzer Bildschirm', 25, 35, 130, 20)
Global $idSelectWindow = GUICtrlCreateRadio('Aktives Fenster', 25, 55, 130, 20)
GUICtrlSetState($idSelectWindow, $GUI_CHECKED)
Global $idWithCursor = GUICtrlCreateCheckbox('Incl. Mauszeiger', 25, 100, 130, 20)
GUICtrlCreateGroup('', -99, -99, 1, 1)
GUICtrlCreateGroup('Capture-Hotkey', 10, 150, 160, 140)
Global $idRegIcon = GUICtrlCreateIcon('', 0, 136, 162, 32, 32) ; -297
Global $hRegIcon = GUICtrlGetHandle($idRegIcon)
Global $idHotkeyMod = GUICtrlCreateCombo(' ', 25, 180, 80, 25, BitOR($CBS_DROPDOWNLIST, $CBS_AUTOHSCROLL, $WS_VSCROLL))
GUICtrlSetData(-1, '{Alt}|{Ctrl}|{Shift}|{Win}')
GUICtrlCreateLabel('&&', 120, 183, 20, 22)
Global $idHotkey = GUICtrlCreateCombo('{PRINTSCREEN}', 25, 210, 130, 25, BitOR($CBS_DROPDOWNLIST, $CBS_AUTOHSCROLL, $WS_VSCROLL))
GUICtrlSetData(-1, '{F1}|{F2}|{F3}|{F4}|{F5}|{F6}|{F7}|{F8}|{F9}|{F10}|{F11}|{F12}')
Global $idRegister = GUICtrlCreateButton('Registrieren', 25, 250, 130, 25)
GUICtrlCreateGroup('', -99, -99, 1, 1)
Global $idSaveAs = GUICtrlCreateButton('Bild speichern...', 10, 320, 160, 35)
GUICtrlSetFont(-1, 12, 400, 0, 'Verdana')
GUICtrlSetState($idSaveAs, $GUI_DISABLE)
Global $idPic = GUICtrlCreatePic('', $iGuiWidth - $iImgWidth, 0, $iImgWidth, $iImgHeight)
Global $hStatus = _GUICtrlStatusBar_Create($hGui)
_GUICtrlStatusBar_SetParts($hStatus, 2, 180)
_GUICtrlStatusBar_SetMinHeight($hStatus, 34)
Global $sHotkey = ''
_SetHotkey()
_WinAPI_SetClassLongEx($hGui, $GCL_HICON, $ahIcon[0]) ; das Icon in der Taskleiste ersetzen
_WinAPI_SetClassLongEx($hGui, $GCL_HICONSM, $ahIcon[0]) ; das Icon oben/links im Fenster ersetzen
GUISetState()
_GUICtrlStatusBar_SetText($hStatus, 'Bereit.', 0)
_GUICtrlStatusBar_SetIcon($hStatus, 0, $ahIcon[1])
While True
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE
Exit
Case $idSaveAs
_SaveAs()
Case $idRegister
_SetHotkey()
EndSwitch
WEnd
Func _Exit()
HotKeySet($sHotkey)
If $hCapture Then _WinAPI_DeleteObject($hCapture)
For $hIcon In $ahIcon
_WinAPI_DestroyIcon($hIcon)
Next
_GDIPlus_Shutdown()
EndFunc ;==>_Exit
Func _SetRegHotkey()
Local $sReg, $sMod = ' '
$sReg = RegRead('HKCU\Software\AutoIt-ScreenCapture', 'Hotkey')
If @error Then $sReg = '{PRINTSCREEN}'
Switch StringLeft($sReg, 1)
Case '!'
$sMod = '{Alt}'
Case '^'
$sMod = '{Ctrl}'
Case '+'
$sMod = '{Shift}'
Case '#'
$sMod = '{Win}'
EndSwitch
_GUICtrlComboBox_SelectString($idHotkeyMod, $sMod)
_GUICtrlComboBox_SelectString($idHotkey, StringRegExpReplace($sReg, '.*({.+})', '$1'))
EndFunc ;==>_SetRegHotkey
Func _SetHotkey()
Local $sNew, $sMod
If $sHotkey = '' Then _SetRegHotkey()
$sMod = StringStripWS(GUICtrlRead($idHotkeyMod), 1)
Switch $sMod
Case '{Alt}'
$sNew = '!'
Case '{Ctrl}'
$sNew = '^'
Case '{Shift}'
$sNew = '+'
Case '{Win}'
$sNew = '#'
EndSwitch
$sNew &= GUICtrlRead($idHotkey)
If $sNew <> $sHotkey And HotKeySet($sNew, '_Capture') Then
HotKeySet($sHotkey)
$sHotkey = $sNew
RegWrite('HKCU\Software\AutoIt-ScreenCapture', 'Hotkey', 'REG_SZ', $sHotkey)
_SendMessage($hRegIcon, $STM_SETIMAGE, 1, $ahIcon[4])
Else
_SetRegHotkey()
$sHotkey = $sNew
_SendMessage($hRegIcon, $STM_SETIMAGE, 1, $ahIcon[5])
EndIf
EndFunc ;==>_SetHotkey
Func _Capture()
Local $bCursor, $tRECT, $bRet, $hWnd, $tPos, $hMonitor, $aData
If $hCapture Then _WinAPI_DeleteObject($hCapture)
$bCursor = BitAND(GUICtrlRead($idWithCursor), $GUI_CHECKED) == $GUI_CHECKED
$tRECT = DllStructCreate($tagRECT)
If BitAND(GUICtrlRead($idSelectWindow), $GUI_CHECKED) Then
$hWnd = _WinAPI_GetForegroundWindow()
If Not IsHWnd($hWnd) Then Return
$tRECT = _WinAPI_DwmGetWindowAttribute($hWnd, $DWMWA_EXTENDED_FRAME_BOUNDS)
If @error Then
$tRECT = _WinAPI_GetWindowRect($hWnd)
If @error Then Return
EndIf
Else
$tPos = _WinAPI_GetMousePos()
$hMonitor = _WinAPI_MonitorFromPoint($tPos)
$aData = _WinAPI_GetMonitorInfo($hMonitor)
If @error Then Return
$tRECT = $aData[0]
EndIf
$hCapture = _CaptureScreenWnd($tRECT.left, $tRECT.top, $tRECT.right, $tRECT.bottom, $bCursor)
If @error Then
$hCapture = 0
Return
EndIf
_GUICtrlStatusBar_SetText($hStatus, StringFormat('Breite x Höhe: %i x %i px', _
$tRECT.right - $tRECT.left, $tRECT.bottom - $tRECT.top), 1)
_GUICtrlStatusBar_SetIcon($hStatus, 1, $ahIcon[2])
_ShowScaledPic($idPic, $hCapture)
_WinAPI_SetForegroundWindow($hGui)
_GUICtrlStatusBar_SetText($hStatus, 'Bild nicht gespeichert.', 0)
_GUICtrlStatusBar_SetIcon($hStatus, 0, $ahIcon[3])
GUICtrlSetState($idSaveAs, $GUI_ENABLE)
EndFunc ;==>_Capture
Func _CaptureScreenWnd($iLeft, $iTop, $iRight, $iBottom, $bCursor)
Local $iW = $iRight - $iLeft
Local $iH = $iBottom - $iTop
Local $hWnd = _WinAPI_GetDesktopWindow()
Local $hDDC = _WinAPI_GetDC($hWnd)
Local $hCDC = _WinAPI_CreateCompatibleDC($hDDC)
Local $hBMP = _WinAPI_CreateCompatibleBitmap($hDDC, $iW, $iH)
_WinAPI_SelectObject($hCDC, $hBMP)
_WinAPI_BitBlt($hCDC, 0, 0, $iW, $iH, $hDDC, $iLeft, $iTop, $SRCCOPY)
If $bCursor Then
Local $aCursor = _WinAPI_GetCursorInfo()
If Not @error And $aCursor[1] Then
Local $hIcon = _WinAPI_CopyIcon($aCursor[2])
Local $aIcon = _WinAPI_GetIconInfo($hIcon)
If Not @error Then
_WinAPI_DeleteObject($aIcon[4])
If $aIcon[5] <> 0 Then _WinAPI_DeleteObject($aIcon[5])
_WinAPI_DrawIcon($hCDC, $aCursor[3] - $aIcon[2] - $iLeft, $aCursor[4] - $aIcon[3] - $iTop, $hIcon)
EndIf
_WinAPI_DestroyIcon($hIcon)
EndIf
EndIf
_WinAPI_ReleaseDC($hWnd, $hDDC)
_WinAPI_DeleteDC($hCDC)
Return $hBMP
EndFunc ;==>_CaptureScreenWnd
Func _SaveAs()
Local $sFilename = FileSaveDialog('Capture speichern unter', '', 'PNG-Bild (*.png)', $FD_PROMPTOVERWRITE)
If @error Then Return
If StringRight($sFilename, 4) <> '.png' Then $sFilename &= '.png'
_ScreenCapture_SaveImage($sFilename, $hCapture, False)
_GUICtrlStatusBar_SetText($hStatus, 'Bild gespeichert.', 0)
_GUICtrlStatusBar_SetIcon($hStatus, 0, $ahIcon[1])
EndFunc ;==>_SaveAs
Func _ShowScaledPic($idCtrl, $hHBitmap)
Local $hCtrl, $hParent, $hBitmap, $hGfx, $hImage, $hResize, $hBMP, $hPrevImage
Local $aDim, $iW, $iH, $iScaleW, $iScaleH, $iScaleF = 1
$hCtrl = GUICtrlGetHandle($idCtrl)
$hParent = _WinAPI_GetParent($hCtrl)
$aCtrlPos = ControlGetPos($hParent, '', $idCtrl)
$iW = $aCtrlPos[2]
$iH = $aCtrlPos[3]
$hBitmap = _GDIPlus_BitmapCreateFromScan0($iW, $iH)
$hGfx = _GDIPlus_ImageGetGraphicsContext($hBitmap)
_GDIPlus_GraphicsClear($hGfx, 0xff888888)
_GDIPlus_GraphicsSetInterpolationMode($hGfx, $GDIP_INTERPOLATIONMODE_HIGHQUALITYBICUBIC)
$hImage = _GDIPlus_BitmapCreateFromHBITMAP($hHBitmap)
$aDim = _GDIPlus_ImageGetDimension($hImage)
If ($iW < $aDim[0] Or $iH < $aDim[1]) Then
$iScaleW = $iW / $aDim[0]
$iScaleH = $iH / $aDim[1]
$iScaleF = ($iScaleW > $iScaleH ? $iScaleH : $iScaleW)
EndIf
$hResize = _GDIPlus_ImageScale($hImage, $iScaleF, $iScaleF)
$aDim = _GDIPlus_ImageGetDimension($hResize)
_GDIPlus_GraphicsDrawImage($hGfx, $hResize, $iW / 2 - $aDim[0] / 2, $iH / 2 - $aDim[1] / 2)
$hBMP = _GDIPlus_BitmapCreateDIBFromBitmap($hBitmap)
$hPrevImage = _SendMessage($hCtrl, $STM_SETIMAGE, $IMAGE_BITMAP, $hBMP)
If $hPrevImage Then _WinAPI_DeleteObject($hPrevImage)
_GDIPlus_BitmapDispose($hResize)
_GDIPlus_BitmapDispose($hImage)
_GDIPlus_GraphicsDispose($hGfx)
_GDIPlus_BitmapDispose($hBitmap)
EndFunc ;==>_ShowScaledPic
Alles anzeigen