Jump to content

Recommended Posts

Posted (edited)

I created a scrollbar control and made it dark.

However, the background remains transparent, so it doesn't look like a normal scrollbar.

The good thing is that you can make it as wide as you want.

Can someone help me make it look like a normal scrollbar?

 

Screenshot_46.png

 

 
 
#include <WinAPIGdi.au3>
#include <WinAPISysWin.au3>
#include <WinAPITheme.au3>
#include <GuiScrollBars.au3>
#include <WindowsStylesConstants.au3>
#include <ScrollBarsConstants.au3>
#include <StructureConstants.au3>
#include <GUIConstantsEx.au3>



Global $hGUI = GUICreate("Dark Win32 Scrollbar", 320, 500)
GUISetBkColor(0x2502020, $hGUI)
_WinAPI_DwmSetWindowAttribute($hGUI, $DWMWA_USE_IMMERSIVE_DARK_MODE, True)

Global $hScrollbar = _WinAPI_CreateWindowEx(0, "SCROLLBAR", "", BitOR($WS_CHILD, $WS_VISIBLE, $SB_VERT), 250, 80, 25, 300, $hGUI)
_WinAPI_SetWindowTheme($hScrollbar, "DarkMode_Explorer", 0)


Global $iMin = 0
Global $iMax = 100
Global $iPage = 10
Global $iCurrentPos = 0


Global $tSCROLLINFO = DllStructCreate($tagSCROLLINFO)
DllStructSetData($tSCROLLINFO, "cbSize", DllStructGetSize($tSCROLLINFO))
DllStructSetData($tSCROLLINFO, "fMask", BitOR($SIF_RANGE, $SIF_PAGE, $SIF_POS))
DllStructSetData($tSCROLLINFO, "nMin", $iMin)
DllStructSetData($tSCROLLINFO, "nMax", $iMax)
DllStructSetData($tSCROLLINFO, "nPage", $iPage)
DllStructSetData($tSCROLLINFO, "nPos", $iCurrentPos)

_GUIScrollBars_SetScrollInfo($hScrollbar, $SB_CTL, DllStructGetPtr($tSCROLLINFO))


Global $idLabel = GUICtrlCreateLabel("Position: 0", 10, 10, 150, 30)
GUICtrlSetFont(-1, 14, 800)
GUICtrlSetColor(-1, 0xFFFFFF) ; Crisp white text
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)


GUIRegisterMsg($WM_VSCROLL, "WM_VSCROLL_Handler")
GUISetState(@SW_SHOW, $hGUI)


While 1
    $msg = GUIGetMsg()
    If $msg = $GUI_EVENT_CLOSE Then Exit
WEnd



Func WM_VSCROLL_Handler($hWnd, $iMsg, $wParam, $lParam)
    #forceref $hWnd, $iMsg

    If $lParam <> $hScrollbar Then Return $GUI_RUNDEFMSG

    Local $iScrollCode = BitAND($wParam, 0xFFFF)
    Local $iTrackPos = BitAND(BitShift($wParam, 16), 0xFFFF)
    Local $iNewPos = $iCurrentPos

    Switch $iScrollCode
        Case $SB_LINEUP
            $iNewPos -= 1
        Case $SB_LINEDOWN
            $iNewPos += 1
        Case $SB_PAGEUP
            $iNewPos -= $iPage
        Case $SB_PAGEDOWN
            $iNewPos += $iPage
        Case $SB_THUMBTRACK, $SB_THUMBPOSITION
            $iNewPos = $iTrackPos
    EndSwitch

    If $iNewPos < $iMin Then $iNewPos = $iMin
    If $iNewPos > ($iMax - $iPage + 1) Then $iNewPos = ($iMax - $iPage + 1)

    If $iNewPos <> $iCurrentPos Then
        $iCurrentPos = $iNewPos
        DllStructSetData($tSCROLLINFO, "fMask", $SIF_POS)
        DllStructSetData($tSCROLLINFO, "nPos", $iCurrentPos)
        _GUIScrollBars_SetScrollInfo($hScrollbar, $SB_CTL, DllStructGetPtr($tSCROLLINFO))
        GUICtrlSetData($idLabel, "Position: " & $iCurrentPos)
    EndIf

    Return 0
EndFunc

 

 

Edited by bladem2003
Posted (edited)

To fix the missing dark track background, i embedded the native SCROLLBAR control inside a native STATIC container

which forces Windows to render the theme properly.

Because the scrollbar is embedded in a static control, the GUIRegisterMsg method no longer works, so I implemented a window subclass via _WinAPI_SetWindowSubclass on the container to properly catch the WM_VSCROLL messages.

Screenshot_47.png

 

#include <WinAPIShellEx.au3>
#include <APIGdiConstants.au3>
#include <WindowsNotifsConstants.au3>
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WinAPIGdi.au3>
#include <WinAPISysWin.au3>
#include <WinAPITheme.au3>
#include <GuiScrollBars.au3>
#include <WindowsStylesConstants.au3>
#include <ScrollBarsConstants.au3>
#include <StructureConstants.au3>


Global $hGUI = GUICreate("Dark Win32 Scrollbar", 400, 500)
GUISetBkColor(0x202020, $hGUI)
_WinAPI_DwmSetWindowAttribute($hGUI, $DWMWA_USE_IMMERSIVE_DARK_MODE, True)

;Static control to act as the dark background
Global $hVContainer = _WinAPI_CreateWindowEx(0, "STATIC", "", BitOR($WS_CHILD, $WS_VISIBLE), 350, 80, 25, 300, $hGUI)

;Embed the native Scrollbar inside the container
Global $hVScrollbar = _WinAPI_CreateWindowEx(0, "SCROLLBAR", "", BitOR($WS_CHILD, $WS_VISIBLE, $SB_VERT), 0, 0, 25, 300, $hVContainer)
_WinAPI_SetWindowTheme($hVScrollbar, "DarkMode_Explorer", 0)

Global $iMin = 0, $iMax = 100, $iPage = 10
Global $iVCurrentPos = 0

; structure
Global $tVSCROLLINFO = DllStructCreate($tagSCROLLINFO)
DllStructSetData($tVSCROLLINFO, "cbSize", DllStructGetSize($tVSCROLLINFO))
DllStructSetData($tVSCROLLINFO, "fMask", BitOR($SIF_RANGE, $SIF_PAGE, $SIF_POS))
DllStructSetData($tVSCROLLINFO, "nMin", $iMin)
DllStructSetData($tVSCROLLINFO, "nMax", $iMax)
DllStructSetData($tVSCROLLINFO, "nPage", $iPage)
DllStructSetData($tVSCROLLINFO, "nPos", $iVCurrentPos)
DllCall("user32.dll", "int", "SetScrollInfo", "hwnd", $hVScrollbar, "int", $SB_CTL, "ptr", DllStructGetPtr($tVSCROLLINFO), "bool", True)


Global $idVLabel = GUICtrlCreateLabel("V-Pos: 0", 10, 10, 150, 30)
GUICtrlSetFont(-1, 14, 800)
GUICtrlSetColor(-1, 0xFFFFFF)
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)

; SUBCLASS
Local $pSubclass = DllCallbackRegister("WM_VSCROLL_Subclass", "lresult", "hwnd;uint;wparam;lparam;uint_ptr;dword_ptr")
_WinAPI_SetWindowSubclass($hVContainer, DllCallbackGetPtr($pSubclass), 1, 0)

GUISetState(@SW_SHOW, $hGUI)


While 1
    $msg = GUIGetMsg()
    If $msg = $GUI_EVENT_CLOSE Then Exit
WEnd


Func WM_VSCROLL_Subclass($hWnd, $iMsg, $wParam, $lParam, $uIdSubclass, $dwRefData)
    #forceref $uIdSubclass, $dwRefData

    If $iMsg = $WM_VSCROLL And $lParam = $hVScrollbar Then
        Local $iScrollCode = BitAND($wParam, 0xFFFF)
        Local $iNewPos = $iVCurrentPos

        Switch $iScrollCode
            Case $SB_LINEUP
                $iNewPos -= 1
            Case $SB_LINEDOWN
                $iNewPos += 1
            Case $SB_PAGEUP
                $iNewPos -= $iPage
            Case $SB_PAGEDOWN
                $iNewPos += $iPage
            Case $SB_THUMBTRACK, $SB_THUMBPOSITION
                Local $tTrackInfo = DllStructCreate($tagSCROLLINFO)
                DllStructSetData($tTrackInfo, "cbSize", DllStructGetSize($tTrackInfo))
                DllStructSetData($tTrackInfo, "fMask", $SIF_TRACKPOS)
                DllCall("user32.dll", "int", "GetScrollInfo", "hwnd", $hVScrollbar, "int", $SB_CTL, "ptr", DllStructGetPtr($tTrackInfo))
                $iNewPos = DllStructGetData($tTrackInfo, "nTrackPos")
        EndSwitch

        If $iNewPos < $iMin Then $iNewPos = $iMin
        If $iNewPos > ($iMax - $iPage + 1) Then $iNewPos = ($iMax - $iPage + 1)

        If $iNewPos <> $iVCurrentPos Then
            $iVCurrentPos = $iNewPos
            DllStructSetData($tVSCROLLINFO, "fMask", $SIF_POS)
            DllStructSetData($tVSCROLLINFO, "nPos", $iVCurrentPos)
            DllCall("user32.dll", "int", "SetScrollInfo", "hwnd", $hVScrollbar, "int", $SB_CTL, "ptr", DllStructGetPtr($tVSCROLLINFO), "bool", True)
            GUICtrlSetData($idVLabel, "V-Pos: " & $iVCurrentPos)
        EndIf
        Return 0
    EndIf

    Return _WinAPI_DefSubclassProc($hWnd, $iMsg, $wParam, $lParam)
EndFunc


 

Edited by bladem2003
Posted
5 hours ago, bladem2003 said:

However, the background remains transparent, so it doesn't look like a normal scrollbar.

The good thing is that you can make it as wide as you want.

Can someone help me make it look like a normal scrollbar?

You can do this without having to add the Static control as a container.

Adding the following will help:

GUIRegisterMsg($WM_CTLCOLORSCROLLBAR, "WM_CTLCOLORSCROLLBAR_Handler")

Func WM_CTLCOLORSCROLLBAR_Handler($hWnd, $iMsg, $wParam, $lParam)
    #forceref $hWnd, $iMsg, $wParam, $lParam
    Local Static $hBrush = _WinAPI_CreateSolidBrush(0x171717)
    Return $hBrush
EndFunc

 

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