UC_Framework - Universal Controls
Hi everyone,
I'd like to share a project I've been working on: UC_Framework.
It is a lightweight framework designed to create modern, reactive, and highly customizable GDI+ controls for AutoIt.
My goal was to create a standardized, extensible way to introduce
custom controls into AutoIt, moving away from static functions
and towards a more "Object-Oriented" logic using AutoIt Maps
Key Features:
-
Reactive Engine: Property changes automatically trigger a redraw of the control.
-
Extensible Architecture: The framework is designed as an "Engine."
Adding a new control (e.g., a Gauge or a Custom Listview) is just a matter of defining its properties in the Map and creating its Draw function. -
Modern UI Elements: Includes Toggles (Round/Rect), Sliders (Horizontal/Vertical), Custom Buttons (Classic/Rounded/Pill), ,Links, labels, (more are coming).
-
Property Management: Centralized property manager for easy control manipulation using
_UC_Setand_UC_Get. -
Customization: Full control over colors, corner radius, fonts, and tooltips.
-
Interactive: Built-in support for hover states, click events, and keyboard accelerators.
Technical Implementation:
The framework uses a Global Map (ID 1) to act as a Provider for system-wide constants, cursors, and shared resources,
ensuring that your GUI remains lightweight and organized.
This framework is currently in its early stages (Alpha).
I am sharing it now because I want to establish a solid foundation and gather feedback on the architecture.
Ideas for new controls to be integrated into the library.
Example1.au3
; https://www.autoitscript.com/forum/topic/213667-uc_framework-universal-controls/ ;---------------------------------------------------------------------------------------- ; Title...........: Example1.au3 ; Description.....: Example of using the UC_Framework.au3 ; AutoIt Version..: 3.3.18.0 Author: ioa747 Script Version: 0.0.8.0 ; Note............: Testet in Windows 11 Pro 25H2 Date:01/05/2026 ;---------------------------------------------------------------------------------------- #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #include <GUIConstantsEx.au3> #include "UC_Framework.au3" _Main() Func _Main() Local $hMainGui = GUICreate("Universal Controls GUI", 520, 450, -1, -1, BitOR($WS_CLIPCHILDREN, $GUI_SS_DEFAULT_GUI)) _UC_GUISetBkColor(0xF0F0F0, $hMainGui) Local $idLblTheme = GUICtrlCreateLabel("GUI Theme", 20, 10, 150, 17) ; === Toggles === Local $idToggleTheme = _UC_Toggle_Create($hMainGui, 20, 30, 50, 25, 0, 0xF0F0F0, 0x758184, 0xD1D1D1) Local $idToggle1 = _UC_Toggle_Create($hMainGui, 20, 80, 50, 25, 0, 0x0094FF) Local $idToggle2 = _UC_Toggle_Create($hMainGui, 20, 130, 50, 25, 1, 0xFF6A00, 0x33AA00) ; === Sliders === Local $idHLabel = GUICtrlCreateLabel("Horizontal Slider (50):", 20, 180) Local $idHSlider = _UC_Slider_Create($hMainGui, 20, 200, 180, 20, 0, 100, 50, 0, 0x4CD964, 0xCCCCCC, 0xFFFFFF, 4) _UC_Set(-1, "SliderXLStep", 10) ; customizable property _MapCW(_UC_Get($idHSlider), "--- $idHSlider Report ---") Local $idVLabel = _UC_Label_Create($hMainGui, "Vertical Slider (0-100):", 340, 25, 20, 150, 3, 0x000000) Local $idVSlider = _UC_Slider_Create($hMainGui, 360, 25, 20, 150, 0, 20, 20, 1, 0x0078D7) _UC_Set(-1, "ShowTooltip", 1) ; standar property _UC_Set(-1, "SliderXLStep", 5) ; customizable property ; === Buttons === Local $btnClassic = _UC_Button_Create($hMainGui, "CLASSIC RECT", 220, 20, 100, 35, 0, 0x3A71B1, 0xFFFFFF) _UC_Set(-1, "State", 0) ; standar property Local $btnModern = _UC_Button_Create($hMainGui, "ROUNDED CORNERS", 220, 70, 100, 35, 5, 0x3C975A, 0xFFFFFF) Local $btnPill = _UC_Button_Create($hMainGui, "PILL BUTTON", 220, 120, 100, 35, 30, 0xA84646, 0xFFFFFF) Local $btnRound1 = _UC_Button_Create($hMainGui, ChrW(59448), 220, 170, 35, 35, 34, 0xA14300, 0xFFFFFF) _UC_Set(-1, "Font", "Segoe Fluent Icons") _UC_Set(-1, "FontSize", 12) _UC_Set(-1, "Tooltip", "FolderOpen") _UC_Set(-1, "ShowTooltip", 1) Local $btnRound2 = _UC_Button_Create($hMainGui, "R2", 260, 170, 35, 35, 34, 0x7800AC, 0xFFFFFF) Local $btnRound3 = _UC_Button_Create($hMainGui, ChrW(59213), 300, 170, 35, 35, 34, 0xFF6A00, 0xFFFFFF) _UC_Set(-1, "Font", "Segoe Fluent Icons") _UC_Set(-1, "FontSize", 12) ; === Progressbar === Local $idProgress = _UC_ProgressBar_Create($hMainGui, 20, 240, 350, 24, 0, 100, 50) _UC_Set(-1, "ShowPercent", True) ; === Radial Progressbar === Local $idRadial = _UC_RadialProgress_Create($hMainGui, 400, 40, 100) _UC_Set(-1, "RingThickness", 12) _UC_Set(-1, "FontSize", 16) _UC_Set(-1, "Value", 50) ; === Links === Local $Link = "https://github.com/ioa747/NetWebView2Lib" Local $idLink = _UC_Link_Create($hMainGui, "webview2autoit", $Link, 100, 30, 80, 20, 12) _UC_Set(-1, "ShowTooltip", 1) ; === Image === Local $iWidth, $sImage = @ScriptDir & "\1272.png" Local $idImage1 = _UC_Image_Create($hMainGui, $sImage, 10, 300, 0.6) $iWidth = _UC_Get(-1, "Width") Local $idImage2 = _UC_Image_Create($hMainGui, $sImage, 10 + $iWidth, 300, 0.4) $iWidth += _UC_Get(-1, "Width") Local $idImage3 = _UC_Image_Create($hMainGui, $sImage, 10 + $iWidth, 300, 0.2) _UC_Set(-1, "SetFocus", 1) ; === Timer === _UC_Timer_Set($idImage3, 100, "_CallBackTimerFunction") _UC_Timer_Set($btnRound2, 500, "_CallBackTimerFlash") Local $id_UP = GUICtrlCreateDummy() Local $id_DOWN = GUICtrlCreateDummy() Local $id_UP_XL = GUICtrlCreateDummy() Local $id_DOWN_XL = GUICtrlCreateDummy() Local $aAccelKeys[4][2] = [["{UP}", $id_UP], ["{DOWN}", $id_DOWN], ["+{UP}", $id_UP_XL], ["+{DOWN}", $id_DOWN_XL]] GUISetAccelerators($aAccelKeys) GUISetState() GUISetState(@SW_SHOW) ; Map (ID 1) to act as a Provider for system-wide Variables _MapCW(_UC_Get(1), "--- System Variable ---") ; report ConsoleWrite("--- " & @CRLF) Local $aMsg, $iSliderXLStep, $iVal While 1 $aMsg = GUIGetMsg() Switch $aMsg Case $GUI_EVENT_CLOSE ExitLoop Case $id_UP _UC_Slider_UpdateFromValue(Default, 1) ; Default is the active control Case $id_DOWN _UC_Slider_UpdateFromValue(Default, -1) ; Default is the active control Case $id_UP_XL $iSliderXLStep = _UC_Get(Default, "SliderXLStep") ; Default is the active control _UC_Slider_UpdateFromValue(Default, $iSliderXLStep) Case $id_DOWN_XL $iSliderXLStep = _UC_Get(Default, "SliderXLStep") ; Default is the active control _UC_Slider_UpdateFromValue(Default, -$iSliderXLStep) Case $idToggleTheme ConsoleWrite("$idToggleTheme:" & GUICtrlRead($idToggleTheme) & @CRLF) Local $iTxtColor If GUICtrlRead($idToggleTheme) Then _UC_GUISetBkColor(0x262A2B, $hMainGui) $iTxtColor = 0xFFFFFF Else _UC_GUISetBkColor(0xF0F0F0, $hMainGui) $iTxtColor = 0x000000 EndIf GUICtrlSetColor($idLblTheme, $iTxtColor) GUICtrlSetColor($idHLabel, $iTxtColor) ; GUICtrlSetColor($idVLabel, $iTxtColor) _UC_Set($idVLabel, "Color", $iTxtColor) _UC_Refresh($hMainGui) Case $idToggle1 ConsoleWrite("$idToggle1:" & GUICtrlRead($idToggle1) & @CRLF) GUISetState((GUICtrlRead($idToggle1) ? @SW_HIDE : @SW_SHOW), _UC_Get($idToggle2, "UC_hWnd")) Case $idToggle2 ConsoleWrite("$idToggle2:" & GUICtrlRead($idToggle2) & @CRLF) _UC_Set($idHSlider, "ThumbType", GUICtrlRead($idToggle2)) Case $idHSlider $iVal = GUICtrlRead($idHSlider) GUICtrlSetData($idHLabel, "Horizontal Slider (" & $iVal & "):") _UC_Set($idProgress, "Value", $iVal) _UC_Set($idRadial, "Value", $iVal) ConsoleWrite("$idHSlider:" & $iVal & @CRLF) Case $idVSlider $iVal = GUICtrlRead($idVSlider) _UC_Set($idVLabel, "Text", "Vertical Slider (" & $iVal & "):") _UC_Set($btnPill, "CornerRadius", $iVal) Case $idLink ConsoleWrite("$idLink:" & GUICtrlRead($idLink) & @CRLF) Local $sText = _UC_Get($idLink, "Value") ConsoleWrite("$sText=" & $sText & @CRLF) ShellExecute($sText) Case $btnClassic, $btnModern, $btnPill ConsoleWrite("'" & _UC_Get(Default, "Text") & "' Button Clicked!" & @CRLF) ; Default is the active control Case $btnRound1 ConsoleWrite("'" & _UC_Get($btnRound1, "Tooltip") & "' Button Clicked!" & @CRLF) _MapCW(_UC_Get($btnRound1), "--- $btnRound1 Report ---") Case $btnRound2 ConsoleWrite("'" & GUICtrlRead($btnRound2) & "' Button Clicked!" & @CRLF) _UC_Timer_Set($idImage3, 100, "_CallBackTimerFunction") Case $btnRound3 ConsoleWrite("'" & GUICtrlRead($btnRound3) & "' Button Clicked!" & @CRLF) Case $idImage1, $idImage2, $idImage3 ConsoleWrite("'" & _UC_Get(Default, "Filename") & "' Scale:" & _UC_Get(Default, "Scale") & @CRLF) ; Default is the active control EndSwitch WEnd _UC_Destroy($hMainGui) EndFunc ;==>_Main Func _CallBackTimerFunction(ByRef $mt) _MapCW($mt, ">>> _CallBackTimerFunction=" & $mt.id & " .Fired=" & $mt.Fired & " <<<") If Not MapExists($mt, "Custom") Then $mt.Custom = 3 $mt.Custom -= 0.2 Local $UC = _UC_Properties($mt.ControlID) WinMove($UC.UC_hWnd, "", Default, Default, $UC.Width * $mt.Custom, $UC.Height * $mt.Custom) If $mt.Custom < 0.9 Then _UC_Timer_Kill($mt.id) EndFunc ;==>_CallBackTimerFunction Func _CallBackTimerFlash(ByRef $mt) Local $iFlash = Mod($mt.Fired, 2) Local $UC = _UC_Properties($mt.ControlID) $UC.BtnColor = ($iFlash ? 0xB200FF : 0x7800AC) _UC_Properties($mt.ControlID, $UC) EndFunc ;==>_CallBackTimerFlash
UC_Framework.au3
; https://www.autoitscript.com/forum/topic/213667-uc_framework-universal-controls/ ;---------------------------------------------------------------------------------------- ; Title...........: UC_Framework.au3 ; Description.....: Universal Controls framework for custom GDI+ controls (Toggles, Sliders, etc.) ; AutoIt Version..: 3.3.18.0 Author: ioa747 Script Version: 0.0.8.0 ; Note............: Testet in Windows 11 Pro 25H2 Date:15/04/2026 ;---------------------------------------------------------------------------------------- #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #include-once #include <GDIPlus.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <WinAPISysWin.au3> #include <WinAPISys.au3> #include <Misc.au3> #include <WinAPIGdi.au3> #include <WindowsNotifsConstants.au3> #include <StaticConstants.au3> #include <String.au3> #include <Array.au3> #include <WinAPIvkeysConstants.au3> #include <Timers.au3> Global $g_UC_DebugInfo = 1 Global Enum _ $UC_TYPE_NONE, _ $UC_TYPE_TOGGLE, _ $UC_TYPE_SLIDER, _ $UC_TYPE_BUTTON, _ $UC_TYPE_LINK, _ $UC_TYPE_LABEL, _ $UC_TYPE_IMAGE, _ $UC_TYPE_PROGRESSBAR, _ $UC_TYPE_RADIALPROGRESS, _ $UC_TYPE_MAX #Region ; ~~~~~~~~~~~~~ Generic UC API ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Func _UC_Redraw($hWnd) Local $id = _WinAPI_GetProp($hWnd, "UC_ControlID") If Not $id Then Return SetError(1, 0, 0) Local $m = _UC_Properties($id) ; get the Map Switch $m.UC_Type Case $UC_TYPE_NONE Return Case $UC_TYPE_TOGGLE _UC_Toggle_Draw($hWnd, $m) Case $UC_TYPE_SLIDER _UC_Slider_Draw($hWnd, $m) Case $UC_TYPE_BUTTON _UC_Button_Draw($hWnd, $m) Case $UC_TYPE_LINK _UC_Link_Draw($hWnd, $m) Case $UC_TYPE_LABEL _UC_Label_Draw($hWnd, $m) Case $UC_TYPE_RADIALPROGRESS _UC_RadialProgress_Draw($hWnd, $m) Case $UC_TYPE_PROGRESSBAR _UC_ProgressBar_Draw($hWnd, $m) Case $UC_TYPE_IMAGE _UC_Image_Draw($hWnd, $m) EndSwitch EndFunc ;==>_UC_Redraw ; #FUNCTION# ==================================================================================================================== ; Name ..........: _UC_Properties ; Description ...: Centralized Property Manager and Reactive Engine for Universal Controls. ; Syntax ........: _UC_Properties($idDummy[, $vName = Default[, $vVal = Default]]) ; Parameters ....: $idDummy - The Control ID (Dummy) assigned to the UC control. ; $vName - [Optional] Property name (String), a complete Map object, or "@Delete". ; $vVal - [Optional] The value to assign. ; If $vName is "@Delete", set $vVal to True to skip final redraw. ; If $vName is a Map, $vVal=False skips the automatic redraw. ; Return values .: Success: ; 1. GET Full Map: (Call: _UC_Properties($id)) -> Returns the entire Map object. ; 2. SET Full Map: (Call: _UC_Properties($id, $mMap)) -> Returns 1, updates memory and Redraws. ; 3. GET Value: (Call: _UC_Properties($id, "PropName")) -> Returns the specific value. ; 4. SET Value: (Call: _UC_Properties($id, "PropName", $vVal)) -> Returns 1 and Redraws. ; 5. DELETE: (Call: _UC_Properties($id, "@Delete")) -> Clears memory slot. ; Failure: ; - Returns SetError(1, 0, $mTemplate) if a requested property name does not exist. ; - Returns SetError(2, 0, 0) if $idDummy property = -1 and control does not exist. ; Author ........: ioa747 ; Remarks .......: This function implements a "Reactive Data Binding" logic. Any change to a property ; automatically triggers the _UC_Redraw() for the associated hWnd. ; ; Internal Architecture & Indexing: ; - Index [0]: Stores the total number of allocated slots (Array Size tracking). ; - Index [1]: Reserved for General Library Parameters (Global settings for the UC framework). ; - Index [2]: Reserved as a Template Map (An empty Map used to initialize new controls). ; - Index [3+]: Stores the unique Map for each individual Control ID (Dummy). ; ; Usage Scenarios: ; - Multi-Property Update: Get the Map, modify multiple keys, then Set it back to trigger one Redraw. ; - Control Initialization: The framework automatically copies the Template Map [2] when a new ; Control ID is first accessed, ensuring consistency across all controls. ; - Memory Management: Map objects are heavy. Always call with "@Delete" when a control is ; destroyed (e.g., during GUIDelete) to prevent memory leaks in long-running scripts. ; =============================================================================================================================== Func _UC_Properties($idDummy = Default, $vName = Default, $vVal = Default) Local Static $aProp[1] = [0], $mMap[] If $idDummy = Default Then Return $aProp If $idDummy = -1 Then If Not MapExists($aProp[1], "UC_LastCreatedID") Then Return SetError(2, 0, 0) $idDummy = $aProp[1].UC_LastCreatedID EndIf ; Dynamic Resize If $idDummy > $aProp[0] Then Local $iNewSize = $idDummy + 10 ReDim $aProp[$iNewSize] $aProp[0] = UBound($aProp) - 1 ; Initialize Template (if it doesn't already exist) If Not IsMap($aProp[2]) Then ; in Autoit allways controls start from 3 $aProp[1] = $mMap ; General Properties $aProp[2] = $mMap ; Timers Map EndIf EndIf ; Map Selection (or Template) Local $m = (IsMap($aProp[$idDummy]) ? $aProp[$idDummy] : $mMap) Select Case $vName = Default Return $aProp[$idDummy] ; GET MAP Case IsMap($vName) $aProp[$idDummy] = $vName ; SET MAP If $vVal = Default And MapExists($vName, "UC_hWnd") Then _UC_Redraw($vName.UC_hWnd) Return 1 Case Else If $vVal = Default Then ; GET Val If MapExists($m, $vName) Then Return $m[$vName] Else Return SetError(1, 0, $m) EndIf Else ; SET Val If $vName = "@Delete" Then $aProp[$idDummy] = "" If $vVal = Default Then _UC_Redraw($m.UC_hWnd) Return 1 EndIf $m[$vName] = $vVal $aProp[$idDummy] = $m _UC_Redraw($m.UC_hWnd) Return 1 EndIf EndSelect EndFunc ;==>_UC_Properties Func _UC_Get($idCtrl = Default, $sProp = Default) If $idCtrl = Default Then $idCtrl = _UC_Properties(1, "UC_ActiveControlID") If Not $idCtrl Then Return SetError(1, 0, 0) If $sProp = Default Then Return $idCtrl EndIf Return _UC_Properties($idCtrl, $sProp) EndFunc ;==>_UC_Get Func _UC_Set($idCtrl = Default, $sProp = Default, $vValue = Default) If $idCtrl = Default Then $idCtrl = _UC_Properties(1, "UC_ActiveControlID") If Not $idCtrl Then Return SetError(1, 0, 0) If $sProp = Default Then Return $idCtrl EndIf Return _UC_Properties($idCtrl, $sProp, $vValue) EndFunc ;==>_UC_Set Func _UC_Destroy($hParent = Default, $idDummy = Default) Local $m, $aAll = _UC_Properties(Default) ; $hParent=Default => Bulk Delete All If $hParent = Default Then For $i = 3 To $aAll[0] $m = $aAll[$i] If IsMap($m) Then _UC_Timer_Remove($idDummy) If MapExists($m, "UC_hWnd") Then _WinAPI_RemoveProp($m.UC_hWnd, "UC_ControlID") GUIDelete($m.UC_hWnd) EndIf _UC_Properties($i, "@Delete", True) EndIf Next Return 1 Else ; $idDummy=Default => Bulk delete All from $hParent UC_hParent If $idDummy = Default Then For $i = 3 To $aAll[0] $m = $aAll[$i] If IsMap($m) Then _UC_Timer_Remove($idDummy) If MapExists($m, "UC_hWnd") Then If $m.UC_hParent = $hParent Then _WinAPI_RemoveProp($m.UC_hWnd, "UC_ControlID") GUIDelete($m.UC_hWnd) _UC_Properties($i, "@Delete", True) EndIf EndIf EndIf Next Return 1 Else ; Individual deletion $m = $aAll[$idDummy] If IsMap($m) Then _UC_Timer_Remove($idDummy) If MapExists($m, "UC_hWnd") Then _WinAPI_RemoveProp($m.UC_hWnd, "UC_ControlID") GUIDelete($m.UC_hWnd) EndIf Return _UC_Properties($idDummy, "@Delete", True) EndIf EndIf EndIf EndFunc ;==>_UC_Destroy Func _UC_Refresh($hWnd) Return _WinAPI_RedrawWindow($hWnd, 0, 0, BitOR($RDW_INVALIDATE, $RDW_UPDATENOW, $RDW_ALLCHILDREN)) EndFunc ;==>_UC_Refresh Func _UC_GUISetBkColor($iBkColor, $hWnd) GUISetBkColor($iBkColor, $hWnd) _WinAPI_SetProp($hWnd, "UC_GUIBkColor", $iBkColor) EndFunc ;==>_UC_GUISetBkColor Func _UC_GetContrastColor($iBkColor) ;, $iPrecent = 20) 🚧 ; Extract RGB components Local $iR = BitAND(BitShift($iBkColor, 16), 0xFF) Local $iG = BitAND(BitShift($iBkColor, 8), 0xFF) Local $iB = BitAND($iBkColor, 0xFF) ; Calculate perceived brightness Local $iLuminance = (0.299 * $iR) + (0.587 * $iG) + (0.114 * $iB) ; Calculate Hover and Pressed colors (Logic: BGR for WinAPI) ;~ Local $iBGR = _WinAPI_SwitchColor($iBkColor) ; If background is bright, return a semi-transparent dark stroke ; If background is dark, return a semi-transparent light stroke If $iLuminance > 128 Then Return 0x80000000 ; Semi-transparent Black ;~ Return _WinAPI_SwitchColor(_WinAPI_ColorAdjustLuma($iBGR, - $iPrecent)) ; 20% Darker Else Return 0x80FFFFFF ; Semi-transparent White ;~ Return _WinAPI_SwitchColor(_WinAPI_ColorAdjustLuma($iBGR, $iPrecent)) ; 20% Lighter EndIf EndFunc ;==>_UC_GetContrastColor Func _UC_SetCursor($idCtrl, $iCursorID = 0) Local $hWnd = _UC_Get($idCtrl, "UC_hWnd") Return GUISetCursor($iCursorID, 0, $hWnd) EndFunc ;==>_UC_SetCursor Func _UC_ToolTip($sText, $iX = -1, $iY = -1, $hParent = 0) Local Static $hToolTipGUI = 0, $idLabel = 0, $idFrame = 0 Local $m = _UC_Properties(1) ; Retrieve global properties/settings context ; Initialization (Run once) If $hToolTipGUI = 0 Then ; Create popup window with ToolWindow style to hide from taskbar $hToolTipGUI = GUICreate("UC_ToolTip", 100, 20, -1, -1, $WS_POPUP, BitOR($WS_EX_TOOLWINDOW, $WS_EX_TOPMOST, $WS_EX_TRANSPARENT), $hParent) $m.UC_ToolTip_hWnd = $hToolTipGUI ; Default Style Settings Local $iBk = 0xFFF8D4 ; Classic tooltip yellow $m.UC_ToolTip_BkColor = $iBk $m.UC_ToolTip_TxtColor = ($iBk < 0x888888 ? 0xFFFFFF : 0x000000) $m.UC_ToolTip_Transparency = 220 $m.UC_ToolTip_FontName = "Segoe UI" $m.UC_ToolTip_FontSize = 9 $m.UC_ToolTip_FontWeight = 400 $m.UC_ToolTip_FontAttribute = 0 ; Create GUI Controls $idFrame = GUICtrlCreateLabel("", 0, 0, 100, 20, $SS_BLACKFRAME) GUICtrlSetState(-1, $GUI_DISABLE) $idLabel = GUICtrlCreateLabel("", 5, 2, 90, 16) GUICtrlSetColor(-1, $m.UC_ToolTip_TxtColor) GUICtrlSetFont(-1, $m.UC_ToolTip_FontSize, $m.UC_ToolTip_FontWeight, $m.UC_ToolTip_FontAttribute, $m.UC_ToolTip_FontName) GUISetBkColor($m.UC_ToolTip_BkColor, $hToolTipGUI) WinSetTrans($hToolTipGUI, "", $m.UC_ToolTip_Transparency) EndIf ; Handle Hide State If $sText == "" Then If BitAND(WinGetState($hToolTipGUI), 2) Then GUISetState(@SW_HIDE, $hToolTipGUI) $m.UC_ToolTip_Text = "" _UC_Properties(1, $m, False) ; update the map Return EndIf ; Optimization: Skip update if text is unchanged (only update position) If $m.UC_ToolTip_Text = $sText Then If $iX = -1 Then Local $aPos = MouseGetPos() WinMove($hToolTipGUI, "", $aPos[0] + 15, $aPos[1] + 15) EndIf Return EndIf $m.UC_ToolTip_Text = $sText ; Update stored text _UC_Properties(1, $m, False) ; update the map ; Dynamic Sizing Logic Local $aTextSize = _UC_GetTextSize($sText, $m.UC_ToolTip_FontName, $m.UC_ToolTip_FontSize) Local $iWidth = $aTextSize[0] + 10 ; Add horizontal padding Local $iHeight = $aTextSize[1] + 4 ; Add vertical padding If $iWidth < 40 Then $iWidth = 40 ; Enforce minimum width ; Positioning If $iX = -1 Then Local $aMousePos = MouseGetPos() $iX = $aMousePos[0] + 15 $iY = $aMousePos[1] + 15 EndIf If $iX + $iWidth > @DesktopWidth Then $iX = @DesktopWidth - $iWidth If $iY + $iHeight > @DesktopHeight Then $iY = @DesktopHeight - $iHeight ; Apply Changes and Display WinMove($hToolTipGUI, "", $iX, $iY, $iWidth, $iHeight) GUICtrlSetPos($idFrame, 0, 0, $iWidth, $iHeight) GUICtrlSetPos($idLabel, 5, 2, $iWidth - 10, $iHeight - 4) GUICtrlSetData($idLabel, $sText) ; Show without stealing focus If Not BitAND(WinGetState($hToolTipGUI), 2) Then GUISetState(@SW_SHOWNOACTIVATE, $hToolTipGUI) EndFunc ;==>_UC_ToolTip Func _UC_GetTextSize($sString, $sFont = "Segoe UI", $fFontSize = 9, $iFontStyle = 0) Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND(_WinAPI_GetDesktopWindow()) Local $hFamily = _GDIPlus_FontFamilyCreate($sFont) Local $hFont = _GDIPlus_FontCreate($hFamily, $fFontSize, $iFontStyle) Local $hFormat = _GDIPlus_StringFormatCreate() Local $tLayout = _GDIPlus_RectFCreate(0, 0, 0, 0) ; aInfo[0] contains the $tagGDIPRECTF with the calculated dimensions Local $aInfo = _GDIPlus_GraphicsMeasureString($hGraphics, $sString, $hFont, $tLayout, $hFormat) Local $aSize[2] If Not @error Then $aSize[0] = Ceiling(DllStructGetData($aInfo[0], "Width")) $aSize[1] = Ceiling(DllStructGetData($aInfo[0], "Height")) Else $aSize[0] = 0 $aSize[1] = 0 EndIf ; Cleanup resources _GDIPlus_StringFormatDispose($hFormat) _GDIPlus_FontDispose($hFont) _GDIPlus_FontFamilyDispose($hFamily) _GDIPlus_GraphicsDispose($hGraphics) Return $aSize EndFunc ;==>_UC_GetTextSize Func _UC_IsMouseOver($hWnd) Local $tPoint = _WinAPI_GetMousePos() Return (_WinAPI_WindowFromPoint($tPoint) = $hWnd) EndFunc ;==>_UC_IsMouseOver #EndRegion ; ~~~~~~~~~~~~~ Generic UC API ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #Region ; ~~~~~~~~~~~~~ Framework Internal Functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Func __UC_Framework_Init($hParent) Static $bInitialized = False If $bInitialized Then Return _GDIPlus_Startup() GUIRegisterMsg($WM_ERASEBKGND, "__UC_Main_MsgHandler") GUIRegisterMsg($WM_PAINT, "__UC_Main_MsgHandler") GUIRegisterMsg($WM_LBUTTONDOWN, "__UC_Main_MsgHandler") GUIRegisterMsg($WM_LBUTTONDBLCLK, "__UC_Main_MsgHandler") GUIRegisterMsg($WM_MOUSEMOVE, "__UC_Main_MsgHandler") GUIRegisterMsg($WM_LBUTTONUP, "__UC_Main_MsgHandler") GUIRegisterMsg($WM_SETFOCUS, "__UC_Main_MsgHandler") GUIRegisterMsg($WM_KEYDOWN, "__UC_Main_MsgHandler") OnAutoItExitRegister("__UC_Framework_Shutdown") _UC_ToolTip("", -1, -1, $hParent) Local $aCursorType = StringSplit("Hand|AppStarting|Arrow|Cross|Help|IBeam|Icon|No|" & _ "Size|SizeAll|SizeNESW|SizeNS|SizeNWSE|SizeWE|UpArrow|Wait|None", "|", 2) For $i = 0 To UBound($aCursorType) - 1 _UC_Properties(1, "Cursor_" & $aCursorType[$i], $i) Next $bInitialized = True EndFunc ;==>__UC_Framework_Init Func __UC_Main_MsgHandler($hWnd, $iMsg, $wParam, $lParam) #forceref $wParam Local Static $hLastChild = 0, $hToolTipGUI = _UC_Properties(1, "UC_ToolTip_hWnd") If $hToolTipGUI = $hWnd Then Return $GUI_RUNDEFMSG ; First we check if the previous control needs "Reset" ; This must be done regardless of whether $hWnd is a UC control or not. If $hLastChild And $hLastChild <> $hWnd Then Local $idLast = _WinAPI_GetProp($hLastChild, "UC_ControlID") If $idLast Then Local $mLast = _UC_Properties($idLast) ; Only if it is not already Normal or Disabled If $mLast.State <> 1 Then _UC_ToolTip("") If $mLast.State <> 0 Then $mLast.State = 1 _UC_Properties($idLast, $mLast) EndIf EndIf EndIf $hLastChild = 0 EndIf ; Now we check the current window Local $idDummy = _WinAPI_GetProp($hWnd, "UC_ControlID") If Not $idDummy Then Return $GUI_RUNDEFMSG ; If we got here, we are in UC Control. Local $iCtrlType = _UC_Properties($idDummy, "UC_Type") Local $iX = BitAND($lParam, 0xFFFF) Local $iY = BitShift($lParam, 16) Switch $iMsg Case $WM_PAINT _UC_Redraw($hWnd) Local $tPAINTSTRUCT = DllStructCreate($tagPAINTSTRUCT) _WinAPI_BeginPaint($hWnd, $tPAINTSTRUCT) _WinAPI_EndPaint($hWnd, $tPAINTSTRUCT) Return 0 Case $WM_ERASEBKGND Return 1 Case $WM_LBUTTONDOWN Switch $iCtrlType Case $UC_TYPE_TOGGLE _UC_Toggle_WM_LBUTTONDOWN($idDummy, $hWnd, $iX, $iY) Case $UC_TYPE_SLIDER _UC_Slider_WM_LBUTTONDOWN($idDummy, $hWnd, $iX, $iY) Case $UC_TYPE_BUTTON _UC_Button_WM_LBUTTONDOWN($idDummy, $hWnd, $iX, $iY) Case $UC_TYPE_LINK _UC_Link_WM_LBUTTONDOWN($idDummy, $hWnd, $iX, $iY) Case $UC_TYPE_IMAGE _UC_Image_WM_LBUTTONDOWN($idDummy, $hWnd, $iX, $iY) EndSwitch Return 0 Case $WM_LBUTTONDBLCLK Switch $iCtrlType Case $UC_TYPE_TOGGLE _UC_Toggle_WM_LBUTTONDBLCLK($idDummy, $hWnd, $iX, $iY) Case $UC_TYPE_SLIDER _UC_Slider_WM_LBUTTONDBLCLK($idDummy, $hWnd, $iX, $iY) Case $UC_TYPE_BUTTON _UC_Button_WM_LBUTTONDBLCLK($idDummy, $hWnd, $iX, $iY) Case $UC_TYPE_LINK _UC_Link_WM_LBUTTONDBLCLK($idDummy, $hWnd, $iX, $iY) Case $UC_TYPE_IMAGE _UC_Image_WM_LBUTTONDBLCLK($idDummy, $hWnd, $iX, $iY) EndSwitch Return 0 Case $WM_LBUTTONUP Switch $iCtrlType Case $UC_TYPE_TOGGLE _UC_Toggle_WM_LBUTTONUP($idDummy, $hWnd, $iX, $iY) Case $UC_TYPE_SLIDER _UC_Slider_WM_LBUTTONUP($idDummy, $hWnd, $iX, $iY) Case $UC_TYPE_BUTTON _UC_Button_WM_LBUTTONUP($idDummy, $hWnd, $iX, $iY) Case $UC_TYPE_LINK _UC_Link_WM_LBUTTONUP($idDummy, $hWnd, $iX, $iY) Case $UC_TYPE_IMAGE _UC_Image_WM_LBUTTONUP($idDummy, $hWnd, $iX, $iY) EndSwitch Return 0 Case $WM_MOUSEMOVE Switch $iCtrlType Case $UC_TYPE_TOGGLE _UC_Toggle_WM_MOUSEMOVE($idDummy, $hWnd, $iX, $iY) Case $UC_TYPE_SLIDER _UC_Slider_WM_MOUSEMOVE($idDummy, $hWnd, $iX, $iY) Case $UC_TYPE_BUTTON _UC_Button_WM_MOUSEMOVE($idDummy, $hWnd, $iX, $iY) Case $UC_TYPE_LINK _UC_Link_WM_MOUSEMOVE($idDummy, $hWnd, $iX, $iY) Case $UC_TYPE_IMAGE _UC_Image_WM_MOUSEMOVE($idDummy, $hWnd, $iX, $iY) EndSwitch $hLastChild = $hWnd _UC_Properties(1, "UC_ActiveControlID", Int($idDummy)) _UC_Properties(1, "UC_ActiveControlType", Int($iCtrlType)) Return 0 Case $WM_SETFOCUS Switch $iCtrlType Case $UC_TYPE_TOGGLE _UC_Toggle_WM_MOUSEMOVE($idDummy, $hWnd, $iX, $iY) Case $UC_TYPE_SLIDER _UC_Slider_WM_MOUSEMOVE($idDummy, $hWnd, $iX, $iY) Case $UC_TYPE_BUTTON _UC_Button_WM_MOUSEMOVE($idDummy, $hWnd, $iX, $iY) Case $UC_TYPE_LINK _UC_Link_WM_MOUSEMOVE($idDummy, $hWnd, $iX, $iY) Case $UC_TYPE_IMAGE _UC_Image_WM_MOUSEMOVE($idDummy, $hWnd, $iX, $iY) EndSwitch ;ConsoleWrite( "$hWnd:" & $hWnd & ", XY:" & $iX & ", " & $iY & @CRLF) $hLastChild = $hWnd _UC_Properties(1, "UC_ActiveControlID", Int($idDummy)) _UC_Properties(1, "UC_ActiveControlType", Int($iCtrlType)) Return 0 Case $WM_KEYDOWN ; $wParam contains the key code (Virtual Key Code) ; ConsoleWrite("$wParam=" & $wParam & @CRLF) Switch $wParam Case $VK_SPACE ; (Space bar) Switch $iCtrlType Case $UC_TYPE_TOGGLE _UC_Toggle_WM_LBUTTONDOWN($idDummy, $hWnd, $iX, $iY) Sleep(50) _UC_Toggle_WM_LBUTTONUP($idDummy, $hWnd, -1, -1) Case $UC_TYPE_BUTTON _UC_Button_WM_LBUTTONDOWN($idDummy, $hWnd, $iX, $iY) Sleep(50) _UC_Button_WM_LBUTTONUP($idDummy, $hWnd, -1, -1) Case $UC_TYPE_LINK _UC_Link_WM_LBUTTONDOWN($idDummy, $hWnd, $iX, $iY) Sleep(50) _UC_Link_WM_LBUTTONUP($idDummy, $hWnd, -1, -1) EndSwitch Return 0 Case $VK_ADD ;, $VK_RIGHT, $VK_UP Switch $iCtrlType Case $UC_TYPE_SLIDER _UC_Slider_UpdateFromValue($idDummy, 1) EndSwitch Return 0 Case $VK_SUBTRACT ;, $VK_LEFT, $VK_DOWN Switch $iCtrlType Case $UC_TYPE_SLIDER _UC_Slider_UpdateFromValue($idDummy, -1) EndSwitch Return 0 ;~ Case Else ;~ ConsoleWrite("Case Else: $wParam=" & $wParam & @CRLF) EndSwitch Return 0 EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>__UC_Main_MsgHandler Func __UC_ParentColor($hWnd) Local $hParent = _WinAPI_GetParent($hWnd) Local $iCol = _WinAPI_GetProp($hParent, "UC_GUIBkColor") Return ($iCol ? $iCol : _WinAPI_GetSysColor($COLOR_BTNFACE)) ; $COLOR_BTNFACE as Default EndFunc ;==>__UC_ParentColor Func __UC_Framework_Shutdown() _UC_Destroy() _GDIPlus_Shutdown() EndFunc ;==>__UC_Framework_Shutdown Func __DW($sString, $iErrorNoLineNo = 1, $iLine = @ScriptLineNumber, $iError = @error, $iExtended = @extended) If Not $g_UC_DebugInfo Then Return SetError($iError, $iExtended, 0) Local $iReturn If $iErrorNoLineNo = 1 Then If $iError Then $iReturn = ConsoleWrite("@@(" & $iLine & ") :: @error:" & $iError & ", @extended:" & $iExtended & ", " & $sString) Else $iReturn = ConsoleWrite("+>(" & $iLine & ") :: " & $sString) EndIf Else $iReturn = ConsoleWrite($sString) EndIf ; Remarks: The @error and @extended are not set on return leaving them as they were before calling. Return SetError($iError, $iExtended, $iReturn) EndFunc ;==>__DW ; #FUNCTION# ==================================================================================================================== ; Name...........: __UC_DrawRoundedRect ; Description....: Internal helper for drawing and/or filling rounded rectangles. ; Parameters.....: $hBrush - Handle to a brush to fill the rect. Set to 0 to skip filling. ; $hPen - Handle to a pen to draw the border. Set to 0 to skip border. ; =============================================================================================================================== Func __UC_DrawRoundedRect($hGraphics, $iX, $iY, $iW, $iH, $iR, $hBrush = 0, $hPen = 0) ; If we have neither Brush nor Pen, there is no point in continuing If $hBrush = 0 And $hPen = 0 Then Return ; Case for simple rectangle (Radius = 0) If $iR <= 0 Then If $hBrush <> 0 Then _GDIPlus_GraphicsFillRect($hGraphics, $iX, $iY, $iW, $iH, $hBrush) If $hPen <> 0 Then _GDIPlus_GraphicsDrawRect($hGraphics, $iX, $iY, $iW, $iH, $hPen) Return EndIf ; Creating the Path Local $id = $iR * 2 Local $hPath = _GDIPlus_PathCreate() _GDIPlus_PathAddArc($hPath, $iX, $iY, $id, $id, 180, 90) _GDIPlus_PathAddArc($hPath, $iX + $iW - $id, $iY, $id, $id, 270, 90) _GDIPlus_PathAddArc($hPath, $iX + $iW - $id, $iY + $iH - $id, $id, $id, 0, 90) _GDIPlus_PathAddArc($hPath, $iX, $iY + $iH - $id, $id, $id, 90, 90) _GDIPlus_PathCloseFigure($hPath) ; First the filling (so as not to cover the outline) If $hBrush <> 0 Then _GDIPlus_GraphicsFillPath($hGraphics, $hPath, $hBrush) ; After the outline If $hPen <> 0 Then _GDIPlus_GraphicsDrawPath($hGraphics, $hPath, $hPen) _GDIPlus_PathDispose($hPath) EndFunc ;==>__UC_DrawRoundedRect #EndRegion ; ~~~~~~~~~~~~~ Framework Internal Functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #Region ; ~~~~~~~~~~~~~ Helper Functions for Map Management ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Func _Map2D(Const ByRef $mMap) Local $aMapKeys = MapKeys($mMap) Local $aMap2D[UBound($aMapKeys)][2] For $i = 0 To UBound($aMapKeys) - 1 $aMap2D[$i][0] = $aMapKeys[$i] $aMap2D[$i][1] = $mMap[$aMapKeys[$i]] Next Return $aMap2D EndFunc ;==>_Map2D Func _ClearMap(ByRef $mMap) Local $m[] $mMap = $m EndFunc ;==>_ClearMap Func _MapCW(ByRef $m, $sTitle = "--- Map info ---") ; ConsoleWrite map ConsoleWrite($sTitle & @CRLF) Local $aObject = _Map2D($m) Local $iMaxKeyLen = 0 Local $sKey For $i = 0 To UBound($aObject) - 1 $sKey = $aObject[$i][0] If StringLen($sKey) > $iMaxKeyLen Then $iMaxKeyLen = StringLen($sKey) EndIf Next For $i = 0 To UBound($aObject) - 1 $sKey = $aObject[$i][0] Local $vValue = $aObject[$i][1] Local $sPadding = _StringRepeat(" ", $iMaxKeyLen - StringLen($sKey) + 1) Local $sDim, $sLabel = "" Local $iDimension If IsMap($vValue) Then $sLabel = "= {Map[" & UBound($vValue) & "]}" ConsoleWrite($sKey & $sPadding & $sLabel & @CRLF) ElseIf IsArray($vValue) Then $iDimension = UBound($vValue, $UBOUND_DIMENSIONS) ; The dimension of the array e.g. 1/2/3 dimensional. $sDim = "" For $d = 1 To $iDimension $sDim &= "[" & UBound($vValue, $d) & "]" Next $sLabel = "= {Array" & $sDim & "}" ConsoleWrite($sKey & $sPadding & $sLabel & @CRLF) Else ConsoleWrite($sKey & $sPadding & "= " & $vValue & @CRLF) EndIf Next EndFunc ;==>_MapCW #EndRegion ; ~~~~~~~~~~~~~ Helper Functions for Map Management ~~~~~~~~~~~~~~~~~~~~~~~~~~~ #Region ; ~~~~~~~~~~~~~ Helper Functions for Window Properties (WinAPI) ~~~~~~~~~~~~~~~ Func _WinAPI_SetProp($hWnd, $sName, $iVal) Local $aRet = DllCall("user32.dll", "bool", "SetPropW", "hwnd", $hWnd, "wstr", $sName, "handle", $iVal) Return $aRet[0] EndFunc ;==>_WinAPI_SetProp Func _WinAPI_GetProp($hWnd, $sName) Local $aRet = DllCall("user32.dll", "handle", "GetPropW", "hwnd", $hWnd, "wstr", $sName) Return $aRet[0] EndFunc ;==>_WinAPI_GetProp Func _WinAPI_RemoveProp($hWnd, $sName) Local $aRet = DllCall("user32.dll", "ptr", "RemovePropW", "hwnd", $hWnd, "wstr", $sName) Return $aRet[0] EndFunc ;==>_WinAPI_RemoveProp #EndRegion ; ~~~~~~~~~~~~~ Helper Functions for Window Properties (WinAPI) ~~~~~~~~~~~~~~~ #Region ; ~~~~~~~~~~~~~ UC Timers API ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Func _UC_Timer_Set($idCtrl, $iElapse = 250, $sUserFunc = "", $iTimerID = -1) Local $UC = _UC_Properties($idCtrl) Local $hParent = $UC.UC_hParent Local $id = _Timer_SetTimer($hParent, $iElapse, "__UC_Timer_Internal_Handler", $iTimerID) If Not $id Then Return SetError(1, 0, 0) ; Timer Data Local $mt[], $mMap[] $mt.id = $id $mt.elapse = $iElapse $mt.UserFunc = $sUserFunc $mt.hwnd = $hParent $mt.ControlID = $idCtrl $mt.Fired = 0 $mt.RetVal = "" $mt.LastError = 0 Local $mTimers = (MapExists($UC, "Timers") ? $UC.Timers : $mMap) $mTimers[String($mt.id)] = $mt $UC.Timers = $mTimers _UC_Properties(2, String($mt.id), $idCtrl) _UC_Properties($idCtrl, $UC, False) Return $id EndFunc ;==>_UC_Timer_Set Func __UC_Timer_Internal_Handler($hWnd, $iMsg, $iIDTimer, $iTime) ; central Timer callback #forceref $hWnd, $iMsg, $iTime Local $m = _UC_TimerMap($iIDTimer) If @error Then Return SetError(1, 0, "") ; It's not our timer. $m.RetVal = "" $m.LastError = 0 If $m.UserFunc <> "" Then $m.Fired += 1 $m.RetVal = Call($m.UserFunc, $m) If @error = 0xDEAD And @extended = 0xBEEF Then $m.LastError = 2 ; *** function does not exist or invalid number of parameters. If MapExists(_UC_Properties(2), String($iIDTimer)) Then _UC_TimerMap($iIDTimer, $m) Return 0 EndIf EndFunc ;==>__UC_Timer_Internal_Handler Func _UC_Timer_Kill($iTimerID) Local $m = _UC_TimerMap($iTimerID) If Not @error Then Local $Result = _Timer_KillTimer($m.hwnd, $m.id) _UC_TimerMap($iTimerID, "@Delete") Local $mTimerIndex = _UC_Properties(2) Local $sKey = String($m.id) If IsMap($mTimerIndex) And MapExists($mTimerIndex, $sKey) Then MapRemove($mTimerIndex, $sKey) _UC_Properties(2, $mTimerIndex) Return $Result EndIf Return False EndFunc ;==>_UC_Timer_Kill Func _UC_Timer_Remove($idCtrl) Local $mUC = _UC_Properties($idCtrl) If MapExists($mUC, "Timers") Then Local $aTimers = _Map2D($mUC.Timers) For $i = 0 To UBound($aTimers) - 1 _UC_Timer_Kill($aTimers[$i][0]) Next EndIf EndFunc ;==>_UC_Timer_Remove Func _UC_TimerMap($iIDTimer, $mTimer = 0) Local $sKey, $idCtrl, $mTimers $sKey = String($iIDTimer) $idCtrl = _UC_Properties(2, $sKey) If Not @error Then Local $mUC = _UC_Properties($idCtrl) If IsMap($mUC) Then $mTimers = $mUC.Timers If $mTimer = 0 Then ; Get map If IsMap($mTimers) And MapExists($mTimers, $sKey) Then Return $mTimers[$sKey] Else ; .............. Set map If IsMap($mTimers) And IsMap($mTimer) Then $mTimers[$sKey] = $mTimer EndIf If IsMap($mTimers) And MapExists($mTimers, $sKey) And $mTimer = "@Delete" Then ; Delete map MapRemove($mTimers, $sKey) EndIf $mUC.Timers = $mTimers Return _UC_Properties($idCtrl, $mUC, False) EndIf EndIf EndIf Return SetError(1, 0, 0) EndFunc ;==>_UC_TimerMap #EndRegion ; ~~~~~~~~~~~~~ UC Timers API ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #Region ; ~~~~~~~~~~~~~ UC Toggle API ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Func _UC_Toggle_Create($hParent, $iX, $iY, $iW, $iH, $iType = 0, $hOnCol = 0x4CD964, $hOffCol = 0xD1D1D1, $hBtnCol = 0xFFFFFF) GUISwitch($hParent) Local $idDummy = GUICtrlCreateDummy() Local $hChild = GUICreate("UC_Control_" & $idDummy, $iW, $iH, $iX, $iY, BitOR($WS_CHILD, $WS_VISIBLE, $WS_CLIPSIBLINGS, $WS_TABSTOP), $WS_EX_TRANSPARENT, $hParent) __UC_Framework_Init($hParent) GUISetCursor(_UC_Get(1, "Cursor_Hand"), $GUI_CURSOR_OVERRIDE, $hChild) Local $m[] ; Universal Properties $m.UC_Type = $UC_TYPE_TOGGLE $m.UC_ControlID = $idDummy $m.UC_hWnd = $hChild $m.UC_hParent = $hParent ; Specific properties for the toggle control $m.State = 1 ; Initially enabled (State 0=Disabled, 1=Normal, 2=Hover, 3=Pressed) $m.Type = $iType ; Type of toggle (0=ROUNDED, 1=RECTANGLE) $m.Value = 0 ; Initial value (0=off, 1=on) $m.OnColor = $hOnCol ; Color when the toggle is on $m.OffColor = $hOffCol ; Color when the toggle is off $m.BtnColor = $hBtnCol ; Color of the Thumb button _WinAPI_SetProp($hChild, "UC_ControlID", $idDummy) _UC_Properties($idDummy, $m) _UC_Properties(1, "UC_LastCreatedID", $idDummy) GUISwitch($hParent) Return $idDummy EndFunc ;==>_UC_Toggle_Create Func _UC_Toggle_Draw($hWnd, ByRef $m) Local $hBGColor = "0xFF" & Hex(__UC_ParentColor($hWnd), 6) Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hWnd) Local $aSize = WinGetClientSize($hWnd) Local $iW = $aSize[0], $iH = $aSize[1] ; Buffer Setup Local $hBitmap = _GDIPlus_BitmapCreateFromGraphics($iW, $iH, $hGraphics) Local $hBack = _GDIPlus_ImageGetGraphicsContext($hBitmap) ; Settings for Sharpening _GDIPlus_GraphicsSetSmoothingMode($hBack, 4) ; HighQuality Antialiasing _GDIPlus_GraphicsSetPixelOffsetMode($hBack, 4) ; HighQuality (Half-pixel offset) ; Clear background _GDIPlus_GraphicsClear($hBack, $hBGColor) ; Resources Local $hColor = "0xFF" & Hex($m.Value ? $m.OnColor : $m.OffColor, 6) Local $hBrushBg = _GDIPlus_BrushCreateSolid($hColor) Local $hBrushBtn = _GDIPlus_BrushCreateSolid("0xFF" & Hex($m.BtnColor, 6)) Local $hPenHotTrack = _GDIPlus_PenCreate("0x80" & Hex($m.BtnColor, 6), 4) ; HotTrack semi-transparent Local $iR, $iXPos, $iBtnW If $m.Type = 0 Then ; ROUND TYPE $iR = $iH / 2 ; Fully rounded corners (Pill shape) ; Draw Toggle Background __UC_DrawRoundedRect($hBack, 0, 0, $iW - 1, $iH - 1, $iR, $hBrushBg, 0) ; Calculate Slider Button Position $iXPos = $m.Value ? ($iW - $iH + 2) : 2 $iBtnW = $iH - 5 ; Circle diameter ; Draw Slider Button __UC_DrawRoundedRect($hBack, $iXPos, 2, $iBtnW, $iBtnW, $iBtnW / 2, $hBrushBtn, ($m.State = 2 ? $hPenHotTrack : 0)) Else ; RECT TYPE $iR = 0 ; Sharp corners ; Draw Toggle Background __UC_DrawRoundedRect($hBack, 0, 0, $iW, $iH, $iR, $hBrushBg, 0) ; Calculate Slider Button Position Local $iSqW = ($iW / 3) - 4 Local $iSqX = $m.Value ? ($iW - $iSqW - 2) : 2 ; Draw Slider Button __UC_DrawRoundedRect($hBack, $iSqX, 2, $iSqW, $iH - 4, $iR, $hBrushBtn, ($m.State = 2 ? $hPenHotTrack : 0)) EndIf ; Present to Screen _GDIPlus_GraphicsDrawImageRect($hGraphics, $hBitmap, 0, 0, $iW, $iH) ; Cleanup _GDIPlus_PenDispose($hPenHotTrack) _GDIPlus_BrushDispose($hBrushBg) _GDIPlus_BrushDispose($hBrushBtn) _GDIPlus_GraphicsDispose($hBack) _GDIPlus_BitmapDispose($hBitmap) _GDIPlus_GraphicsDispose($hGraphics) EndFunc ;==>_UC_Toggle_Draw Func _UC_Toggle_WM_LBUTTONDOWN($idDummy, $hWnd, $iX, $iY) #forceref $hWnd, $iX, $iY Local $m = _UC_Properties($idDummy) If $m.State = 0 Then Return ; If is Disabled $m.State = 3 ; is pressed _UC_Properties($idDummy, $m) _WinAPI_SetCapture($hWnd) EndFunc ;==>_UC_Toggle_WM_LBUTTONDOWN Func _UC_Toggle_WM_LBUTTONUP($idDummy, $hWnd, $iX, $iY) #forceref $idDummy, $iX, $iY Local $m = _UC_Properties($idDummy) If $m.State = 3 Then ; If is pressed _WinAPI_ReleaseCapture() ; Area control If _UC_IsMouseOver($hWnd) Or ($iX = -1 And $iY = -1) Then $m.State = 2 ; Hover $m.Value = ($m.Value = 1 ? 0 : 1) _UC_Properties($idDummy, $m) GUICtrlSendToDummy($idDummy, $m.Value) ; Execution! Else $m.State = 1 ; Normal (Cancel execution) _UC_Properties($idDummy, $m) EndIf EndIf EndFunc ;==>_UC_Toggle_WM_LBUTTONUP Func _UC_Toggle_WM_MOUSEMOVE($idDummy, $hWnd, $iX, $iY) #forceref $hWnd, $iX, $iY Local $m = _UC_Properties($idDummy) If $m.State = 0 Then Return ; If is Disabled If $m.State = 1 Then ; If is normal $m.State = 2 ; Hover _UC_Properties($idDummy, $m) EndIf EndFunc ;==>_UC_Toggle_WM_MOUSEMOVE Func _UC_Toggle_WM_LBUTTONDBLCLK($idDummy, $hWnd, $iX, $iY) #forceref $hWnd, $iX, $iY ; For now, a double click on a button should behave exactly like a fast single click. ; So we just forward the parameters straight to the Down handler. Return _UC_Toggle_WM_LBUTTONDOWN($idDummy, $hWnd, $iX, $iY) EndFunc ;==>_UC_Toggle_WM_LBUTTONDBLCLK #EndRegion ; ~~~~~~~~~~~~~ UC Toggle API ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #Region ; ~~~~~~~~~~~~~ UC Slider API ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Func _UC_Slider_Create($hParent, $iX, $iY, $iW, $iH, $iMin = 0, $iMax = 100, $iValue = 0, $iType = 0, _ $hCol = 0x4CD964, $hTrackCol = 0xD1D1D1, $hThumbCol = 0xFFFFFF, $iTrackSize = 4) GUISwitch($hParent) Local $idDummy = GUICtrlCreateDummy() Local $hChild = GUICreate("UC_Control_" & $idDummy, $iW, $iH, $iX, $iY, BitOR($WS_CHILD, $WS_VISIBLE, $WS_CLIPSIBLINGS, $WS_TABSTOP), $WS_EX_TRANSPARENT, $hParent) __UC_Framework_Init($hParent) GUISetCursor(_UC_Get(1, "Cursor_Hand"), $GUI_CURSOR_OVERRIDE, $hChild) Local $m[], $iShowTooltip = 0, $iThumbType = 0 ; Universal Properties $m.UC_Type = $UC_TYPE_SLIDER $m.UC_ControlID = $idDummy $m.UC_hWnd = $hChild $m.UC_hParent = $hParent ; Toggle Specific Properties $m.State = 1 ; 0=Disable ; 1=Normal ; 2=Hover ; 3=Pressed $m.IsDragging = 0 ; Is now Dragging $m.DragOffset = 0 ; DragOffset property $m.Min = $iMin ; Min Value $m.Max = $iMax ; Max Value $m.Value = $iValue ; curent Value $m.Type = $iType ; 0=Horizontal; 1=Vertical $m.ThumbType = $iThumbType ; 0=Round; 1=Rectangular $m.ShowTooltip = $iShowTooltip ; show Tooltip while dragging $m.Color = $hCol ; Color $m.TrackColor = $hTrackCol ; TrackColor $m.ThumbColor = $hThumbCol ; ThumbColor $m.TrackSize = $iTrackSize ; Size of Color line _WinAPI_SetProp($hChild, "UC_ControlID", $idDummy) _UC_Properties($idDummy, $m) _UC_Properties(1, "UC_LastCreatedID", $idDummy) GUISwitch($hParent) Return $idDummy EndFunc ;==>_UC_Slider_Create Func _UC_Slider_Draw($hWnd, ByRef $m) Local $hBGColor = "0xFF" & Hex(__UC_ParentColor($hWnd), 6) Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hWnd) Local $aSize = WinGetClientSize($hWnd) Local $iW = $aSize[0], $iH = $aSize[1] ; Buffer Setup Local $hBitmap = _GDIPlus_BitmapCreateFromGraphics($iW, $iH, $hGraphics) Local $hBack = _GDIPlus_ImageGetGraphicsContext($hBitmap) ; Settings for Sharpening _GDIPlus_GraphicsSetSmoothingMode($hBack, 4) ; HighQuality Antialiasing _GDIPlus_GraphicsSetPixelOffsetMode($hBack, 4) ; HighQuality (Half-pixel offset) ; Clear background _GDIPlus_GraphicsClear($hBack, $hBGColor) ; Percentage calculation Local $iRange = $m.Max - $m.Min If $iRange <= 0 Then $iRange = 1 Local $fPercent = ($m.Value - $m.Min) / $iRange ; Brushes & Pens Local $hBrushTrack = _GDIPlus_BrushCreateSolid("0xFF" & Hex($m.TrackColor, 6)) Local $hBrushFill = _GDIPlus_BrushCreateSolid("0xFF" & Hex($m.Color, 6)) Local $hBrushThumb = _GDIPlus_BrushCreateSolid("0xFF" & Hex($m.ThumbColor, 6)) Local $hPenThumbBorder = _GDIPlus_PenCreate(0xFF888888, 1) Local $hPenHotTrack = _GDIPlus_PenCreate("0x80" & Hex($m.ThumbColor, 6), 4) Local $iThumbSizeW, $iThumbSizeH, $iR, $iTrackR If $m.Type = 0 Then ; HORIZONTAL ; Define Thumb Dimensions $iThumbSizeH = $iH - 4 $iThumbSizeW = ($m.ThumbType = 0 ? $iThumbSizeH : $iThumbSizeH / 2) $iR = ($m.ThumbType = 0 ? $iThumbSizeW / 2 : 0) ; Round or Rect Thumb $iTrackR = $m.TrackSize / 2 ; Rounded track ends Local $iXPos = (($iW - $iThumbSizeW - 1) * $fPercent) Local $iTrackY = ($iH - $m.TrackSize) / 2 ; Draw Track Background __UC_DrawRoundedRect($hBack, ($iThumbSizeW / 4), $iTrackY, $iW - ($iThumbSizeW / 2), $m.TrackSize, $iTrackR, $hBrushTrack, 0) ; Draw Track Fill __UC_DrawRoundedRect($hBack, ($iThumbSizeW / 4), $iTrackY, $iXPos + ($iThumbSizeW / 2), $m.TrackSize, $iTrackR, $hBrushFill, 0) ; Draw Thumb (With HotTrack Pen if hovered) __UC_DrawRoundedRect($hBack, $iXPos, 2, $iThumbSizeW, $iThumbSizeH, $iR, $hBrushThumb, ($m.State = 2 ? $hPenHotTrack : $hPenThumbBorder)) Else ; VERTICAL ; Define Thumb Dimensions $iThumbSizeW = $iW - 4 $iThumbSizeH = ($m.ThumbType = 0 ? $iThumbSizeW : $iThumbSizeW / 2) $iR = ($m.ThumbType = 0 ? $iThumbSizeH / 2 : 0) ; Round or Rect Thumb $iTrackR = $m.TrackSize / 2 Local $iYPos = ($iH - $iThumbSizeH - 1) - (($iH - $iThumbSizeH - 2) * $fPercent) Local $iTrackX = ($iW - $m.TrackSize) / 2 ; Draw Track Background __UC_DrawRoundedRect($hBack, $iTrackX, ($iThumbSizeH / 4), $m.TrackSize, $iH - ($iThumbSizeH / 2), $iTrackR, $hBrushTrack, 0) ; Draw Track Fill __UC_DrawRoundedRect($hBack, $iTrackX, $iYPos + ($iThumbSizeH / 4), $m.TrackSize, $iH - $iYPos - ($iThumbSizeH / 2), $iTrackR, $hBrushFill, 0) ; Draw Thumb (With HotTrack Pen if hovered) __UC_DrawRoundedRect($hBack, 2, $iYPos, $iThumbSizeW, $iThumbSizeH, $iR, $hBrushThumb, ($m.State = 2 ? $hPenHotTrack : $hPenThumbBorder)) EndIf ; Present to Screen _GDIPlus_GraphicsDrawImageRect($hGraphics, $hBitmap, 0, 0, $iW, $iH) ; Cleanup _GDIPlus_PenDispose($hPenHotTrack) _GDIPlus_PenDispose($hPenThumbBorder) _GDIPlus_BrushDispose($hBrushTrack) _GDIPlus_BrushDispose($hBrushFill) _GDIPlus_BrushDispose($hBrushThumb) _GDIPlus_GraphicsDispose($hBack) _GDIPlus_BitmapDispose($hBitmap) _GDIPlus_GraphicsDispose($hGraphics) EndFunc ;==>_UC_Slider_Draw Func _UC_Slider_UpdateFromMouse($hWnd, ByRef $m, $iX, $iY) Local $aSize = WinGetClientSize($hWnd) ; Fix for negative values (when mouse moves left/up) ; Windows sends 16-bit signed values in lParam If $iX > 32767 Then $iX -= 65536 If $iY > 32767 Then $iY -= 65536 ; Calculate the offset to center the thumb on the mouse position Local $iThumbSize, $iAvailableTrack, $fPercent = 0 If $m.Type = 0 Then ; HORIZONTAL ; The thumb starts at 0 and reaches the GUI width minus its own width $iThumbSize = $aSize[1] ; In horizontal, the thumb's width is the height of the GUI $iAvailableTrack = $aSize[0] - $iThumbSize $fPercent = ($iX - ($iThumbSize / 2)) / $iAvailableTrack Else ; VERTICAL $iThumbSize = $aSize[0] ; In vertical, the thumb's height is the width of the GUI $iAvailableTrack = $aSize[1] - $iThumbSize ; For vertical, by default 0 is below, so: $fPercent = ($aSize[1] - $iY - ($iThumbSize / 2)) / $iAvailableTrack EndIf ; LIMITATION If $fPercent < 0 Then $fPercent = 0 If $fPercent > 1 Then $fPercent = 1 Local $iNewVal = Int($m.Min + ($fPercent * ($m.Max - $m.Min))) If $iNewVal <> $m.Value Then $m.Value = $iNewVal _UC_Properties($m.UC_ControlID, $m) GUICtrlSendToDummy($m.UC_ControlID, $iNewVal) If $m.ShowTooltip Then _UC_ToolTip($iNewVal) EndIf EndFunc ;==>_UC_Slider_UpdateFromMouse Func _UC_Slider_WM_LBUTTONDOWN($idDummy, $hWnd, $iX, $iY) #forceref $hWnd, $iX, $iY Local $m = _UC_Properties($idDummy) If $m.State = 0 Then Return ; If is Disabled $m.IsDragging = 1 $m.State = 3 ; Pressed If $m.ShowTooltip Then _UC_ToolTip(String($m.Value)) _UC_Properties($idDummy, $m, False) ; *** False to avoid _UC_Redraw _WinAPI_SetCapture($hWnd) _UC_Slider_UpdateFromMouse($hWnd, $m, $iX, $iY) EndFunc ;==>_UC_Slider_WM_LBUTTONDOWN Func _UC_Slider_WM_LBUTTONUP($idDummy, $hWnd, $iX, $iY) #forceref $hWnd, $iX, $iY Local $m = _UC_Properties($idDummy) If $m.State = 0 Then Return ; If is Disabled $m.State = 2 ; Hover If $m.IsDragging Then $m.IsDragging = 0 _UC_Properties($idDummy, $m) _WinAPI_ReleaseCapture() _UC_ToolTip("") EndIf EndFunc ;==>_UC_Slider_WM_LBUTTONUP Func _UC_Slider_WM_MOUSEMOVE($idDummy, $hWnd, $iX, $iY) #forceref $hWnd, $iX, $iY Local $m = _UC_Properties($idDummy) If $m.State = 0 Then Return ; If is Disabled If $m.IsDragging Then _UC_Slider_UpdateFromMouse($hWnd, $m, $iX, $iY) Else If $m.State <> 0 And $m.State <> 2 And $m.State <> 3 Then $m.State = 2 ; Hover _UC_Properties($idDummy, $m) EndIf EndIf EndFunc ;==>_UC_Slider_WM_MOUSEMOVE Func _UC_Slider_UpdateFromValue($idDummy = Default, $iValue = 1) If $idDummy = Default Then $idDummy = _UC_Properties(1, "UC_ActiveControlID") If Not $idDummy Then Return SetError(1, 0, 0) Local $m = _UC_Properties($idDummy) If Not ($m.UC_Type = $UC_TYPE_SLIDER) Then Return SetError(2, 0, 0) Local $iNewValue $iNewValue = $m.Value + $iValue $iNewValue = ($iNewValue > $m.Max ? $m.Max : $iNewValue) $iNewValue = ($iNewValue < $m.Min ? $m.Min : $iNewValue) $m.Value = $iNewValue _UC_Properties($idDummy, $m) GUICtrlSendToDummy($idDummy, $iNewValue) EndFunc ;==>_UC_Slider_UpdateFromValue Func _UC_Slider_WM_LBUTTONDBLCLK($idDummy, $hWnd, $iX, $iY) #forceref $hWnd, $iX, $iY ; For now, a double click on a button should behave exactly like a fast single click. ; So we just forward the parameters straight to the Down handler. Return _UC_Slider_WM_LBUTTONDOWN($idDummy, $hWnd, $iX, $iY) EndFunc ;==>_UC_Slider_WM_LBUTTONDBLCLK #EndRegion ; ~~~~~~~~~~~~~ UC Slider API ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #Region ; ~~~~~~~~~~~~~ UC Button API ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Func _UC_Button_Create($hParent, $sText, $iX, $iY, $iW, $iH, $iCorner = 0, $hBtnCol = 0xFFFFFF, $hTxtCol = 0x000000) GUISwitch($hParent) Local $idDummy = GUICtrlCreateDummy() Local $hChild = GUICreate("", $iW, $iH, $iX, $iY, BitOR($WS_CHILD, $WS_VISIBLE, $WS_CLIPSIBLINGS, $WS_TABSTOP), $WS_EX_TRANSPARENT, $hParent) ; Store the button text in the Dummy control GUICtrlSetData($idDummy, $sText) __UC_Framework_Init($hParent) GUISetCursor(_UC_Get(1, "Cursor_Hand"), $GUI_CURSOR_OVERRIDE, $hChild) ; Calculate Hover and Pressed colors (Logic: BGR for WinAPI) Local $iBGR = _WinAPI_SwitchColor($hBtnCol) Local $iHov = _WinAPI_SwitchColor(_WinAPI_ColorAdjustLuma($iBGR, 20)) ; 20% Lighter Local $iPre = _WinAPI_SwitchColor(_WinAPI_ColorAdjustLuma($iBGR, -10)) ; 10% Darker Local $m[] ; Universal Properties $m.UC_Type = $UC_TYPE_BUTTON $m.UC_ControlID = $idDummy $m.UC_hWnd = $hChild $m.UC_hParent = $hParent ; Toggle Specific Properties $m.State = 1 ; 0=Disable ; 1=Normal ; 2=Hover ; 3=Pressed $m.CornerRadius = $iCorner $m.BtnColor = $hBtnCol $m.HoverColor = $iHov $m.PressColor = $iPre $m.TextColor = $hTxtCol $m.DisableColor = 0xCCCCCC $m.DisableTxtColor = 0x888888 $m.Text = $sText $m.Font = "Segoe UI" $m.FontSize = 9 $m.FontStyle = 0 ; 0=Normal ; 1=Bold ; 2=Italic ; 4=Underline; 8=Strikethrough $m.FontHorAlg = 1 ; Horizontal aligned ; 0=left ; 1=Center ; 2=right $m.FontVerAlg = 1 ; Vertical aligned ; 0=left ; 1=Center ; 2=right $m.ShowTooltip = 0 $m.Tooltip = "" _WinAPI_SetProp($hChild, "UC_ControlID", $idDummy) _UC_Properties($idDummy, $m) _UC_Properties(1, "UC_LastCreatedID", $idDummy) GUISwitch($hParent) Return $idDummy EndFunc ;==>_UC_Button_Create Func _UC_Button_Draw($hWnd, ByRef $m) Local $aSize = WinGetClientSize($hWnd) Local $iW = $aSize[0], $iH = $aSize[1] If $iW <= 0 Or $iH <= 0 Then Return Local $iR = $m.CornerRadius Local $hBGColor = "0xFF" & Hex(__UC_ParentColor($hWnd), 6) Local $hDrawCol, $hTextCol = $m.TextColor ; State-based color selection Switch $m.State Case 0 ; Disabled $hDrawCol = $m.DisableColor $hTextCol = $m.DisableTxtColor Case 2 ; Hover $hDrawCol = $m.HoverColor Case 3 ; Pressed $hDrawCol = $m.PressColor Case Else ; Normal (1) $hDrawCol = $m.BtnColor EndSwitch ; Initialize GDI+ Context Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hWnd) Local $hBitmap = _GDIPlus_BitmapCreateFromGraphics($iW, $iH, $hGraphics) Local $hBack = _GDIPlus_ImageGetGraphicsContext($hBitmap) ; Settings for Sharpening _GDIPlus_GraphicsSetSmoothingMode($hBack, 4) ; HighQuality Antialiasing _GDIPlus_GraphicsSetPixelOffsetMode($hBack, 4) ; HighQuality (Half-pixel offset) _GDIPlus_GraphicsSetTextRenderingHint($hBack, 5) ; TextRenderingHintClearTypeGridFit ; Clear background with parent color _GDIPlus_GraphicsClear($hBack, $hBGColor) ; Create Background Brush Local $hBrushBg = _GDIPlus_BrushCreateSolid("0xFF" & Hex($hDrawCol, 6)) ; Apply "Golden Rule" for Pill Shape: Radius cannot exceed Height / 2 Local $iMaxR = $iH / 2 If $iR > $iMaxR Then $iR = $iMaxR ; Draw Button Shape ; We pass 0 for the Pen because the button currently uses only Fill __UC_DrawRoundedRect($hBack, 0, 0, $iW - 1, $iH - 1, $iR, $hBrushBg, 0) ; Draw Text Local $hFamily = _GDIPlus_FontFamilyCreate($m.Font) Local $hFont = _GDIPlus_FontCreate($hFamily, $m.FontSize, $m.FontStyle) Local $hFormat = _GDIPlus_StringFormatCreate() _GDIPlus_StringFormatSetAlign($hFormat, $m.FontHorAlg) ; Horizontal alignment _GDIPlus_StringFormatSetLineAlign($hFormat, $m.FontVerAlg) ; Vertical alignment Local $hBrushTxt = _GDIPlus_BrushCreateSolid("0xFF" & Hex($hTextCol, 6)) Local $tLayout = _GDIPlus_RectFCreate(0, 0, $iW, $iH) _GDIPlus_GraphicsDrawStringEx($hBack, $m.Text, $hFont, $tLayout, $hFormat, $hBrushTxt) ; Present to Screen (Double Buffering) _GDIPlus_GraphicsDrawImage($hGraphics, $hBitmap, 0, 0) ; Cleanup Section _GDIPlus_BrushDispose($hBrushBg) _GDIPlus_BrushDispose($hBrushTxt) _GDIPlus_FontDispose($hFont) _GDIPlus_FontFamilyDispose($hFamily) _GDIPlus_StringFormatDispose($hFormat) _GDIPlus_GraphicsDispose($hBack) _GDIPlus_BitmapDispose($hBitmap) _GDIPlus_GraphicsDispose($hGraphics) EndFunc ;==>_UC_Button_Draw Func _UC_Button_WM_LBUTTONDOWN($idDummy, $hWnd, $iX, $iY) #forceref $hWnd, $iX, $iY Local $m = _UC_Properties($idDummy) If $m.State = 0 Then Return ; If is Disabled $m.State = 3 ; Pressed _UC_Properties($idDummy, $m) _WinAPI_SetCapture($hWnd) EndFunc ;==>_UC_Button_WM_LBUTTONDOWN Func _UC_Button_WM_LBUTTONUP($idDummy, $hWnd, $iX, $iY) #forceref $idDummy, $iX, $iY Local $m = _UC_Properties($idDummy) If $m.State = 3 Then ; If is pressed _WinAPI_ReleaseCapture() ; Area control If _UC_IsMouseOver($hWnd) Or ($iX = -1 And $iY = -1) Then $m.State = 2 ; Hover _UC_Properties($idDummy, $m) GUICtrlSendToDummy($idDummy, $m.Text) ; Execution! Else $m.State = 1 ; Normal (Cancel execution) _UC_Properties($idDummy, $m) EndIf EndIf EndFunc ;==>_UC_Button_WM_LBUTTONUP Func _UC_Button_WM_MOUSEMOVE($idDummy, $hWnd, $iX, $iY) #forceref $hWnd, $iX, $iY Local $m = _UC_Properties($idDummy) If $m.State = 0 Then Return ; If is Disabled If $m.State = 1 Then ; If is normal $m.State = 2 ; Hover _UC_Properties($idDummy, $m) If $m.ShowTooltip And _UC_IsMouseOver($hWnd) Then _UC_ToolTip($m.Tooltip) EndIf EndFunc ;==>_UC_Button_WM_MOUSEMOVE Func _UC_Button_WM_LBUTTONDBLCLK($idDummy, $hWnd, $iX, $iY) #forceref $hWnd, $iX, $iY ; For now, a double click on a button should behave exactly like a fast single click. ; So we just forward the parameters straight to the Down handler. Return _UC_Button_WM_LBUTTONDOWN($idDummy, $hWnd, $iX, $iY) EndFunc ;==>_UC_Button_WM_LBUTTONDBLCLK #EndRegion ; ~~~~~~~~~~~~~ UC Button API ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #Region ; ~~~~~~~~~~~~~ UC Link API ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Func _UC_Link_Create($hParent, $sText, $sURL, $iX, $iY, $iW, $iH, $iFontSize = 9, $hColor = 0x0094FF, $hHoverColor = 0xFF0000) GUISwitch($hParent) Local $idDummy = GUICtrlCreateDummy() Local $hChild = GUICreate("", $iW, $iH, $iX, $iY, BitOR($WS_CHILD, $WS_VISIBLE, $WS_CLIPSIBLINGS, $WS_TABSTOP), $WS_EX_TRANSPARENT, $hParent) __UC_Framework_Init($hParent) GUISetCursor(_UC_Get(1, "Cursor_Hand"), $GUI_CURSOR_OVERRIDE, $hChild) Local $m[] $m.UC_Type = $UC_TYPE_LINK $m.UC_ControlID = $idDummy $m.UC_hWnd = $hChild $m.UC_hParent = $hParent ; Link Specific $m.Text = $sText ; text to display $m.Value = $sURL ; link (local or remote) $m.State = 1 ; 0=Disable ; 1=Normal ; 2=Hover ; 3=Pressed $m.Color = $hColor ; Text Color $m.HoverColor = $hHoverColor ; hover Color $m.DisableTxtColor = 0x888888 ; Disabled Text Color $m.Font = "Segoe UI" $m.FontSize = $iFontSize $m.ShowTooltip = 0 _WinAPI_SetProp($hChild, "UC_ControlID", $idDummy) _UC_Properties($idDummy, $m) _UC_Properties(1, "UC_LastCreatedID", $idDummy) GUISwitch($hParent) Return $idDummy EndFunc ;==>_UC_Link_Create Func _UC_Link_Draw($hWnd, ByRef $m) Local $aSize = WinGetClientSize($hWnd) Local $iW = $aSize[0], $iH = $aSize[1] Local $hBGColor = "0xFF" & Hex(__UC_ParentColor($hWnd), 6) ;~ GUISetCursor(_UC_Get(1, ($m.State == 0 ? "Cursor_Arrow" : "Cursor_Hand")), $GUI_CURSOR_OVERRIDE, $hWnd) Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hWnd) Local $hBitmap = _GDIPlus_BitmapCreateFromGraphics($iW, $iH, $hGraphics) Local $hBack = _GDIPlus_ImageGetGraphicsContext($hBitmap) ; Settings for Sharpening _GDIPlus_GraphicsSetSmoothingMode($hBack, 4) ; HighQuality Antialiasing _GDIPlus_GraphicsSetPixelOffsetMode($hBack, 4) ; HighQuality (Half-pixel offset) _GDIPlus_GraphicsSetTextRenderingHint($hBack, 5) ; TextRenderingHintClearTypeGridFit ; Clear background with parent color _GDIPlus_GraphicsClear($hBack, $hBGColor) ; Color and style selection based on State Local $iDrawCol Local $iStyle ; 0=Normal, 1=Bold, 2=Italic, 4=Underline, 8=Strikethrough Switch $m.State Case 0 ; Disabled $iDrawCol = $m.DisableColor $iStyle = 2 Case 1 ; Normal $iDrawCol = $m.Color $iStyle = 0 Case 2 ; Hover $iDrawCol = $m.HoverColor $iStyle = 4 Case Else ; Normal (1) $iDrawCol = $m.Color $iStyle = 0 EndSwitch Local $hBrushTxt = _GDIPlus_BrushCreateSolid("0xFF" & Hex($iDrawCol, 6)) Local $hFamily = _GDIPlus_FontFamilyCreate($m.Font) Local $hFont = _GDIPlus_FontCreate($hFamily, $m.FontSize, $iStyle) Local $tLayout = _GDIPlus_RectFCreate(0, 0, $iW, $iH) Local $hFormat = _GDIPlus_StringFormatCreate() ; Present to Screen _GDIPlus_GraphicsDrawStringEx($hBack, $m.Text, $hFont, $tLayout, $hFormat, $hBrushTxt) _GDIPlus_GraphicsDrawImage($hGraphics, $hBitmap, 0, 0) ; Cleanup _GDIPlus_FontDispose($hFont) _GDIPlus_FontFamilyDispose($hFamily) _GDIPlus_BrushDispose($hBrushTxt) _GDIPlus_GraphicsDispose($hBack) _GDIPlus_BitmapDispose($hBitmap) _GDIPlus_GraphicsDispose($hGraphics) EndFunc ;==>_UC_Link_Draw Func _UC_Link_WM_LBUTTONDOWN($idDummy, $hWnd, $iX, $iY) #forceref $hWnd, $iX, $iY Local $m = _UC_Properties($idDummy) If $m.State = 0 Then Return ; If is Disabled $m.State = 3 ; is pressed _UC_Properties($idDummy, $m) _WinAPI_SetCapture($hWnd) _UC_ToolTip("") EndFunc ;==>_UC_Link_WM_LBUTTONDOWN Func _UC_Link_WM_LBUTTONUP($idDummy, $hWnd, $iX, $iY) #forceref $idDummy, $iX, $iY Local $m = _UC_Properties($idDummy) If $m.State = 3 Then ; If is pressed _WinAPI_ReleaseCapture() ; Area control If _UC_IsMouseOver($hWnd) Or ($iX = -1 And $iY = -1) Then $m.State = 2 ; Hover _UC_Properties($idDummy, $m) GUICtrlSendToDummy($idDummy, $m.Value) ; Execution! Else $m.State = 1 ; Normal (Cancel execution) _UC_Properties($idDummy, $m) EndIf EndIf EndFunc ;==>_UC_Link_WM_LBUTTONUP Func _UC_Link_WM_MOUSEMOVE($idDummy, $hWnd, $iX, $iY) #forceref $hWnd, $iX, $iY Local $m = _UC_Properties($idDummy) If $m.State = 0 Then Return ; If is Disabled If $m.State = 1 Then ; If is normal $m.State = 2 ; Hover _UC_Properties($idDummy, $m) If $m.ShowTooltip And _UC_IsMouseOver($hWnd) Then _UC_ToolTip($m.Value) EndIf EndFunc ;==>_UC_Link_WM_MOUSEMOVE Func _UC_Link_WM_LBUTTONDBLCLK($idDummy, $hWnd, $iX, $iY) #forceref $hWnd, $iX, $iY ; For now, a double click on a button should behave exactly like a fast single click. ; So we just forward the parameters straight to the Down handler. Return _UC_Link_WM_LBUTTONDOWN($idDummy, $hWnd, $iX, $iY) EndFunc ;==>_UC_Link_WM_LBUTTONDBLCLK #EndRegion ; ~~~~~~~~~~~~~ UC Link API ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #Region ; ~~~~~~~~~~~~~ UC Label API ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Func _UC_Label_Create($hParent, $sText, $iX, $iY, $iW, $iH, $iRotationIdx = 0, $hColor = 0xFFFFFF, $hBkColor = -2) GUISwitch($hParent) Local $idDummy = GUICtrlCreateDummy() Local $hChild = GUICreate("", $iW, $iH, $iX, $iY, BitOR($WS_CHILD, $WS_VISIBLE, $WS_CLIPSIBLINGS), $WS_EX_TRANSPARENT, $hParent) If $iRotationIdx > 3 Or $iRotationIdx < 0 Then $iRotationIdx = 0 __UC_Framework_Init($hParent) ;~ GUISetCursor(_UC_Get(1, "Cursor_Hand"), $GUI_CURSOR_OVERRIDE, $hChild) Local $m[] $m.UC_Type = $UC_TYPE_LABEL $m.UC_ControlID = $idDummy $m.UC_hWnd = $hChild $m.UC_hParent = $hParent ; Properties $m.Text = $sText $m.RotationIdx = $iRotationIdx ; 0=0, 1=90, 2=180, 3=270 $m.Color = $hColor ; Text Color $m.Color_Bk = $hBkColor ; -2 = Transparent (Parent Color) ; $GUI_BKCOLOR_TRANSPARENT $m.Color_Hover = $hColor ; Default: same as color $m.Font = "Segoe UI" ; font name $m.FontSize = 9 ; Initial Size $m.FontStyle = 0 ; 0=Normal, 1=Bold, etc. $m.Padding = 4 ; Internal safety margin $m.State = 1 ; 0=Disable ; 1=Normal ; 2=Hover ; 3=Pressed _WinAPI_SetProp($hChild, "UC_ControlID", $idDummy) _UC_Properties($idDummy, $m) _UC_Properties(1, "UC_LastCreatedID", $idDummy) GUISwitch($hParent) Return $idDummy EndFunc ;==>_UC_Label_Create Func _UC_Label_Draw($hWnd, ByRef $m) Local $aClientSize = WinGetClientSize($hWnd) Local $iW = $aClientSize[0], $iH = $aClientSize[1] ; GUISetCursor(_UC_Get(1, ($m.State == 0 ? "Cursor_Arrow" : "Cursor_Hand")), $GUI_CURSOR_OVERRIDE, $hWnd) Local $hBGColor = "0xFF" & Hex(($m.Color_Bk == -2 ? __UC_ParentColor($hWnd) : $m.Color_Bk), 6) Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hWnd) Local $hBitmap = _GDIPlus_BitmapCreateFromGraphics($iW, $iH, $hGraphics) Local $hBack = _GDIPlus_ImageGetGraphicsContext($hBitmap) ; Settings for Sharpening _GDIPlus_GraphicsSetSmoothingMode($hBack, 4) ; HighQuality Antialiasing _GDIPlus_GraphicsSetPixelOffsetMode($hBack, 4) ; HighQuality (Half-pixel offset) _GDIPlus_GraphicsSetTextRenderingHint($hBack, 5) ; TextRenderingHintClearTypeGridFit _GDIPlus_GraphicsClear($hBack, $hBGColor) ; --- CLAMPING LOGIC --- Local $fFitSize = $m.FontSize Local $aSize Local $aAngles = [0, 90, 180, 270] Local $iAngle = $aAngles[$m.RotationIdx] While 1 $aSize = _UC_GetTextSize($m.Text, $m.Font, $fFitSize, $m.FontStyle) Local $iTargetDim = ($iAngle = 90 Or $iAngle = 270) ? $iH : $iW If $aSize[0] > ($iTargetDim - $m.Padding) And $fFitSize > 4 Then $fFitSize -= 0.5 Else ExitLoop EndIf WEnd $m.FontSize = $fFitSize ; --- STYLING --- Local $iDrawCol = ($m.State = 2 ? $m.Color_Hover : $m.Color) Local $hBrushTxt = _GDIPlus_BrushCreateSolid("0xFF" & Hex($iDrawCol, 6)) Local $hFamily = _GDIPlus_FontFamilyCreate($m.Font) Local $hFont = _GDIPlus_FontCreate($hFamily, $m.FontSize, $m.FontStyle) Local $hFormat = _GDIPlus_StringFormatCreate(0x1000) _GDIPlus_StringFormatSetAlign($hFormat, 1) _GDIPlus_StringFormatSetLineAlign($hFormat, 1) ; --- ROTATION & TRANSLATION --- _GDIPlus_GraphicsTranslateTransform($hBack, $iW / 2, $iH / 2) _GDIPlus_GraphicsRotateTransform($hBack, $iAngle) ; We use large values to avoid clipping. Local $iDim = ($iW > $iH ? $iW : $iH) * 2 Local $tLayout = _GDIPlus_RectFCreate(-$iDim / 2, -$iDim / 2, $iDim, $iDim) ; Present to Screen _GDIPlus_GraphicsDrawStringEx($hBack, $m.Text, $hFont, $tLayout, $hFormat, $hBrushTxt) _GDIPlus_GraphicsDrawImage($hGraphics, $hBitmap, 0, 0) ; Cleanup _GDIPlus_StringFormatDispose($hFormat) _GDIPlus_FontDispose($hFont) _GDIPlus_FontFamilyDispose($hFamily) _GDIPlus_BrushDispose($hBrushTxt) _GDIPlus_GraphicsDispose($hBack) _GDIPlus_BitmapDispose($hBitmap) _GDIPlus_GraphicsDispose($hGraphics) EndFunc ;==>_UC_Label_Draw Func _UC_Label_WM_LBUTTONDOWN($idDummy, $hWnd, $iX, $iY) Return #forceref $idDummy, $hWnd, $iX, $iY ;~ Local $m = _UC_Properties($idDummy) ;~ If $m.State = 0 Then Return ; If is Disabled ;~ $m.State = 3 ; is pressed ;~ _UC_Properties($idDummy, $m) ;~ _WinAPI_SetCapture($hWnd) ;~ _UC_ToolTip("") EndFunc ;==>_UC_Label_WM_LBUTTONDOWN Func _UC_Label_WM_MOUSEMOVE($idDummy, $hWnd, $iX, $iY) #forceref $hWnd, $iX, $iY Local $m = _UC_Properties($idDummy) If $m.State = 0 Then Return ; If is Disabled If $m.State = 1 Then ; If is normal $m.State = 2 _UC_Properties($idDummy, $m) EndIf EndFunc ;==>_UC_Label_WM_MOUSEMOVE Func _UC_Label_WM_LBUTTONDBLCLK($idDummy, $hWnd, $iX, $iY) #forceref $hWnd, $iX, $iY ; For now, a double click on a button should behave exactly like a fast single click. ; So we just forward the parameters straight to the Down handler. Return _UC_Label_WM_LBUTTONDOWN($idDummy, $hWnd, $iX, $iY) EndFunc ;==>_UC_Label_WM_LBUTTONDBLCLK #EndRegion ; ~~~~~~~~~~~~~ UC Label API ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #Region ; ~~~~~~~~~~~~~ UC Image API ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Func _UC_Image_Create($hParent, $sFilename, $iX, $iY, $fScale = 1.0) GUISwitch($hParent) Local $idDummy = GUICtrlCreateDummy() Local $hImage = _GDIPlus_ImageLoadFromFile($sFilename) Local $iW = Int(_GDIPlus_ImageGetWidth($hImage) * $fScale) Local $iH = Int(_GDIPlus_ImageGetHeight($hImage) * $fScale) Local $hChild = GUICreate("UC_Control_" & $idDummy, $iW, $iH, $iX, $iY, BitOR($WS_CHILD, $WS_VISIBLE, $WS_CLIPSIBLINGS), $WS_EX_TRANSPARENT, $hParent) __UC_Framework_Init($hParent) Local $m[] $m.UC_Type = $UC_TYPE_IMAGE $m.UC_ControlID = $idDummy $m.UC_hWnd = $hChild $m.UC_hParent = $hParent $m.State = 1 ; 1=Normal, 2=Hover, 3=Pressed $m.Filename = $sFilename $m.Scale = $fScale $m.Image = $hImage $m.Width = $iW $m.Height = $iH $m.Resampling = 7 ; HighQualityBicubic $m.ShowTooltip = 0 $m.Tooltip = "" $m.SetFocus = 0 _WinAPI_SetProp($hChild, "UC_ControlID", $idDummy) _UC_Properties($idDummy, $m) _UC_Properties(1, "UC_LastCreatedID", $idDummy) GUISwitch($hParent) Return $idDummy EndFunc ;==>_UC_Image_Create Func _UC_Image_Draw($hWnd, ByRef $m) Local $aSize = WinGetClientSize($hWnd) Local $iW = $aSize[0], $iH = $aSize[1] If $iW <= 0 Or $iH <= 0 Then Return Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hWnd) Local $hBitmap = _GDIPlus_BitmapCreateFromGraphics($iW, $iH, $hGraphics) Local $hBack = _GDIPlus_ImageGetGraphicsContext($hBitmap) _GDIPlus_GraphicsSetInterpolationMode($hBack, $m.Resampling) _GDIPlus_GraphicsSetPixelOffsetMode($hBack, 4) Local $hBGColor = "0xFF" & Hex(__UC_ParentColor($hWnd), 6) _GDIPlus_GraphicsClear($hBack, $hBGColor) If $m.Image <> 0 Then _GDIPlus_GraphicsDrawImageRect($hBack, $m.Image, 0, 0, $iW, $iH) EndIf ; Visual feedback for Hover/Pressed (Optional) If $m.State = 3 And $m.SetFocus Then ; Pressed: Slight darkening Local $hBrushOver = _GDIPlus_BrushCreateSolid(0x30000000) _GDIPlus_GraphicsFillRect($hBack, 0, 0, $iW, $iH, $hBrushOver) _GDIPlus_BrushDispose($hBrushOver) EndIf _GDIPlus_GraphicsDrawImage($hGraphics, $hBitmap, 0, 0) _GDIPlus_GraphicsDispose($hBack) _GDIPlus_BitmapDispose($hBitmap) _GDIPlus_GraphicsDispose($hGraphics) EndFunc ;==>_UC_Image_Draw Func _UC_Image_WM_LBUTTONDOWN($idDummy, $hWnd, $iX, $iY) #forceref $hWnd, $iX, $iY Local $m = _UC_Properties($idDummy) If $m.State = 0 Then Return $m.State = 3 ; Pressed _UC_Properties($idDummy, $m) ; ReDraw to show feedback _WinAPI_SetCapture($hWnd) EndFunc ;==>_UC_Image_WM_LBUTTONDOWN Func _UC_Image_WM_LBUTTONUP($idDummy, $hWnd, $iX, $iY) Local $m = _UC_Properties($idDummy) If $m.State = 3 Then _WinAPI_ReleaseCapture() If _UC_IsMouseOver($hWnd) Or ($iX = -1 And $iY = -1) Then $m.State = 2 ; Hover _UC_Properties($idDummy, $m) GUICtrlSendToDummy($idDummy, $m.UC_ControlID) Else $m.State = 1 ; Normal _UC_Properties($idDummy, $m, True) EndIf EndIf EndFunc ;==>_UC_Image_WM_LBUTTONUP Func _UC_Image_WM_MOUSEMOVE($idDummy, $hWnd, $iX, $iY) #forceref $hWnd, $iX, $iY Local $m = _UC_Properties($idDummy) If $m.State = 0 Or $m.State = 3 Then Return If $m.State = 1 Then $m.State = 2 ; Hover _UC_Properties($idDummy, $m) ; ReDraw for hover effect If $m.ShowTooltip Then _UC_ToolTip($m.Tooltip) EndIf EndFunc ;==>_UC_Image_WM_MOUSEMOVE Func _UC_Image_WM_LBUTTONDBLCLK($idDummy, $hWnd, $iX, $iY) #forceref $hWnd, $iX, $iY ; For now, a double click on a button should behave exactly like a fast single click. ; So we just forward the parameters straight to the Down handler. Return _UC_Image_WM_LBUTTONDOWN($idDummy, $hWnd, $iX, $iY) EndFunc ;==>_UC_Image_WM_LBUTTONDBLCLK #EndRegion ; ~~~~~~~~~~~~~ UC Image API ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #Region ; ~~~~~~~~~~~~~ UC ProgressBar API ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; #FUNCTION# ==================================================================================================================== ; Name...........: _UC_ProgressBar_Create ; Description....: Creates a custom GDI+ ProgressBar control. ; Syntax.........: _UC_ProgressBar_Create($hParent, $iX, $iY, $iW, $iH [, ...]) ; Author.........: Polar ; =============================================================================================================================== Func _UC_ProgressBar_Create($hParent, $iX, $iY, $iW, $iH, $iMin = 0, $iMax = 100, $iValue = 0, _ $iType = 0, $iCornerRadius = 0, $hFillColor = 0x4CD964, $hTrackColor = 0xD1D1D1, $hBorderColor = 0xA0A0A0) GUISwitch($hParent) Local $idDummy = GUICtrlCreateDummy() Local $hChild = GUICreate("", $iW, $iH, $iX, $iY, BitOR($WS_CHILD, $WS_VISIBLE, $WS_CLIPSIBLINGS), $WS_EX_TRANSPARENT, $hParent) __UC_Framework_Init($hParent) Local $m[] ; Universal Properties $m.UC_Type = $UC_TYPE_PROGRESSBAR $m.UC_ControlID = $idDummy $m.UC_hWnd = $hChild $m.UC_hParent = $hParent ; ProgressBar Properties $m.State = 1 $m.Min = $iMin $m.Max = $iMax $m.Value = $iValue $m.Type = $iType ; 0=Horizontal | 1=Vertical $m.CornerRadius = $iCornerRadius $m.FillColor = $hFillColor $m.TrackColor = $hTrackColor $m.BorderColor = $hBorderColor $m.ShowPercent = False $m.TextColor = 0x000000 $m.Font = "Segoe UI" $m.FontSize = 9 $m.FontStyle = 1 _WinAPI_SetProp($hChild, "UC_ControlID", $idDummy) _UC_Properties($idDummy, $m) _UC_Properties(1, "UC_LastCreatedID", $idDummy) GUISwitch($hParent) Return $idDummy EndFunc ;==>_UC_ProgressBar_Create Func _UC_ProgressBar_Draw($hWnd, ByRef $m) Local $aSize = WinGetClientSize($hWnd) Local $iW = $aSize[0] Local $iH = $aSize[1] If $iW <= 0 Or $iH <= 0 Then Return Local $hBGColor = "0xFF" & Hex(__UC_ParentColor($hWnd), 6) ; Clamp value If $m.Value < $m.Min Then $m.Value = $m.Min If $m.Value > $m.Max Then $m.Value = $m.Max ; Calculate Percentage Local $iRange = ($m.Max - $m.Min) If $iRange <= 0 Then $iRange = 1 Local $fPercent = ($m.Value - $m.Min) / $iRange ; GDI+ Initialization Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hWnd) Local $hBitmap = _GDIPlus_BitmapCreateFromGraphics($iW, $iH, $hGraphics) Local $hBack = _GDIPlus_ImageGetGraphicsContext($hBitmap) ; Set High Quality Rendering _GDIPlus_GraphicsSetSmoothingMode($hBack, 4) _GDIPlus_GraphicsSetPixelOffsetMode($hBack, 4) _GDIPlus_GraphicsSetTextRenderingHint($hBack, 5) ; Clear Background _GDIPlus_GraphicsClear($hBack, $hBGColor) ; Create Resources Local $hBrushTrack = _GDIPlus_BrushCreateSolid("0xFF" & Hex($m.TrackColor, 6)) Local $hBrushFill = _GDIPlus_BrushCreateSolid("0xFF" & Hex($m.FillColor, 6)) Local $hBrushText = _GDIPlus_BrushCreateSolid("0xFF" & Hex($m.TextColor, 6)) Local $hPenBorder = _GDIPlus_PenCreate("0xFF" & Hex($m.BorderColor, 6), 1) ; Radius Calculation Local $iR = $m.CornerRadius Local $iMaxR = (($iH < $iW) ? $iH : $iW) / 2 If $iR > $iMaxR Then $iR = $iMaxR ; Draw Track (Background of the Progress Bar) __UC_DrawRoundedRect($hBack, 0, 0, $iW - 1, $iH - 1, $iR, $hBrushTrack, $hPenBorder) ; Draw Fill (The actual progress) Local $iFillX, $iFillY, $iFillW, $iFillH If $m.Type = 0 Then ; Horizontal $iFillW = Int(($iW - 2) * $fPercent) If $iFillW > 0 Then ; Fill only, no border for the inner bar __UC_DrawRoundedRect($hBack, 1, 1, $iFillW, $iH - 3, $iR, $hBrushFill, 0) EndIf Else ; Vertical $iFillH = Int(($iH - 2) * $fPercent) If $iFillH > 0 Then $iFillX = 1 $iFillY = $iH - $iFillH - 1 ; Fill only, no border for the inner bar __UC_DrawRoundedRect($hBack, $iFillX, $iFillY, $iW - 3, $iFillH, $iR, $hBrushFill, 0) EndIf EndIf ; Draw Percent Text (Optional) If $m.ShowPercent Then Local $iPercent = Int($fPercent * 100) Local $hFamily = _GDIPlus_FontFamilyCreate($m.Font) Local $hFont = _GDIPlus_FontCreate($hFamily, $m.FontSize, $m.FontStyle) Local $hFormat = _GDIPlus_StringFormatCreate() _GDIPlus_StringFormatSetAlign($hFormat, 1) ; Center _GDIPlus_StringFormatSetLineAlign($hFormat, 1) ; Center Local $tLayout = _GDIPlus_RectFCreate(0, 0, $iW, $iH) _GDIPlus_GraphicsDrawStringEx($hBack, $iPercent & "%", $hFont, $tLayout, $hFormat, $hBrushText) ; Text Resources Cleanup _GDIPlus_StringFormatDispose($hFormat) _GDIPlus_FontDispose($hFont) _GDIPlus_FontFamilyDispose($hFamily) EndIf ; Present to Screen _GDIPlus_GraphicsDrawImageRect($hGraphics, $hBitmap, 0, 0, $iW, $iH) ; Final Cleanup _GDIPlus_PenDispose($hPenBorder) _GDIPlus_BrushDispose($hBrushTrack) _GDIPlus_BrushDispose($hBrushFill) _GDIPlus_BrushDispose($hBrushText) _GDIPlus_GraphicsDispose($hBack) _GDIPlus_BitmapDispose($hBitmap) _GDIPlus_GraphicsDispose($hGraphics) EndFunc ;==>_UC_ProgressBar_Draw #EndRegion ; ~~~~~~~~~~~~~ UC ProgressBar API ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #Region ; ~~~~~~~~~~~~~ UC Radial Progress API ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Func _UC_RadialProgress_Create( _ $hParent, _ $iX, _ $iY, _ $iSize, _ $iMin = 0, _ $iMax = 100, _ $iValue = 0, _ $hProgressColor = 0x0078D7, _ $hTrackColor = 0x404040) GUISwitch($hParent) Local $idDummy = GUICtrlCreateDummy() Local $hChild = GUICreate( _ "", _ $iSize, _ $iSize, _ $iX, _ $iY, _ BitOR($WS_CHILD, $WS_VISIBLE, $WS_CLIPSIBLINGS), _ $WS_EX_TRANSPARENT, _ $hParent) __UC_Framework_Init($hParent) Local $m[] ; Universal $m.UC_Type = $UC_TYPE_RADIALPROGRESS $m.UC_ControlID = $idDummy $m.UC_hWnd = $hChild $m.UC_hParent = $hParent ; Values $m.Min = $iMin $m.Max = $iMax $m.Value = $iValue ; Appearance $m.ProgressColor = $hProgressColor $m.TrackColor = $hTrackColor ; Ring $m.RingThickness = 10 $m.StartAngle = -90 $m.RoundCap = 1 ; Text $m.ShowPercent = 1 $m.TextColor = 0xFFFFFF $m.Font = "Segoe UI" $m.FontSize = 18 $m.FontStyle = 1 ; Optional glow $m.Glow = 0 ; Background center $m.CenterColor = 0x202020 _WinAPI_SetProp($hChild, "UC_ControlID", $idDummy) _UC_Properties($idDummy, $m) _UC_Properties(1, "UC_LastCreatedID", $idDummy) GUISwitch($hParent) Return $idDummy EndFunc ;==>_UC_RadialProgress_Create Func _UC_RadialProgress_Draw($hWnd, ByRef $m) Local $aSize = WinGetClientSize($hWnd) Local $iW = $aSize[0] Local $iH = $aSize[1] If $iW <= 0 Or $iH <= 0 Then Return Local $hBGColor = "0xFF" & Hex(__UC_ParentColor($hWnd), 6) Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hWnd) Local $hBitmap = _GDIPlus_BitmapCreateFromGraphics($iW, $iH, $hGraphics) Local $hBack = _GDIPlus_ImageGetGraphicsContext($hBitmap) ; Quality _GDIPlus_GraphicsSetSmoothingMode($hBack, 4) _GDIPlus_GraphicsSetPixelOffsetMode($hBack, 4) _GDIPlus_GraphicsSetTextRenderingHint($hBack, 5) ; Clear _GDIPlus_GraphicsClear($hBack, $hBGColor) ; Percent Local $iRange = $m.Max - $m.Min If $iRange <= 0 Then $iRange = 1 Local $fPercent = ($m.Value - $m.Min) / $iRange If $fPercent < 0 Then $fPercent = 0 If $fPercent > 1 Then $fPercent = 1 Local $fSweep = 360 * $fPercent ; Geometry Local $iThickness = $m.RingThickness Local $iPad = Ceiling($iThickness / 2) + 2 Local $iArcW = $iW - ($iPad * 2) Local $iArcH = $iH - ($iPad * 2) ; Pens Local $hTrackPen = _GDIPlus_PenCreate( _ "0xFF" & Hex($m.TrackColor, 6), _ $iThickness) Local $hProgPen = _GDIPlus_PenCreate( _ "0xFF" & Hex($m.ProgressColor, 6), _ $iThickness) ; Round caps If $m.RoundCap Then _GDIPlus_PenSetStartCap($hProgPen, 2) _GDIPlus_PenSetEndCap($hProgPen, 2) EndIf ; Track _GDIPlus_GraphicsDrawArc( _ $hBack, _ $iPad, _ $iPad, _ $iArcW, _ $iArcH, _ 0, _ 360, _ $hTrackPen) ; Glow If $m.Glow Then Local $hGlowPen = _GDIPlus_PenCreate( _ "0x40" & Hex($m.ProgressColor, 6), _ $iThickness + 8) If $m.RoundCap Then _GDIPlus_PenSetStartCap($hGlowPen, 2) _GDIPlus_PenSetEndCap($hGlowPen, 2) EndIf _GDIPlus_GraphicsDrawArc( _ $hBack, _ $iPad, _ $iPad, _ $iArcW, _ $iArcH, _ $m.StartAngle, _ $fSweep, _ $hGlowPen) _GDIPlus_PenDispose($hGlowPen) EndIf ; Progress arc _GDIPlus_GraphicsDrawArc( _ $hBack, _ $iPad, _ $iPad, _ $iArcW, _ $iArcH, _ $m.StartAngle, _ $fSweep, _ $hProgPen) ; Center fill If $m.CenterColor <> -1 Then Local $hCenterBrush = _GDIPlus_BrushCreateSolid( _ "0xFF" & Hex($m.CenterColor, 6)) Local $iCenter = $iThickness + 4 _GDIPlus_GraphicsFillEllipse( _ $hBack, _ $iCenter, _ $iCenter, _ $iW - ($iCenter * 2), _ $iH - ($iCenter * 2), _ $hCenterBrush) _GDIPlus_BrushDispose($hCenterBrush) EndIf ; Percentage text If $m.ShowPercent Then Local $sText = Int($fPercent * 100) & "%" Local $hFamily = _GDIPlus_FontFamilyCreate($m.Font) Local $hFont = _GDIPlus_FontCreate( _ $hFamily, _ $m.FontSize, _ $m.FontStyle) Local $hBrushTxt = _GDIPlus_BrushCreateSolid( _ "0xFF" & Hex($m.TextColor, 6)) Local $hFormat = _GDIPlus_StringFormatCreate() _GDIPlus_StringFormatSetAlign($hFormat, 1) _GDIPlus_StringFormatSetLineAlign($hFormat, 1) Local $tLayout = _GDIPlus_RectFCreate(0, 0, $iW, $iH) _GDIPlus_GraphicsDrawStringEx( _ $hBack, _ $sText, _ $hFont, _ $tLayout, _ $hFormat, _ $hBrushTxt) _GDIPlus_StringFormatDispose($hFormat) _GDIPlus_BrushDispose($hBrushTxt) _GDIPlus_FontDispose($hFont) _GDIPlus_FontFamilyDispose($hFamily) EndIf ; Present _GDIPlus_GraphicsDrawImageRect( _ $hGraphics, _ $hBitmap, _ 0, _ 0, _ $iW, _ $iH) ; Cleanup _GDIPlus_PenDispose($hTrackPen) _GDIPlus_PenDispose($hProgPen) _GDIPlus_GraphicsDispose($hBack) _GDIPlus_BitmapDispose($hBitmap) _GDIPlus_GraphicsDispose($hGraphics) EndFunc ;==>_UC_RadialProgress_Draw #EndRegion ; ~~~~~~~~~~~~~ UC Radial Progress API ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Please, every comment is appreciated!
leave your comments and experiences here!
Thank you very much
Edited by ioa747
Version (0.0.8.0)


Comments
Post a Comment