Double Buffering using uxtheme.lib?
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)
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)
-
- Always Here
- Posts: 6425
- 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
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.
If it sounds simple, you have not grasped the complexity.
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.
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.
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.
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.
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.
Re: Double Buffering using uxtheme.lib?
Have you tried setting the #WS_EX_COMPOSITED extended style to the main window?
Re: Double Buffering using uxtheme.lib?
I've tried it but what i get is the heaviest flicker of all.
- Fluid Byte
- Addict
- Posts: 2336
- Joined: Fri Jul 21, 2006 4:41 am
- Location: Berlin, Germany
Re: Double Buffering using uxtheme.lib?
Got any source code? Using #WS_CLIPCHILDREN / #WS_CLIPSIBLINGS can help reducing the flicker drasticly.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.
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?
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, "")
PanelGadget(#Panel1, 5, 55, 192, 140)
AddGadgetItem(#Panel1, -1, "Tab 01")
StringGadget(#Str3, 5, 5, 172, 20, "")
StringGadget(#Str4, 5, 30, 172, 20, "")
AddGadgetItem(#Panel1, -1, "Tab 02")
CloseGadgetList()
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_Gadget
EventGadget = EventGadget()
EventType = EventType()
Case #PB_Event_SizeWindow
ResizeGadget(#Str1, #PB_Ignore, #PB_Ignore, WindowWidth(0) - 10, #PB_Ignore)
ResizeGadget(#Str2, #PB_Ignore, #PB_Ignore, GadgetWidth(#Str1), #PB_Ignore)
ResizeGadget(#Panel1, #PB_Ignore, #PB_Ignore, WindowWidth(0) - 8, WindowHeight(0) - GadgetY(#Panel1) - 5)
ResizeGadget(#Str3, #PB_Ignore, #PB_Ignore, GadgetWidth(#Panel1) - 18, #PB_Ignore)
ResizeGadget(#Str4, #PB_Ignore, #PB_Ignore, GadgetWidth(#Str3), #PB_Ignore)
Case #PB_Event_CloseWindow
EventWindow = EventWindow()
If EventWindow = 0
CloseWindow(0)
Break
EndIf
EndSelect
ForEver
EndIf
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.
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)
PanelGadget(#Panel1, 5, 55, 192, 140)
AddGadgetItem(#Panel1, -1, "Tab 01")
StringGadget(#Str3, 5, 5, 172, 20, "", #WS_CLIPSIBLINGS)
StringGadget(#Str4, 5, 30, 172, 20, "", #WS_CLIPSIBLINGS)
AddGadgetItem(#Panel1, -1, "Tab 02")
CloseGadgetList()
;Set #WS_CLIPCHILDREN to the panel and its childrens, only the statics are necessary i guess
SetWindowLongPtr_(GadgetID(#Panel1), #GWL_STYLE, GetWindowLongPtr_(GadgetID(#Panel1), #GWL_STYLE) | #WS_CLIPCHILDREN)
EnumChildWindows_(GadgetID(#Panel1), @EnumChilds(), 0)
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_Gadget
EventGadget = EventGadget()
EventType = EventType()
Case #PB_Event_SizeWindow
ResizeGadget(#Str1, #PB_Ignore, #PB_Ignore, WindowWidth(0) - 10, #PB_Ignore)
ResizeGadget(#Str2, #PB_Ignore, #PB_Ignore, GadgetWidth(#Str1), #PB_Ignore)
ResizeGadget(#Panel1, #PB_Ignore, #PB_Ignore, WindowWidth(0) - 8, WindowHeight(0) - GadgetY(#Panel1) - 5)
ResizeGadget(#Str3, #PB_Ignore, #PB_Ignore, GadgetWidth(#Panel1) - 18, #PB_Ignore)
ResizeGadget(#Str4, #PB_Ignore, #PB_Ignore, GadgetWidth(#Str3), #PB_Ignore)
Case #PB_Event_CloseWindow
EventWindow = EventWindow()
If EventWindow = 0
CloseWindow(0)
Break
EndIf
EndSelect
ForEver
EndIf
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)
PanelGadget(#Panel1, 5, 55, 192, 140)
AddGadgetItem(#Panel1, -1, "Tab 01")
StringGadget(#Str3, 5, 5, 172, 20, "", #WS_CLIPSIBLINGS)
StringGadget(#Str4, 5, 30, 172, 20, "", #WS_CLIPSIBLINGS)
AddGadgetItem(#Panel1, -1, "Tab 02")
StringGadget(#Str5, 5, 5, 172, 20, "", #WS_CLIPSIBLINGS)
StringGadget(#Str6, 5, 30, 172, 20, "", #WS_CLIPSIBLINGS)
CloseGadgetList()
;Set #WS_CLIPCHILDREN to the panel and its childrens, only the statics are necessary i guess
SetWindowLongPtr_(GadgetID(#Panel1), #GWL_STYLE, GetWindowLongPtr_(GadgetID(#Panel1), #GWL_STYLE) | #WS_CLIPCHILDREN)
EnumChildWindows_(GadgetID(#Panel1), @EnumChilds(), 0)
Panel1OldProcedure = SetWindowLongPtr_(GadgetID(#Panel1), #GWLP_WNDPROC, @PanelMainCallBack())
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_Gadget
EventGadget = EventGadget()
EventType = EventType()
Case #PB_Event_SizeWindow
ResizeGadget(#Str1, #PB_Ignore, #PB_Ignore, WindowWidth(0) - 10, #PB_Ignore)
ResizeGadget(#Str2, #PB_Ignore, #PB_Ignore, GadgetWidth(#Str1), #PB_Ignore)
ResizeGadget(#Panel1, #PB_Ignore, #PB_Ignore, WindowWidth(0) - 8, WindowHeight(0) - GadgetY(#Panel1) - 5)
ResizeGadget(#Str3, #PB_Ignore, #PB_Ignore, GadgetWidth(#Panel1) - 18, #PB_Ignore)
ResizeGadget(#Str4, #PB_Ignore, #PB_Ignore, GadgetWidth(#Str3), #PB_Ignore)
ResizeGadget(#Str5, #PB_Ignore, #PB_Ignore, GadgetWidth(#Panel1) - 18, #PB_Ignore)
ResizeGadget(#Str6, #PB_Ignore, #PB_Ignore, GadgetWidth(#Str5), #PB_Ignore)
Case #PB_Event_CloseWindow
EventWindow = EventWindow()
If EventWindow = 0
CloseWindow(0)
Break
EndIf
EndSelect
ForEver
EndIf
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.
It is a style which must be used with care.
I may look like a mule, but I'm not a complete ass.
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?
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.
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.