﻿#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_AU3Check_Parameters=-w 3 -w 5
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include-once
#include <GDIPlus.au3>
#include <StaticConstants.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>

;===============================================================================
; Name:             : _GuiCtrlSetImageEx
; Description:		: Funktion zum laden von Grafikdateien (alle die GDI+ unterstützt) in ein Pic-Control
;                     Dabei werden die Grafikdateien proportional in das Pic-Control eingepasst (skaliert)
;                     Die Grafikdatei darf auch als Variable mit Binärdaten übergeben werden.
; Syntax:           : _GuiCtrlSetImageEx([$idPic][, $sImgFile][, $fUpscale][, $iBkColor][, $fDebugInfo])
; Parameter(s):		: $idPic = ID des Pic-Control (kann auch "Default" oder "-1" sein)
;                     $sImgFile = der Pfad und Dateiname der Grafikdatei oder die Grafikdatei als Variable mit Binärdaten
;                     $fUpscale = falls TRUE, wird die Grafikdatei auf die Maße des Pic-Control hochscaliert
;                     $iBkColor = Hintergrundfarbe (Format: ARGB) für das Pic-Control
;                     $fDebugInfo = falls TRUE, werden ein paar Debugdaten in der Console angezeigt
; Requirement:		: oben stehende Includes und AutoIt-Version >= v3.3.12.0
; Return Value(s):	: Im Erfolgsfall wird TRUE zurückgegeben (@error = 0). Ansonsten:
;                     @error = 1 wenn das Pic-Control nicht existiert
;                     @error = 2 wenn die Abmessungen des Pic-Control nicht gelesen werden konnten
;                     @error = 3 wenn die Grafikdatei nicht geladen werden konnte
; Author(s):		: Oscar (www.autoit.de)
; Version / Date:   : 1.1.0.0 / 14.07.2015
;===============================================================================
Func _GuiCtrlSetImageEx($idPic = Default, $sImgFile = '', $fUpscale = False, $iBkColor = 0x00000000, $fDebugInfo = False)
	Local $hPic, $hParent, $aPos, $hGfx, $hImage, $hBitmap, $hGfxCtxt, $iImgWidth, $iImgHeight, $hBitmapScaled, $hBMP
	Local $iScalefactor = 1, $iFactorW, $iFactorH, $iScaleWidth, $iScaleHeight, $iError = 0
	If $idPic = Default Or $idPic <= 0 Then $idPic = _WinAPI_GetDlgCtrlID(GUICtrlGetHandle($idPic))
	$hPic = GUICtrlGetHandle($idPic) ; das Handle vom Pic-Control holen
	If Not IsHWnd($hPic) Then Return SetError(1, 0, 0) ; wenn kein Handle, dann Funktion mit Fehlermeldung verlassen
	$hParent = _WinAPI_GetParent($hPic) ; das Fenster des Pic-Controls ermitteln
	GUISetState(@SW_LOCK, $hParent) ; das Fenster sperren
	$aPos = ControlGetPos($hParent, '', $idPic) ; die Koordinaten und Abmessungen des Pic-Control ermitteln
	_GDIPlus_Startup() ; GDI-Plus starten
	$hBitmap = _GDIPlus_BitmapCreateFromScan0($aPos[2], $aPos[3]) ; Eine Bitmap erstellen
	$hGfxCtxt = _GDIPlus_ImageGetGraphicsContext($hBitmap) ; Graphic-Context der Bitmap holen
	_GDIPlus_GraphicsSetInterpolationMode($hGfxCtxt, $GDIP_INTERPOLATIONMODE_HIGHQUALITYBICUBIC)
	_GDIPlus_GraphicsClear($hGfxCtxt, $iBkColor) ; Die Bitmap mit der Hintergrundfarbe füllen
	If IsBinary($sImgFile) Then ; wenn die Grafikdatei als Binärdaten übergeben wurde, dann...
		$hImage = _GDIPlus_BitmapCreateFromMemory($sImgFile) ; die Grafikdatei aus den Binärdaten laden
		If @error Then $iError = 3 ; wenn das laden der Binärdaten fehlgeschlagen ist, dann Errorcode speichern
	Else ; sonst (Grafikdatei befindet sich auf Datenträger)...
		$hImage = _GDIPlus_BitmapCreateFromFile($sImgFile) ; die Grafikdatei laden
		If @error Then $iError = 3 ; wenn das laden der Datei fehlgeschlagen ist, dann Errorcode speichern
	EndIf
	If Not $iError Then ; wenn kein Fehler aufgetreten ist, dann...
		$iImgWidth = _GDIPlus_ImageGetWidth($hImage) ; die Breite der Grafikdatei holen
		$iImgHeight = _GDIPlus_ImageGetHeight($hImage) ; die Höhe der Grafikdatei holen
		; wenn die Größe des Pic-Controls kleiner als die Grafikdatei ist oder $fUpscale = True,
		; dann muss die Grafikdatei skaliert werden (Scalefactor berechnen):
		If ($aPos[2] < $iImgWidth Or $aPos[3] < $iImgHeight) Or ($fUpscale = True) Then
			$iFactorW = $aPos[2] / $iImgWidth
			$iFactorH = $aPos[3] / $iImgHeight
			$iScalefactor = ($iFactorW > $iFactorH ? $iFactorH : $iFactorW)
		EndIf
		$iScaleWidth = Int($iImgWidth * $iScalefactor) ; die Breite der skalierten Grafikdatei berechnen
		$iScaleHeight = Int($iImgHeight * $iScalefactor) ; die Höhe der skalierten Grafikdatei berechnen
		If $fDebugInfo Then ; Debuginformationen ausgeben, wenn gewünscht:
			ConsoleWrite(StringFormat('Ctrl-Size: %i x %i\n', $aPos[2], $aPos[3]))
			ConsoleWrite(StringFormat('Img-Size: %i x %i\n', $iImgWidth, $iImgHeight))
			ConsoleWrite(StringFormat('Scale-Factor: %f\n', $iScalefactor))
			ConsoleWrite(StringFormat('Scale-Size: %i x %i\n\n', $iScaleWidth, $iScaleHeight))
		EndIf
		$hBitmapScaled = _GDIPlus_ImageResize($hImage, $iScaleWidth, $iScaleHeight) ; die Grafikdatei skalieren
		; und zentriert in die Bitmap zeichnen:
		_GDIPlus_GraphicsDrawImageRect($hGfxCtxt, $hBitmapScaled, ($aPos[2] - $iScaleWidth) / 2, ($aPos[3] - $iScaleHeight) / 2, $iScaleWidth, $iScaleHeight)
	EndIf
	_WinAPI_DeleteObject(GUICtrlSendMsg($idPic, $STM_SETIMAGE, $IMAGE_BITMAP, -1)) ; den alten Inhalt des Pic-Control löschen
	$hBMP = _GDIPlus_BitmapCreateDIBFromBitmap($hBitmap) ; HBitmap von der Bitmap erstellen
	_WinAPI_DeleteObject(GUICtrlSendMsg($idPic, $STM_SETIMAGE, $IMAGE_BITMAP, $hBMP)) ; und an das Pic-Control senden
	GUISetState(@SW_UNLOCK, $hParent) ; und wieder freigeben
	; zum Schluss noch aufräumen...
	_WinAPI_DeleteObject($hBMP)
	_GDIPlus_BitmapDispose($hBitmapScaled)
	_GDIPlus_GraphicsDispose($hGfxCtxt)
	_GDIPlus_BitmapDispose($hBitmap)
	_GDIPlus_GraphicsDispose($hGfx)
	_GDIPlus_BitmapDispose($hImage)
	_GDIPlus_Shutdown()
	Return SetError($iError, 0, $iError = 0)
EndFunc   ;==>_GuiCtrlSetImageEx
