Flicker-Free Tab Control

Windows specific forum
User avatar
Fluid Byte
Addict
Addict
Posts: 2336
Joined: Fri Jul 21, 2006 4:41 am
Location: Berlin, Germany

Flicker-Free Tab Control

Post by Fluid Byte »

It seems to be a common problem that when resizing a PanelGadget in PB that it suffers from serious redrawing problems. This is especially true when used in a SplitterGadget. It's so bad that even in small windows while resizing the whole gadget just disappears or heavily smears. For regular gadgets it can be fixed most of the time by obtaining all necessary window handles (SplitterMain -> SplitterChild -> owned gadgets) and applying the #WS_CLIPCHILDREN style were needed.

Now a tab control seems to be a different kind of breed. Even if it's created solo via API with no static childs and it's parent has the #WS_CLIPCHILDREN style it still fickers.

Code: Select all

OpenWindow(0,0,0,640,480,"void",#WS_OVERLAPPEDWINDOW | #WS_CLIPCHILDREN | 1)

hwndPanel = CreateWindowEx_(0,"SysTabControl32",0,#WS_CHILD | #WS_CLIPSIBLINGS | #WS_VISIBLE,0,0,0,0,WindowID(0),0,0,0)

tci.TC_ITEM
tci\mask = #TCIF_TEXT
tci\pszText = @"untitled1"
SendMessage_(hwndPanel,#TCM_INSERTITEM,0,tci)
tci\pszText = @"untitled2"
SendMessage_(hwndPanel,#TCM_INSERTITEM,1,tci)
tci\pszText = @"untitled3"
SendMessage_(hwndPanel,#TCM_INSERTITEM,2,tci)

Repeat
	EventID = WaitWindowEvent()

	If EventID = #PB_Event_SizeWindow
		MoveWindow_(hwndPanel,10,10,WindowWidth(0)-20,WindowHeight(0)-20,1)
	EndIf
Until EventID = #PB_Event_CloseWindow
Is there any chance of fixing that?
Windows 10 Pro, 64-Bit / Whose Hoff is it anyway?
User avatar
Fluid Byte
Addict
Addict
Posts: 2336
Joined: Fri Jul 21, 2006 4:41 am
Location: Berlin, Germany

Post by Fluid Byte »

Well I knew the continuous redrawing is caused by these class styles: #CS_HREDRAW / #CS_VREDRAW. The problem is after removing those the tab control will stop flickering but it won't update it's client area which results in further redrawing issues. So removing these styles is not an option.

I did some googling and found this useful thread:

http://www.codeguru.com/forum/showthread.php?t=324061

The conclusion is that #WS_EX_COMPOSITED actually fixes the flickering but I think I remember that there were problems involved using that message. That it is only available since Windows XP being one of them.

Is that safe to use? Sparkie? Anyone?
Windows 10 Pro, 64-Bit / Whose Hoff is it anyway?
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

When I used that style with a Purebasic panel gadget (didn't test with the api equivalent without the static containers) then there were horrendous problems when child gadgets had been added.

I gave up with it in the end! :wink:

Edit : BeginDeferWindowPos_()... never used those before! I'd be interested to know if using this function together with the accompanying ones makes a difference to overall flicker?
I may look like a mule, but I'm not a complete ass.
User avatar
Fluid Byte
Addict
Addict
Posts: 2336
Joined: Fri Jul 21, 2006 4:41 am
Location: Berlin, Germany

Post by Fluid Byte »

srod wrote:Edit : BeginDeferWindowPos_()... never used those before! I'd be interested to know if using this function together with the accompanying ones makes a difference to overall flicker?
Sure it is interesting ..., but it doesn't work! :lol:

Code: Select all

OpenWindow(0,0,0,640,480,"void",#WS_OVERLAPPEDWINDOW | #WS_OVERLAPPEDWINDOW | 1)

hwndPanel = CreateWindowEx_(0,"SysTabControl32",0,#WS_CHILD | #WS_VISIBLE | #WS_TABSTOP,0,0,0,0,WindowID(0),0,0,0)

tci.TC_ITEM
tci\mask = #TCIF_TEXT
tci\pszText = @"untitled1"
SendMessage_(hwndPanel,#TCM_INSERTITEM,0,tci)
tci\pszText = @"untitled2"
SendMessage_(hwndPanel,#TCM_INSERTITEM,1,tci)
tci\pszText = @"untitled3"
SendMessage_(hwndPanel,#TCM_INSERTITEM,2,tci)

Repeat
	EventID = WaitWindowEvent()

	If EventID = #PB_Event_SizeWindow
 		HDWP = BeginDeferWindowPos_(1)
		DeferWindowPos_(HDWP,hwndPanel,0,10,10,WindowWidth(0)-20,WindowHeight(0)-20,0)
 		EndDeferWindowPos_(HDWP)	
	EndIf
Until EventID = #PB_Event_CloseWindow
I guess it just allows to modify multiple windows using SetWindowPos_().
Windows 10 Pro, 64-Bit / Whose Hoff is it anyway?
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

I don't get a great deal of flicker here if we use #WS_CLIPCHILDREN on the parent! (Vista 32).
I may look like a mule, but I'm not a complete ass.
User avatar
Fluid Byte
Addict
Addict
Posts: 2336
Joined: Fri Jul 21, 2006 4:41 am
Location: Berlin, Germany

Post by Fluid Byte »

You know what? **** it. Gonna play some Wolfenstein ET now ...
Windows 10 Pro, 64-Bit / Whose Hoff is it anyway?
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Fluid Byte wrote:You know what? **** it. Gonna play some Wolfenstein ET now ...
Aye, that's the path I took when I tried reducing flicker with panel gadgets! :wink:
I may look like a mule, but I'm not a complete ass.
User avatar
Fluid Byte
Addict
Addict
Posts: 2336
Joined: Fri Jul 21, 2006 4:41 am
Location: Berlin, Germany

Post by Fluid Byte »

srod wrote:Aye, that's the path I took when I tried reducing flicker with panel gadgets! :wink:
Hehe :lol:

I can feel your pain now. I actually think it would be easier to code your own tab control. Yeah, if I think about it I really feel like giving it a try. So if you excuse me now, I have an appointment with MSDN.com. Laters!
Windows 10 Pro, 64-Bit / Whose Hoff is it anyway?
Marco2007
Enthusiast
Enthusiast
Posts: 648
Joined: Tue Jun 12, 2007 10:30 am
Location: not there...

Post by Marco2007 »

It`s getting better by doing this (at least at my PC -> of course slower, but better):

Code: Select all

Repeat 
   EventID = WaitWindowEvent() 
    
   If EventID = #PB_Event_SizeWindow 
     MoveWindow_(hwndPanel,10,10,WindowWidth(0)-20,WindowHeight(0)-20,1) : While WindowEvent(): Wend :Delay(90) 
   EndIf 

Until EventID = #PB_Event_CloseWindow
May this be a hint or crap?
PureBasic for Windows
milan1612
Addict
Addict
Posts: 894
Joined: Thu Apr 05, 2007 12:15 am
Location: Nuremberg, Germany
Contact:

Post by milan1612 »

I just had a look on the .Net Framework sources (.Net reflector for the win!) but
couldn't figure out exactly how they got the TabControl to be flicker free. But I know
that Microsoft used double buffering, maybe that can be done in PB as well?
Windows 7 & PureBasic 4.4
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

milan1612 wrote:I just had a look on the .Net Framework sources (.Net reflector for the win!) but
couldn't figure out exactly how they got the TabControl to be flicker free. But I know
that Microsoft used double buffering, maybe that can be done in PB as well?
I had a go at a tab control in VB.Net (VS 2005) and it flickers just the same here if you anchor the gadget. :)
I may look like a mule, but I'm not a complete ass.
milan1612
Addict
Addict
Posts: 894
Joined: Thu Apr 05, 2007 12:15 am
Location: Nuremberg, Germany
Contact:

Post by milan1612 »

srod wrote:
milan1612 wrote:I just had a look on the .Net Framework sources (.Net reflector for the win!) but
couldn't figure out exactly how they got the TabControl to be flicker free. But I know
that Microsoft used double buffering, maybe that can be done in PB as well?
I had a go at a tab control in VB.Net (VS 2005) and it flickers just the same here if you anchor the gadget. :)
You're right, I ran a small test with VS 2008 and noticed that even with enabled Double Buffering
there seems to be a tiny flicker when being resized. But at least it's almost unnoticeable :?
Windows 7 & PureBasic 4.4
Post Reply