﻿#include <Array.au3>
#include <GDIPlus.au3>
#include <StructureConstants.au3>
#include <WinAPIConstants.au3>
#include <WinAPIGdiDC.au3>
#include <WinAPIHObj.au3>
#include <WinAPISysInternals.au3>
#include <WinAPISysWin.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 $hDummy = GUICreate('Dummy', $iVSW, $iVSH, $iVSX, $iVSY, $WS_POPUP, BitOR($WS_EX_TOOLWINDOW, $WS_EX_LAYERED)) ; Dummy-Gui nur, damit man mit der Maus nicht "durchklicken" kann
;~     GUISetBkColor($iTransColor)
    WinSetTrans($hDummy, '', 10)

    Local $hBgGui = GUICreate('FullScreen', $iVSW, $iVSH, $iVSX, $iVSY, $WS_POPUP, BitOR($WS_EX_TOPMOST, $WS_EX_TOOLWINDOW, $WS_EX_LAYERED), $hDummy)
;~     GUISetBkColor($iTransColor)
;~     GUISetCursor(3, 1, $hBgGui)

    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 $hMagnifier = GUICreate('Magnifier', 200, 200, 0, 0, $WS_POPUPWINDOW, $WS_EX_TOOLWINDOW, $hDummy) ; Vergrößerungsfensters / Breite und Höhe jeweils -5, damit das Kreuz mittig ist (ermittelt durch probieren)

    GUISetState(@SW_SHOW, $hDummy)
    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)
        _BlendBitmap($hBgGui, $hBuffer, 60)
        Sleep(10)
    Until $aInfo[3] ; warten, bis rechte Maustaste gedrueckt
    GUIDelete($hBgGui)
    GUIDelete($hDummy)
    GUIDelete($hMagnifier)
    _GDIPlus_PenDispose($hPen)
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_GraphicsDispose($hGfxBuffer)
    _GDIPlus_BitmapDispose($hBuffer)
    _GDIPlus_GraphicsDispose($hGraphic)
    $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   ;==>Lupe