Page 1 of 1

Flicker-Free Tab Control

Posted: Mon May 11, 2009 3:43 pm
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?

Posted: Mon May 11, 2009 5:07 pm
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?

Posted: Mon May 11, 2009 5:10 pm
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?

Posted: Mon May 11, 2009 5:51 pm
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_().

Posted: Mon May 11, 2009 5:56 pm
by srod
I don't get a great deal of flicker here if we use #WS_CLIPCHILDREN on the parent! (Vista 32).

Posted: Mon May 11, 2009 5:59 pm
by Fluid Byte
You know what? **** it. Gonna play some Wolfenstein ET now ...

Posted: Mon May 11, 2009 6:01 pm
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:

Posted: Mon May 11, 2009 8:28 pm
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!

Posted: Mon May 11, 2009 8:43 pm
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?

Posted: Mon May 11, 2009 9:05 pm
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?

Posted: Mon May 11, 2009 9:08 pm
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. :)

Posted: Mon May 11, 2009 9:45 pm
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 :?