## Double Buffering using uxtheme.lib?

Just starting out? Need help? Post your questions and find answers here.
PyroStrex
User
Posts: 61
Joined: Mon Mar 22, 2010 3:08 pm

### Double Buffering using uxtheme.lib?

like stated here:

http://www.codeguru.com/cpp/w-p/vista/a ... hp/c15709/

1. How can I do the same thing in PureBasic?.
2. Even if i can, is there any difference to the flicker?
3. Do I need to install Windows 7 SDK for this? (I'm using windows 7)
IdeasVacuum
Always Here
Posts: 6387
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

### Re: Double Buffering using uxtheme.lib?

1) The Code Guru example is c/c++ and looks to be using the Win API plus the 'uxtheme' lib. The API functions can be easily used by PB, as described here: http://www.purebasic.fr/english/viewtopic.php?t=10046

2) The article sounds convincing - proof of the pudding is in the eating though.

3) Apparently not, unless the 'uxtheme' is a member of the SDK.
http://msdn.microsoft.com/en-us/library ... 85%29.aspx

You need 3 files, UxTheme.dll, UxTheme.lib, UxTheme.h
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
PyroStrex
User
Posts: 61
Joined: Mon Mar 22, 2010 3:08 pm

### Re: Double Buffering using uxtheme.lib?

Hmm.. I will see If i can make ur tips work. Actually I just wanna free all flickers in my application. I have a problem while trying to free flickers for Tab Control or PanelGadget. It is when i was changing the tab and not resize. The flicker is not on the tab (since i already found a way to free the flicker for the tabs) but when the child changing. I don't really have a problem for checkboxgadget and optiongadget but for gadget like listviewgadget (not listicongadget) or stringgadget, It really is flickering.
srod
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

### Re: Double Buffering using uxtheme.lib?

That library will not help with child controls, it is designed for custom painting routines which, to be honest, is easy enough to implement directly without using the uxTheme library.

When performing some custom painting all you need do is configure your painting routines to draw to an arbitrary HDC given a horizontal and vertical offset. This will allow the said routine to then render directly to the screen or to an off-screen bitmap as appropriate. If wishing to double-buffer then simply create a bitmap the exact size of the update rectangle and which is compatible with the painting DC, select it into a compatible DC and call your painting routine with the offsets of the update rectangle etc. Once done, blt this to the screen directly atop the update rectangle.

I've done this many times and it works fine. The good thing though is that this method does not require Vista or above.
I may look like a mule, but I'm not a complete ass.
PyroStrex
User
Posts: 61
Joined: Mon Mar 22, 2010 3:08 pm

### Re: Double Buffering using uxtheme.lib?

Can you give me an example to do that for panelgadget's child? I can't seem to get it work. If you mean I will not be getting flickers with vista and above.. I'm using Windows 7 Professional and still, I see a huge flicker.
srod
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

### Re: Double Buffering using uxtheme.lib?

As I say, the uxTheme library will not help with such matters, the double-buffering is for custom painting only.
I may look like a mule, but I'm not a complete ass.
Justin
Enthusiast
Posts: 726
Joined: Sat Apr 26, 2003 2:49 pm

### Re: Double Buffering using uxtheme.lib?

Have you tried setting the #WS_EX_COMPOSITED extended style to the main window?
PyroStrex
User
Posts: 61
Joined: Mon Mar 22, 2010 3:08 pm

### Re: Double Buffering using uxtheme.lib?

I've tried it but what i get is the heaviest flicker of all.
Fluid Byte
Posts: 2336
Joined: Fri Jul 21, 2006 4:41 am
Location: Berlin, Germany

### Re: Double Buffering using uxtheme.lib?

Hmm.. I will see If i can make ur tips work. Actually I just wanna free all flickers in my application. I have a problem while trying to free flickers for Tab Control or PanelGadget.
Got any source code? Using #WS_CLIPCHILDREN / #WS_CLIPSIBLINGS can help reducing the flicker drasticly.
In fact, I was able to fix even the nastiest flickering caused by dozens of nested windows.
Windows 10 Pro, 64-Bit / Whose Hoff is it anyway?
PyroStrex
User
Posts: 61
Joined: Mon Mar 22, 2010 3:08 pm

### Re: Double Buffering using uxtheme.lib?

I don't know.. I don't have any flickers when I didn't use PanelGadget. But here is my source code for the demonstration.

Code: Select all

Enumeration
#Str1
#Str2

#Panel1
#Str3
#Str4
EndEnumeration

If OpenWindow(0, 0, 0, 200, 200, "Flicker Free Test", #PB_Window_SizeGadget | #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #WS_CLIPCHILDREN)
;Making huge flicker to the PanelGadget
;SetWindowLongPtr_(WindowID(0), #GWL_EXSTYLE, GetWindowLongPtr_(WindowID(0), #GWL_EXSTYLE) | #WS_EX_COMPOSITED)

StringGadget(#Str1, 5, 5, 190, 20, "")
StringGadget(#Str2, 5, 30, 190, 20, "")

StringGadget(#Str3, 5, 5, 172, 20, "")
StringGadget(#Str4, 5, 30, 172, 20, "")

Repeat
Event = WaitWindowEvent()
Select Event
EventType = EventType()
Case #PB_Event_SizeWindow
ResizeGadget(#Str1, #PB_Ignore, #PB_Ignore, WindowWidth(0) - 10, #PB_Ignore)
Case #PB_Event_CloseWindow
EventWindow = EventWindow()
If EventWindow = 0
CloseWindow(0)
Break
EndIf
EndSelect
ForEver
EndIf
Justin
Enthusiast
Posts: 726
Joined: Sat Apr 26, 2003 2:49 pm

### Re: Double Buffering using uxtheme.lib?

Strange, here on xp #WS_EX_COMPOSITED produces zero flickering but the string gadgets appear disabled.
Anyway, the problem is the static control the panel uses as a container, setting #WS_CLIPCHILDREN to it seems to fix it, also #WS_CLIPSIBLINGS is needed to its childs.
This code removes the flickering on xp, although the tab items flicker a little, you can't avoid that.

Code: Select all

Enumeration
#Str1
#Str2

#Panel1
#Str3
#Str4
EndEnumeration

procedure EnumChilds(hwnd.i, param.i)
SetWindowLongPtr_(hwnd, #GWL_STYLE, GetWindowLongPtr_(hwnd, #GWL_STYLE) | #WS_CLIPCHILDREN)

procedurereturn #true
endprocedure

If OpenWindow(0, 0, 0, 200, 200, "Flicker Free Test", #PB_Window_SizeGadget | #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #WS_CLIPCHILDREN)
;Making huge flicker to the PanelGadget
;SetWindowLongPtr_(WindowID(0), #GWL_EXSTYLE, GetWindowLongPtr_(WindowID(0), #GWL_EXSTYLE) | #WS_EX_COMPOSITED)

StringGadget(#Str1, 5, 5, 190, 20, "", #WS_CLIPSIBLINGS)
StringGadget(#Str2, 5, 30, 190, 20, "", #WS_CLIPSIBLINGS)

StringGadget(#Str3, 5, 5, 172, 20, "", #WS_CLIPSIBLINGS)
StringGadget(#Str4, 5, 30, 172, 20, "", #WS_CLIPSIBLINGS)

;Set #WS_CLIPCHILDREN to the panel and its childrens, only the statics are necessary i guess

Repeat
Event = WaitWindowEvent()
Select Event
EventType = EventType()
Case #PB_Event_SizeWindow
ResizeGadget(#Str1, #PB_Ignore, #PB_Ignore, WindowWidth(0) - 10, #PB_Ignore)
Case #PB_Event_CloseWindow
EventWindow = EventWindow()
If EventWindow = 0
CloseWindow(0)
Break
EndIf
EndSelect
ForEver
EndIf

PyroStrex
User
Posts: 61
Joined: Mon Mar 22, 2010 3:08 pm

### Re: Double Buffering using uxtheme.lib?

Here is the latest code which reduce the flicker and thanks to you Justin, no more flicker to the controls inside the PanelGadget. But, one last thing, The Tab doesn't flick when the tab was changed (The control is). But when resized, the tab is flicking again. Any way to prevent it?

Code: Select all

Enumeration
#Str1
#Str2

#Panel1
#Str3
#Str4
#Str5
#Str6
EndEnumeration

Global Panel1OldProcedure = #Null

Procedure PanelMainCallBack(hWnd, uMsg, wparam, lparam)
Protected ps.PAINTSTRUCT

Select uMsg
Case #WM_ERASEBKGND
ProcedureReturn 1
Case #WM_PAINT
If wparam
ProcedureReturn CallWindowProc_(PanelMainOldProcedure, hWnd, uMsg, wparam, lparam)
EndIf
hdc = BeginPaint_(hWnd, ps)
memDC = CreateCompatibleDC_(hdc)
hBMP = CreateCompatibleBitmap_(hdc, ps\rcPaint\right, ps\rcPaint\bottom)
hOldBMP = SelectObject_(memDC, hBMP)

CallWindowProc_(Panel1OldProcedure, hWnd, #WM_ERASEBKGND, memDC, 0)
CallWindowProc_(Panel1OldProcedure, hWnd, #WM_PRINT, memDC, #PRF_CLIENT)

BitBlt_(hdc, ps\rcPaint\left, ps\rcPaint\top, ps\rcPaint\right, ps\rcPaint\bottom, memDC, ps\rcPaint\left, ps\rcPaint\top, #SRCCOPY)

;Cleanup
SelectObject_(memDC, hOldBMP)
DeleteObject_(hBMP)
DeleteDC_(memDC)

EndPaint_(hwin, ps)
ProcedureReturn 0
Default
ProcedureReturn CallWindowProc_(Panel1OldProcedure, hWnd, uMsg, wparam, lparam)
EndSelect
EndProcedure

Procedure EnumChilds(hwnd.i, param.i)
SetWindowLongPtr_(hwnd, #GWL_STYLE, GetWindowLongPtr_(hwnd, #GWL_STYLE) | #WS_CLIPCHILDREN)

ProcedureReturn #True
EndProcedure

If OpenWindow(0, 0, 0, 200, 200, "Flicker Free Test", #PB_Window_SizeGadget | #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #WS_CLIPCHILDREN)
;Making huge flicker to the PanelGadget
;SetWindowLongPtr_(WindowID(0), #GWL_EXSTYLE, GetWindowLongPtr_(WindowID(0), #GWL_EXSTYLE) | #WS_EX_COMPOSITED)

StringGadget(#Str1, 5, 5, 190, 20, "", #WS_CLIPSIBLINGS)
StringGadget(#Str2, 5, 30, 190, 20, "", #WS_CLIPSIBLINGS)

StringGadget(#Str3, 5, 5, 172, 20, "", #WS_CLIPSIBLINGS)
StringGadget(#Str4, 5, 30, 172, 20, "", #WS_CLIPSIBLINGS)
StringGadget(#Str5, 5, 5, 172, 20, "", #WS_CLIPSIBLINGS)
StringGadget(#Str6, 5, 30, 172, 20, "", #WS_CLIPSIBLINGS)

;Set #WS_CLIPCHILDREN to the panel and its childrens, only the statics are necessary i guess

Repeat
Event = WaitWindowEvent()
Select Event
EventType = EventType()
Case #PB_Event_SizeWindow
ResizeGadget(#Str1, #PB_Ignore, #PB_Ignore, WindowWidth(0) - 10, #PB_Ignore)
Case #PB_Event_CloseWindow
EventWindow = EventWindow()
If EventWindow = 0
CloseWindow(0)
Break
EndIf
EndSelect
ForEver
EndIf
srod
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

### Re: Double Buffering using uxtheme.lib?

With XP themes enabled the panels are not filled correctly here because of the #WS_CLIPCHILDREN style. They appear greyed when they should be themed.

It is a style which must be used with care.
I may look like a mule, but I'm not a complete ass.
PyroStrex
User
Posts: 61
Joined: Mon Mar 22, 2010 3:08 pm

### Re: Double Buffering using uxtheme.lib?

Did you mean about the tab is not filled with white background but instead was filled with the backcolor of the window? If yes, then I also noticed the same thing. So, do you have any workaround for this case?
srod
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

### Re: Double Buffering using uxtheme.lib?

Not the tab no, the panel (unless you are confusing tabs with panels? )

Workaround... don't resize the panel gadget until after the user has finished resizing the window (use a callback and look out for the #WM_EXITSIZEMOVE message).

I have managed to reduce flicker with panels by employing some custom erasing, but that can be a bit fiddly. Styles such as #WS_EX_COMPOSITED just do not seem to work correctly and cause more problems than they solve etc. Themed panels are a right pain when it comes to flicker.
I may look like a mule, but I'm not a complete ass.