﻿#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
