﻿#include <APIResConstants.au3>
#include <GDIPlus.au3>
#include <StructureConstants.au3>
#include <WinAPIConstants.au3>
#include <WinAPIGdi.au3>
#include <WinAPIGdiDC.au3>
#include <WinAPIHObj.au3>
#include <WinAPIInternals.au3>
#include <WinAPIRes.au3>
#include <WinAPISys.au3>
#include <WinAPISysInternals.au3>
#include <WinAPISysWin.au3>
#include <WinAPIvkeysConstants.au3>
#include <WindowsConstants.au3>

_GDIPlus_Startup()

Global $aSelect = _SelectRange() ; Rueckgabe: Array[Left, Top, Width, Height]
;~ _ArrayDisplay($aSelect)

_GDIPlus_Shutdown()

Func _SelectRange($iCrossW = 3, $iCrossColor = 0x0000FF, $iSelColor = 0xFF0000, $iTransColor = 0xEEEEEE)
	Local $iVSX = _WinAPI_GetSystemMetrics($SM_XVIRTUALSCREEN)
	Local $iVSY = _WinAPI_GetSystemMetrics($SM_YVIRTUALSCREEN)
	Local $iVSW = _WinAPI_GetSystemMetrics($SM_CXVIRTUALSCREEN)
	Local $iVSH = _WinAPI_GetSystemMetrics($SM_CYVIRTUALSCREEN)

	Local $hBgGui = GUICreate('FullScreen', $iVSW, $iVSH, $iVSX, $iVSY, $WS_POPUP, BitOR($WS_EX_TOPMOST, $WS_EX_TOOLWINDOW, $WS_EX_LAYERED))

	Local $hMagnifier = GUICreate('Magnifier', 200, 200, 0, 0, $WS_POPUPWINDOW, $WS_EX_TOOLWINDOW)

	Local $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hBgGui)
	Local $hBuffer = _GDIPlus_BitmapCreateFromGraphics($iVSW, $iVSH, $hGraphic)
	Local $hGfxBuffer = _GDIPlus_ImageGetGraphicsContext($hBuffer)
	Local $hPen = _GDIPlus_PenCreate(0xFF000000 + $iCrossColor, $iCrossW)
	Local $hBrush = _GDIPlus_BrushCreateSolid(0xFF000000 + $iSelColor)

	Local $hCursor = _WinAPI_LoadCursor(0, $OCR_NORMAL) ; Cursor als Icon laden
	Local $hCursorBitmap = _GDIPlus_BitmapCreateFromHICON32($hCursor) ; in GDI+ Bitmap umwandeln
	GUISetCursor(16, 1, $hBgGui) ; den richtigen Mauszeiger verstecken

	GUISetState(@SW_SHOW, $hBgGui)
	GUISetState(@SW_SHOW, $hMagnifier)

	Local $aOldPos[4] = [$iVSX, $iVSY, 0, 0], $aInfo[5], $aSelCoord[4] = [0, 0, 0, 0], $iX, $iY
	Do
		$aInfo = GUIGetCursorInfo($hBgGui)
		If $aInfo[0] <> $aOldPos[0] Or $aInfo[1] <> $aOldPos[1] Then
			$aOldPos[0] = $aInfo[0]
			$aOldPos[1] = $aInfo[1]
			_ShowMagnifier($hMagnifier, $aInfo)
		EndIf
		If $aInfo[2] Then ; wenn linke Maustaste gedrueckt
			If Not $aOldPos[2] Then ; wenn vorher nicht gedrueckt
				$aOldPos[2] = 1
				$aSelCoord[0] = $aInfo[0]
				$aSelCoord[1] = $aInfo[1]
			EndIf
			$aSelCoord[2] = Abs($aInfo[0] - $aSelCoord[0])
			$aSelCoord[3] = Abs($aInfo[1] - $aSelCoord[1])
			$iX = $aInfo[0] > $aSelCoord[0] ? $aSelCoord[0] : $aSelCoord[0] - $aSelCoord[2]
			$iY = $aInfo[1] > $aSelCoord[1] ? $aSelCoord[1] : $aSelCoord[1] - $aSelCoord[3]
		Else ; wenn linke Maustaste losgelassen
			$aOldPos[2] = 0
		EndIf
		_GDIPlus_GraphicsClear($hGfxBuffer, 0xFF000000 + $iTransColor)
		_GDIPlus_GraphicsFillRect($hGfxBuffer, $iX, $iY, $aSelCoord[2], $aSelCoord[3], $hBrush)
		_GDIPlus_GraphicsDrawRect($hGfxBuffer, $iX, $iY, $aSelCoord[2], $aSelCoord[3])
		_GDIPlus_GraphicsDrawLine($hGfxBuffer, $iVSX, $aInfo[1], $iVSW, $aInfo[1], $hPen)
		_GDIPlus_GraphicsDrawLine($hGfxBuffer, $aInfo[0], $iVSY, $aInfo[0], $iVSH, $hPen)
		_GDIPlus_GraphicsDrawImage($hGfxBuffer, $hCursorBitmap, $aInfo[0], $aInfo[1]) ; den Cursor (Bitmap) zeichnen
		_BlendBitmap($hBgGui, $hBuffer, 80)
		Sleep(10)
	Until $aInfo[3] ; warten, bis rechte Maustaste gedrueckt
	GUIDelete($hBgGui)
	GUIDelete($hMagnifier)
	_GDIPlus_PenDispose($hPen)
	_GDIPlus_BrushDispose($hBrush)
	_GDIPlus_GraphicsDispose($hGfxBuffer)
	_GDIPlus_BitmapDispose($hBuffer)
	_GDIPlus_BitmapDispose($hCursorBitmap)
	_GDIPlus_GraphicsDispose($hGraphic)
	_WinAPI_DestroyCursor($hCursor)
	$aSelCoord[0] += $iVSX
	$aSelCoord[1] += $iVSY
	Return $aSelCoord
EndFunc   ;==>_SelectRange

Func _BlendBitmap($hWnd, $hImage, $iOpacity)
	Local $hDestDC, $hSrcDC, $hBMP, $hOld, $pSize, $tSize, $tPtSrc, $pPtSrc, $pBlend, $tBlend
	$hDestDC = _WinAPI_GetDC($hWnd)
	$hSrcDC = _WinAPI_CreateCompatibleDC($hDestDC)
	$hBMP = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
	$hOld = _WinAPI_SelectObject($hSrcDC, $hBMP)
	$tSize = DllStructCreate($tagSIZE)
	$pSize = DllStructGetPtr($tSize)
	$tSize.X = _GDIPlus_ImageGetWidth($hImage)
	$tSize.Y = _GDIPlus_ImageGetHeight($hImage)
	$tPtSrc = DllStructCreate($tagPOINT)
	$pPtSrc = DllStructGetPtr($tPtSrc)
	$tBlend = DllStructCreate($tagBLENDFUNCTION)
	$pBlend = DllStructGetPtr($tBlend)
	DllStructSetData($tBlend, "Alpha", $iOpacity)
	DllStructSetData($tBlend, "Format", 1)
	_WinAPI_UpdateLayeredWindow($hWnd, $hDestDC, $pPtSrc, $pSize, $hSrcDC, $pPtSrc, 0, $pBlend, $ULW_ALPHA)
;~     _WinAPI_UpdateLayeredWindow($hWnd, $hDestDC, 0, $pSize, $hSrcDC, $pPtSrc, 0xEEEEEE, 0, $ULW_COLORKEY)
	_WinAPI_ReleaseDC($hWnd, $hDestDC)
	_WinAPI_SelectObject($hSrcDC, $hOld)
	_WinAPI_DeleteObject($hBMP)
	_WinAPI_DeleteDC($hSrcDC)
EndFunc   ;==>_BlendBitmap

Func _ShowMagnifier($hWnd, $aInfo)
	Local $hSrcDC, $hDestDC, $iLeft, $iTop
	$hDestDC = _WinAPI_GetDC($hWnd)
	If @error Then Return
	$hSrcDC = _WinAPI_GetDC(0)
	If Not @error Then
		$iLeft = $aInfo[0] - 25
		$iTop = $aInfo[1] - 25
		_WinAPI_StretchBlt($hDestDC, 0, 0, 200, 200, $hSrcDC, $iLeft, $iTop, 50, 50, $SRCCOPY)
		_WinAPI_ReleaseDC(0, $hDestDC)
	EndIf
	_WinAPI_ReleaseDC($hWnd, $hSrcDC)
EndFunc   ;==>_ShowMagnifier
