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

Just starting out? Need help? Post your questions and find answers here.
User avatar
Michael Vogel
Addict
Addict
Posts: 2860
Joined: Thu Feb 09, 2006 11:27 pm
Contact:

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

Post 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 //
Last edited by Michael Vogel on Wed Feb 18, 2026 7:11 am, edited 2 times in total.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 5038
Joined: Sun Apr 12, 2009 6:27 am

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

Post 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))
Egypt my love
User avatar
Michael Vogel
Addict
Addict
Posts: 2860
Joined: Thu Feb 09, 2006 11:27 pm
Contact:

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

Post 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.
User avatar
Michael Vogel
Addict
Addict
Posts: 2860
Joined: Thu Feb 09, 2006 11:27 pm
Contact:

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

Post 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
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 5038
Joined: Sun Apr 12, 2009 6:27 am

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

Post 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)
Egypt my love
User avatar
chi
Addict
Addict
Posts: 1092
Joined: Sat May 05, 2007 5:31 pm
Location: Austria

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

Post 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.
Et cetera is my worst enemy
User avatar
Michael Vogel
Addict
Addict
Posts: 2860
Joined: Thu Feb 09, 2006 11:27 pm
Contact:

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

Post by Michael Vogel »

Ooh - I didn't see the wood for the trees, thank you so much.
Post Reply