- Offizieller Beitrag
Hi,
vor ein paar Tagen tauchte im Forum die Frage nach einer Progressbar mit 2 Slidern auf.
Ich fand den Gedanken gar nicht übel und da ich kein dementsprechendes Ctrl gefunden habe, ist nun dieses Projekt entstanden:
Ein selbstgezeichnetes Ctrl zur Bereichsauswahl durch Verschieben der Unter- und/oder Obergrenze (Klicken, Ziehen).
Hier der aktuelle Status:
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
Spielt mal ein bischen damit und gebt euren Kommentar ab.
Edit 24.05.2010
- Das Mausverhalten ist jetzt etwas verbessert. Ich könnte damit leben.
- Neuer Parameter: Transparenz
- Bar, Ticks und Label werden in eigenen Buffer gezeichnet und nur was sich ändert, wird neu gezeichnet.
- Funktion zur Ausgabe der tatsächlichen Control-Größe hinzugefügt (Je nach Style unterschiedlich). Rückgabe als Array mit Einzelwerten und RECT-Struktur.
Spoiler anzeigen
#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')
$aSize = _GDIPlus_RangeBar_GetSize($RangeCtrl)
ConsoleWrite('Controlgröße:' & @CRLF & _
'x: ' & $aSize[0] & @CRLF & _
'y: ' & $aSize[1] & @CRLF & _
'w: ' & $aSize[2] & @CRLF & _
'h: ' & $aSize[3] & @CRLF)
; === 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, ; 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, And Not $bIsActive Then
$bIsActive = True
Return __GDIPlus_RangeBar_Draw($RangeCtrl, $iMode)
ElseIf Not BitAND($iWinState, 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