Jump to content

Recommended Posts

Posted
7 hours ago, argumentum said:

Edit: I was running on x64. It don't crash on x86.

this is a Timer management issue 😬
which I am trying to solve
thanks for pointing it out 🫡

I know that I know nothing

Posted
1 hour ago, ioa747 said:

this is a Timer management issue 😬
which I am trying to solve

It seems it might be an issue with _Timer_KillTimer on x64.

This little script demonstrates. 
Tried on v3.3.16.1 and a fresh download of v3.3.18.0

#NoTrayIcon
#include <GUIConstantsEx.au3>
#include <Timers.au3>
#include <WinAPISys.au3>

Opt("GUIOnEventMode", 1)

$hWnd = GUICreate("", 700, 320)

GUISetState(@SW_SHOW, $hWnd)

GUISetOnEvent($GUI_EVENT_CLOSE, "OnClose", $hWnd)

Global $iTimer = _Timer_SetTimer($hWnd, 15, "Tick")
ConsoleWrite($iTimer&@CRLF)

Global $iStartTime = _WinAPI_GetTickCount64()

$iDuration = 1000

Func Tick($hWnd, $iMsg, $iIDTimer, $iTime)
    Local $iNow = _WinAPI_GetTickCount64()

    Local $fRatio = ($iNow - $iStartTime) / $iDuration

    If $fRatio >= 1.0 Then
        ConsoleWrite("Timer End"&@CRLF)
        ConsoleWrite($iIDTimer&@CRLF)
        _Timer_KillTimer($hWnd, $iIDTimer)
    EndIf
EndFunc

While 1
    Sleep(10)
WEnd

Func OnClose()
    GUIDelete($hWnd)
    Exit
EndFunc

 

Posted
10 minutes ago, genius257 said:

It seems it might be an issue with _Timer_KillTimer on x64.

_Timer_KillTimer has always crashed for me and I only use x64. As a workaround, I've always used _Timer_KillAllTimers instead which does not crash. Although that may not be the best choice in all situations, of course.

Posted (edited)
31 minutes ago, genius257 said:

It seems it might be an issue with _Timer_KillTimer on x64.


you are right, I have solved it by using it directly, bypassing the
native _Timer_SetTimer and _Timer_KillTimer
by using my own functions

Func _UC_Timer_Set($idCtrl, $iElapse = 250, $sUserFunc = "", $iTimerID = 0)
    Local $UC = _UC_Properties($idCtrl)
    Local $hParent = $UC.UC_hParent

    ; If $iTimerID is 0 (new timer), generate a unique ID above 10000 to avoid conflicts
    If $iTimerID = 0 Then
        Static $iUC_TimerCounter = 10000
        $iUC_TimerCounter += 1
        $iTimerID = $iUC_TimerCounter
    EndIf

    Local $pCallback = _UC_Properties(1, "UC_TimerCallbackPtr")

    ; Call our API wrapper with the explicit custom ID
    Local $id = _UC_Timer_SetTimer($hParent, $iElapse, $pCallback, $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

; Internal API call to SetTimer using our specific pointer
Func _UC_Timer_SetTimer($hWnd, $iElapse, $pTimerFunc, $iTimerID = 0)
    Local $aCall = DllCall("user32.dll", "uint_ptr", "SetTimer", _
            "hwnd", $hWnd, _
            "uint_ptr", $iTimerID, _
            "uint", $iElapse, _
            "ptr", $pTimerFunc)

    If @error Or Not $aCall[0] Then Return SetError(1, 0, 0)
    Return $aCall[0] ; Returns the valid Timer ID
EndFunc   ;==>_UC_Timer_SetTimer

Func _UC_Timer_KillTimer($hWnd, $iTimerID)
    Local $aCall = DllCall("user32.dll", "bool", "KillTimer", "hwnd", $hWnd, "uint_ptr", $iTimerID)
    If @error Then Return False
    Return $aCall[0]
EndFunc   ;==>_UC_Timer_KillTimer

Thank you for the support. :)

As soon as I integrate the _UC_HourMinute_
of  Polar, I will update the original.

Edited by ioa747

I know that I know nothing

Posted

Version: 0.0.9.0

I updated the first post  Version (0.0.9.0)  :)  

 

23 hours ago, Polar said:

but the click on the buttons don't are fast as your buttons

Thank you for your awesome contribution! 🤩

One small thing that was missing was the handling of the double click, which can simply forward parameters to the single click handler.

Also, a useful tip regarding the framework's logic:
When you call _UC_Properties($idDummy, $m), it automatically triggers a redraw, so you don't need to manually call the draw function right after. If you want to update properties without triggering a redraw, you can simply use _UC_Properties($idDummy, $m, False).

I know that I know nothing

Posted
4 minutes ago, Polar said:

A rating component

Spoiler
Func _UC_Rating_WM_MOUSEMOVE($idDummy, $hWnd,
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
"C:\Users\Owner\Downloads\GUIDarkTheme-2.0.0\Rating\UC_Framework.au3"(2621,52) : warning: $iX: declared, but not used in func.
Func _UC_Rating_WM_LBUTTONDOWN($idDummy, $hWnd, $iX,
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
"C:\Users\Owner\Downloads\GUIDarkTheme-2.0.0\Rating\Example1.au3"(134,43) : warning: $idLblTime: possibly used before declaration.
                GUICtrlSetColor($idLblTime,
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
"C:\Users\Owner\Downloads\GUIDarkTheme-2.0.0\Rating\Example1.au3"(135,51) : warning: $idLblSelectedTime: possibly used before declaration.
                GUICtrlSetColor($idLblSelectedTime,
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
"C:\Users\Owner\Downloads\GUIDarkTheme-2.0.0\Rating\Example1.au3"(78,71) : warning: $idRating: declared, but not used in func.
    Local $idRating = _UC_Rating_Create($hMainGui, 400, 260, 24, 5, 3, 0)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
"C:\Users\Owner\Downloads\GUIDarkTheme-2.0.0\Rating\Example1.au3"(98,52) : warning: $iTimeValue: declared, but not used in func.
    Local $aMsg, $iSliderXLStep, $iVal, $iTimeValue
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
"C:\Users\Owner\Downloads\GUIDarkTheme-2.0.0\Rating\Example1.au3"(134,43) : error: $idLblTime: undeclared global variable.
                GUICtrlSetColor($idLblTime,
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
"C:\Users\Owner\Downloads\GUIDarkTheme-2.0.0\Rating\Example1.au3"(135,51) : error: $idLblSelectedTime: undeclared global variable.
                GUICtrlSetColor($idLblSelectedTime,
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
C:\Users\Owner\Downloads\GUIDarkTheme-2.0.0\Rating\Example1.au3 - 2 error(s), 6 warning(s)

I like the ideas. But the code... 🤒

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting  image.gif.922e3a93535f431de08b31ee669cc446.gif
autoit_scripter_blue_userbar.png

Posted
26 minutes ago, argumentum said:
  Hide contents
Func _UC_Rating_WM_MOUSEMOVE($idDummy, $hWnd,
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
"C:\Users\Owner\Downloads\GUIDarkTheme-2.0.0\Rating\UC_Framework.au3"(2621,52) : warning: $iX: declared, but not used in func.
Func _UC_Rating_WM_LBUTTONDOWN($idDummy, $hWnd, $iX,
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
"C:\Users\Owner\Downloads\GUIDarkTheme-2.0.0\Rating\Example1.au3"(134,43) : warning: $idLblTime: possibly used before declaration.
                GUICtrlSetColor($idLblTime,
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
"C:\Users\Owner\Downloads\GUIDarkTheme-2.0.0\Rating\Example1.au3"(135,51) : warning: $idLblSelectedTime: possibly used before declaration.
                GUICtrlSetColor($idLblSelectedTime,
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
"C:\Users\Owner\Downloads\GUIDarkTheme-2.0.0\Rating\Example1.au3"(78,71) : warning: $idRating: declared, but not used in func.
    Local $idRating = _UC_Rating_Create($hMainGui, 400, 260, 24, 5, 3, 0)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
"C:\Users\Owner\Downloads\GUIDarkTheme-2.0.0\Rating\Example1.au3"(98,52) : warning: $iTimeValue: declared, but not used in func.
    Local $aMsg, $iSliderXLStep, $iVal, $iTimeValue
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
"C:\Users\Owner\Downloads\GUIDarkTheme-2.0.0\Rating\Example1.au3"(134,43) : error: $idLblTime: undeclared global variable.
                GUICtrlSetColor($idLblTime,
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
"C:\Users\Owner\Downloads\GUIDarkTheme-2.0.0\Rating\Example1.au3"(135,51) : error: $idLblSelectedTime: undeclared global variable.
                GUICtrlSetColor($idLblSelectedTime,
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
C:\Users\Owner\Downloads\GUIDarkTheme-2.0.0\Rating\Example1.au3 - 2 error(s), 6 warning(s)

I like the ideas. But the code... 🤒

@argumentum Sorry again, and thanks to inform. In nexts contributes I will use Scite to check the syntax. I use Notepad++ to do the work. i reuploaded the zip file

Posted (edited)

I was wondering about the future possibility of theme presets. Whether it's theme colors or color schemes, it would be generally the same in the end.

My thought is: What if you could select a color theme/scheme and that set of colors would be changed on all controls within the UC_Framework?

The reason why I am mentioning it now is because you are still in the earlier stages of the development of UC_Framework. Something like this would need to be considered and planned early on because it would be much more difficult to add later on.

Edited by WildByDesign
Posted
5 hours ago, WildByDesign said:

I was wondering about the future possibility of theme presets.

Thank you for that insightful suggestion.
You are absolutely right , planning for a decoupled theme engine during the early stages of development is critical, and it is something we have prioritized in the core architecture of the UC_Framework.

Lately, I’ve been extensively iterating on the logic for this.
The UC_Framework is inherently flexible and highly adaptable, but it needed a formalized 'Theme Logic' to truly shine.
We have now structured this as a 'Centralized Theme Registry', where a theme is not just a collection of colors,
but a complete 'Resource Box' (containing colors, fonts, and even cached GDI+ brushes and pens).

Here is how we are addressing the theme preset challenge:

  • The 'Resource Box' Concept: We are treating themes as dynamic objects that hold both data (colors) and resources (GDI+ brushes/pens).
    Instead of raw color constants, the framework uses a sub-map for these assets.

  • Lazy Initialization & Caching: To solve the performance concerns of dynamic switching, we implement lazy loading for GDI+ resources.
    Objects are generated only when needed and stored within the theme’s own 'Resource Box.' This ensures we avoid GDI leaks while maintaining high performance.

  • Modular & Dynamic Loading: Beyond theme logic, the framework is designed to be highly modular. It only initializes the controls actually required by the user, rather than loading the entire suite of components into memory. This keeps the framework lightweight, reduces startup times, and ensures that the system footprint remains minimal regardless of project size.

  • Extensibility: Because the logic is decoupled, adding new theme presets is as simple as defining a new Map object and registering it with the system.
    The controls remain agnostic to the source, they simply query the current active theme, making the entire framework incredibly easy to adapt to any aesthetic requirement.

  • Unified State Management: By using a system where controls 'pull' their style from an active registry, we ensure that a single command can propagate a theme change across every UI component instantly.

In short, your concern is well-taken. We are treating themes not as an afterthought, but as a primary data layer.
By formalizing this 'Resource Box' approach now, we ensure that the framework remains lightweight, memory-efficient, and easily themeable as it continues to grow

For now, I'm spin it over in my head.

Thank you for the support. :)

I know that I know nothing

Posted (edited)

Version: 0.0.11.0

  • Architecture: Complete project refactoring. Separated core engine (Frame/) from individual components (UC/) and assets,
    improving maintainability and reducing footprint.

I updated the first post   :)  
 

Polar  Thank you for your awesome contribution! 🤩  (These new InfoBoxes are very nice.)  

 

Changes worth noting

now you call UC_Framework with

#include "UC_Framework\UC_Framework.au3"

which functions as a Central Manifest, because

#include-once

;----------------------------------------------------------------------------------------
; Title...........: UC_Framework.au3
; Description.....: Universal Controls framework for custom GDI+ controls (Toggles, Sliders, etc.)
; Link............: https://github.com/ioa747/UC_Framework
; Link............: https://www.autoitscript.com/forum/topic/213667-uc_framework-universal-controls/
;----------------------------------------------------------------------------------------

#include "UC\Frame\UC_Frame.au3"

#Region ; ~~~~~~~~~~~~~ Components ~~~~~~~~~~~~~
#include "UC\UC_Toggle.au3"
;~ #include "UC\UC_Slider.au3"
#include "UC\UC_Button.au3"
;~ #include "UC\UC_Link.au3"
;~ #include "UC\UC_Label.au3"
;~ #include "UC\UC_Image.au3"
;~ #include "UC\UC_ProgressBar.au3"
;~ #include "UC\UC_RadialProgress.au3"
;~ #include "UC\UC_HourMinute.au3"
;~ #include "UC\UC_Rating.au3"
#include "UC\UC_InfoBox.au3"
#EndRegion ; ~~~~~~~~~~~~~ Components ~~~~~~~~~~~~~

The UC_Framework.au3 file acts as your central configuration hub.
Keep your compiled script lean by loading only the components you need.

Now each new control is a standalone udf
which will be placed in the folder  ' \UC_Framework\UC\'
and you add a reference here in UC_Framework.au3

Now each new control does not need to be imported into __UC_Main_MsgHandler  function. 

Now configure this with the Registered Event Handlers in the maps,
thus allowing the use of only the Events that the control needs.

Local $m[]
    ; Universal Properties
    $m.UC_Type = $UC_TYPE_INFOBOX
    $m.UC_ControlID = $idDummy
    $m.UC_hWnd = $hChild
    $m.UC_hParent = $hParent

    ; Registered Event Handlers
    $m["UC_WM_" & $WM_LBUTTONDOWN] = "_WM_LBUTTONDOWN"
    $m["UC_WM_" & $WM_LBUTTONDBLCLK] = "_WM_LBUTTONDBLCLK"
    $m["UC_WM_" & $WM_LBUTTONUP] = "_WM_LBUTTONUP"
;~  $m["UC_WM_" & $WM_RBUTTONDOWN] = "_WM_RBUTTONDOWN"
;~  $m["UC_WM_" & $WM_RBUTTONUP] = "_WM_RBUTTONUP"
    $m["UC_WM_" & $WM_MOUSEMOVE] = "_WM_MOUSEMOVE"
    $m["UC_WM_" & $WM_SETFOCUS] = "_WM_SETFOCUS"
    $m["UC_WM_" & $WM_KEYDOWN] = "_WM_KEYDOWN"

which correspond to the corresponding functions

Func _UC_InfoBox_WM_LBUTTONDOWN($idDummy, $hWnd, $iX, $iY)
Func _UC_InfoBox_WM_LBUTTONDBLCLK($idDummy, $hWnd, $iX, $iY)
Func _UC_InfoBox_WM_LBUTTONUP($idDummy, $hWnd, $iX, $iY)
Func _UC_InfoBox_WM_MOUSEMOVE($idDummy, $hWnd, $iX, $iY)
Func _UC_InfoBox_WM_SETFOCUS($idDummy, $hWnd, $iX, $iY)
Func _UC_InfoBox_WM_KEYDOWN($idDummy, $hWnd, $iKeyCode, $aXY)

The only modification that needs to be made to UC_Framework is to "\UC_Framework\UC\Frame\UC_Frame_Generic.au3"
which needs to be imported into the Global Enum and into $aUC_Types    (making sure they have the same index)

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_HOURMINUTE, _
        $UC_TYPE_RATING, _
        $UC_TYPE_INFOBOX, _
        $UC_TYPE_MAX

Global Const $aUC_Types[] = [ _
    "None", _             ; $UC_TYPE_NONE
    "Toggle", _           ; $UC_TYPE_TOGGLE
    "Slider", _           ; $UC_TYPE_SLIDER
    "Button", _           ; $UC_TYPE_BUTTON
    "Link", _             ; $UC_TYPE_LINK
    "Label", _            ; $UC_TYPE_LABEL
    "Image", _            ; $UC_TYPE_IMAGE
    "ProgressBar", _      ; $UC_TYPE_PROGRESSBAR
    "RadialProgress", _   ; $UC_TYPE_RADIALPROGRESS
    "HourMinute", _       ; $UC_TYPE_HOURMINUTE
    "Rating", _           ; $UC_TYPE_RATING
    "InfoBox" _           ; $UC_TYPE_INFOBOX
]

The system will automatically link your
_UC_[Type]_Draw and _UC_[Type]_WM_[Event] functions without modifying the core engine.

 

Folder PATH listing 

Spoiler
PROJECT
│   Example1.au3
│   
└───UC_Framework
    │   UC_Framework.au3
    │   
    └───UC
        │   UC_Button.au3
        │   UC_HourMinute.au3
        │   UC_Image.au3
        │   UC_InfoBox.au3
        │   UC_Label.au3
        │   UC_Link.au3
        │   UC_ProgressBar.au3
        │   UC_RadialProgress.au3
        │   UC_Rating.au3
        │   UC_Slider.au3
        │   UC_Toggle.au3
        │   
        ├───Assets
        │       116386-ioa747.png
        │       1272.png
        │       260527-120731-420_AutoIt3_6dpJp.gif
        │       
        └───Frame
                UC_Frame.au3
                UC_Frame_GDI.au3
                UC_Frame_Generic.au3
                UC_Frame_Internal.au3
                UC_Frame_Map.au3
                UC_Frame_Timers.au3
                UC_Frame_WinAPI.au3

 

 

Please, every comment is appreciated!
leave your comments and experiences here!
Thank you very much  :)

 

Edited by ioa747

I know that I know nothing

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...