Is there a way to double-buffer the common controls? Currently when they resize they flicker. A lot.....
EDIT: If it helps, it is a bunch of button controls and a fe
Larry Osterman recently blogged about this subject; you might find some interesting details there.
indeed,
someone posted an answer for this on one of my posts a while ago. Check it out: Here
and be sure to upvote him for being awesome.
The code is C#, hopefully there is a simple translation.
You're not using WS_EX_TRANSPARENT, are you? That will cause underlying windows to be painted before the controls, and when the bottom window erases you get flicker.
I understand the topic is quite old, but this may be relevant to someone who's running into trouble with a flicker problem.
Very much like Billy, I have run into an issue that pops up when switching tabs, where controls that are placed on the tab flicker when being shown and hidden. For reference, I'm using ShowWindow function extensively to hide and show controls.
I have been fiddling with WS_EX_COMPOSITED for a few hours and it gave me very odd results. I'm also not resizing anything, the dialog is designed to run fullscreen and it adapts to the current desktop resolution.
This is the layout of my dialog, which I have created manually, calling the CreateWindowEx function for every control:
Main window -- some controls -- tab control ---- some more controls
Indent represents the parent-child relations. The tab control has WS_CHILD and WS_CLIPCHILDREN styles set on creation, all of the controls have WS_CHILD style set.
What in the end did the trick was the following
MainProc proc hWnd:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
mov eax,uMsg
cmp eax,WM_INITDIALOG
je @WM_INITDIALOG
...
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
@WM_INITDIALOG:
...
invoke GetWindowLong,hWnd,GWL_EXSTYLE
or eax,WS_EX_COMPOSITED
invoke SetWindowLong,hWnd,GWL_EXSTYLE,eax
...
MainProc endp
This bit is written in assembly (MASM32), but I'm sure you get the gist of it. Simply, get the EX_STYLE of your main window sometime during WM_INITDIALOG and add WS_EX_COMPOSITED to it.
In this singular case, this method works both on 32bit Windows XP SP3 and 64bit Windows 7 SP1. There was no need to add the WS_EX_COMPOSITED style to any of the tab's child controls (some of the static controls I use have WS_EX_TRANSPARENT set, but that's for other reasons) and at this time there is no apparent need to return non-zero on WM_ERASEBKGND message. I'm also not experiencing any performance problems on a moderately powerful C2D machine.
For reference, this is my Main
Main proc hInst:DWORD,hPrevInst:DWORD,CmdLine:DWORD,CmdShow:DWORD
LOCAL wc:WNDCLASSEX,msg:MSG
mov wc.cbSize,sizeof WNDCLASSEX
mov wc.style,CS_HREDRAW or CS_VREDRAW
mov wc.lpfnWndProc,offset MainProc
mov wc.cbClsExtra,NULL
mov wc.cbWndExtra,DLGWINDOWEXTRA
push hInst
pop wc.hInstance
mov wc.hbrBackground,COLOR_BTNFACE+1
mov wc.lpszClassName,offset szClassName
invoke LoadIcon,NULL,IDI_APPLICATION
mov wc.hIcon,eax
mov wc.hIconSm,eax
invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor,eax
invoke RegisterClassEx,addr wc
invoke CreateDialogParam,hInstance,IDD_MAIN,NULL,addr MainProc,NULL
invoke ShowWindow,hWin,SW_SHOWNORMAL
invoke UpdateWindow,hWin
invoke LoadAccelerators,hInstance,IDD_ACC_TABLE
mov hAcc,eax
jmp @2
@1:
invoke TranslateAccelerator,hWin,hAcc,addr msg
test eax,eax
jne @2
invoke TranslateMessage,addr msg
invoke DispatchMessage,addr msg
@2:
invoke GetMessage,addr msg,NULL,0,0
test eax,eax
jne @1
mov eax,msg.wParam
ret
Main endp
There's nothing special here, neither. I'm setting the "dialog control grey" as the background color and using the CS_*REDRAW styles, those appear not to affect this situation. The "empty" dialog template I used to create the main windows is this
IDD_MAIN DIALOGEX 0,0,318,177
FONT 8,"MS Sans Serif",0,0,0
CLASS "DLGCLASS"
STYLE 0x90800000
EXSTYLE 0x00000008
BEGIN
END
Hopefully this may save some time to people looking for answers. It's a tad long, but I wanted to detail it as much as possible.
Regards.
We use WTL::CDoubleBufferImpl
mix-in for that purpose. We even draw stuff with GDI+ over. Zero flickering.
Usage is pretty simple: you just public-ly inherit from WTL::CDoubleBufferImpl<YourClass>
, and chain it in the ATL message map.
Look at using WS_EX_COMPOSITED
and WS_EX_TRANSPARENT
styles. They provide doublebuffering, altough WM_PAINT will be called when the underlying bitmap is finished drawing, since it draws child controls from bottom to top, so you can paint only in your window procedure. I've used it in the past and work pretty well.
Set your top-level window (container) to extended style WS_EX_COMPOSITED and your child windows with WS_EX_TRANSPARENT. Also, remember to define:
#define WINVER 0x501
See CreateWindowEx for information on the composited style. This also makes possible to do perpixel transparency on child windows.
UPDATE
What about usign WM_PRINTCLIENT to transfer the client area to a bitmap on a DC and blit all the client area as a whole?
http://blogs.msdn.com/larryosterman/archive/2008/08/27/larry-s-new-favorite-windows-message-wm-printclient.aspx