Page 1 of 1

[Windows, Solved] Get rid of 3D border in Progressbar

Posted: Sun Feb 15, 2026 6:31 pm
by Michael Vogel
I started a thread showing the difficulties changing the width of statusbar fields when using a progressar - not sure if the behaviour can be called a bug or it's just 'unsupported'.

When trying to find a woraround I embedded a ProgressBarGadget instead the use of a StatusBarProgress - but as soon the gadget will be resized a 3D border appears. So help is still needed - to fix the workaround :wink:

The code below draws the progressbar without 3D border until its size changes (code ResizeGadget...201...):

Code: Select all

; Define

	#PB_DpiBits=		16
	#PB_DpiScale=		1<<#PB_DpiBits

	Global DpiScale=GetDeviceCaps_(GetDC_(0),#LOGPIXELSX)<<#PB_DpiBits/96;	12 Bit (statt Fließkommaberechnung)

	#SB_SETBKCOLOR=					$2001
	#PBM_SETBARCOLOR=				1033
	#PBM_SETBKCOLOR=				8193

	Macro ScaleUp(value)
		(((value)*DpiScale)/#PB_DpiScale)
	EndMacro
	Macro ScaleDown(value)
		(((value)<<#PB_DpiBits)/DpiScale)
	EndMacro

; EndDefine
Procedure StatusBarFieldWidth(StatusBar,Field.i,Width.l)

	If IsStatusBar(StatusBar)

		Protected StatusBarID=StatusBarID(StatusBar)
		Protected nParts,lResult
		Protected lLeftField.l
		Protected *dwFields

		nParts=SendMessage_(StatusBarID,#SB_GETPARTS,0,0)
		*dwFields=AllocateMemory(nParts*4)

		If *dwFields
			SendMessage_(StatusBarID,#SB_GETPARTS,nParts,*dwFields)
			If Field>0
				lLeftField=PeekL(*dwFields+(Field-1)*4)
			EndIf
			PokeL(*dwFields+Field*4,lLeftField+ScaleUp(Width))
			lResult=SendMessage_(StatusBarID,#SB_SETPARTS,nParts,*dwFields)
			FreeMemory(*dwFields)
			ProcedureReturn lResult
		EndIf

		ProcedureReturn #False

	EndIf

EndProcedure
Procedure Main()

	OpenWindow(0,0,0,600,200,"Progress Bar", #PB_Window_SystemMenu|#PB_Window_TitleBar|#PB_Window_ScreenCentered)

	CreateStatusBar(0, WindowID(0))
	AddStatusBarField(ScaleUp(20))
	AddStatusBarField(ScaleUp(200))
	AddStatusBarField(#PB_Ignore)
	StatusBarText(0,0,"> >",#PB_StatusBar_BorderLess)
	StatusBarText(0,1,"",#PB_StatusBar_BorderLess)
	StatusBarText(0,2,"< < < < < < < < < <",#PB_StatusBar_BorderLess)

	ProgressBarGadget(0,ScaleUp(20),4,ScaleUp(200),ScaleUp(16),0,100)
	SetGadgetState(0,50)
	SetParent_(GadgetID(0),StatusBarID(0))
	SetWindowTheme_(GadgetID(0),#Null,"")
	SendMessage_(GadgetID(0),#PBM_SETBARCOLOR,0,$0A0AAA)
	SendMessage_(GadgetID(0),#PBM_SETBKCOLOR,0,$F8E7DC)

	SetWindowTheme_(StatusBarID(0),#Null,"")
	SendMessage_(StatusBarID(0),#SB_SETBKCOLOR,0,$EFD0BB)


	AddWindowTimer(0,0,10)
	p=0

	Repeat
		Select WaitWindowEvent()

		Case #PB_Event_Timer
			p+1
			If p<100
				SetGadgetState(0,p)
			ElseIf p=100
				ResizeGadget(0,#PB_Ignore,#PB_Ignore,ScaleUp(200),#PB_Ignore)
			ElseIf p=110
				StatusBarText(0,2,"< < ATTENTION < <",#PB_StatusBar_BorderLess)
			ElseIf p=150
				ResizeGadget(0,#PB_Ignore,#PB_Ignore,ScaleUp(201),#PB_Ignore)
			ElseIf p=200
				StatusBarText(0,2,"<  3D BORDER  : (",#PB_StatusBar_BorderLess)
			EndIf

		Case #PB_Event_CloseWindow
			End

		EndSelect

	ForEver

EndProcedure
Main()


// Solved by chi - search for #WS_EX_STATICEDGE in this thread //

Re: [Windows] Get rid of 3D border in Progressbar

Posted: Sun Feb 15, 2026 10:19 pm
by RASHAD
Hi MV
Adapt any suitable one for your needs

#1 :

Code: Select all

ProgressBarGadget(0,-1,-1,ScaleUp(200),ScaleUp(16),0,100)
SetWindowLongPtr_(GadgetID(0), #GWL_EXSTYLE,GetWindowLongPtr_(GadgetID(0), #GWL_EXSTYLE)&~#WS_EX_CLIENTEDGE)
#2:

Code: Select all

	ContainerGadget(10,ScaleUp(20),4,ScaleUp(200),ScaleUp(16), #PB_Container_BorderLess )	
	ProgressBarGadget(0,-1,-1,ScaleUp(200),ScaleUp(16)+2,0,100)
	CloseGadgetList()
	SetGadgetState(0,50)
	SetParent_(GadgetID(10),StatusBarID(0))

Re: [Windows] Get rid of 3D border in Progressbar

Posted: Mon Feb 16, 2026 9:06 am
by Michael Vogel
Thanks, I have tried your #1 already before - which would have been my preferred way but it fails here (Windows 11, PB6.21). Was not clever enough for #2, but also the container doesn't fix the problem :cry:

Added the following line directly after the #PB_Event_Timer line but there's no single bit which will be changed during the whole run:

Code: Select all

Debug Str(p)+": "+Hex(GetWindowLongPtr_(GadgetID(0),#GWL_EXSTYLE))+" - "+Hex(GetWindowLong_(GadgetID(0),#GWL_STYLE))
When adding the following line (for example also in the timer loop) an even deeper 3D frame will be seen at the end:

Code: Select all

SetWindowLongPtr_(GadgetID(0),#GWL_EXSTYLE,GetWindowLongPtr_(GadgetID(0),#GWL_EXSTYLE)|#WS_EX_CLIENTEDGE)
Resizing the gadget will show a frame which can be forced by using the flag #SWP_DRAWFRAME - I have no idea why this flag seems to be used also when resizing the gadget.

Re: [Windows] Get rid of 3D border in Progressbar

Posted: Tue Feb 17, 2026 7:47 pm
by Michael Vogel
Still fighting with the frame appearing when resizing a progressbar gadget. Got some hints but it is still not solved.

Actual state (see lines below 'Case 40'):
hacking the object style does change the behaviour of the progressbar but a frame get added around the progressbar before being resized and also as soon the statusbar will be redrawn (which is done when the window get resized).

When removing the three lines after the 'Case 40' statement resizing the window does not add a frame around the progressbar.

Code: Select all

EnableExplicit

#PBM_SETRANGE32   = #WM_USER + 6
#PBM_SETPOS       = #WM_USER + 2
#PBM_SETBARCOLOR  = #WM_USER + 9
#PBM_SETBKCOLOR   = #CCM_FIRST + 1
#SB_SETBKCOLOR    = $2001
#PB_DpiBits       = 16
#PB_DpiScale      = 1 << #PB_DpiBits

Global DpiScale = GetDeviceCaps_(GetDC_(0), #LOGPIXELSX) << #PB_DpiBits / 96
Global handle, Progress

Macro ScaleUp(value)
	(((value) * DpiScale) / #PB_DpiScale)
EndMacro

Macro ScaleDown(value)
	(((value) << #PB_DpiBits) / DpiScale)
EndMacro

If OpenWindow(0, 0, 0, 600, 200, "Progress Bar", #PB_Window_SystemMenu | #PB_Window_TitleBar | #PB_Window_ScreenCentered|#PB_Window_SizeGadget)
	CreateStatusBar(0, WindowID(0))
	AddStatusBarField(ScaleUp(20))
	AddStatusBarField(ScaleUp(300))
	AddStatusBarField(#PB_Ignore)
	StatusBarText(0, 0, "> >", #PB_StatusBar_BorderLess)
	StatusBarText(0, 1, "", #PB_StatusBar_BorderLess)
	StatusBarText(0, 2, "< < < < < < < < < <", #PB_StatusBar_BorderLess)

	If 0
		; JHPJHP
		handle=CreateWindowEx_(0, "msctls_progress32", "", #WS_CHILD | #WS_VISIBLE | #WS_CLIPSIBLINGS | #PBS_SMOOTH,ScaleUp(20), 4, ScaleUp(200), ScaleUp(16), StatusBarID(0), 0, GetModuleHandle_(0), 0)
		SetWindowTheme_(handle, #Null, "")
		SendMessage_(handle, #PBM_SETRANGE32, 0, 100)
		SendMessage_(handle, #PBM_SETBARCOLOR, 0, $0A0AAA)
		SendMessage_(handle, #PBM_SETBKCOLOR, 0, $F8E7DC)
		SendMessage_(StatusBarID(0), #SB_SETBKCOLOR, 0, $EFD0BB)

	Else
		handle=ProgressBarGadget(0,ScaleUp(20), 4, ScaleUp(120), ScaleUp(16),0,100)
		SetGadgetState(0,50)
		SetParent_(GadgetID(0),StatusBarID(0))
		SetWindowTheme_(GadgetID(0),#Null,"")
		SetWindowLong_(handle,#GWL_STYLE,$54000001)

		SendMessage_(GadgetID(0),#PBM_SETBARCOLOR,0,$0A0AAA)
		SendMessage_(GadgetID(0),#PBM_SETBKCOLOR,0,$F8E7DC)

		SetWindowTheme_(StatusBarID(0),#Null,"")
		SendMessage_(StatusBarID(0),#SB_SETBKCOLOR,0,$C09070)

	EndIf

	AddWindowTimer(0, 0, 10)

	Repeat
		Select WaitWindowEvent()
		Case #PB_Event_Timer
			Progress + 1

			Select Progress
			Case 40
				; New attempt...
				SetWindowLong_(handle,#GWL_STYLE,$44000001)
				ResizeGadget(0,#PB_Ignore,#PB_Ignore,ScaleUp(251),#PB_Ignore)
				SetWindowLong_(handle,#GWL_STYLE,$54000001)

			Case 1 To 100
				SetGadgetState(0,progress)

			EndSelect

		Case #PB_Event_CloseWindow
			Break
		EndSelect
	ForEver
EndIf

Re: [Windows] Get rid of 3D border in Progressbar

Posted: Tue Feb 17, 2026 8:48 pm
by RASHAD
The border you get is the border of the track shaft of the progressbar
The only way to get rid of it is to use ContainerGadget or FraneGadget(Not sure about the frame)

Re: [Windows] Get rid of 3D border in Progressbar

Posted: Tue Feb 17, 2026 8:50 pm
by chi
You mean like this?

Code: Select all

EnableExplicit

#PBM_SETRANGE32   = #WM_USER + 6
#PBM_SETPOS       = #WM_USER + 2
#PBM_SETBARCOLOR  = #WM_USER + 9
#PBM_SETBKCOLOR   = #CCM_FIRST + 1
#SB_SETBKCOLOR    = $2001
#PB_DpiBits       = 16
#PB_DpiScale      = 1 << #PB_DpiBits

Global DpiScale = GetDeviceCaps_(GetDC_(0), #LOGPIXELSX) << #PB_DpiBits / 96
Global handle, Progress

Macro ScaleUp(value)
	(((value) * DpiScale) / #PB_DpiScale)
EndMacro

Macro ScaleDown(value)
	(((value) << #PB_DpiBits) / DpiScale)
EndMacro

If OpenWindow(0, 0, 0, 600, 200, "Progress Bar", #PB_Window_SystemMenu | #PB_Window_TitleBar | #PB_Window_ScreenCentered|#PB_Window_SizeGadget)
	CreateStatusBar(0, WindowID(0))
	AddStatusBarField(ScaleUp(20))
	AddStatusBarField(ScaleUp(300))
	AddStatusBarField(#PB_Ignore)
	StatusBarText(0, 0, "> >", #PB_StatusBar_BorderLess)
	StatusBarText(0, 1, "", #PB_StatusBar_BorderLess)
	StatusBarText(0, 2, "< < < < < < < < < <", #PB_StatusBar_BorderLess)

	If 0
		; JHPJHP
		handle=CreateWindowEx_(0, "msctls_progress32", "", #WS_CHILD | #WS_VISIBLE | #WS_CLIPSIBLINGS | #PBS_SMOOTH,ScaleUp(20), 4, ScaleUp(200), ScaleUp(16), StatusBarID(0), 0, GetModuleHandle_(0), 0)
		SetWindowTheme_(handle, #Null, "")
		SendMessage_(handle, #PBM_SETRANGE32, 0, 100)
		SendMessage_(handle, #PBM_SETBARCOLOR, 0, $0A0AAA)
		SendMessage_(handle, #PBM_SETBKCOLOR, 0, $F8E7DC)
		SendMessage_(StatusBarID(0), #SB_SETBKCOLOR, 0, $EFD0BB)

	Else
		handle=ProgressBarGadget(0,ScaleUp(20), 4, ScaleUp(120), ScaleUp(16),0,100)
		SetGadgetState(0,50)
		SetParent_(GadgetID(0),StatusBarID(0))
		SetWindowTheme_(GadgetID(0),#Null,"")
		SetWindowLongPtr_(handle,#GWL_STYLE,$54000001)

		SendMessage_(GadgetID(0),#PBM_SETBARCOLOR,0,$0A0AAA)
		SendMessage_(GadgetID(0),#PBM_SETBKCOLOR,0,$F8E7DC)

		SetWindowTheme_(StatusBarID(0),#Null,"")
		SendMessage_(StatusBarID(0),#SB_SETBKCOLOR,0,$C09070)
		
		SetWindowLongPtr_(handle, #GWL_EXSTYLE, GetWindowLongPtr_(handle, #GWL_EXSTYLE)&~#WS_EX_STATICEDGE)
		;SetWindowPos_(handle, #HWND_TOP, 0, 0, 0, 0, #SWP_NOSIZE|#SWP_NOMOVE|#SWP_NOZORDER|#SWP_NOACTIVATE|#SWP_FRAMECHANGED)

	EndIf

	AddWindowTimer(0, 0, 10)

	Repeat
		Select WaitWindowEvent()
		Case #PB_Event_Timer
			Progress + 1

			Select Progress
			Case 40
				; New attempt...
				;SetWindowLongPtr_(handle,#GWL_STYLE,$44000001)
				ResizeGadget(0,#PB_Ignore,#PB_Ignore,ScaleUp(251),#PB_Ignore)
				;SetWindowLongPtr_(handle,#GWL_STYLE,$54000001)

			Case 1 To 100
				SetGadgetState(0,progress)

			EndSelect

		Case #PB_Event_CloseWindow
			Break
		EndSelect
	ForEver
EndIf
I just opened WinSpy++, dragged the finder tool over your progressbar, switched to "Styles" and saw that WS_EX_STATICEDGE was still active.

Re: [Windows, Solved] Get rid of 3D border in Progressbar

Posted: Wed Feb 18, 2026 7:13 am
by Michael Vogel
Ooh - I didn't see the wood for the trees, thank you so much.