#cs
RangeBar-Control

- Auswahl eines Werte-Bereiches durch Verschieben der Unter- und/oder Obergrenze (klicken-ziehen)
- Funktionalität eines Sliders aber von zwei Seiten einstellbar
- Optik einer Progressbar
- einstellbar:
  Farbe gewählter Bereich (Range),
  Farbe ungenutzter Bereich (BackColor),
  Farbe Marker (Begrenzungen der Range),
  Farbe Ticks,
  Farbe Label
- Ticks u. Label optional, Label enthalten zwangsweise Ticks
- Setzen Anzahl Ticks (optional auch gleich Limit)
- nach Anzahl Ticks autom. Berechnung der Labelwerte
- Positionierung der Label mittig unter den Ticks nach tatsächlicher Schriftbreite
- Formatierung der Label als Dezimaldarstellung (Standard) oder Stunden / Minuten Darstellung
- Setzen Limit (unterster, oberster Wert)

- Hinweis:
  Durch Pixelweises Verschieben der Range (um möglichst hohe Genauigkeit der Werte zu erreichen) kann nur relativ langsam
  die Bereichsgrenze gezogen werden. Man "rutscht" recht schnell ab.

- In Planung:
  Verschieben der gesamten Range durch STRG+MouseMove
  Style für vertikale Anordnung des Ctrl
  Style für Ticks oberhalb der Bar
  Möglichkeit mehrere Ctrl gleichzeitig zu erstellen
#ce

#include-once
#include <GDIPlus.au3>
#include <WindowsConstants.au3>

#region - RangeBar-Style
Global Const $RBS_HORICONTAL        = 0x1  ; Ctrl als horizontale Bar
Global Const $RBS_VERTICAL          = 0x2  ; noch nicht implementiert
Global Const $RBS_TICKS_BELOW_LEFT  = 0x4  ; Ticks (und Label falls gesetzt) unten oder bei VERTICAL links
Global Const $RBS_TICKS_ONTOP_RIGHT = 0x8  ; Ticks (und Label falls gesetzt) oben oder bei VERTICAL rechts
Global Const $RBS_LABEL             = 0x10 ; Beschriftung der Ticks mit den Werten
Global Const $RBS_BASE60            = 0x20 ; Verwendung bei Stunden- oder Minutendarstellung, formatiert auf [h]h:mm bzw. [m]m:ss
Global Const $RBS_DEFAULT           = BitOR($RBS_HORICONTAL,$RBS_TICKS_BELOW_LEFT)
#endregion

Global $tLeftMarker, $tRightMarker, $tRange, $bSetCursor = False ; <== zur Positionskontrolle Maus über Marker/Range
Global $bIsActive = False, $aCheck[4] = [-1,-1,-1,-1]  ; <== Kontrolle GUI aktiv/wird bewegt wg. Neuzeichnen Ctrl
Global $Dll_user32 = DllOpen("user32")

Global $guiRange = GUICreate('Bereichsauswahl [Ober- /Untergrenze]')
Global $RangeCtrl = _GDIPlus_RangeBar_Create($guiRange, 20, 10, 300, 17, BitOR($RBS_DEFAULT,$RBS_LABEL,$RBS_BASE60)) ; <== Variablennamen  für Ctrl in _WM_MOVE u. __WinStateCheck ggf. anpassen
GUICtrlCreateLabel('von               bis', 90, 105)
GUICtrlCreateLabel('%', 65, 123)
GUICtrlCreateLabel('Wert', 50, 153)
Global $inLeftpercent = GUICtrlCreateInput('', 80, 120, 40, 20)
Global $inRightpercent = GUICtrlCreateInput('', 140, 120, 40, 20)
Global $inLeftvalue = GUICtrlCreateInput('', 80, 150, 40, 20)
Global $inRightvalue = GUICtrlCreateInput('', 140, 150, 40, 20)
GUICtrlCreateLabel('=',187, 153)
Global $inValue = GUICtrlCreateInput('', 200, 150, 40, 20)
GUISetState()


AdlibRegister('__WinStateCheck', 100)
GUIRegisterMsg($WM_MOUSEMOVE, '_WM_MOUSEMOVE')


; === Range neu setzen
_GDIPlus_RangeBar_SetRange($RangeCtrl, 20, 50)

; === Tick-Anzahl und Limit setzen
_GDIPlus_RangeBar_SetTickLimit($RangeCtrl, 6, '6 18')

Do
Until GUIGetMsg() = -3
_GDIPlus_RangeBar_Dispose($RangeCtrl)




; =================================================================================================
; Range-Ctrl erstellen
; Rückgabe Strukturvariable zur Verwendung in den Einzelfunktionen
; Parameter: $hWnd          - Handle der GUI, in der das Ctrl erstellt wird
;            $x             - X-Position der Bar des Ctrl, Zeichnungsfläche beginnt bei $x-20 !!
;            $y             - Y-Position der Bar des Ctrl
;            $width         - Breite der Bar des Ctrl, Zeichnungsbreite = 20+$width+20
;            $height        - Höhe der Bar des Ctrl, Zeichnungshöhe (inkl. Platz f. Ticks u. Label) = $height+40
;            $iStyle        - -1 od. Default für $RBS_DEFAULT, Details s. Konstantendeklaration
;            $bGDIstart     - wenn GDI noch nicht initialisiert wurde = True (Standard)
;            $iRangeColor   - Farbe für den gewählten Bereich, -1 od. Default für 0x0000FF
;            $iBackColor    - Farbe für den ungentzten Bereich, -1 od. Default für 0x696969
;            $iMarkerColor  - Farbe der Bereichsbegrenzer, -1 od. Default für 0xFFFFFF
;            $iTickColor    - Farbe der Skalierung (Ticks), -1 od. Default für 0xA9A9A9
;            $iLabelColor   - Farbe der Tickbeschriftung, -1 od. Default für 0xB22222
;            $iTrans        - Transparenz 0 - 255, Standard: 255 = keine Transparenz
; =================================================================================================
Func _GDIPlus_RangeBar_Create($hWnd, $x, $y, $width, $height = 17, $iStyle = -1, $bGDIstart = True, $iRangeColor = 0x0000FF, _
		$iBackColor = 0x696969, $iMarkerColor = 0xFFFFFF, $iTickColor = 0xA9A9A9, $iLabelColor = 0xB22222, $iTrans=255) ; Range-Ctrl erstellen
	If $iStyle       = -1 Or IsKeyword($iStyle)       Then $iStyle       = $RBS_DEFAULT
	If $bGDIstart    = -1 Or IsKeyword($bGDIstart)    Then $bGDIstart    = True
	If $iRangeColor  = -1 Or IsKeyword($iRangeColor)  Then $iRangeColor  = 0x0000FF
	If $iBackColor   = -1 Or IsKeyword($iBackColor)   Then $iBackColor   = 0x696969
	If $iMarkerColor = -1 Or IsKeyword($iMarkerColor) Then $iMarkerColor = 0xFFFFFF
	If $iTickColor   = -1 Or IsKeyword($iTickColor)   Then $iTickColor   = 0xA9A9A9
	If $iLabelColor  = -1 Or IsKeyword($iLabelColor)  Then $iLabelColor  = 0xB22222
	Local $hGraphic, $hBrushRange, $hBrushBack, $hPenMarker, $hPenTicks
	Local $hFormat, $hFamily, $hFont, $hBrushFont, $hBitmapBar, $hBitmapTicks, $hBitmapLabel, $tLayout, $aInfo, $chrX
	Local $hImageBar, $hImageTicks, $hImageLabel, $aCtrlSize[4] = [$x,$y,$width,$height]
	Local $sRangeColor  = '0x' & Hex($iTrans, 2) & Hex($iRangeColor, 6)
	Local $sBackColor   = '0x' & Hex($iTrans, 2) & Hex($iBackColor, 6)
	Local $sMarkerColor = '0x' & Hex($iTrans, 2) & Hex($iMarkerColor, 6)
	Local $sTickColor   = '0x' & Hex($iTrans, 2) & Hex($iTickColor, 6)
	Local $sLabelColor  = '0x' & Hex($iTrans, 2) & Hex($iLabelColor, 6)
	Local $xLMark = 0, $xRMark = 100 ; Marker links und rechts
	Local $tRangeCtrl = DllStructCreate( _       ; Struktur zur Aufnahme aller Ctrl-Infos
			"int Style;"        & _  ; Ctrl Style
			"hwnd Graphics;"    & _  ; Graphics Handle
			"hwnd BrushRange;"  & _  ; Brush Range Handle
			"hwnd BrushBack;"   & _  ; Brush Hintergrund Handle
			"hwnd PenMarker;"   & _  ; Pen Marker Handle
			"hwnd PenTicks;"    & _  ; Pen Tick Handle
			"hwnd Format;"      & _  ; Stringformat Handle
			"hwnd Family;"      & _  ; FontFamily Handle
			"hwnd Font;"        & _  ; Font Handle
			"hwnd BrushFont;"   & _  ; Brush Font Handle
			"hwnd Bitmap[3];"   & _  ; für Buffer [Bar,Ticks,Label]
			"hwnd Image[3];"    & _  ; für Buffer [Bar,Ticks,Label]
			"int RECTBar[4];"   & _  ; Koordinaten Bar [$x,$y,$width,$height]
			"int RECTCtrl[4];"  & _  ; Koordinaten ges. Ctrl inkl. Ticks/Label (sofern gesetzt) [L,T,R,B]
			"int Marker[2];"    & _  ; X-Koordinaten Marker [links,rechts] px relativ zur Bar
			"int Ticks;"        & _  ; Anzahl Markierungen (Minimum Anfang u. Ende - automatisch)
			"char Label[128];"  & _  ; Beschriftung unter den Ticks (Limit, Skalierung)
			"int RECTleft[4];"  & _  ; RECT linker Marker [L,T,R,B]
			"int RECTright[4];")     ; RECT rechter Marker [L,T,R,B]
	If $bGDIstart Then _GDIPlus_Startup()                                        ; Initialize GDI+ library
	$hFormat     = _GDIPlus_StringFormatCreate(0)                                ; Create string format object
	$hFamily     = _GDIPlus_FontFamilyCreate("Arial")                            ; Create font family
	$hFont       = _GDIPlus_FontCreate($hFamily, 8)                              ; Create font
	$hBrushRange = _GDIPlus_BrushCreateSolid($sRangeColor)                       ; Create brush used range
	$hBrushBack  = _GDIPlus_BrushCreateSolid($sBackColor)                        ; Create brush unused range
	$hPenMarker  = _GDIPlus_PenCreate($sMarkerColor)                             ; Create pen marker
	$hGraphic    = _GDIPlus_GraphicsCreateFromHWND($hWnd)                        ; Create graphics object
	$hBitmapBar  = _GDIPlus_BitmapCreateFromGraphics($width, $height, $hGraphic) ; Create bmp Bar
	$hImageBar   = _GDIPlus_ImageGetGraphicsContext($hBitmapBar)                 ; Create buffer Bar
	_GDIPlus_GraphicsSetSmoothingMode($hImageBar, 4)
	Select
		Case BitAND($iStyle, $RBS_LABEL)
			$hPenTicks    = _GDIPlus_PenCreate($sTickColor)                              ; Create pen ticks
			$hBitmapTicks = _GDIPlus_BitmapCreateFromGraphics($width, 6, $hGraphic)      ; Create bitmap ticks
			$hImageTicks  = _GDIPlus_ImageGetGraphicsContext($hBitmapTicks)              ; Create buffer ticks
			$hBrushFont   = _GDIPlus_BrushCreateSolid($sLabelColor)                      ; Create brush label
			$hBitmapLabel = _GDIPlus_BitmapCreateFromGraphics($width +40, 12, $hGraphic) ; Create bmp label
			$hImageLabel  = _GDIPlus_ImageGetGraphicsContext($hBitmapLabel)              ; Create buffer label
			_GDIPlus_GraphicsSetSmoothingMode($hImageTicks, 4)
			_GDIPlus_GraphicsSetSmoothingMode($hImageLabel, 4)
			$aCtrlSize[0] -= 20
			$aCtrlSize[2] += 40
			$aCtrlSize[3] += 20
		Case BitAND($iStyle, $RBS_TICKS_BELOW_LEFT)
			$hPenTicks    = _GDIPlus_PenCreate($sTickColor)
			$hBitmapTicks = _GDIPlus_BitmapCreateFromGraphics($width, 6, $hGraphic)
			$hBitmapLabel = _GDIPlus_BitmapCreateFromGraphics($width +40, 12, $hGraphic)
			$hImageTicks  = _GDIPlus_ImageGetGraphicsContext($hBitmapTicks)
			_GDIPlus_GraphicsSetSmoothingMode($hImageTicks, 4)
			$aCtrlSize[3] += 8
	EndSelect
	DllStructSetData($tRangeCtrl, "Style"     , $iStyle)
	DllStructSetData($tRangeCtrl, "Graphics"  , $hGraphic)
	DllStructSetData($tRangeCtrl, "BrushRange", $hBrushRange)
	DllStructSetData($tRangeCtrl, "BrushBack" , $hBrushBack)
	DllStructSetData($tRangeCtrl, "PenMarker" , $hPenMarker)
	DllStructSetData($tRangeCtrl, "PenTicks"  , $hPenTicks)
	DllStructSetData($tRangeCtrl, "Format"    , $hFormat)
	DllStructSetData($tRangeCtrl, "Family"    , $hFamily)
	DllStructSetData($tRangeCtrl, "Font"      , $hFont)
	DllStructSetData($tRangeCtrl, "BrushFont" , $hBrushFont)
	DllStructSetData($tRangeCtrl, "Bitmap"    , $hBitmapBar, 1)
	DllStructSetData($tRangeCtrl, "Bitmap"    , $hBitmapTicks, 2)
	DllStructSetData($tRangeCtrl, "Bitmap"    , $hBitmapLabel, 3)
	DllStructSetData($tRangeCtrl, "Image"     , $hImageBar, 1)
	DllStructSetData($tRangeCtrl, "Image"     , $hImageTicks, 2)
	DllStructSetData($tRangeCtrl, "Image"     , $hImageLabel, 3)
	DllStructSetData($tRangeCtrl, "RECTBar"   , $x, 1)
	DllStructSetData($tRangeCtrl, "RECTBar"   , $y, 2)
	DllStructSetData($tRangeCtrl, "RECTBar"   , $width, 3)
	DllStructSetData($tRangeCtrl, "RECTBar"   , $height, 4)
	DllStructSetData($tRangeCtrl, "RECTCtrl"  , $aCtrlSize[0], 1)
	DllStructSetData($tRangeCtrl, "RECTCtrl"  , $aCtrlSize[1], 2)
	DllStructSetData($tRangeCtrl, "RECTCtrl"  , $aCtrlSize[0] +$aCtrlSize[2], 3)
	DllStructSetData($tRangeCtrl, "RECTCtrl"  , $aCtrlSize[1] +$aCtrlSize[3], 4)
	DllStructSetData($tRangeCtrl, "Marker"    , 0, 1)
	DllStructSetData($tRangeCtrl, "Marker"    , $width, 2)
	DllStructSetData($tRangeCtrl, "Ticks"     , 2)
	DllStructSetData($tRangeCtrl, "Label"     , '0 100')
	DllStructSetData($tRangeCtrl, "RECTleft"  , $x - 4, 1)
	DllStructSetData($tRangeCtrl, "RECTleft"  , $y - 2, 2)
	DllStructSetData($tRangeCtrl, "RECTleft"  , $x + 4, 3)
	DllStructSetData($tRangeCtrl, "RECTleft"  , $y + $height + 2, 4)
	DllStructSetData($tRangeCtrl, "RECTright" , $x + $width - 4, 1)
	DllStructSetData($tRangeCtrl, "RECTright" , $y - 2, 2)
	DllStructSetData($tRangeCtrl, "RECTright" , $x + $width + 4, 3)
	DllStructSetData($tRangeCtrl, "RECTright" , $y + $height + 2, 4)
	Return $tRangeCtrl
EndFunc   ;==>_GDIPlus_RangeBar_Create

; =================================================================================================
; Anzahl Ticks setzen, min. 2 (Anfang u. Ende), Zehner-Teilung = 11 etc.
; $sLabel = erster und letzter Wert, Leerzeichen als Trenner
; Berechnung Labelwerte für einzelne Ticks automatisch
; =================================================================================================
Func _GDIPlus_RangeBar_SetTickLimit(ByRef $tRangeCtrl, $iTickCount = 2, $sLabel = '') ; Anzahl Ticks setzen, min. 2 (Anfang u. Ende), Zehner-Teilung = 11 etc.
	Local $iMode = 6
	If StringLen($sLabel) Then DllStructSetData($tRangeCtrl, "Label", StringReplace($sLabel, ',', '.')) ; $sLabel = erster und letzter Wert, Leerzeichen als Trenner
	If $iTickCount < 2 Then $iTickCount = 2
	DllStructSetData($tRangeCtrl, "Ticks", $iTickCount)
	__GDIPlus_RangeBar_Draw($tRangeCtrl, $iMode)
EndFunc   ;==>_GDIPlus_RangeBar_SetTickLimit

; =================================================================================================
; Limit setzen (Anfangswert / Endwert) als Leerzeichen getrennter String
; =================================================================================================
Func _GDIPlus_RangeBar_SetLimit(ByRef $tRangeCtrl, $sLimit = '0 100')
	Local $tmp = StringSplit($sLimit, ' '), $iMode = 4
	If $tmp[0] <> 2 Then Return SetError(1, 0, 0)
	DllStructSetData($tRangeCtrl, "Label", $sLimit)
	__GDIPlus_RangeBar_Draw($tRangeCtrl, $iMode)
	Return 1
EndFunc   ;==>_GDIPlus_RangeBar_SetLimit

; =================================================================================================
; Range setzen, Anfang/Ende als Prozentwert
; =================================================================================================
Func _GDIPlus_RangeBar_SetRange(ByRef $tRangeCtrl, $iStartRange = 0, $iEndRange = 100) ; Range Anfang/Ende als Prozentwert
	If $iEndRange < $iStartRange Then
		Local $tmp = $iEndRange
		$iEndRange = $iStartRange
		$iStartRange = $tmp
	EndIf
	Local $iMode = 4
	Local $x = DllStructGetData($tRangeCtrl, "RECTBar", 1)
	Local $width = DllStructGetData($tRangeCtrl, "RECTBar", 3)
	Local $xLeft = Int($iStartRange * $width / 100)
	Local $xRight = Int($iEndRange * $width / 100)
	DllStructSetData($tRangeCtrl, "Marker", $xLeft, 1)
	DllStructSetData($tRangeCtrl, "Marker", $xRight, 2)
	DllStructSetData($tRangeCtrl, "RECTleft", $x + $xLeft - 8, 1)
	DllStructSetData($tRangeCtrl, "RECTleft", $x + $xLeft + 8, 3)
	DllStructSetData($tRangeCtrl, "RECTright", $x + $xRight - 8, 1)
	DllStructSetData($tRangeCtrl, "RECTright", $x + $xRight + 8, 3)
	__GDIPlus_RangeBar_Draw($tRangeCtrl, $iMode)
EndFunc   ;==>_GDIPlus_RangeBar_SetRange

; =================================================================================================
; Range-Ctrl neu zeichnen
; $iDrawMode: 1- nur Bar, 2- nur Ticks, 4- nur Label (Kombinationen), enthaltenes Element wird gezeichnet
; =================================================================================================
Func __GDIPlus_RangeBar_Draw(ByRef $tRangeCtrl, $iDrawMode = 1, $iWndColor = 0xD4D0C8) ; Range-Ctrl zeichnen
	Local $hGraphic     = DllStructGetData($tRangeCtrl, "Graphics")
	Local $hBrushRange  = DllStructGetData($tRangeCtrl, "BrushRange")
	Local $hBrushBack   = DllStructGetData($tRangeCtrl, "BrushBack")
	Local $hPenMarker   = DllStructGetData($tRangeCtrl, "PenMarker")
	Local $hPenTicks    = DllStructGetData($tRangeCtrl, "PenTicks")
	Local $hBitmapBar   = DllStructGetData($tRangeCtrl, "Bitmap", 1)
	Local $hBitmapTicks = DllStructGetData($tRangeCtrl, "Bitmap", 2)
	Local $hBitmapLabel = DllStructGetData($tRangeCtrl, "Bitmap", 3)
	Local $hImageBar    = DllStructGetData($tRangeCtrl, "Image", 1)
	Local $hImageTicks  = DllStructGetData($tRangeCtrl, "Image", 2)
	Local $hImageLabel  = DllStructGetData($tRangeCtrl, "Image", 3)
	Local $iStyle       = DllStructGetData($tRangeCtrl, "Style")
	Local $x            = DllStructGetData($tRangeCtrl, "RECTBar", 1)
	Local $y            = DllStructGetData($tRangeCtrl, "RECTBar", 2)
	Local $width        = DllStructGetData($tRangeCtrl, "RECTBar", 3)
	Local $height       = DllStructGetData($tRangeCtrl, "RECTBar", 4)
	Local $lM           = DllStructGetData($tRangeCtrl, "Marker", 1)
	Local $rM           = DllStructGetData($tRangeCtrl, "Marker", 2)
	Local $ticks        = DllStructGetData($tRangeCtrl, "Ticks")
	Local $drawBar = False, $drawTicks = False, $drawLabel = False
	If BitAND($iDrawMode, 1) Then $drawBar   = True
	If BitAND($iDrawMode, 2) Then $drawTicks = True
	If BitAND($iDrawMode, 4) Then $drawLabel = True
	Local $hFormat, $hFamily, $hFont, $hBrushFont, $tLayout, $aInfo, $chrX
	Local $rangeWidth = $rM - $lM, $aLabel, $LabelStep, $text
	Local $left = $x, $step, $bTicks = False, $bLabel = False, $bB60 = False
	If BitAND($iStyle, BitOR($RBS_TICKS_BELOW_LEFT,$RBS_TICKS_ONTOP_RIGHT)) Then $bTicks = True
	If BitAND($iStyle, $RBS_LABEL) Then $bLabel = True
	If $bLabel Then
		If BitAND($iStyle, $RBS_BASE60) Then $bB60 = True
		$aLabel = StringSplit(DllStructGetData($tRangeCtrl, "Label"), ' ', 2)
		$LabelStep = ($aLabel[1] - $aLabel[0]) / ($ticks - 1)
	EndIf
	If $drawBar Then
		_GDIPlus_GraphicsClear($hImageBar, '0xFF' & Hex($iWndColor, 6))
		_GDIPlus_GraphicsFillRect($hImageBar, 0, 0, $width, $height, $hBrushBack)
		_GDIPlus_GraphicsFillRect($hImageBar, $lM, 0, $rangeWidth, $height, $hBrushRange)
		_GDIPlus_GraphicsDrawLine($hImageBar, $lM, 0, $lM, $height - 1, $hPenMarker)
		_GDIPlus_GraphicsDrawLine($hImageBar, $rM-1, 0, $rM-1, $height - 1, $hPenMarker)
		_GDIPlus_GraphicsDrawImageRect($hGraphic, $hBitmapBar, $x, $y, $width, $height)
	EndIf
	If $drawLabel And $bLabel Then
		_GDIPlus_GraphicsClear($hImageLabel, '0xFF' & Hex($iWndColor, 6))
		$hFormat    = DllStructGetData($tRangeCtrl, "Format")
		$hFamily    = DllStructGetData($tRangeCtrl, "Family")
		$hFont      = DllStructGetData($tRangeCtrl, "Font")
		$hBrushFont = DllStructGetData($tRangeCtrl, "BrushFont")
	EndIf
	If $drawTicks And $bTicks Then
		_GDIPlus_GraphicsClear($hImageTicks, '0xFF' & Hex($iWndColor, 6))
		If $ticks > 2 Then
			$step = Int($width / ($ticks - 1))
			$left = 0
			For $i = 0 To $ticks - 2
				_GDIPlus_GraphicsDrawLine($hImageTicks, $left, 0, $left, 6, $hPenTicks)
				If $bLabel Then
					Switch $i
						Case 0
							$text = $aLabel[0]
						Case Else
							$text = Round($i * $LabelStep + $aLabel[0], 2)
					EndSwitch
					If $bB60 Then $text = __DecToBase60($text)
					$aInfo = __TextSize($tRangeCtrl, $text)
					$chrX = $x + $left - (Ceiling(DllStructGetData($aInfo[0], "Width") / 2))
					$tLayout = _GDIPlus_RectFCreate($chrX)
					_GDIPlus_GraphicsDrawStringEx($hImageLabel, $text, $hFont, $tLayout, $hFormat, $hBrushFont)
				EndIf
				$left += $step
			Next
			_GDIPlus_GraphicsDrawLine($hImageTicks, $width-1, 0, $width-1, 6, $hPenTicks)
			If $bLabel Then
				$text = $aLabel[1]
				If $bB60 Then $text = __DecToBase60($text)
				$aInfo = __TextSize($tRangeCtrl, $text)
				$chrX = $x + $width -1 - (Ceiling(DllStructGetData($aInfo[0], "Width") / 2))
				$tLayout = _GDIPlus_RectFCreate($chrX)
				_GDIPlus_GraphicsDrawStringEx($hImageLabel, $text, $hFont, $tLayout, $hFormat, $hBrushFont)
			EndIf
		Else
			_GDIPlus_GraphicsDrawLine($hImageTicks, 0, 0, 0, 6, $hPenTicks)
			_GDIPlus_GraphicsDrawLine($hImageTicks, $width-1, 0, $width-1, 6, $hPenTicks)
			If $bLabel Then
				$text = $aLabel[0]
				If $bB60 Then $text = __DecToBase60($aLabel[0])
				$aInfo = __TextSize($tRangeCtrl, $text)
				$chrX = $x - (Ceiling(DllStructGetData($aInfo[0], "Width") / 2))
				$tLayout = _GDIPlus_RectFCreate($chrX)
				_GDIPlus_GraphicsDrawStringEx($hImageLabel, $text, $hFont, $tLayout, $hFormat, $hBrushFont)
				$text = $aLabel[1]
				If $bB60 Then $text = __DecToBase60($aLabel[1])
				$aInfo = __TextSize($tRangeCtrl, $text)
				$chrX = $x + $width -1 - (Ceiling(DllStructGetData($aInfo[0], "Width") / 2))
				$tLayout = _GDIPlus_RectFCreate($chrX, 0, 0, DllStructGetData($aInfo[0], "Height"))
				_GDIPlus_GraphicsDrawStringEx($hImageLabel, $text, $hFont, $tLayout, $hFormat, $hBrushFont)
			EndIf
		EndIf
		_GDIPlus_GraphicsDrawImageRect($hGraphic, $hBitmapTicks, $x, $y+$height+2, $width, 6)
		If $bLabel Then _GDIPlus_GraphicsDrawImageRect($hGraphic, $hBitmapLabel, $x-20, $y+$height+8, $width+40, 12)
	EndIf
EndFunc   ;==>__GDIPlus_RangeBar_Draw

; =================================================================================================
; Rückgabe Array aktueller Start- u. Endwert der Range [links_%,rechts_%,links_Wert,rechts_Wert]
; =================================================================================================
Func _GDIPlus_RangeBar_GetRange($tRangeCtrl) ; Rückgabe aktueller Start- u. Endwert der Range [links_%,rechts_%,links_Wert,rechts_Wert]
	Local $width = DllStructGetData($tRangeCtrl, "RECTBar", 3)
	Local $lMpercent = Round(DllStructGetData($tRangeCtrl, "Marker", 1) * 100 / $width, 2)
	Local $rMpercent = Round(DllStructGetData($tRangeCtrl, "Marker", 2) * 100 / $width, 2)
	Local $aLimit = StringSplit(DllStructGetData($tRangeCtrl, "Label"), ' ', 2)
	Local $FullValue = $aLimit[1] - $aLimit[0]
	Local $aOut[4] = [$lMpercent, _
			$rMpercent, _
			$aLimit[0] + Round($lMpercent * $FullValue / 100, 2), _
			$aLimit[0] + Round($rMpercent * $FullValue / 100, 2)]
	Return $aOut
EndFunc   ;==>_GDIPlus_RangeBar_GetRange

; =================================================================================================
; Controlgröße ermitteln
; tatsächliche Größe je nach Style wird als Einzelwert und als RECT-Struktur zurückgegeben
; =================================================================================================
Func _GDIPlus_RangeBar_GetSize($tRangeCtrl) ; [$x,$y,$width,$height,$tRECT]
	Local $aOut[5] = [ _
	DllStructGetData($tRangeCtrl, "RECTCtrl", 1), _
	DllStructGetData($tRangeCtrl, "RECTCtrl", 2), _
	DllStructGetData($tRangeCtrl, "RECTCtrl", 3) - DllStructGetData($tRangeCtrl, "RECTCtrl", 1), _
	DllStructGetData($tRangeCtrl, "RECTCtrl", 4) - DllStructGetData($tRangeCtrl, "RECTCtrl", 2)]
	$aOut[4] = DllStructCreate("int Left;int Top;int Right;int Bottom")
	DllCall($Dll_user32, 'long', 'SetRect', 'ptr', DllStructGetPtr($aOut[4]), _
		                 'long', $aOut[0], 'long', $aOut[1], 'long', $aOut[0]+$aOut[2], 'long', $aOut[1]+$aOut[3])
	Return $aOut
EndFunc

; =================================================================================================
; Ressourcen löschen
; =================================================================================================
Func _GDIPlus_RangeBar_Dispose($tRangeCtrl, $bGDI_down = True) ; Ressourcen löschen
	_GDIPlus_GraphicsDispose(DllStructGetData($tRangeCtrl, "Graphics"))
	_GDIPlus_BrushDispose(DllStructGetData($tRangeCtrl, "BrushRange"))
	_GDIPlus_BrushDispose(DllStructGetData($tRangeCtrl, "BrushBack"))
	_GDIPlus_BrushDispose(DllStructGetData($tRangeCtrl, "BrushFont"))
	_GDIPlus_PenDispose(DllStructGetData($tRangeCtrl, "PenMarker"))
	_GDIPlus_PenDispose(DllStructGetData($tRangeCtrl, "PenTicks"))
	_GDIPlus_StringFormatDispose(DllStructGetData($tRangeCtrl, "Format"))
	_GDIPlus_FontFamilyDispose(DllStructGetData($tRangeCtrl, "Family"))
	_GDIPlus_FontDispose(DllStructGetData($tRangeCtrl, "Font"))
	_GDIPlus_BitmapDispose(DllStructGetData($tRangeCtrl, "Bitmap"))
	If $bGDI_down Then _GDIPlus_Shutdown()
	DllClose($Dll_user32)
EndFunc   ;==>_GDIPlus_RangeBar_Dispose

#region - Hilfsfunktionen
Func __WinStateCheck() ; prüft ob GDI+ Ctrl neu gezeichnet werden muß
	Local $iWinState = WinGetState($guiRange)
	Local $iMode = 1+2+4
	If BitAND($iWinState, 8) And Not $bIsActive Then
		$bIsActive = True
		Return __GDIPlus_RangeBar_Draw($RangeCtrl, $iMode)
	ElseIf Not BitAND($iWinState, 8) And $bIsActive Then
		$bIsActive = False
	EndIf
	Local $pos = WinGetPos($guiRange)
	Local $moved = 0, $aCheckNew[4] = [$pos[0], $pos[1], $pos[0], $pos[1]]
	For $i = 0 To 3
		If $aCheck[$i] <> $aCheckNew[$i] Then
			$aCheck[$i] = $aCheckNew[$i]
			$moved = 1
		EndIf
	Next
	If $moved Then __GDIPlus_RangeBar_Draw($RangeCtrl, $iMode)
EndFunc   ;==>__WinStateCheck

Func __MoveMarker(ByRef $tRangeCtrl, $iMarker, $iX) ; $iMarker: 0=links, 1=rechts
	Local $x = DllStructGetData($tRangeCtrl, "RECTBar", 1)
	Local $w = DllStructGetData($tRangeCtrl, "RECTBar", 3)
	Local $aElement[2] = ["RECTleft", "RECTright"], $aIndex[2] = [1, 2]
	Local $oldMarker = DllStructGetData($tRangeCtrl, "Marker", $aIndex[$iMarker])
	Local $lM = DllStructGetData($tRangeCtrl, "Marker", 1)
	Local $rM = DllStructGetData($tRangeCtrl, "Marker", 2)
	Local $iMode = 1, $next = 1
	If Abs($oldMarker-$iX) > 2 Then $next = 2
	If $iX - $x < $oldMarker Then
		$iX = $oldMarker - $next
	ElseIf $iX - $x > $oldMarker Then
		$iX = $oldMarker + $next
	Else
		Return
	EndIf
	Switch $iMarker
		Case 0
			If $iX < 0 Then $iX = 0
			If $iX >= $rM Then $iX = $rM - 1
		Case 1
			If $iX <= $lM Then $iX = $lM + 1
			If $iX > $w Then $iX = $w
	EndSwitch
	DllStructSetData($tRangeCtrl, "Marker", $iX, $aIndex[$iMarker])
	DllStructSetData($tRangeCtrl, $aElement[$iMarker], $x + $iX - 4, 1)
	DllStructSetData($tRangeCtrl, $aElement[$iMarker], $x + $iX + 4, 3)
	__GDIPlus_RangeBar_Draw($tRangeCtrl, $iMode)

	; === Werte in GUI anzeigen	 (nur Test) ====
	_showValue()
	; ==========================================
EndFunc   ;==>__MoveMarker


Func __TextSize(ByRef $tRangeCtrl, $nText)
	If $nText = '' Then Return
	Local $hGraphic = DllStructGetData($tRangeCtrl, "Graphics")
    Local $hFormat = DllStructGetData($tRangeCtrl, "Format")
    Local $hFamily = DllStructGetData($tRangeCtrl, "Family")
    Local $hFont = DllStructGetData($tRangeCtrl, "Font")
    Local $tLayout = _GDIPlus_RectFCreate()
    Local $aInfo = _GDIPlus_GraphicsMeasureString($hGraphic, $nText, $hFont, $tLayout, $hFormat)
	Return $aInfo
EndFunc  ;==>__TextSize

Func __DecToBase60($i)
	Return Floor($i) & ':' & StringFormat('%02d', Round(($i - Floor($i))*60))
EndFunc  ;==>__DecToBase60
#endregion

Func _WM_MOUSEMOVE($hWnd, $uMsg, $wParam, $lParam)
	Local $x, $y, $x1, $y1, $xC, $xM, $retL, $retR, $posWin, $xPos = BitAND($lParam, 0xFFFF), $yPos = BitShift($lParam, 16)
	Local Const $MK_LBUTTON = 1, $MK_CONTROL = 8
	$xM = DllStructGetData($RangeCtrl, "Mouse")
	If Not IsDllStruct($tLeftMarker) Or Not IsDllStruct($tRightMarker) Or Not IsDllStruct($tRange) Then
		$tLeftMarker = DllStructCreate("int Left;int Top;int Right;int Bottom")
		$tRightMarker = DllStructCreate("int Left;int Top;int Right;int Bottom")
		$tRange = DllStructCreate("int Left;int Top;int Right;int Bottom")
	EndIf
	$x  = DllStructGetData($RangeCtrl, "RECTleft", 1)
	$y  = DllStructGetData($RangeCtrl, "RECTleft", 2)
	$x1 = DllStructGetData($RangeCtrl, "RECTleft", 3)
	$y1 = DllStructGetData($RangeCtrl, "RECTleft", 4)
	DllCall($Dll_user32, 'long', 'SetRect', 'ptr', DllStructGetPtr($tLeftMarker), 'long', $x, 'long', $y, 'long', $x1, 'long', $y1)
	$x  = DllStructGetData($RangeCtrl, "RECTright", 1)
	$y  = DllStructGetData($RangeCtrl, "RECTright", 2)
	$x1 = DllStructGetData($RangeCtrl, "RECTright", 3)
	$y1 = DllStructGetData($RangeCtrl, "RECTright", 4)
	DllCall($Dll_user32, 'long', 'SetRect', 'ptr', DllStructGetPtr($tRightMarker), 'long', $x, 'long', $y, 'long', $x1, 'long', $y1)
	$xC = DllStructGetData($RangeCtrl, "RECTBar", 1)
	$x  = DllStructGetData($RangeCtrl, "Marker", 1) + $xC
	$y  = DllStructGetData($RangeCtrl, "RECTBar", 2)
	$x1 = DllStructGetData($RangeCtrl, "Marker", 2) + $xC
	$y1 = DllStructGetData($RangeCtrl, "RECTBar", 4) + $y
	DllCall($Dll_user32, 'long', 'SetRect', 'ptr', DllStructGetPtr($tRange), 'long', $x, 'long', $y, 'long', $x1, 'long', $y1)
	$retLM = DllCall($Dll_user32, 'long', 'PtInRect', 'ptr', DllStructGetPtr($tLeftMarker), 'long', $xPos, 'long', $yPos)
	$retRM = DllCall($Dll_user32, 'long', 'PtInRect', 'ptr', DllStructGetPtr($tRightMarker), 'long', $xPos, 'long', $yPos)
	Local $posWin = WinGetPos($hWnd)
	Switch $wParam
		Case $MK_LBUTTON ; Maus bewegt und Links geklickt
			If $retLM[0] > 0 Then
				__MoveMarker($RangeCtrl, 0, $xPos)
			ElseIf $retRM[0] > 0 Then
				__MoveMarker($RangeCtrl, 1, $xPos)
			EndIf
;~ 		Case $MK_CONTROL ; Maus bewegt und STRG gedrückt
;~ 			$retR = DllCall($Dll_user32, 'long', 'PtInRect', 'ptr', DllStructGetPtr($tRange), 'long', $xPos, 'long', $yPos)
;~ 			If $retR[0] > 0 Then
;~ 				If ($xM > $xPos + 10) Or ($xM < $xPos - 10) Then DllStructSetData($RangeCtrl, "Mouse", $xPos)
;~ 				__MoveRange($RangeCtrl, $xPos) ;ConsoleWrite(@SEC & ' STRG-Mouse' & @CRLF)
;~ 			EndIf
		Case Else
			If $retLM[0] > 0 Or $retRM[0] > 0 Then
				If Not $bSetCursor Then
					GUISetCursor(0)
					$bSetCursor = True
				EndIf
			Else
				If $bSetCursor Then
					GUISetCursor(-1)
					$bSetCursor = False
				EndIf
			EndIf
	EndSwitch
	Return 0
EndFunc   ;==>_WM_MOUSEMOVE


Func _showValue() ; Testanzeige
	Local $aRange = _GDIPlus_RangeBar_GetRange($RangeCtrl)
	GUICtrlSetData($inLeftpercent, $aRange[0])
	GUICtrlSetData($inRightpercent, $aRange[1])
	GUICtrlSetData($inLeftvalue, __DecToBase60($aRange[2]))
	GUICtrlSetData($inRightvalue, __DecToBase60($aRange[3]))
	GUICtrlSetData($inValue, __DecToBase60($aRange[3] - $aRange[2]))
EndFunc

