Jump to content

Recommended Posts

Posted

I really like this. I love simplicity. It also has a nice, soothing design. Personally, I would use this for a To Do list and things like that.

I didn't test it much (yet), but I saw bullet points which is good. Checkboxes might be an idea for things like To Do lists.

One main suggestion:

It really needs support for DPI scaling. I added it while testing the uncompiled script on my system and it looks fabulous with the DPI scaling.

You can add the following just after your includes (or at least before GUI creation):

; System aware DPI awareness
DllCall("User32.dll", "bool", "SetProcessDPIAware")
; Per-monitor V2 DPI awareness
;DllCall("User32.dll", "bool", "SetProcessDpiAwarenessContext" , "HWND", "DPI_AWARENESS_CONTEXT" -4)

You can comment out the first one (system aware) and uncomment the second one if you want per-monitor DPI aware, but that can be more complicated.

Posted (edited)

WildByDesign,

; System aware DPI awareness
DllCall("User32.dll", "bool", "SetProcessDPIAware")
; Per-monitor V2 DPI awareness
;DllCall("User32.dll", "bool", "SetProcessDpiAwarenessContext" , "HWND", "DPI_AWARENESS_CONTEXT" -4)

I didn't even know that dll call existed before you showed me.
Gonna add this to the code for sure, thanks for letting me know!

BTW, about the design (spoiler alert), it's getting an update:

image.thumb.png.32f5e25845d59b4215196e956dfbd72d.png

and you're the first to get to see it :p

updated code (and credits to you) coming soon!

Edited by TheAutomator
Posted (edited)
23 minutes ago, argumentum said:

..in the Info GUI, add a link to Made By: @TheAutomator for users to open this thread.
Maybe there is an update ? Maybe I wanna know where I got this from ? ...if I replaced the example/welcome file or am working on another file.

Good idea! Added to the todo list :) Thanks argumentum.

EDIT:

image.png.3b6c3b59b5bb1f3ceafd3cdd3d8cca3c.png

Edited by TheAutomator
  • 2 weeks later...
Posted

Update,

The code is getting a huge update, that's why it takes a little longer for me to post the new version.
I also found a solution for the scrollbar that finds the balance between simplicty and performance, it now updates how it should and works a little diffirently.
Implementing your own scrollbar is not the most easy task I learned, but a lot of people have showed me inspiring code and examples.

Updates coming soon:

• better search gui in same style and functions
• better gui design with stylized popup messages
• no 100 images anymore, but just a few with the text on them being generated on the fly
• final touches on the graphics
• save as function added

I also wanna thank Nine for giving me some new insight in the more low level functions of autoit, and everyone in this topic for all the idea's and effort:

Please have a look at Nine's UDF, it's very cool! Also the windows "dark mode" one :)

Regards!

Posted

Everything looks sharp, beautiful and stylish!

The only real negative that I spot initially is that the custom scrollbar position does not change when using the touchpad swipe up/down gestures. A standard scrollbar in AutoIt does not have this problem.

Posted

If you check RoundGUI Example3.au3 from (https://www.autoitscript.com/forum/topic/212767-round-corner-gui-and-controls-udf/)  you will see in that example that the design of the scrollbar fits perfectly within your design, but also works properly with the touchpad swipe up/down gestures. I feel like it's a bit smoother as well when scrolling through a larger RichText box. The custom scrollbar in MiniMark V4 Beta seems a bit glitchy while scrolling.

Posted (edited)
On 4/5/2025 at 2:40 PM, WildByDesign said:

If you check RoundGUI Example3.au3 from (https://www.autoitscript.com/forum/topic/212767-round-corner-gui-and-controls-udf/)  you will see in that example that the design of the scrollbar fits perfectly within your design, but also works properly with the touchpad swipe up/down gestures. I feel like it's a bit smoother as well when scrolling through a larger RichText box. The custom scrollbar in MiniMark V4 Beta seems a bit glitchy while scrolling.

yep.. but I don't understand the code of Nine very well, and I only want to implement the scrollbar part (and like to know what i'm doing instead of accidentally creating memory leaks), feel free to help if you wanna add such scrollbar and/or understand Nine's code :)

From what I understand from it, it uses a lot of DllCallbackRegisters, DllCallbackGetPtrs, and api calls like "_WinAPI_SetWindowSubclass", a bit of Chinese to me :)

Edited by TheAutomator
Posted (edited)

@TheAutomator there are always good things to learn from @Nine's code, but it takes time to (try to) understand it, because our knowledge of AutoIt/Windows isn't as high as his. I always said he's a great coder !

Nine uses Subclassing a lot, which seems to be the shortest way to accomplish many tasks, which would require much code when not used. For example, with the code below I can mimic a scrollbar (using 4 label controls) without subclassing, by registering WM_COMMAND & WM_NOTIFY, but it requires more code than subclassing :

#include <GUIConstantsEx.au3>
#include <GuiRichEdit.au3>
#include <Misc.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>

Opt("MustDeclareVars", 1) ;0=no, 1=require pre-declaration

Global $g_hRichEdit, $g_idDummy, $g_idThumb, $g_idUp, $g_idDn, $g_idBack, $g_aBack
Global $g_aCheckLine[3] ; [0] = 1st visible line, [1] = last visible line, [2] = total lines

Example()

Func Example()

    ; Constants changeable in these 4 lines
    Local $hGui = GUICreate("Label is Scrollbar", 320, 416)
    Local $aEdit[4] = [10, 10, 210, 396] ; coords richedit control
    Local $iGap = 3 ; number of pixels between right border of edit control & vertical scrollbar
    Local $aUp[4] = [$aEdit[0] + $aEdit[2] + $iGap, $aEdit[1], 15, 20] ; coords Up arrow

    ; Nothing to change here
    Dim $g_aBack[4] = [$aUp[0], $aUp[1] + $aUp[3], $aUp[2], $aEdit[3] - $aUp[3] * 2]
    Local $aDn[4] = [$aUp[0], $aEdit[1] + $aEdit[3] - $aUp[3], $aUp[2], $aUp[3]]

    Local $sString
    For $i = 1 To 100
        $sString &= @crlf & "Line " & $i
    Next
    $sString = StringTrimLeft($sString, 2) ; remove 2 first characters (@cr & @lf)

    $g_hRichEdit = _GUICtrlRichEdit_Create($hGui, $sString, $aEdit[0], $aEdit[1], $aEdit[2], $aEdit[3], _
        BitOR($ES_MULTILINE, $ES_AUTOVSCROLL))

    $g_idUp = GUICtrlCreateLabel(Chr(241), $aUp[0], $aUp[1], $aUp[2], $aUp[3], BitOr($SS_CENTERIMAGE, $SS_CENTER))
    GUICtrlSetFont(-1, 15, $FW_MEDIUM, $GUI_FONTNORMAL, "Wingdings")
    GUICtrlSetBkColor(-1, 0xE0DFE3) ; my GUI light grey background

    $g_idDn = GUICtrlCreateLabel(Chr(242), $aDn[0], $aDn[1], $aDn[2], $aDn[3], BitOr($SS_CENTERIMAGE, $SS_CENTER))
    GUICtrlSetFont(-1, 15, $FW_MEDIUM, $GUI_FONTNORMAL, "Wingdings")
    GUICtrlSetBkColor(-1, 0xE0DFE3) ; my GUI light grey background

    ;======= create $g_idThumb BEFORE $g_idBack (as they overlap) . $WS_CLIPSIBLINGS style for $g_idBack
    $g_idThumb = GUICtrlCreateLabel("", $g_aBack[0], $g_aBack[1], 0, 0)
    GUICtrlSetBkColor(-1, 0xFF0000) ; red

    $g_idBack = GUICtrlCreateLabel("", $g_aBack[0], $g_aBack[1], $g_aBack[2], $g_aBack[3], $WS_CLIPSIBLINGS)
    GUICtrlSetBkColor(-1, 0x808080) ; dark grey
    ;=======

    $g_idDummy = GUICtrlCreateDummy()
    Local $idButton = GUICtrlCreateButton("Button", $aUp[0] + $aUp[2] + 10, $aUp[1], 60, 30)

    _GUICtrlRichEdit_SetEventMask($g_hRichEdit, $ENM_SCROLLEVENTS)
    GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
    GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")

    GUISetState(@SW_SHOW)

    _GUICtrlRichEdit_SetScrollPos($g_hRichEdit, 0, 0) ; good behavior when placed after GUISetState (in case total lines = total visible + 1)

    While True
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                _GUICtrlRichEdit_Destroy($g_hRichEdit)
                GUIDelete($hGUI)
                Exit

            Case $g_idDummy ; triggered by WM_COMMAND . Needed to process ALL repeated clicks on labels
                Local $iDummyVal = GUICtrlRead($g_idDummy)
                Switch $iDummyVal
                    Case $g_idUp, $g_idDn ; line up / line down
                        _GUICtrlRichEdit_ScrollLines($g_hRichEdit, ($iDummyVal = $g_idUp) ? -1 : 1)
                        Sleep(200)
                        While _IsPressed("01")
                            _GUICtrlRichEdit_ScrollLines($g_hRichEdit, ($iDummyVal = $g_idUp) ? -1 : 1)
                            Sleep(100)
                        WEnd

                    Case $g_idBack ; page up / page down
                        If BitAnd(GUICtrlGetState($g_idThumb), $GUI_SHOW) Then
                            Local $aPosThumb, $iY, $iOpt = Opt("MouseCoordMode", 2) ; 2 = relative to client area
                            While True
                                $aPosThumb = ControlGetPos($hGUI, "", $g_idThumb)
                                $iY = MouseGetPos(1)
                                If $iY < $aPosThumb[1] Then
                                    _GUICtrlRichEdit_ScrollLineOrPage($g_hRichEdit, "pu")
                                ElseIf $iY > $aPosThumb[1] + $aPosThumb[3] Then
                                    _GUICtrlRichEdit_ScrollLineOrPage($g_hRichEdit, "pd")
                                EndIf
                                Sleep(200)
                                If Not _IsPressed("01") Then ExitLoop
                            WEnd
                            Opt("MouseCoordMode", $iOpt)
                        EndIf
                EndSwitch

            Case $g_idThumb ; based on Nine's formula
                Local $iOpt = Opt("MouseCoordMode", 2)
                Local $aThumb = ControlGetPos($hGUI, "", $g_idThumb)
                Local $iTop = $g_aBack[1], $iTop2, $iBottom = $g_aBack[3] - $aThumb[3]
                Local $iY = MouseGetPos(1), $iY1 = $iY, $iY2, $iDeltaInit = $aThumb[1] - $iY
                While _IsPressed("01")
                    $iY2 = MouseGetPos(1)
                    If $iY2 <> $iY1 Then
                        $iY2 += $iDeltaInit
                        $iY2 = $iY2 < $iTop ? $iTop : ($iY2 > $iBottom ? $iBottom : $iY2)
                        $iTop2 = _ScrollCalc(($iY2 - $iTop) / ($iBottom - $iTop))
                        _GUICtrlRichEdit_ScrollLines($g_hRichEdit, $iTop2 - $g_aCheckLine[0])
                        $iY1 = $iY2
                    EndIf
                    Sleep(10)
                WEnd
                Opt("MouseCoordMode", $iOpt)

            Case $idButton
                _ScrollCalc() ; just to display the result of 1st visible line, last visible line, total lines
                ConsoleWrite("Button pressed   " & $g_aCheckLine[0] & "   " & $g_aCheckLine[1] & "   " & $g_aCheckLine[2] & @crlf)
        EndSwitch
    WEnd
EndFunc   ;==>Example

;===========================================
Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)

    Local $tMsgFilter = DllStructCreate($tagMSGFILTER, $lParam)
    If $tMsgFilter.hwndFrom = $g_hRichEdit Then _GUICtrlRichEdit_ScrollLines($g_hRichEdit, $tMsgFilter.wParam ? 1 : -1)
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

;===========================================
Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)

    If $lParam = $g_hRichEdit Then
        If BitShift($wParam, 16) = $EN_UPDATE Then ; Hi Word (control notification code)
            _ScrollUpdate()
        EndIf
    Else
        Local $iIDFrom = BitAND($wParam, 0xFFFF) ; Low Word (control ID)
        Switch $iIDFrom
            Case $g_idUp, $g_idDn, $g_idBack
                GUICtrlSendToDummy($g_idDummy, $iIDFrom)
        EndSwitch
    EndIf
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_COMMAND

;===========================================
Func _ScrollUpdate()

    _ScrollCalc()

    If $g_aCheckLine[0] = 1 And $g_aCheckLine[1] = $g_aCheckLine[2] Then
        GUICtrlSetState($g_idThumb, $GUI_HIDE)
        Return
    EndIf

    Local $fRatio = ($g_aCheckLine[1] - $g_aCheckLine[0] + 1) / $g_aCheckLine[2]
    Local $iThumbHeight = Int($g_aBack[3] * $fRatio), $iY

    Select
        Case $g_aCheckLine[0] = 1
            $iY = $g_aBack[1]
        Case $g_aCheckLine[1] = $g_aCheckLine[2]
            $iY = $g_aBack[1] + $g_aBack[3] - $iThumbHeight
        Case Else
            Local $iTotalHiddenLines = $g_aCheckLine[2] - ($g_aCheckLine[1] - $g_aCheckLine[0] + 1)
            Local $fRatio2 = ($g_aCheckLine[0] - 1) / $iTotalHiddenLines
            Local $iYPosThumb = Int(($g_aBack[3] - $iThumbHeight) * $fRatio2)
            $iY = $g_aBack[1] + $iYPosThumb
    EndSelect

    GUICtrlSetPos($g_idThumb, $g_aBack[0], $iY, $g_aBack[2], $iThumbHeight)
    GUICtrlSetState($g_idThumb, $GUI_SHOW)
EndFunc   ;==>_ScrollUpdate

;===========================================
Func _ScrollCalc($nPos = 0)

    Local Static $aRect = _GUICtrlRichEdit_GetRECT($g_hRichEdit)
    Local $iCharIndex = _GUICtrlRichEdit_GetCharPosFromXY($g_hRichEdit, $aRect[0] + 2, $aRect[3] - 2)
    $g_aCheckLine[0] = _GUICtrlRichEdit_GetNumberOfFirstVisibleLine($g_hRichEdit)
    $g_aCheckLine[1] = _GUICtrlRichEdit_GetLineNumberFromCharPos($g_hRichEdit, $iCharIndex) ; last visible line
    $g_aCheckLine[2] = _GUICtrlRichEdit_GetLineCount($g_hRichEdit)
    If $nPos Then
        Local $iShown = $g_aCheckLine[1] - $g_aCheckLine[0] + 1
        Local $iTop2 = Int($nPos * ($g_aCheckLine[2] - $iShown)) + 1
        Return $iTop2
    EndIf
EndFunc   ;==>_ScrollCalc

LabelisScrollbar.png.18f7c3afd8b81310aeea2e6b111e5cbf.png

In this script, the scroll "thumb" (a label control) has a dynamic height, it's not static as in your script (or Nine's) and its height varies with the number of total lines in the richedit control . Also I can click on the "scroll background rectangle" (another label control which overlaps with the thumb control) to scroll 1 page up/down, or on the 2 scrolls arrows (2 other label controls) to scroll 1 line up/down, as in a normal scrollbar.

I'm not satisfied with the fact that clicking quickly on the scroll arrows doesn't scroll 1 line up/down each time the user clicks on a scroll arrow. I just discovered why today : clicking quickly twice on a label control doesn't trigger (twice) the corresponding Case in main loop, because it's recognized as a double click on the label control, which should be taken care of in WM_COMMAND as @Melba23 indicates here  . This "annoyance" doesn't occur with button controls.

[ Note : the preceding "Strikethrough" comment has been fixed in the code by using a Dummy control, triggered by WM_COMMAND and processed in main loop. ]

Using Pic controls (as you do) instead of Label controls seem to work , as both are static controls. What is important is the order of creation of the 2 overlapping controls, as found in the script, e.g. the big "scroll bar rectangle" (dark grey in the pic) and the smaller "scroll thumb" (red in the pic)

I scripted this only for educational purpose, because simply adding the "WS_SCROLL" style to the richedit control would solve it all, but I understand why you don't want to use WS_SCROLL (you explained it before)

Maybe the script above will help you, maybe not, or maybe it will be a good occasion for you to spend some time on Nine's subclassing part & the learning of DllCallbackRegister etc... For example, see in this post how @LarsJ quickly used subclassing to efficiently solve OP's question, amazing !

Good luck :)

Update: April 8th : simplified code in Case $g_idBack

Edited by pixelsearch
Update (April 8th)

"I think you are searching a bug where there is no bug."
"Don't listen to bad advice."

Posted
12 hours ago, TheAutomator said:

I will have a look at it soon, seems promising :D thanks for this!

You're welcome, it was interesting to script.
As I just did a new update today (7th april), may I suggest you delete the old quoted code from your last post, so we keep only the updated version ?

Thanks and have a great day :)

"I think you are searching a bug where there is no bug."
"Don't listen to bad advice."

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...