Jump to content

Resizable status bar without SBARS_SIZEGRIP


Go to solution Solved by pixelsearch,

Recommended Posts

Posted
2 hours ago, WildByDesign said:

I just tested the latest update with all variations and did not experience any issues.

Delighted to hear this, thanks for the 4 tests !

By the way, I'll try to find a way to solve this : while we resize the GUI, the distance between the right side of the last statusbar part and the sizebox should stay constant.

Actually, this distance increases a bit while we enlarge the GUI ( due to the calculation which uses $g_aRatioW ) but it would probably display better if this particular distance was constant, with the sizebox always "stuck" to the right size of the last statusbar part during resizing.

It's not really important, we'll see... Meanwhile, I tried to group several examples from the help file, so I'll be able to have results not only from my computer, but also from a Win11 computer in a few days. These results may help to understand better what should exactly be the height/width of the sizebox etc...

StatusBartests.png.ad91db050d3c3307e8c334436ff503a4.png

I'll have a bit less time to do this, as family is coming tomorrow and we'll spend some time together :)

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

Posted
2 hours ago, jpm said:

the fact that the last part is not forcing filling to end of status bar will be a breaking script

imho it may be a breaking script change, for example those who already scripted like this during the last years...

Local $aParts[3] = [75, 150, 230] ; user's code

...which was seen like this inside Gary's function...

Local $aParts[3] = [75, 150, -1] ; UDF's code

...then they had a status bar which used all the GUI width and maybe they were happy with this display. If today you change Gary's function, they'll have a much smaller status bar and won't be happy at all, unless they rework their code.

2 hours ago, jpm said:

Do you think your solution is good for every body?

No it is not, because my function _MyGUICtrlStatusBar_SetParts got only 2 parameters (Gary got 3 in _GUICtrlStatusBar_SetParts)

Even the following line I added in my last script won't help in the UDF : it seems to solve everything in the script (I tested the 4 possibilities and @WildByDesign kindly re-tested them in his last post, confirming all possibilities passed the test) :

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

I think it's a bit late to change Gary's function and it's not really important after all. My one and only regret is this : I've always been told and read that AutoIt was a "wrapper" for msdn, so I don't understand why did Gary force the last parameters to be -1 in any case, when msdn never said it was mandatory.

I understand that a status bar should use all the GUI width, but as msdn didn't make it mandatory (on their SB_SETPARTS web page) then AutoIt should have done same, years ago, no more, no less and no big deal.

So please let's not change anything in the UDF, noone ever complained about it... until we started this thread ;)

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

Posted
On 4/22/2025 at 12:21 PM, argumentum said:

I say fake it 'till you make it

I didn't get a chance to say this earlier but I wanted to say that your fake it 'till you make it label-type status bar is absolutely worthy of a UDF, someday. I understand that you are busy lately. But someday in the future. Your examples for very nice looking and functionally great. In many ways, they are easier to size and manage in comparison to the real status bars. Also, the real status bars do not play as nicely with theming such as the Dark Mode UDF. Yours does. Thank you for your time on this as well.

The current reality is, I think that I will end up using your fake it 'till you make it label-type status bar in my current project. The problem is that my current project already has a UDF which uses $WM_DRAWITEM and it conflicts with the $WM_DRAWITEM used with the other status bar examples here. I tried everything possible during the past few days with no luck.

Posted
3 hours ago, WildByDesign said:

uses $WM_DRAWITEM and it conflicts with the $WM_DRAWITEM used

Func WM_DRAWITEM($hWnd, $iMsg, $wParam, $lParam)
    #forceref $hWnd, $iMsg, $wParam
    WM_DRAWITEM_forSomethingElse($hWnd, $iMsg, $wParam, $lParam)
    ... ...
    Return $GUI_RUNDEFMSG
EndFunc

Func WM_DRAWITEM_forSomethingElse($hWnd, $iMsg, $wParam, $lParam)
    #forceref $hWnd, $iMsg, $wParam
    ... ...
EndFunc

if merging them is hard, then get creative :) 

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

Posted
12 hours ago, argumentum said:

if merging them is hard, then get creative

Thank you for the suggestion. I tried setting them with different function name as you mentioned but it still failed. However, I never give up. I'm a bit too persistent. So I ended up using a few If Then statements to navigate between the two WM_DRAWITEM functions and that worked. I'm hoping to finish up in the next day or two so that I can share the results.

Posted
On 4/24/2025 at 11:17 AM, WildByDesign said:

The current reality is, I think that I will end up using your fake it 'till you make it label-type status bar in my current project. The problem is that my current project already has a UDF which uses $WM_DRAWITEM and it conflicts with the $WM_DRAWITEM used with the other status bar examples here. I tried everything possible during the past few days with no luck.

If you're using argumentum's label-type status bar (which doesn't require $WM_DRAWITEM) then nothing should be changed in your UDF, which already uses $WM_DRAWITEM, right ?

10 hours ago, WildByDesign said:

However, I never give up. I'm a bit too persistent. So I ended up using a few If Then statements to navigate between the two WM_DRAWITEM functions and that worked.

"I'm a bit too persistent"... that makes two of us :D
If you're simply testing how to merge 2 "different" WM_DRAWITEM functions, here is what I just did :

1) Let's take the final version of @Nine's script  found in this post, where Tabs are colored during a WM_DRAWITEM function.
2) Let's add a simple status bar (simple = no parts, just for test) in the same script. As we want the status bar text colored in white (which requires also a WM_DRAWITEM function) then both WM_DRAWITEM functions could be merged to a single one, like this :

#include <GuiConstantsEx.au3>
#include <GuiListView.au3>
#include <GuiStatusBar.au3>
#include <GuiTab.au3>
#include <WinAPITheme.au3>
#include <WindowsConstants.au3>

Opt("MustDeclareVars", 1)

Global Const $ODT_TAB = 101, $ODS_SELECTED = 1, $ODA_DRAWENTIRE = 1
Global Const $tagDRAWITEM = "uint CtlType;uint CtlID;uint itemID;uint itemAction;uint itemState;hwnd hwndItem;handle hDC;long rcItem[4];ulong_ptr itemData"

Global $g_hDCTab
Global $g_hStatus, $g_aText

Main()

;==============================================
Func Main()

    Local $hGUI = GUICreate("Draw Tabs & Status", 300, 250)
    Local $idTab = GUICtrlCreateTab(10, 10, 280, 180, $TCS_OWNERDRAWFIXED)
    $g_hDCTab = _WinAPI_GetDC(GUICtrlGetHandle($idTab))

    Local $TabItem_1 = GUICtrlCreateTabItem("TabItem 1")
    CreateGUIItems("A")
    Local $TabItem_2 = GUICtrlCreateTabItem("TabItem 2")
    CreateGUIItems("B")
    GUICtrlCreateTabItem("")

    $g_hStatus = _GUICtrlStatusBar_Create($hGui)
    Dim $g_aText[1] = ["This is a simple Status bar"]
    _GUICtrlStatusBar_SetText($g_hStatus, "", 0, $SBT_OWNERDRAW)

    ; 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, 0x808080)

    GUIRegisterMsg($WM_DRAWITEM, "WM_DRAWITEM") ; to be placed before GUISetState +++
    GUISetState()

    _GUICtrlTab_SetCurSel($idTab, 1)
    _GUICtrlTab_SetCurSel($idTab, 0)

    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE

    _GUICtrlStatusBar_Destroy($g_hStatus)
EndFunc   ;==>Main

;==============================================
Func WM_DRAWITEM($hWnd, $Msg, $wParam, $lParam)

    Local $tDrawItem = DllStructCreate($tagDRAWITEM, $lParam)

    Select
        Case $tDrawItem.CtlType = $ODT_TAB
            Local $itemID = DllStructGetData($tDrawItem, "itemID")
            Local $itemAction = DllStructGetData($tDrawItem, "itemAction")
            Local $hDC = DllStructGetData($tDrawItem, "hDC")

            If $itemAction <> $ODA_DRAWENTIRE Then Return $GUI_RUNDEFMSG
            Local $iTextColor, $itemText, $iBrushColor, $tRect
            Switch $itemID
                Case 0
                    $iBrushColor = 0x11AADD
                Case 1
                    $iBrushColor = 0xEEBB99
            EndSwitch

            _WinAPI_SetBkMode($hDC, 1)
            Local $iBrush = _WinAPI_CreateSolidBrush($iBrushColor)
            $tRect = DllStructCreate($tagRect, DllStructGetPtr($tDrawItem, "rcItem"))
            _WinAPI_FillRect($hDC, $tRect, $iBrush)

            Local $tBuffer = DllStructCreate("char[256]")
            DllStructSetData($tBuffer, 1, "Item" & $itemID)
            $itemText = DllStructGetData($tBuffer, 1)

            DllStructSetData($tDrawItem, "rcItem", DllStructGetData($tDrawItem, "rcItem", 1) + 10, 1)
            DllStructSetData($tDrawItem, "rcItem", DllStructGetData($tDrawItem, "rcItem", 2) + 5, 2)

            _WinAPI_DrawText($hDC, $itemText, $tRect, $DT_LEFT)
            $tRect = DllStructCreate($tagRect)
            $tRect.left = 2
            $tRect.top = 22
            $tRect.right = 278
            $tRect.bottom = 178

            _WinAPI_FillRect($g_hDCTab, $tRect, $iBrush)
            _WinAPI_DeleteObject($iBrush)

        Case $tDrawItem.hwndItem = $g_hStatus
            Local $itemID = $tDrawItem.itemID ; status bar part number : 0 if simple bar (or 0, 1, 2... if multi parts)
            Local $hDC = $tDrawItem.hDC
            Local $tRect = DllStructCreate("long left;long top;long right;long bottom", DllStructGetPtr($tDrawItem, "rcItem"))
            _WinAPI_SetTextColor($hDC, 0xFFFFFF) ; 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)
    EndSelect

    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_DRAWITEM

;==============================================
Func CreateGUIItems($sPrefix)

    Local $iExStyle = ($sPrefix = "A") _
        ? BitOr($LVS_EX_GRIDLINES, $LVS_EX_INFOTIP, $LVS_EX_FULLROWSELECT) _
        : BitOr($LVS_EX_GRIDLINES, $LVS_EX_INFOTIP)
    Local $idListView = GUICtrlCreateListView("Directories|Files", 15, 35, 170, 150, -1, 0)
    _GUICtrlListView_SetExtendedListViewStyle($idListView, $iExStyle)

    Local $sString
    For $i = 0 To 5
        $sString = ""
        For $c = 0 To 10 Step 1
            $sString &= Chr(65 + $i)
        Next
        GUICtrlCreateListViewItem($sPrefix & $i & "-" & $sString, $idListView)
    Next
EndFunc   ;==>CreateGUIItems

 

DrawTabsStatus.png.170d57a55293a04c8650eca31e317a21.png

Does it display correctly on your computer ?

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

Posted
1 hour ago, pixelsearch said:

If you're using argumentum's label-type status bar (which doesn't require $WM_DRAWITEM) then nothing should be changed in your UDF, which already uses $WM_DRAWITEM, right ?

I did have argumentum's label-type status bar fully integrated into my current project initially. But after you posted your 3rd script, I decided to switch to yours. I've got the parts width set as a percentage of the GUI width and everything just works so well. Particularly, I really liked the NOBORDERS option. Yours worked better under all HiDPI scenarios that I tested. I've got it set to automatically change depending on the OS being in light mode or dark mode, but the screenshot below is likely the final design that will get pushed in the next few days. 

image.thumb.png.61f574dcd03dd833dd7eec55f2aab340.png

1 hour ago, pixelsearch said:

Does it display correctly on your computer ?

Yes, it displays on mine identically to your screenshots.

By the way, thank you for taking your time to share that code example of breaking down the WM_DRAWITEM functions and combining them. Those type of examples are great for helping me learn quicker.

It took me about 4-5 days to solve my WM_DRAWITEM issue. But I wasn't going to give up. I always try to learn to fix or implement things myself at least for a handful of days before I ask for help. The help in this forum is the absolute best, without a doubt. I like to challenge myself first for a while and see if I can come up with ways to overcome whatever obstacles are in the way.

Posted (edited)
1 hour ago, WildByDesign said:

I always try to learn to fix or implement things myself at least for a handful of days before I ask for help.

Same here :)

1 hour ago, WildByDesign said:

Should I change the solution to your 3rd script?

Yes please, if you're allowed, then the 3rd script would be a better choice than the 1st one. Just try the change from script 1 to script 3 and if it doesn't work, maybe a Mod could help, thanks for that.

For what it's worth, here is how I kept track of the script numbers, concerning this thread :

Keeptrackofscriptsversions.png.21feb08c7e140bcefe2fcb4f99a9edcb.png

2 - 2a - 2b (Forum) are different steps of the 2nd version with 2a replacing 2, then 2b (Forum) replacing 2a, all these "#2" versions were uploaded, at a moment or another, in the same post. And as many scripters do here (I guess) the link to the Forum post is included in the script.

For the record, the script just above is not a "script 4", its name on my computer is : "Merging two WM_DRAWITEM functions to one - Forum .au3"

By the way, at least 2 things will (or should) be changed in script 3 :

1) I'm gonna comment out very soon all 4 lines concerning $g_hbrush (better comment out than delete in this case) . These 4 lines are :

; Global $g_hBrush ; no need, as _GUICtrlStatusBar_SetBkColor() placed after _WinAPI_SetWindowTheme() does the job correctly

; $g_hBrush = _WinAPI_CreateSolidBrush($g_iBkColor)

; _WinAPI_DeleteObject($g_hBrush)

; _WinAPI_FillRect($hDC, DllStructGetPtr($tRect), $g_hBrush) ; backgound color

Maybe you did notice that these 4 lines are not found in the script above ("Merging 2 WM_DRAWITEM functions to 1 - Forum .au3") and the display is still correct, as you kindly indicated in your last post. So why should we use a useless brush when it comes to painting the background of a status bar ?

[ @argumentum answer could be : "because we want a different back color for each part of a multi part status bar" :frantics:Honestly I like argumentum, he's always in a good mood and funny, no matter what his avatar shows ]

2)

On 4/24/2025 at 12:38 AM, pixelsearch said:

By the way, I'll try to find a way to solve this : while we resize the GUI, the distance between the right side of the last statusbar part and the sizebox should stay constant.

I'm not forgetting this, one of these days for sure :bye:

Edited by pixelsearch
typo

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

Posted
20 minutes ago, pixelsearch said:

Yes please, if you're allowed, then the 3rd script would be a better choice than the 1st one. Just try the change from script 1 to script 3 and if it doesn't work, maybe a Mod could help, thanks for that.

I just changed the solution successfully to the 3rd one now.

20 minutes ago, pixelsearch said:

Maybe you did notice that these 4 lines are not found in the script above ("Merging 2 WM_DRAWITEM functions to 1 - Forum .au3") and the display is still correct, as you kindly indicated in your last post. So why should we use a useless brush when it comes to painting the background of a status bar ?

Yes, great point. I commented out the lines on mine and it's working perfectly well just as before.

I did find a problem with DPI though, unfortunately. I think it was argumentum's label-type status bars that was working perfectly with DPI scaling and I somehow mixed up which one worked with DPI scaling and which did not.

I find that the best way to scale a control with DPI scaling is by measuring the height of the text and scaling the surrounding control (label, etc.) based on that because the text is one obvious thing that changes with DPI scaling.

But I am not as familiar with status bars.

Do you have any control over the height of a status bar?

If not, you might have to change the size of the text to match the height of the status bar.

Posted (edited)

For what it's worth, I was already obtaining the height of the status bar to benefit other scaling areas of my GUI with the following:

; get status bar height for GUI and listview height
$StatusBarCtrlID = _WinAPI_GetDlgCtrlID($g_hStatus)
$aPos = ControlGetPos($hGUI, "", $StatusBarCtrlID)
$StatusBarCtrlIDHeight = $aPos[3]

However, I do not know how to scaling the text to match that size. I don't know much at all about GDI stuff.

 

We can change font size with this (from rasim):

; set font
;_GUICtrlStatusBar_SetFont($g_hStatus, 16, 400, 0, "Segoe UI Variable")

Func _GUICtrlStatusBar_SetFont($hWnd, $iHeight = 12, $iWeight = 400, $iFontAtrributes = 0, $sFontName = "Arial")
    ;Author: Rasim
        $hFont = _WinAPI_CreateFont($iHeight, 0, 0, 0, $iWeight, BitAND($iFontAtrributes, 2), BitAND($iFontAtrributes, 4), _
                                    BitAND($iFontAtrributes, 8), $DEFAULT_CHARSET, $OUT_DEFAULT_PRECIS, $CLIP_DEFAULT_PRECIS, _
                                    $DEFAULT_QUALITY, 0, $sFontName)
    
        _SendMessage($hWnd, $WM_SETFONT, $hFont, 1)
EndFunc ;==>_GUICtrlStatusBar_SetFont

 

I was using that as well, but it messed up the size of your sizebox in the corner.

 

EDIT: I know about _GUICtrlStatusBar_GetHeight() but all of those built-in UDFs provide wrong info on modern computers. They don't show the actual DPI scaled size of controls. But my measured status bar height method above does show the correct height whether your are at 125%, 150%, 200%, etc. for DPI scaling.

Edited by WildByDesign
Posted

Now that it comes to changing fonts, DPI etc... I suggest you think twice : if argumentum script solves it in these situations, why not giving a complete try with his script based on labels to detect the eventual flaws ?

It will be probably easier to manage with labels, if you need to work on fonts & DPI
Just my 2 cts...

Dinner in town with family in a few min, see you soon.
Have a great week-end everybody :bye:

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

Posted
4 hours ago, pixelsearch said:

Now that it comes to changing fonts, DPI etc... I suggest you think twice : if argumentum script solves it in these situations, why not giving a complete try with his script based on labels to detect the eventual flaws ?

It will be probably easier to manage with labels, if you need to work on fonts & DPI
Just my 2 cts...

Please disregard my last comment about DPI scaling issues with your status bar. I made one minor measurement mistake and it was causing my ListView to partly cover the status bar under different DPI scaling settings.

Your status bar is 100% perfect as it is under different DPI scaling settings.

Further, my suggestion to add changing of the font was also a bad suggestion. The font in your status bar already scales the text size properly with DPI scaling. Changing the font, as I found out the hard way, actually caused the text of the status bar to no longer scale properly under different DPI settings.

TL;DR: Everything is perfect. No changes required. :)

Have a great weekend with the family!

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