argumentum Posted Monday at 04:30 PM Posted Monday at 04:30 PM (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 expandcollapse popup#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 Monday at 04:32 PM by argumentum English pixelsearch 1 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
WildByDesign Posted Monday at 04:39 PM Author Posted Monday at 04:39 PM 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: 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.
WildByDesign Posted Monday at 04:58 PM Author Posted Monday at 04:58 PM @pixelsearch@argumentum I was able to fix this properly without workaround. It ended up just being a matter of applying the theme with _WinAPI_SetWindowTheme on that status bar control. argumentum 1
WildByDesign Posted Monday at 05:04 PM Author Posted Monday at 05:04 PM So for dark mode it was: _WinAPI_SetWindowTheme($hStatus, "DarkMode_Explorer", "Explorer") Light mode (haven't tested light mode yet): _WinAPI_SetWindowTheme($hStatus, "Explorer", "Explorer") argumentum 1
WildByDesign Posted Monday at 05:08 PM Author Posted Monday at 05:08 PM Screenshot: 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. Thank you so much to everyone who helped dig into this issue for me. I am thankful and appreciate your time on this. ioa747, pixelsearch and argumentum 3
argumentum Posted Monday at 05:17 PM Posted Monday at 05:17 PM (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 Monday at 05:29 PM by argumentum English WildByDesign 1 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
pixelsearch Posted Monday at 11:17 PM Posted Monday at 11:17 PM 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 : 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 WildByDesign and argumentum 2 "I think you are searching a bug where there is no bug... don't listen to bad advice."
pixelsearch Posted Tuesday at 06:50 AM Posted Tuesday at 06:50 AM 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 : 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... ioa747 and WildByDesign 2 "I think you are searching a bug where there is no bug... don't listen to bad advice."
WildByDesign Posted Tuesday at 10:33 AM Author Posted Tuesday at 10:33 AM 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. pixelsearch 1
WildByDesign Posted Tuesday at 01:14 PM Author Posted Tuesday at 01:14 PM 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?
pixelsearch Posted Tuesday at 04:03 PM Posted Tuesday at 04:03 PM (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 : 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 Tuesday at 04:56 PM by pixelsearch typo "I think you are searching a bug where there is no bug... don't listen to bad advice."
argumentum Posted Tuesday at 04:09 PM Posted Tuesday at 04:09 PM 5 minutes ago, pixelsearch said: ... though I may be answered that "a status bar should always fill the whole parent width" that's what I would answer. pixelsearch 1 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
argumentum Posted Tuesday at 04:21 PM Posted Tuesday at 04:21 PM (edited) Spoiler expandcollapse popup#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 Spoiler expandcollapse popup#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 Spoiler expandcollapse popup#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 Tuesday at 04:51 PM by argumentum better ? WildByDesign, ioa747 and pixelsearch 3 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
argumentum Posted Tuesday at 05:00 PM Posted Tuesday at 05:00 PM 37 minutes ago, argumentum said: ..thinking about this, it could be turned into a UDF ( not by me right now ) and it'd be good to have. - Why not @argumentum ? - Because I'd have to test in HiDPI or not, DarkMode or not, from WinXP to Win11 and don't have the time for such task. Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
jpm Posted yesterday at 08:31 AM Posted yesterday at 08:31 AM @pixelsearch For me it is logical that the last part fill the end of the windows whatever the value is pixelsearch 1
pixelsearch Posted yesterday at 09:28 AM Posted yesterday at 09:28 AM (edited) Hellooo @jpm thanks for your answer, it's always nice to hear from you. So I did well not opening a trac ticket 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 : 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] expandcollapse popup#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 16 hours ago by pixelsearch function WM_SIZE recoded WildByDesign, ioa747 and argumentum 3 "I think you are searching a bug where there is no bug... don't listen to bad advice."
WildByDesign Posted yesterday at 10:21 AM Author Posted yesterday at 10:21 AM (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 yesterday at 10:21 AM by WildByDesign spelling
pixelsearch Posted 22 hours ago Posted 22 hours ago 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."
jpm Posted 15 hours ago Posted 15 hours ago @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?
WildByDesign Posted 15 hours ago Author Posted 15 hours ago 6 hours ago, pixelsearch said: So now any of these 4 combinations seem to work, please be kind to try them, thanks. I just tested the latest update with all variations and did not experience any issues. pixelsearch 1
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now