Jump to content

Resizable status bar without SBARS_SIZEGRIP


Go to solution Solved by pixelsearch,

Recommended Posts

Posted (edited)
1 hour ago, WildByDesign said:

example script that @water suggested which adds the appearance of gripper dots in the bottom corner. This, of course, would be hidden when maximized.

Spoiler
#include <GUIConstants.au3>
#include <WinAPI.au3> ; for _WinAPI_CreateWindowEx()
#include <GDIPlus.au3>

Opt("MustDeclareVars", 1)

Global Const $SBS_SIZEBOX = 0x08
Global Const $SBS_SIZEGRIP = 0x10

Global $hGui
Global $g__ScrollbarSizeCorner_hSizeBox, $g__ScrollbarSizeCorner_hProc, $g__ScrollbarSizeCorner_OldProc, $g__ScrollbarSizeCorner_iResize = 0, _
     $g__ScrollbarSizeCorner_hDots, $g__ScrollbarSizeCorner_idLabel, $g__ScrollbarSizeCorner_iBoxSize = 20

; change $g__ScrollbarSizeCorner_iBoxSize depending on HiDPI or what not

Example() ; https://www.autoitscript.com/forum/topic/211606-_winapi_createwindowex-set-bgcolor/#findComment-1531071

Func Example()
    Local $iW = 250, $iH = 90
    $hGui = GUICreate("Resize corner", $iW, $iH, -1, -1, $WS_OVERLAPPEDWINDOW)

    GUISetBkColor(0x383838)
    ScrollbarDots_Create(0x383838, 0xBFBFBF)

    GUIRegisterMsg($WM_SIZE, "WM_SIZE")
    GUIRegisterMsg($WM_MOVE, "WM_MOVE")
    GUISetState()

    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop

            Case $GUI_EVENT_PRIMARYUP
                ScrollbarDots_OnPrimaryUp()

            Case $g__ScrollbarSizeCorner_idLabel
                ScrollbarDots_OnClickLabel()

        EndSwitch
    WEnd

    GUIDelete($hGui)
    ScrollbarDots_Cleanup()
    Exit
EndFunc   ;==>Example

Func ScrollbarDots_OnClickLabel()
    $g__ScrollbarSizeCorner_iResize = 1
    GUICtrlSetState($g__ScrollbarSizeCorner_idLabel, $GUI_HIDE)
    GUISetCursor(12, 1, $hGui)
    MouseDown("MAIN") ; ..now that the Ctrl is hidden, nothing is held down, so we fake it ;)
EndFunc

Func ScrollbarDots_OnPrimaryUp()
    If Not $g__ScrollbarSizeCorner_iResize Then Return
    $g__ScrollbarSizeCorner_iResize = 0 ; restore the default mouse behaviour
    GUISetCursor(2, 0, $hGui)
    GUICtrlSetState($g__ScrollbarSizeCorner_idLabel, $GUI_SHOW)
    _WinAPI_RedrawWindow($g__ScrollbarSizeCorner_hSizeBox)
EndFunc

Func ScrollbarDots_Create($bgColor, $fgColor, $iW = 100, $iH = 100) ; $iW & $iH are irrelevant as WM_SIZE will place them accordingly
    $bgColor = 0xFF000000 + $bgColor
    $fgColor = 0xFF000000 + $fgColor
    $g__ScrollbarSizeCorner_idLabel = GUICtrlCreateLabel("", $iW - $g__ScrollbarSizeCorner_iBoxSize + 2, _
        $iH - $g__ScrollbarSizeCorner_iBoxSize + 2, $g__ScrollbarSizeCorner_iBoxSize, $g__ScrollbarSizeCorner_iBoxSize)
    GUICtrlSetResizing(-1, $GUI_DOCKRIGHT + $GUI_DOCKBOTTOM + $GUI_DOCKWIDTH + $GUI_DOCKHEIGHT)
    GUICtrlSetCursor(-1, 12)
    $g__ScrollbarSizeCorner_hSizeBox = _WinAPI_CreateWindowEx(0, "Scrollbar", "", _
        $WS_CHILD + $WS_VISIBLE + $SBS_SIZEBOX, $iW - $g__ScrollbarSizeCorner_iBoxSize, _
        $iH - $g__ScrollbarSizeCorner_iBoxSize, $g__ScrollbarSizeCorner_iBoxSize, _
        $g__ScrollbarSizeCorner_iBoxSize, $hGui) ; $SBS_SIZEBOX or $SBS_SIZEGRIP
    _GDIPlus_Startup()
    $g__ScrollbarSizeCorner_hProc = DllCallbackRegister('ScrollbarProc', 'lresult', 'hwnd;uint;wparam;lparam')
    $g__ScrollbarSizeCorner_OldProc = _WinAPI_SetWindowLong($g__ScrollbarSizeCorner_hSizeBox, $GWL_WNDPROC, DllCallbackGetPtr($g__ScrollbarSizeCorner_hProc))
    $g__ScrollbarSizeCorner_hDots = CreateDots($g__ScrollbarSizeCorner_iBoxSize, $g__ScrollbarSizeCorner_iBoxSize, $bgColor, $fgColor)
EndFunc

Func ScrollbarDots_Cleanup()
    _GDIPlus_BitmapDispose($g__ScrollbarSizeCorner_hDots)
    _WinAPI_SetWindowLong($g__ScrollbarSizeCorner_hSizeBox, $GWL_WNDPROC, $g__ScrollbarSizeCorner_OldProc)
    DllCallbackFree($g__ScrollbarSizeCorner_hProc)
    _GDIPlus_Shutdown()
EndFunc

Func WM_MOVE($hWnd, $iMsg, $wParam, $lParam)
    #forceref $hWnd, $iMsg, $wParam, $lParam
    _WinAPI_RedrawWindow($g__ScrollbarSizeCorner_hSizeBox)
EndFunc

Func WM_SIZE($hWnd, $iMsg, $wParam, $lParam)
    #forceref $hWnd, $iMsg, $wParam, $lParam
    Local $aSize = WinGetClientSize($hGui)
    If Not @error Then WinMove($g__ScrollbarSizeCorner_hSizeBox, "", $aSize[0] - $g__ScrollbarSizeCorner_iBoxSize, $aSize[1] - $g__ScrollbarSizeCorner_iBoxSize)
    Local $iWinState = WinGetState($hWnd) ; nice idea from @pixelsearch
    If Not @error Then _WinAPI_ShowWindow($g__ScrollbarSizeCorner_hSizeBox, (BitAND($iWinState, $WIN_STATE_MAXIMIZED) ? @SW_HIDE : @SW_SHOW))
EndFunc   ;==>WM_SIZE

Func ScrollbarProc($hWnd, $iMsg, $wParam, $lParam)
    #forceref $hWnd, $iMsg, $wParam, $lParam
    If $hWnd = $g__ScrollbarSizeCorner_hSizeBox And $iMsg = $WM_PAINT Then
        Local $tPAINTSTRUCT
        Local $hDC = _WinAPI_BeginPaint($hWnd, $tPAINTSTRUCT)
        Local $iWidth = DllStructGetData($tPAINTSTRUCT, 'rPaint', 3) - DllStructGetData($tPAINTSTRUCT, 'rPaint', 1)
        Local $iHeight = DllStructGetData($tPAINTSTRUCT, 'rPaint', 4) - DllStructGetData($tPAINTSTRUCT, 'rPaint', 2)
        Local $hGraphics = _GDIPlus_GraphicsCreateFromHDC($hDC)
        _GDIPlus_GraphicsDrawImageRect($hGraphics, $g__ScrollbarSizeCorner_hDots, 0, 0, $iWidth, $iHeight)
        _GDIPlus_GraphicsDispose($hGraphics)
        _WinAPI_EndPaint($hWnd, $tPAINTSTRUCT)
        Return True
    EndIf
    Return _WinAPI_CallWindowProc($g__ScrollbarSizeCorner_OldProc, $hWnd, $iMsg, $wParam, $lParam)
EndFunc   ;==>ScrollbarProc

Func CreateDots($iWidth, $iHeight, $iBackgroundColor, $iDotsColor)
    Local $iDotSize = Int($iHeight / 10)
    Local $hBitmap = _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight)
    Local $hGraphics = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    Local $hBrush = _GDIPlus_BrushCreateSolid($iDotsColor)
    _GDIPlus_GraphicsClear($hGraphics, $iBackgroundColor)
    _GDIPlus_GraphicsFillRect($hGraphics, $iWidth - ($iDotSize * 2), $iHeight - ($iDotSize * 6), $iDotSize, $iDotSize, $hBrush)
    _GDIPlus_GraphicsFillRect($hGraphics, $iWidth - ($iDotSize * 2), $iHeight - ($iDotSize * 4), $iDotSize, $iDotSize, $hBrush)
    _GDIPlus_GraphicsFillRect($hGraphics, $iWidth - ($iDotSize * 2), $iHeight - ($iDotSize * 2), $iDotSize, $iDotSize, $hBrush)
    _GDIPlus_GraphicsFillRect($hGraphics, $iWidth - ($iDotSize * 4), $iHeight - ($iDotSize * 4), $iDotSize, $iDotSize, $hBrush)
    _GDIPlus_GraphicsFillRect($hGraphics, $iWidth - ($iDotSize * 4), $iHeight - ($iDotSize * 2), $iDotSize, $iDotSize, $hBrush)
    _GDIPlus_GraphicsFillRect($hGraphics, $iWidth - ($iDotSize * 6), $iHeight - ($iDotSize * 2), $iDotSize, $iDotSize, $hBrush)
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_GraphicsDispose($hGraphics)
    Return $hBitmap
EndFunc   ;==>CreateDots

..playing with it. All I did is add @pixelsearch idea. Am personally not too sure about GUICtrlStatusBars because, is a GUI thing. Is about how the graphic interface looks and feel, and in that regard, the Win32 looks may not feel as homogeneous as it did back in Win95 with the now, Win11 and darkmode. ( my 2 cents of fears and views )

Edited by argumentum
English

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

Posted

I started to realize that every other win32 app uses the proper theme style for the SIZEGRIP control. So I had to take a deep dive here and figure out why AutoIt is not using it.

Example: image.png.2852fc0c9942d95c2fff284a83e122d7.png

All win32 apps with a status bar have this. So I dug deeper...

AutoIt status bar is pulling it's image for the status bar SIZEBOX from a font file called Marlett (marlett.ttf) which is from 1995. (Ahh!)

So there must be an easier fix to tell AutoIt to use the theming from the actual Windows theme (aero.msstyles is where the actual SIZEBOX gripper image is used for all other win32 apps).

I have some ideas to try but can't until later today.

I'm still digging into this more but will take some time.

Posted (edited)
20 minutes ago, WildByDesign said:

The only downside is that it makes the border lines between parts thicker. But that is better than having to do all of the workarounds to ownerdraw it and such.

That is why I just fixed the maximized thing but left the rest of it as is. One can add a button, or label, or what not, to do what the status bar does which is to show a status.

Edited by argumentum
English

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

Posted

A new functionality has been added to my 2nd script (found on previous page)
Now all parts of the status bar got a flexible width during resizing :

Resizecorner3.png.3e0164907a020e27cbfdb1daba3a01db.png

On the left side of the image above, the status bar parts show (on purpose) too long texts... which won't be a problem after we resize the GUI

You'll notice 2 GUI's on the right side of the image above :
1) One got a visible border around the status bar parts
2) The 2nd one doesn't have borders : just pick the line of code you prefer in the script :

_GUICtrlStatusBar_SetText($g_hStatus, "", $i, $SBT_OWNERDRAW)
; _GUICtrlStatusBar_SetText($g_hStatus, "", $i, $SBT_OWNERDRAW + $SBT_NOBORDERS) ; interesting ?

Also, I added this test...

If _GUICtrlStatusBar_IsSimple($g_hStatus) Then
    _GUICtrlStatusBar_Resize($g_hStatus)
Else
    ...
EndIf

...because maybe someone will use the script with a simple status bar ("simple" = no parts) just for the color change. Without the test, a normal fatal error would happen. The test on a simple status bar has been done, it seems correct, fingers crossed :)

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

Posted

imho there's something wrong in the function _GUICtrlStatusBar_SetParts found in the include file GuiStatusBar.au3
Gary Frost forces the last part of the status bar to have a value of -1, even if the user explicitely indicates another value, for example :

User in script...

Local $aParts[3] = [75, 150, 230]

...becomes in UDF

Local $aParts[3] = [75, 150, -1]

Here are the results below :

Resizecorner4.png.4535f2e4a7ebd5999952403093a97364.png

The picture on the right is what the user wants (better display of the last Part 2) and not what the UDF forces us to display. msdn never wrote that the last parameter must be -1, here is what we can read on msdn's site :

If an element is -1, the right edge of the corresponding part extends to the border of the window.

It's written "IF", not "it must be -1 and you have to use all the window width for your status bar"
For what it's worth...

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

Posted
11 hours ago, pixelsearch said:

You'll notice 2 GUI's on the right side of the image above :
1) One got a visible border around the status bar parts
2) The 2nd one doesn't have borders : just pick the line of code you prefer in the script :

Both of these are nice features to have. I got a chance to test these this morning and it's working great. And the addition of the expanding status bar parts is wonderful and important.

In my opinion, after testing every possible option over several days, I honestly think that the best possible UI/UX experience is a combination of real status bar and fake. Your script offers removing the terrible looking old-style grip, while @argumentum's script could use a fake status bar (label) with those beautiful modern squares added as a grip.

If you could somehow add those squares over your blank space, that would be the icing on the cake. At least as an option, anyway. I spent some more time this morning trying to combine the two but failed again. It's beyond my skills.

3 hours ago, pixelsearch said:

The picture on the right is what the user wants (better display of the last Part 2) and not what the UDF forces us to display. msdn never wrote that the last parameter must be -1, here is what we can read on msdn's site :

This is quite an interesting find. It would be nice to be able to specify what you want for the third part size without it being forced to -1. I suppose that would require adding a fixed version of the _GUICtrlStatusBar_SetParts function to your script.

Posted

One problem that I ran into is that the text color reverts back to default anytime you change the text in any of the parts.

How do you properly call the WM_DRAWITEM function again after each status text update?

Posted (edited)
3 hours ago, WildByDesign said:

How do you properly call the WM_DRAWITEM function again after each status text update?

By calling _WinAPI_RedrawWindow()
I just added a few code to my 2nd script (found on previous page), for this result :

Resizecorner5.png.af4e3be4c60dd540ea6942619e0cd613.png

6 hours ago, WildByDesign said:

I suppose that would require adding a fixed version of the _GUICtrlStatusBar_SetParts function to your script.

Before doing that, I wonder if I should open a Trac Ticket for this, though I may be answered that "a status bar should always fill the whole parent width"

I wish @jpm could read all this, so he may give his advice about the code found in function _GUICtrlStatusBar_SetParts, which forces the last part of the status bar to always reach the right side of the window. If -1 is not mandatory for msdn, then why is it mandatory for AutoIt ?

Edited by pixelsearch
typo

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

Posted (edited)

image.png.10a408d617f82ee3ff457cc916a6155b.png

Spoiler
#include <GUIConstants.au3>
#include <WinAPI.au3> ; for _WinAPI_CreateWindowEx()
#include <GDIPlus.au3>

Opt("MustDeclareVars", 1)

Global Const $SBS_SIZEBOX = 0x08
Global Const $SBS_SIZEGRIP = 0x10 ; _WinAPI_SetWindowTheme($hStatus, "DarkMode_Explorer", "Explorer")

Global $hGui
Global $g__ScrollbarSizeCorner_hSizeBox, $g__ScrollbarSizeCorner_hProc, $g__ScrollbarSizeCorner_OldProc, $g__ScrollbarSizeCorner_iResize = 0, _
        $g__ScrollbarSizeCorner_hDots, $g__ScrollbarSizeCorner_idLabel, $g__ScrollbarSizeCorner_iBoxSize = 20

; change $g__ScrollbarSizeCorner_iBoxSize depending on HiDPI or what not

Example() ; https://www.autoitscript.com/forum/topic/211606-_winapi_createwindowex-set-bgcolor/#findComment-1531071

Func Example()
    Local $iW = 250, $iH = 90, $iLeft
    $hGui = GUICreate("Resize corner", $iW, $iH, -1, -1, $WS_OVERLAPPEDWINDOW)

    GUISetBkColor(0x383838)
    ScrollbarDots_Create(0x383838, 0xBFBFBF)

    Local $iExStyle = $WS_EX_STATICEDGE
    $iLeft = 5 ; replace GUICtrlCreateLabel() with any control you'd like
    Local $Label1 = GUICtrlCreateLabel("Label1", $iLeft, $iH - 17, 70, 17, -1, $iExStyle)
    GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKBOTTOM + $GUI_DOCKWIDTH + $GUI_DOCKHEIGHT)
    $iLeft += 70 + 2
    Local $Label2 = GUICtrlCreateLabel("Label2", $iLeft, $iH - 17, 70, 17, $SS_CENTER, $iExStyle)
    GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKBOTTOM + $GUI_DOCKWIDTH + $GUI_DOCKHEIGHT)
    $iLeft += 70 + 2
    Local $Label3 = GUICtrlCreateLabel("Label3", $iLeft, $iH - 17, $iW - $iLeft - 22, 17, $SS_RIGHT, $iExStyle)
    GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKRIGHT + $GUI_DOCKBOTTOM + $GUI_DOCKHEIGHT)


    GUIRegisterMsg($WM_SIZE, "WM_SIZE")
    GUIRegisterMsg($WM_MOVE, "WM_MOVE")
    GUISetState()

    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop

            Case $GUI_EVENT_PRIMARYUP
                ScrollbarDots_OnPrimaryUp()

            Case $g__ScrollbarSizeCorner_idLabel
                ScrollbarDots_OnClickLabel()

        EndSwitch
    WEnd

    GUIDelete($hGui)
    ScrollbarDots_Cleanup()
    Exit
EndFunc   ;==>Example

Func ScrollbarDots_OnClickLabel()
    $g__ScrollbarSizeCorner_iResize = 1
    GUICtrlSetState($g__ScrollbarSizeCorner_idLabel, $GUI_HIDE)
    GUISetCursor(12, 1, $hGui)
    MouseDown("MAIN") ; ..now that the Ctrl is hidden, nothing is held down, so we fake it ;)
EndFunc   ;==>ScrollbarDots_OnClickLabel

Func ScrollbarDots_OnPrimaryUp()
    If Not $g__ScrollbarSizeCorner_iResize Then Return
    $g__ScrollbarSizeCorner_iResize = 0 ; restore the default mouse behaviour
    GUISetCursor(2, 0, $hGui)
    GUICtrlSetState($g__ScrollbarSizeCorner_idLabel, $GUI_SHOW)
    _WinAPI_RedrawWindow($g__ScrollbarSizeCorner_hSizeBox)
EndFunc   ;==>ScrollbarDots_OnPrimaryUp

Func ScrollbarDots_Create($bgColor, $fgColor, $iW = 100, $iH = 100) ; $iW & $iH are irrelevant as WM_SIZE will place them accordingly
    $bgColor = 0xFF000000 + $bgColor
    $fgColor = 0xFF000000 + $fgColor
    $g__ScrollbarSizeCorner_idLabel = GUICtrlCreateLabel("", $iW - $g__ScrollbarSizeCorner_iBoxSize + 2, _
            $iH - $g__ScrollbarSizeCorner_iBoxSize + 2, $g__ScrollbarSizeCorner_iBoxSize, $g__ScrollbarSizeCorner_iBoxSize)
    GUICtrlSetResizing(-1, $GUI_DOCKRIGHT + $GUI_DOCKBOTTOM + $GUI_DOCKWIDTH + $GUI_DOCKHEIGHT)
    GUICtrlSetCursor(-1, 12)
    $g__ScrollbarSizeCorner_hSizeBox = _WinAPI_CreateWindowEx(0, "Scrollbar", "", _
            $WS_CHILD + $WS_VISIBLE + $SBS_SIZEBOX, $iW - $g__ScrollbarSizeCorner_iBoxSize, _
            $iH - $g__ScrollbarSizeCorner_iBoxSize, $g__ScrollbarSizeCorner_iBoxSize, _
            $g__ScrollbarSizeCorner_iBoxSize, $hGui) ; $SBS_SIZEBOX or $SBS_SIZEGRIP
    _GDIPlus_Startup()
    $g__ScrollbarSizeCorner_hProc = DllCallbackRegister('ScrollbarProc', 'lresult', 'hwnd;uint;wparam;lparam')
    $g__ScrollbarSizeCorner_OldProc = _WinAPI_SetWindowLong($g__ScrollbarSizeCorner_hSizeBox, $GWL_WNDPROC, DllCallbackGetPtr($g__ScrollbarSizeCorner_hProc))
    $g__ScrollbarSizeCorner_hDots = CreateDots($g__ScrollbarSizeCorner_iBoxSize, $g__ScrollbarSizeCorner_iBoxSize, $bgColor, $fgColor)
EndFunc   ;==>ScrollbarDots_Create

Func ScrollbarDots_Cleanup()
    _GDIPlus_BitmapDispose($g__ScrollbarSizeCorner_hDots)
    _WinAPI_SetWindowLong($g__ScrollbarSizeCorner_hSizeBox, $GWL_WNDPROC, $g__ScrollbarSizeCorner_OldProc)
    DllCallbackFree($g__ScrollbarSizeCorner_hProc)
    _GDIPlus_Shutdown()
EndFunc   ;==>ScrollbarDots_Cleanup

Func WM_MOVE($hWnd, $iMsg, $wParam, $lParam)
    #forceref $hWnd, $iMsg, $wParam, $lParam
    _WinAPI_RedrawWindow($g__ScrollbarSizeCorner_hSizeBox)
EndFunc   ;==>WM_MOVE

Func WM_SIZE($hWnd, $iMsg, $wParam, $lParam)
    #forceref $hWnd, $iMsg, $wParam, $lParam
    Local $aSize = WinGetClientSize($hGui)
    If Not @error Then WinMove($g__ScrollbarSizeCorner_hSizeBox, "", $aSize[0] - $g__ScrollbarSizeCorner_iBoxSize, $aSize[1] - $g__ScrollbarSizeCorner_iBoxSize)
    Local $iWinState = WinGetState($hWnd) ; nice idea from @pixelsearch
    If Not @error Then _WinAPI_ShowWindow($g__ScrollbarSizeCorner_hSizeBox, (BitAND($iWinState, $WIN_STATE_MAXIMIZED) ? @SW_HIDE : @SW_SHOW))
EndFunc   ;==>WM_SIZE

Func ScrollbarProc($hWnd, $iMsg, $wParam, $lParam)
    #forceref $hWnd, $iMsg, $wParam, $lParam
    If $hWnd = $g__ScrollbarSizeCorner_hSizeBox And $iMsg = $WM_PAINT Then
        Local $tPAINTSTRUCT
        Local $hDC = _WinAPI_BeginPaint($hWnd, $tPAINTSTRUCT)
        Local $iWidth = DllStructGetData($tPAINTSTRUCT, 'rPaint', 3) - DllStructGetData($tPAINTSTRUCT, 'rPaint', 1)
        Local $iHeight = DllStructGetData($tPAINTSTRUCT, 'rPaint', 4) - DllStructGetData($tPAINTSTRUCT, 'rPaint', 2)
        Local $hGraphics = _GDIPlus_GraphicsCreateFromHDC($hDC)
        _GDIPlus_GraphicsDrawImageRect($hGraphics, $g__ScrollbarSizeCorner_hDots, 0, 0, $iWidth, $iHeight)
        _GDIPlus_GraphicsDispose($hGraphics)
        _WinAPI_EndPaint($hWnd, $tPAINTSTRUCT)
        Return True
    EndIf
    Return _WinAPI_CallWindowProc($g__ScrollbarSizeCorner_OldProc, $hWnd, $iMsg, $wParam, $lParam)
EndFunc   ;==>ScrollbarProc

Func CreateDots($iWidth, $iHeight, $iBackgroundColor, $iDotsColor)
    Local $iDotSize = Int($iHeight / 10)
    Local $hBitmap = _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight)
    Local $hGraphics = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    Local $hBrush = _GDIPlus_BrushCreateSolid($iDotsColor)
    _GDIPlus_GraphicsClear($hGraphics, $iBackgroundColor)
    _GDIPlus_GraphicsFillRect($hGraphics, $iWidth - ($iDotSize * 2), $iHeight - ($iDotSize * 6), $iDotSize, $iDotSize, $hBrush)
    _GDIPlus_GraphicsFillRect($hGraphics, $iWidth - ($iDotSize * 2), $iHeight - ($iDotSize * 4), $iDotSize, $iDotSize, $hBrush)
    _GDIPlus_GraphicsFillRect($hGraphics, $iWidth - ($iDotSize * 2), $iHeight - ($iDotSize * 2), $iDotSize, $iDotSize, $hBrush)
    _GDIPlus_GraphicsFillRect($hGraphics, $iWidth - ($iDotSize * 4), $iHeight - ($iDotSize * 4), $iDotSize, $iDotSize, $hBrush)
    _GDIPlus_GraphicsFillRect($hGraphics, $iWidth - ($iDotSize * 4), $iHeight - ($iDotSize * 2), $iDotSize, $iDotSize, $hBrush)
    _GDIPlus_GraphicsFillRect($hGraphics, $iWidth - ($iDotSize * 6), $iHeight - ($iDotSize * 2), $iDotSize, $iDotSize, $hBrush)
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_GraphicsDispose($hGraphics)
    Return $hBitmap
EndFunc   ;==>CreateDots

I say fake it 'till you make it :lol:


 

Spoiler
#include <GUIConstants.au3>
#include <WinAPI.au3> ; for _WinAPI_CreateWindowEx()
#include <GDIPlus.au3>

Opt("MustDeclareVars", 1)

Global Const $SBS_SIZEBOX = 0x08
Global Const $SBS_SIZEGRIP = 0x10 ; _WinAPI_SetWindowTheme($hStatus, "DarkMode_Explorer", "Explorer")

Global $hGui
Global $g__ScrollbarSizeCorner_hSizeBox, $g__ScrollbarSizeCorner_hProc, $g__ScrollbarSizeCorner_OldProc, $g__ScrollbarSizeCorner_iResize = 0, _
        $g__ScrollbarSizeCorner_hDots, $g__ScrollbarSizeCorner_idLabel, $g__ScrollbarSizeCorner_iBoxSize = 20

; change $g__ScrollbarSizeCorner_iBoxSize depending on HiDPI or what not

Example() ; https://www.autoitscript.com/forum/topic/211606-_winapi_createwindowex-set-bgcolor/#findComment-1531071

Func Example()
    Local $iW = 250, $iH = 90, $iLeft
    $hGui = GUICreate("Resize corner", $iW, $iH, -1, -1, $WS_OVERLAPPEDWINDOW)

    GUISetBkColor(0x383838)
    ScrollbarDots_Create(0x383838, 0xBFBFBF)

    Local $iExStyle = -1 ; $WS_EX_STATICEDGE
    $iLeft = 5 ; replace GUICtrlCreateLabel() with any control you'd like
    Local $Label1 = GUICtrlCreateLabel("Label1", $iLeft, $iH - 17, 70, 17, -1, $iExStyle)
    GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKBOTTOM + $GUI_DOCKWIDTH + $GUI_DOCKHEIGHT)
    $iLeft += 70 + 2
    Local $Label2 = GUICtrlCreateLabel("Label2", $iLeft, $iH - 17, 70, 17, $SS_CENTER, $iExStyle)
    GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKBOTTOM + $GUI_DOCKWIDTH + $GUI_DOCKHEIGHT)
    $iLeft += 70 + 2
    Local $Label3 = GUICtrlCreateLabel("Label3", $iLeft, $iH - 17, $iW - $iLeft - 22, 17, $SS_RIGHT, $iExStyle)
    GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKRIGHT + $GUI_DOCKBOTTOM + $GUI_DOCKHEIGHT)

    Local $LabelDivider = GUICtrlCreateLabel("", 0, $iH - 17 - 4, $iW, 2, $SS_RIGHT, $WS_EX_STATICEDGE)
    GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKRIGHT + $GUI_DOCKBOTTOM + $GUI_DOCKHEIGHT)


    GUIRegisterMsg($WM_SIZE, "WM_SIZE")
    GUIRegisterMsg($WM_MOVE, "WM_MOVE")
    GUISetState()

    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop

            Case $GUI_EVENT_PRIMARYUP
                ScrollbarDots_OnPrimaryUp()

            Case $g__ScrollbarSizeCorner_idLabel
                ScrollbarDots_OnClickLabel()

        EndSwitch
    WEnd

    GUIDelete($hGui)
    ScrollbarDots_Cleanup()
    Exit
EndFunc   ;==>Example

Func ScrollbarDots_OnClickLabel()
    $g__ScrollbarSizeCorner_iResize = 1
    GUICtrlSetState($g__ScrollbarSizeCorner_idLabel, $GUI_HIDE)
    GUISetCursor(12, 1, $hGui)
    MouseDown("MAIN") ; ..now that the Ctrl is hidden, nothing is held down, so we fake it ;)
EndFunc   ;==>ScrollbarDots_OnClickLabel

Func ScrollbarDots_OnPrimaryUp()
    If Not $g__ScrollbarSizeCorner_iResize Then Return
    $g__ScrollbarSizeCorner_iResize = 0 ; restore the default mouse behaviour
    GUISetCursor(2, 0, $hGui)
    GUICtrlSetState($g__ScrollbarSizeCorner_idLabel, $GUI_SHOW)
    _WinAPI_RedrawWindow($g__ScrollbarSizeCorner_hSizeBox)
EndFunc   ;==>ScrollbarDots_OnPrimaryUp

Func ScrollbarDots_Create($bgColor, $fgColor, $iW = 100, $iH = 100) ; $iW & $iH are irrelevant as WM_SIZE will place them accordingly
    $bgColor = 0xFF000000 + $bgColor
    $fgColor = 0xFF000000 + $fgColor
    $g__ScrollbarSizeCorner_idLabel = GUICtrlCreateLabel("", $iW - $g__ScrollbarSizeCorner_iBoxSize + 2, _
            $iH - $g__ScrollbarSizeCorner_iBoxSize + 2, $g__ScrollbarSizeCorner_iBoxSize, $g__ScrollbarSizeCorner_iBoxSize)
    GUICtrlSetResizing(-1, $GUI_DOCKRIGHT + $GUI_DOCKBOTTOM + $GUI_DOCKWIDTH + $GUI_DOCKHEIGHT)
    GUICtrlSetCursor(-1, 12)
    $g__ScrollbarSizeCorner_hSizeBox = _WinAPI_CreateWindowEx(0, "Scrollbar", "", _
            $WS_CHILD + $WS_VISIBLE + $SBS_SIZEBOX, $iW - $g__ScrollbarSizeCorner_iBoxSize, _
            $iH - $g__ScrollbarSizeCorner_iBoxSize, $g__ScrollbarSizeCorner_iBoxSize, _
            $g__ScrollbarSizeCorner_iBoxSize, $hGui) ; $SBS_SIZEBOX or $SBS_SIZEGRIP
    _GDIPlus_Startup()
    $g__ScrollbarSizeCorner_hProc = DllCallbackRegister('ScrollbarProc', 'lresult', 'hwnd;uint;wparam;lparam')
    $g__ScrollbarSizeCorner_OldProc = _WinAPI_SetWindowLong($g__ScrollbarSizeCorner_hSizeBox, $GWL_WNDPROC, DllCallbackGetPtr($g__ScrollbarSizeCorner_hProc))
    $g__ScrollbarSizeCorner_hDots = CreateDots($g__ScrollbarSizeCorner_iBoxSize, $g__ScrollbarSizeCorner_iBoxSize, $bgColor, $fgColor)
EndFunc   ;==>ScrollbarDots_Create

Func ScrollbarDots_Cleanup()
    _GDIPlus_BitmapDispose($g__ScrollbarSizeCorner_hDots)
    _WinAPI_SetWindowLong($g__ScrollbarSizeCorner_hSizeBox, $GWL_WNDPROC, $g__ScrollbarSizeCorner_OldProc)
    DllCallbackFree($g__ScrollbarSizeCorner_hProc)
    _GDIPlus_Shutdown()
EndFunc   ;==>ScrollbarDots_Cleanup

Func WM_MOVE($hWnd, $iMsg, $wParam, $lParam)
    #forceref $hWnd, $iMsg, $wParam, $lParam
    _WinAPI_RedrawWindow($g__ScrollbarSizeCorner_hSizeBox)
EndFunc   ;==>WM_MOVE

Func WM_SIZE($hWnd, $iMsg, $wParam, $lParam)
    #forceref $hWnd, $iMsg, $wParam, $lParam
    Local $aSize = WinGetClientSize($hGui)
    If Not @error Then WinMove($g__ScrollbarSizeCorner_hSizeBox, "", $aSize[0] - $g__ScrollbarSizeCorner_iBoxSize, $aSize[1] - $g__ScrollbarSizeCorner_iBoxSize)
    Local $iWinState = WinGetState($hWnd) ; nice idea from @pixelsearch
    If Not @error Then _WinAPI_ShowWindow($g__ScrollbarSizeCorner_hSizeBox, (BitAND($iWinState, $WIN_STATE_MAXIMIZED) ? @SW_HIDE : @SW_SHOW))
EndFunc   ;==>WM_SIZE

Func ScrollbarProc($hWnd, $iMsg, $wParam, $lParam)
    #forceref $hWnd, $iMsg, $wParam, $lParam
    If $hWnd = $g__ScrollbarSizeCorner_hSizeBox And $iMsg = $WM_PAINT Then
        Local $tPAINTSTRUCT
        Local $hDC = _WinAPI_BeginPaint($hWnd, $tPAINTSTRUCT)
        Local $iWidth = DllStructGetData($tPAINTSTRUCT, 'rPaint', 3) - DllStructGetData($tPAINTSTRUCT, 'rPaint', 1)
        Local $iHeight = DllStructGetData($tPAINTSTRUCT, 'rPaint', 4) - DllStructGetData($tPAINTSTRUCT, 'rPaint', 2)
        Local $hGraphics = _GDIPlus_GraphicsCreateFromHDC($hDC)
        _GDIPlus_GraphicsDrawImageRect($hGraphics, $g__ScrollbarSizeCorner_hDots, 0, 0, $iWidth, $iHeight)
        _GDIPlus_GraphicsDispose($hGraphics)
        _WinAPI_EndPaint($hWnd, $tPAINTSTRUCT)
        Return True
    EndIf
    Return _WinAPI_CallWindowProc($g__ScrollbarSizeCorner_OldProc, $hWnd, $iMsg, $wParam, $lParam)
EndFunc   ;==>ScrollbarProc

Func CreateDots($iWidth, $iHeight, $iBackgroundColor, $iDotsColor)
    Local $iDotSize = Int($iHeight / 10)
    Local $hBitmap = _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight)
    Local $hGraphics = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    Local $hBrush = _GDIPlus_BrushCreateSolid($iDotsColor)
    _GDIPlus_GraphicsClear($hGraphics, $iBackgroundColor)
    _GDIPlus_GraphicsFillRect($hGraphics, $iWidth - ($iDotSize * 2), $iHeight - ($iDotSize * 6), $iDotSize, $iDotSize, $hBrush)
    _GDIPlus_GraphicsFillRect($hGraphics, $iWidth - ($iDotSize * 2), $iHeight - ($iDotSize * 4), $iDotSize, $iDotSize, $hBrush)
    _GDIPlus_GraphicsFillRect($hGraphics, $iWidth - ($iDotSize * 2), $iHeight - ($iDotSize * 2), $iDotSize, $iDotSize, $hBrush)
    _GDIPlus_GraphicsFillRect($hGraphics, $iWidth - ($iDotSize * 4), $iHeight - ($iDotSize * 4), $iDotSize, $iDotSize, $hBrush)
    _GDIPlus_GraphicsFillRect($hGraphics, $iWidth - ($iDotSize * 4), $iHeight - ($iDotSize * 2), $iDotSize, $iDotSize, $hBrush)
    _GDIPlus_GraphicsFillRect($hGraphics, $iWidth - ($iDotSize * 6), $iHeight - ($iDotSize * 2), $iDotSize, $iDotSize, $hBrush)
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_GraphicsDispose($hGraphics)
    Return $hBitmap
EndFunc   ;==>CreateDots

 

image.png.07068803ba5e53cc20d53d544cdb18e7.png


image.png.f2ba6e7a5660fa9b9fef169e2b81a72c.png

Spoiler
#include <GUIConstants.au3>
#include <WinAPI.au3> ; for _WinAPI_CreateWindowEx()
#include <GDIPlus.au3>

Opt("MustDeclareVars", 1)

Global Const $SBS_SIZEBOX = 0x08
Global Const $SBS_SIZEGRIP = 0x10 ; _WinAPI_SetWindowTheme($hStatus, "DarkMode_Explorer", "Explorer")

Global $hGui
Global $g__ScrollbarSizeCorner_hSizeBox, $g__ScrollbarSizeCorner_hProc, $g__ScrollbarSizeCorner_OldProc, $g__ScrollbarSizeCorner_iResize = 0, _
        $g__ScrollbarSizeCorner_hDots, $g__ScrollbarSizeCorner_idLabel, $g__ScrollbarSizeCorner_iBoxSize = 20

; change $g__ScrollbarSizeCorner_iBoxSize depending on HiDPI or what not

Example() ; https://www.autoitscript.com/forum/topic/211606-_winapi_createwindowex-set-bgcolor/#findComment-1531071

Func Example()
    Local $iW = 250, $iH = 90, $iLeft
    $hGui = GUICreate("Resize corner", $iW, $iH, -1, -1, $WS_OVERLAPPEDWINDOW)

    GUISetBkColor(0x383838)
    ScrollbarDots_Create(0x383838, 0xBFBFBF)

    Local $iExStyle = -1 ; $WS_EX_STATICEDGE
    $iLeft = 5 ; replace GUICtrlCreateLabel() with any control you'd like
    Local $Label1 = GUICtrlCreateLabel("Left", $iLeft, $iH - 17, 70, 17, -1, $iExStyle)
    GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKBOTTOM + $GUI_DOCKWIDTH + $GUI_DOCKHEIGHT)
    $iLeft += 70 + 2
    Local $Label2 = GUICtrlCreateLabel("Centered", $iLeft, $iH - 17, 70, 17, $SS_CENTER, $iExStyle)
    GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKBOTTOM + $GUI_DOCKWIDTH + $GUI_DOCKHEIGHT)

    GUICtrlCreateLabel("", 71, $iH - 17 - 5, 2, 22, $SS_RIGHT, $WS_EX_STATICEDGE)
    GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKWIDTH + $GUI_DOCKBOTTOM + $GUI_DOCKHEIGHT)

    $iLeft += 70 + 3
    Local $Label3 = GUICtrlCreateLabel("Right", $iLeft + 2 , $iH - 17, $iW - $iLeft - 22, 17, $SS_RIGHT, $iExStyle)
    GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKRIGHT + $GUI_DOCKBOTTOM + $GUI_DOCKHEIGHT)

    GUICtrlCreateLabel("", $iLeft, $iH - 17 - 5, 2, 22, $SS_RIGHT, $WS_EX_STATICEDGE)
    GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKWIDTH + $GUI_DOCKBOTTOM + $GUI_DOCKHEIGHT)

    Local $LabelDivider = GUICtrlCreateLabel("", 0, $iH - 17 - 5, $iW, 2, $SS_RIGHT, $WS_EX_STATICEDGE)
    GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKRIGHT + $GUI_DOCKBOTTOM + $GUI_DOCKHEIGHT)


    GUIRegisterMsg($WM_SIZE, "WM_SIZE")
    GUIRegisterMsg($WM_MOVE, "WM_MOVE")
    GUISetState()

    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop

            Case $GUI_EVENT_PRIMARYUP
                ScrollbarDots_OnPrimaryUp()

            Case $g__ScrollbarSizeCorner_idLabel
                ScrollbarDots_OnClickLabel()

        EndSwitch
    WEnd

    GUIDelete($hGui)
    ScrollbarDots_Cleanup()
    Exit
EndFunc   ;==>Example

Func ScrollbarDots_OnClickLabel()
    $g__ScrollbarSizeCorner_iResize = 1
    GUICtrlSetState($g__ScrollbarSizeCorner_idLabel, $GUI_HIDE)
    GUISetCursor(12, 1, $hGui)
    MouseDown("MAIN") ; ..now that the Ctrl is hidden, nothing is held down, so we fake it ;)
EndFunc   ;==>ScrollbarDots_OnClickLabel

Func ScrollbarDots_OnPrimaryUp()
    If Not $g__ScrollbarSizeCorner_iResize Then Return
    $g__ScrollbarSizeCorner_iResize = 0 ; restore the default mouse behaviour
    GUISetCursor(2, 0, $hGui)
    GUICtrlSetState($g__ScrollbarSizeCorner_idLabel, $GUI_SHOW)
    _WinAPI_RedrawWindow($g__ScrollbarSizeCorner_hSizeBox)
EndFunc   ;==>ScrollbarDots_OnPrimaryUp

Func ScrollbarDots_Create($bgColor, $fgColor, $iW = 100, $iH = 100) ; $iW & $iH are irrelevant as WM_SIZE will place them accordingly
    $bgColor = 0xFF000000 + $bgColor
    $fgColor = 0xFF000000 + $fgColor
    $g__ScrollbarSizeCorner_idLabel = GUICtrlCreateLabel("", $iW - $g__ScrollbarSizeCorner_iBoxSize + 2, _
            $iH - $g__ScrollbarSizeCorner_iBoxSize + 2, $g__ScrollbarSizeCorner_iBoxSize, $g__ScrollbarSizeCorner_iBoxSize)
    GUICtrlSetResizing(-1, $GUI_DOCKRIGHT + $GUI_DOCKBOTTOM + $GUI_DOCKWIDTH + $GUI_DOCKHEIGHT)
    GUICtrlSetCursor(-1, 12)
    $g__ScrollbarSizeCorner_hSizeBox = _WinAPI_CreateWindowEx(0, "Scrollbar", "", _
            $WS_CHILD + $WS_VISIBLE + $SBS_SIZEBOX, $iW - $g__ScrollbarSizeCorner_iBoxSize, _
            $iH - $g__ScrollbarSizeCorner_iBoxSize, $g__ScrollbarSizeCorner_iBoxSize, _
            $g__ScrollbarSizeCorner_iBoxSize, $hGui) ; $SBS_SIZEBOX or $SBS_SIZEGRIP
    _GDIPlus_Startup()
    $g__ScrollbarSizeCorner_hProc = DllCallbackRegister('ScrollbarProc', 'lresult', 'hwnd;uint;wparam;lparam')
    $g__ScrollbarSizeCorner_OldProc = _WinAPI_SetWindowLong($g__ScrollbarSizeCorner_hSizeBox, $GWL_WNDPROC, DllCallbackGetPtr($g__ScrollbarSizeCorner_hProc))
    $g__ScrollbarSizeCorner_hDots = CreateDots($g__ScrollbarSizeCorner_iBoxSize, $g__ScrollbarSizeCorner_iBoxSize, $bgColor, $fgColor)
EndFunc   ;==>ScrollbarDots_Create

Func ScrollbarDots_Cleanup()
    _GDIPlus_BitmapDispose($g__ScrollbarSizeCorner_hDots)
    _WinAPI_SetWindowLong($g__ScrollbarSizeCorner_hSizeBox, $GWL_WNDPROC, $g__ScrollbarSizeCorner_OldProc)
    DllCallbackFree($g__ScrollbarSizeCorner_hProc)
    _GDIPlus_Shutdown()
EndFunc   ;==>ScrollbarDots_Cleanup

Func WM_MOVE($hWnd, $iMsg, $wParam, $lParam)
    #forceref $hWnd, $iMsg, $wParam, $lParam
    _WinAPI_RedrawWindow($g__ScrollbarSizeCorner_hSizeBox)
EndFunc   ;==>WM_MOVE

Func WM_SIZE($hWnd, $iMsg, $wParam, $lParam)
    #forceref $hWnd, $iMsg, $wParam, $lParam
    Local $aSize = WinGetClientSize($hGui)
    If Not @error Then WinMove($g__ScrollbarSizeCorner_hSizeBox, "", $aSize[0] - $g__ScrollbarSizeCorner_iBoxSize, $aSize[1] - $g__ScrollbarSizeCorner_iBoxSize)
    Local $iWinState = WinGetState($hWnd) ; nice idea from @pixelsearch
    If Not @error Then _WinAPI_ShowWindow($g__ScrollbarSizeCorner_hSizeBox, (BitAND($iWinState, $WIN_STATE_MAXIMIZED) ? @SW_HIDE : @SW_SHOW))
EndFunc   ;==>WM_SIZE

Func ScrollbarProc($hWnd, $iMsg, $wParam, $lParam)
    #forceref $hWnd, $iMsg, $wParam, $lParam
    If $hWnd = $g__ScrollbarSizeCorner_hSizeBox And $iMsg = $WM_PAINT Then
        Local $tPAINTSTRUCT
        Local $hDC = _WinAPI_BeginPaint($hWnd, $tPAINTSTRUCT)
        Local $iWidth = DllStructGetData($tPAINTSTRUCT, 'rPaint', 3) - DllStructGetData($tPAINTSTRUCT, 'rPaint', 1)
        Local $iHeight = DllStructGetData($tPAINTSTRUCT, 'rPaint', 4) - DllStructGetData($tPAINTSTRUCT, 'rPaint', 2)
        Local $hGraphics = _GDIPlus_GraphicsCreateFromHDC($hDC)
        _GDIPlus_GraphicsDrawImageRect($hGraphics, $g__ScrollbarSizeCorner_hDots, 0, 0, $iWidth, $iHeight)
        _GDIPlus_GraphicsDispose($hGraphics)
        _WinAPI_EndPaint($hWnd, $tPAINTSTRUCT)
        Return True
    EndIf
    Return _WinAPI_CallWindowProc($g__ScrollbarSizeCorner_OldProc, $hWnd, $iMsg, $wParam, $lParam)
EndFunc   ;==>ScrollbarProc

Func CreateDots($iWidth, $iHeight, $iBackgroundColor, $iDotsColor)
    Local $iDotSize = Int($iHeight / 10)
    Local $hBitmap = _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight)
    Local $hGraphics = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    Local $hBrush = _GDIPlus_BrushCreateSolid($iDotsColor)
    _GDIPlus_GraphicsClear($hGraphics, $iBackgroundColor)
    _GDIPlus_GraphicsFillRect($hGraphics, $iWidth - ($iDotSize * 2), $iHeight - ($iDotSize * 6), $iDotSize, $iDotSize, $hBrush)
    _GDIPlus_GraphicsFillRect($hGraphics, $iWidth - ($iDotSize * 2), $iHeight - ($iDotSize * 4), $iDotSize, $iDotSize, $hBrush)
    _GDIPlus_GraphicsFillRect($hGraphics, $iWidth - ($iDotSize * 2), $iHeight - ($iDotSize * 2), $iDotSize, $iDotSize, $hBrush)
    _GDIPlus_GraphicsFillRect($hGraphics, $iWidth - ($iDotSize * 4), $iHeight - ($iDotSize * 4), $iDotSize, $iDotSize, $hBrush)
    _GDIPlus_GraphicsFillRect($hGraphics, $iWidth - ($iDotSize * 4), $iHeight - ($iDotSize * 2), $iDotSize, $iDotSize, $hBrush)
    _GDIPlus_GraphicsFillRect($hGraphics, $iWidth - ($iDotSize * 6), $iHeight - ($iDotSize * 2), $iDotSize, $iDotSize, $hBrush)
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_GraphicsDispose($hGraphics)
    Return $hBitmap
EndFunc   ;==>CreateDots

Edit: ..thinking about this, it could be turned into a UDF ( not by me right now ) and it'd be good to have.

Edited by argumentum
better ?

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

Posted (edited)

Hellooo @jpm thanks for your answer, it's always nice to hear from you.
So I did well not opening a trac ticket :P

On 4/22/2025 at 11:33 AM, WildByDesign said:

I suppose that would require adding a fixed version of the _GUICtrlStatusBar_SetParts function to your script [...]

If you could somehow add those squares over your blank space, that would be the icing on the cake.

Done and done, without label, thanks to @Andreik and @argumentum for the inspiration.

The status bar doesn't reach the right side of the window, because a function named _MyGUICtrlStatusBar_SetParts is called, with this result :

Resizecorner6.png.2ad55353e7eca1cd7c96722dd2d759b4.png

If someone wants the status bar to reach the right side of the window, then just call (twice) the original function _GUICtrlStatusBar_SetParts instead, with the little artefact display found in the preceding pics, no big deal. [edit 5 hours after : this has been simplified and amended with the new code below]

#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <GuiStatusBar.au3>
#include <StaticConstants.au3>
#include <WinAPIGdi.au3>
#include <WinAPIRes.au3>
#include <WinAPISysWin.au3>
#include <WinAPITheme.au3>
#include <WindowsConstants.au3>

Opt("MustDeclareVars", 1)

Global $g_hGui, $g_hSizebox, $g_hOldProc, $g_hBrush, $g_hStatus, $g_iHeight, $g_aText, $g_aRatioW, $g_iBkColor, $g_iTextColor, $g_hDots

Example()

;==============================================
Func Example()

    _GDIPlus_Startup()

    Local Const $SBS_SIZEBOX = 0x08, $SBS_SIZEGRIP = 0x10
    Local $iW = 300, $iH = 100
    Dim $g_iBkColor = 0x383838, $g_iTextColor = 0xFFFFFF

    $g_hGui = GUICreate("Resize corner", $iW, $iH, -1, -1, $WS_OVERLAPPEDWINDOW)
    GUISetBkColor($g_iBkColor)

    ;-----------------
    ; Create a sizebox window (Scrollbar class) BEFORE creating the StatusBar control
    $g_hSizebox = _WinAPI_CreateWindowEx(0, "Scrollbar", "", $WS_CHILD + $WS_VISIBLE + $SBS_SIZEBOX, _
        0, 0, 0, 0, $g_hGui) ; $SBS_SIZEBOX or $SBS_SIZEGRIP

    ; Subclass the sizebox (by changing the window procedure associated with the Scrollbar class)
    Local $hProc = DllCallbackRegister('ScrollbarProc', 'lresult', 'hwnd;uint;wparam;lparam')
    $g_hOldProc = _WinAPI_SetWindowLong($g_hSizebox, $GWL_WNDPROC, DllCallbackGetPtr($hProc))

    Local $hCursor = _WinAPI_LoadCursor(0, $OCR_SIZENWSE)
    _WinAPI_SetClassLongEx($g_hSizebox, -12, $hCursor) ; $GCL_HCURSOR = -12

    $g_hBrush = _WinAPI_CreateSolidBrush($g_iBkColor)

    ;-----------------
    $g_hStatus = _GUICtrlStatusBar_Create($g_hGui, -1, "", $WS_CLIPSIBLINGS) ; ClipSiblings style +++
    Local $aParts[3] = [90, 180, 280]
    If $aParts[Ubound($aParts) - 1] = -1 Then $aParts[Ubound($aParts) - 1] = $iW ; client width size
    _MyGUICtrlStatusBar_SetParts($g_hStatus, $aParts)

    Dim $g_aText[Ubound($aParts)] = ["Part 0", "Part 1", "Part 2"]
    Dim $g_aRatioW[Ubound($aParts)]
    For $i = 0 To UBound($g_aText) - 1
        _GUICtrlStatusBar_SetText($g_hStatus, "", $i, $SBT_OWNERDRAW)
        ; _GUICtrlStatusBar_SetText($g_hStatus, "", $i, $SBT_OWNERDRAW + $SBT_NOBORDERS) ; interesting ?
        $g_aRatioW[$i] = $aParts[$i] / $iW
    Next

    Local $idChangeText = GUICtrlCreateLabel("Change Text", 110, 25, 80, 30, $SS_CENTER + $SS_CENTERIMAGE), $iInc
    GUICtrlSetColor(-1, 0xFFFF00) ; yellow

    ; to allow the setting of StatusBar BkColor at least under Windows 10
    _WinAPI_SetWindowTheme($g_hStatus, "", "")

    ; Set status bar background color
    _GUICtrlStatusBar_SetBkColor($g_hStatus, $g_iBkColor)

    $g_iHeight = _GUICtrlStatusBar_GetHeight($g_hStatus) + 3 ; change the constant (+3) if necessary
    $g_hDots = CreateDots($g_iHeight, $g_iHeight, 0xFF000000 + $g_iBkColor, 0xFF000000 + $g_iTextColor)

    GUIRegisterMsg($WM_SIZE, "WM_SIZE")
    GUIRegisterMsg($WM_MOVE, "WM_MOVE")
    GUIRegisterMsg($WM_DRAWITEM, "WM_DRAWITEM")
    GUISetState()

    While 1
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop

            Case $idChangeText
                $iInc += 1
                For $i = 0 To UBound($g_aText) - 1
                    $g_aText[$i] = "Part " & $i & " : Inc " & $iInc
                Next
                _WinAPI_RedrawWindow($g_hStatus)
        EndSwitch
    WEnd

    _GDIPlus_BitmapDispose($g_hDots)
    _GUICtrlStatusBar_Destroy($g_hStatus)
    _WinAPI_DestroyCursor($hCursor)
    _WinAPI_DeleteObject($g_hBrush)
    _WinAPI_SetWindowLong($g_hSizebox, $GWL_WNDPROC, $g_hOldProc)
    DllCallbackFree($hProc)
    _GDIPlus_Shutdown()
EndFunc   ;==>Example

;==============================================
Func ScrollbarProc($hWnd, $iMsg, $wParam, $lParam) ; Andreik

    If $hWnd = $g_hSizebox And $iMsg = $WM_PAINT Then
        Local $tPAINTSTRUCT
        Local $hDC = _WinAPI_BeginPaint($hWnd, $tPAINTSTRUCT)
        Local $iWidth = DllStructGetData($tPAINTSTRUCT, 'rPaint', 3) - DllStructGetData($tPAINTSTRUCT, 'rPaint', 1)
        Local $iHeight = DllStructGetData($tPAINTSTRUCT, 'rPaint', 4) - DllStructGetData($tPAINTSTRUCT, 'rPaint', 2)
        Local $hGraphics = _GDIPlus_GraphicsCreateFromHDC($hDC)
        _GDIPlus_GraphicsDrawImageRect($hGraphics, $g_hDots, 0, 0, $iWidth, $iHeight)
        _GDIPlus_GraphicsDispose($hGraphics)
        _WinAPI_EndPaint($hWnd, $tPAINTSTRUCT)
        Return 0
    EndIf
    Return _WinAPI_CallWindowProc($g_hOldProc, $hWnd, $iMsg, $wParam, $lParam)
EndFunc   ;==>ScrollbarProc

;==============================================
Func CreateDots($iWidth, $iHeight, $iBackgroundColor, $iDotsColor) ; Andreik

    Local $iDotSize = Int($iHeight / 10)
    Local $hBitmap = _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight)
    Local $hGraphics = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    Local $hBrush = _GDIPlus_BrushCreateSolid($iDotsColor)
    _GDIPlus_GraphicsClear($hGraphics, $iBackgroundColor)
    Local $a[6][2] = [[2,6], [2,4], [2,2], [4,4], [4,2], [6,2]]
    For $i = 0 To UBound($a) - 1
        _GDIPlus_GraphicsFillRect($hGraphics, $iWidth - $iDotSize * $a[$i][0], $iHeight - $iDotSize * $a[$i][1], $iDotSize, $iDotSize, $hBrush)
    Next
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_GraphicsDispose($hGraphics)
    Return $hBitmap
EndFunc   ;==>CreateDots

;==============================================
Func _MyGUICtrlStatusBar_SetParts($hWnd, $aPartEdge) ; Pixelsearch

    If Not IsArray($aPartEdge) Then Return False
    Local $iParts = UBound($aPartEdge)
    Local $tParts = DllStructCreate("int[" & $iParts & "]")
    For $i = 0 To $iParts - 1
        DllStructSetData($tParts, 1, $aPartEdge[$i], $i + 1)
    Next
    DllCall("user32.dll", "lresult", "SendMessageW", "hwnd", $hWnd, "uint", $SB_SETPARTS, "wparam", $iParts, "struct*", $tParts)
    _GUICtrlStatusBar_Resize($hWnd)
    Return True
EndFunc   ;==>_MyGUICtrlStatusBar_SetParts

;==============================================
Func WM_SIZE($hWnd, $iMsg, $wParam, $lParam) ; Pixelsearch
    #forceref $iMsg, $wParam, $lParam

    If $hWnd = $g_hGUI Then
        Local Static $bIsSizeBoxShown = True
        Local $aSize = WinGetClientSize($g_hGui)
        Local $aGetParts = _GUICtrlStatusBar_GetParts($g_hStatus)
        Local $aParts[$aGetParts[0]]
        For $i = 0 To $aGetParts[0] - 1
            $aParts[$i] = Int($aSize[0] * $g_aRatioW[$i])
        Next
        If BitAND(WinGetState($g_hGui), $WIN_STATE_MAXIMIZED) Then
            _GUICtrlStatusBar_SetParts($g_hStatus, $aParts) ; set parts until GUI right border
            _WinAPI_ShowWindow($g_hSizebox, @SW_HIDE)
            $bIsSizeBoxShown = False
        Else
            _MyGUICtrlStatusBar_SetParts($g_hStatus, $aParts) ; set parts as user scripted them
            WinMove($g_hSizebox, "", $aSize[0] - $g_iHeight, $aSize[1] - $g_iHeight, $g_iHeight, $g_iHeight)
            If Not $bIsSizeBoxShown Then
                _WinAPI_ShowWindow($g_hSizebox, @SW_SHOW)
                $bIsSizeBoxShown = True
            EndIf
        EndIf
    EndIf
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_SIZE

;==============================================
Func WM_MOVE($hWnd, $iMsg, $wParam, $lParam)
    #forceref $iMsg, $wParam, $lParam

    If $hWnd = $g_hGUI Then
        _WinAPI_RedrawWindow($g_hSizebox)
    EndIf
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_MOVE

;==============================================
Func WM_DRAWITEM($hWnd, $iMsg, $wParam, $lParam) ; Kafu
    #forceref $hWnd, $iMsg, $wParam

    Local Static $tagDRAWITEM = "uint CtlType;uint CtlID;uint itemID;uint itemAction;uint itemState;hwnd hwndItem;handle hDC;long rcItem[4];ulong_ptr itemData"
    Local $tDRAWITEM = DllStructCreate($tagDRAWITEM, $lParam)
    If $tDRAWITEM.hwndItem <> $g_hStatus Then Return $GUI_RUNDEFMSG ; only process the statusbar

    Local $itemID = $tDRAWITEM.itemID ; status bar part number (0, 1, ...)
    Local $hDC = $tDRAWITEM.hDC
    Local $tRect = DllStructCreate("long left;long top;long right;long bottom", DllStructGetPtr($tDRAWITEM, "rcItem"))
    _WinAPI_FillRect($hDC, DllStructGetPtr($tRect), $g_hBrush) ; backgound color
    _WinAPI_SetTextColor($hDC, $g_iTextColor) ; text color
    _WinAPI_SetBkMode($hDC, $TRANSPARENT)
    DllStructSetData($tRect, "top", $tRect.top + 1)
    DllStructSetData($tRect, "left", $tRect.left + 1)
    _WinAPI_DrawText($hDC, $g_aText[$itemID], $tRect, $DT_LEFT)

    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_DRAWITEM
Edited by pixelsearch
function WM_SIZE recoded

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

Posted (edited)
52 minutes ago, pixelsearch said:

If someone wants the status bar to reach the right side of the window, then just call (twice) the original function _GUICtrlStatusBar_SetParts instead, with the little artefact display found in the preceding pics, no big deal.

This latest version of your script is beautiful. I like how you have the option of full length status bar or not. I have one suggestion:

If BitAND($iState, $WIN_STATE_MAXIMIZED) Then
            _GUICtrlStatusBar_SetParts($g_hStatus, $aParts)
        EndIf

Add that to your WM_MOVE function so that when the window is maximized, it will stretch the status bar full length which makes sense. When the window is no longer maximized, it goes back to regular _MyGUICtrlStatusBar_SetParts() automatically.

Edited by WildByDesign
spelling
Posted
4 hours ago, WildByDesign said:

Add that to your WM_SIZE function so that when the window is maximized, it will stretch the status bar full length which makes sense. When the window is no longer maximized, it goes back to regular _MyGUICtrlStatusBar_SetParts() automatically.

I just rewrote the WM_SIZE function to accomplish this, in the 3rd script amended just above (my preceding post)
By the way, there is something I didn't like a lot with this one-liner...

_WinAPI_ShowWindow($g_hSizebox, (BitAND(WinGetState($g_hGui), $WIN_STATE_MAXIMIZED) ? @SW_HIDE : @SW_SHOW))

...because the function _WinAPI_ShowWindow was constantly called (to show the sizebox) while the GUI was resizing, meaning dozen of superfluous calls for nothing, when 1 call should be enough. That's why I'm adding this local static variable...

Local Static $bIsSizeBoxShown = True

...now _WinAPI_ShowWindow (to show the sizebox) will be called only once, when necessary.

Also, as -1 for last $aParts[] could now create some issues, to be consistent with the script, I added this line :

If $aParts[Ubound($aParts) - 1] = -1 Then $aParts[Ubound($aParts) - 1] = $iW ; client width size

So now any of these 4 combinations seem to work, please be kind to try them, thanks.

Local $aParts[3] = [90, 180, 280] ; the actual script
Dim $g_aText[Ubound($aParts)] = ["Part 0", "Part 1", "Part 2"]

Local $aParts[3] = [90, 180, -1]
Dim $g_aText[Ubound($aParts)] = ["Part 0", "Part 1", "Part 2"]

Local $aParts[1] = [280]
Dim $g_aText[Ubound($aParts)] = ["Part 0"]

Local $aParts[1] = [-1]
Dim $g_aText[Ubound($aParts)] = ["Part 0"]

It should run fine in any case, fingers crossed :)

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

Posted

@pixelsearch I don't kown if the fact that the last part is not forcing filling to end of status bar will be a breaking script

Do you think your solution is good for every body?

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
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...