Controls are flicker madly on resize. I'm trying double buffering but I still ...
ok so for the past half year I've been trying to double buffer my app as it flickers madly when I resize it. Well I was able to Set WM_ERASEBGRND to true to stop it from erasing the Background and under my WM_PAINT my windows procedure I was able to blitblt a gray background on my form so its just not all black.
The thing is is that all of the controls flicker and I even replaced all of my SetWindowPos with DeferWindowPos.
Before this I used WS_EX_COMPOSITED and eve though it does a pretty good job with it, it doesn't update any of my scroll bars. For example if I clicked on a scroll thumb and moved it to the top you have to let go of it for it to update the scroll bar. And when you click down on the buttons for the scroll bars they no longer sink in like they use to which causes problems.
Anyways here is the code I'm using which I found off line and trying to get it to work so my controls stop flickering:
Code:
case WM_ERASEBKGND:
return 1;
break;
HDC hdcMem;
HBITMAP hbmMem;
HANDLE hOld;
PAINTSTRUCT ps;
HDC hdc;
RECT Temp_Rect;
case WM_PAINT:
Temp_Rect=SSMAIN_RECT;
// Get DC for window
hdc = BeginPaint(hwnd, &ps);
// Create an off-screen DC for double-buffering
hdcMem = CreateCompatibleDC(hdc);
hbmMem = CreateCompatibleBitmap(hdc, SSMAIN_WIDTH,SSMAIN_HEIGHT);
hOld = (HBITMAP)SelectObject(hdcMem, hbmMem);
// Draw into hdcMem here
// Transfer the off-screen DC to the screen
Temp_Rect.left=-200;
Temp_Rect.top=-200;
FillRect(hdcMem, &Temp_Rect, (HBRUSH) (COLOR_WINDOW+7));
BitBlt(hdc, 0, 0, SSMAIN_WIDTH, SSMAIN_HEIGHT, hdcMem, 0, 0, SRCCOPY);
// Free-up the off-screen DC
SelectObject(hdcMem, hOld);
DeleteObject(hbmMem);
DeleteDC (hdcMem);
EndPaint(hwnd, &ps);
break;
Re: Controls are flicker madly on resize. I'm trying double buffering but I still ...
I don't know what controls do you use. I had a tab control. I did subclassing only for it, not for controls that is have. I worked for me.
As i understood you have flickering when you resize your parent form. Try to subclass only this parent form and see if it helps.
Re: Controls are flicker madly on resize. I'm trying double buffering but I still ...
Originally Posted by Sh@dow
I don't know what controls do you use. I had a tab control. I did subclassing only for it, not for controls that is have. I worked for me.
As i understood you have flickering when you resize your parent form. Try to subclass only this parent form and see if it helps.
How would I go about subclassing the parent form?
Wouldn't that be the same as editing the WM_PAINT message of your windows procedure?
Also I changed the size of bitblt for a certain area.
Now heres the thing, the area where the bitblt is flickers while the rest of my windows doesn't as it leaves a trail of the other controls of the form when I resize it.
Also I have a toolbar,rebar,buttons,static, and a rtf control on my form.
Re: Controls are flicker madly on resize. I'm trying double buffering but I still ...
Originally Posted by Senith
ok guys since this is not working for me I guess I'm going have to clip the areas where the controls are after I figure out how to do that
In fact, what you really have to do is to prepare a simple minimalistic compilable project that reproduces your problem, and upload the one here in the thread. usually this is most effective way to investigate your problem and provide a solution to it.
Re: Controls are flicker madly on resize. I'm trying double buffering but I still ...
Originally Posted by Igor Vartanov
In fact, what you really have to do is to prepare a simple minimalistic compilable project that reproduces your problem, and upload the one here in the thread. usually this is most effective way to investigate your problem and provide a solution to it.
Ok thanks, I really appreciate that .
I have to get some work done though so when I get back I'll upload my program for you all
Don't pay attention to the "object->". Since TabCtrlSubclassProc must be defined as static i use object as an additional parameter to the procedure to get handles and other window specific data. I store it using"
Re: Controls are flicker madly on resize. I'm trying double buffering but I still ...
It seems like your code for double-buffering is in the WndProc for the main window (please confirm).
From your screenshots, it also seems like you do not actually have any controls per se, but rather you are brute-force-drawing the _shapes_ of what look like controls (but aren't actually "real" controls) into the the double buffer.
If so, then you are setting about this in the wrong way. In addition, it explains why a few of your "real" controls (you mentioned a static control and a list box) are behaving properly.
The correct way is to let the controls draw themselves from their own WndProcs (which may be the windows-supplied default WndProc for the control). Then in your main window, do only one thing: set the WS_CLIPCHILDREN style. No need to override the main window's WM_ERASEBKGRD.
Anyway, we look forward to your post of the source code for a minimal program that exhibits the problems you are experiencing.
Re: Controls are flicker madly on resize. I'm trying double buffering but I still ...
Originally Posted by MikeAThon
It seems like your code for double-buffering is in the WndProc for the main window (please confirm).
From your screenshots, it also seems like you do not actually have any controls per se, but rather you are brute-force-drawing the _shapes_ of what look like controls (but aren't actually "real" controls) into the the double buffer.
If so, then you are setting about this in the wrong way. In addition, it explains why a few of your "real" controls (you mentioned a static control and a list box) are behaving properly.
The correct way is to let the controls draw themselves from their own WndProcs (which may be the windows-supplied default WndProc for the control). Then in your main window, do only one thing: set the WS_CLIPCHILDREN style. No need to override the main window's WM_ERASEBKGRD.
Anyway, we look forward to your post of the source code for a minimal program that exhibits the problems you are experiencing.
Mike
(I haven't been online for a while due to work and the internet not working correctly)
And that is correct as the double buffer is within the WndProc of my application.
Also I have the double buffering working now. Some styles of the control such as "WS_CLIPCHILDREN, WS_CLIPSIBLINGS AND WS_EX_TRANSPARENT" were causing some problems with my double buffering which I have working now
(Thanks for your info WS_CLIPCHILDREN really appreciate it. I've tried that though with my first application, Everything withing it flickered. )
Also if I misunderstood your post please let me know .
Also all the controls on my form are real controls and not custom made (Yet)
Also I ran into the problem with my frame control. For some reason every other control within my app has its background clipped besides my frame(button). So of course everytime I resize the frame will flicker. Now if I add WS_EX_TRANSPARENT to the frame control the background of it is not being up dated as leaves a trail of windows behind. Almost as if its being clipped after I set it to WS_EX_TRANSPARENT.
So I know how to get around that too(an idea that popped into my mind. Explained below) as well, but i'm stuck atm.
I need to be able to draw onto the background of the frame control without erasing the frames border(ie I want to preserve the frames edges and text)
Thanks everyone for your help. It really helped me out.
Also if you guys will still like to see my code let me know and I'll post it. (Still need to clean it up as its a mess now *Working on it*)
Re: Controls are flicker madly on resize. I'm trying double buffering but I still ...
Originally Posted by Senith
Also if I misunderstood your post please let me know .
I think it's possible that you might have misunderstood. As requested by JohnCz, please post code. Not the actual code of your project, but simple code that demonstrates the flicker that you are encountering.
Generally speaking, with no special effort at all, a resizable dialog will not show any appreciable flicker until there are maybe 50-80 controls on it simultaneously. I don't think you have that many controls. And note that I said that "no special effort" is required for flicker-free performance. Just ensure that WS_CLIPCHILDREN is set. So the fact that you are seeing significant flicker, and the fact that WS_CLIPCHILDREN made it worse, tell me that there is something wrong with the overall architecture, fundamentally.
You state that you are using "actual" controls ("actual" meaning that the controls have their own WndProcs that are probably the default WndProcs supplied by Windows). If so, you are somehow overriding the WM_PAINT messages sent to the controls themselves, and somehow painting the controls in a doulbe-buffering mechanism in the WM_PAINT handler for the parent dialog. Please let us know (show the code) if you are using some abomination like a SendMessage of WM_PAINT to the control from within the WM_PAINT handler of the dialog, like so:
Code:
// from the WM_PAINT handler of the parent dialog
// pseudo-code
hdc = BeginPaint()
hdcMem = create memory device context
SendMessage( hwndControl_1, WM_PAINT, hdcMem, 0L );
SendMessage( hwndControl_2, WM_PAINT, hdcMem, 0L );
BitBlt( hdcMem into the hdc );
ReleaseEverything
EndPaint();
If you are doing something like this, then it's not a wonder that there is flicker.
Re: Controls are flicker madly on resize. I'm trying double buffering but I still ...
Originally Posted by MikeAThon
I think it's possible that you might have misunderstood. As requested by JohnCz, please post code. Not the actual code of your project, but simple code that demonstrates the flicker that you are encountering.
Generally speaking, with no special effort at all, a resizable dialog will not show any appreciable flicker until there are maybe 50-80 controls on it simultaneously. I don't think you have that many controls. And note that I said that "no special effort" is required for flicker-free performance. Just ensure that WS_CLIPCHILDREN is set. So the fact that you are seeing significant flicker, and the fact that WS_CLIPCHILDREN made it worse, tell me that there is something wrong with the overall architecture, fundamentally.
You state that you are using "actual" controls ("actual" meaning that the controls have their own WndProcs that are probably the default WndProcs supplied by Windows). If so, you are somehow overriding the WM_PAINT messages sent to the controls themselves, and somehow painting the controls in a doulbe-buffering mechanism in the WM_PAINT handler for the parent dialog. Please let us know (show the code) if you are using some abomination like a SendMessage of WM_PAINT to the control from within the WM_PAINT handler of the dialog, like so:
Code:
// from the WM_PAINT handler of the parent dialog
// pseudo-code
hdc = BeginPaint()
hdcMem = create memory device context
SendMessage( hwndControl_1, WM_PAINT, hdcMem, 0L );
SendMessage( hwndControl_2, WM_PAINT, hdcMem, 0L );
BitBlt( hdcMem into the hdc );
ReleaseEverything
EndPaint();
If you are doing something like this, then it's not a wonder that there is flicker.
Mike
Well what you said so far is pretty much true other then using SendMessage within the WM_PAINT.
Also I somehow manage to fix most of the flickering within my control other then the frame. I'm using WS_CLIPCHILDREN now on my main form as without it would cause all of my controls to flicker.
What ever I did it allowed the CLIPCHILDREN style to work correctly now from the looks of it
Also I read on another forum that you should never send a WM_PAINT message to a control using SendMessage other then windows. So I haven't done that.
Now for the WM_PAINT of my control for the WndProc is as fallows:
Also so far I'm still new to the double buffer procedure so I've been looking around sites to find more info out about it and used the basic code below and adopted it from their.
Code:
WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
hdcMem = CreateCompatibleDC(hdc);
hbmMem = CreateCompatibleBitmap(hdc, SSMAIN_WIDTH,SSMAIN_HEIGHT);
hOld = (HBITMAP)SelectObject(hdcMem, hbmMem);
//... Code that I added on my self
SelectObject(hdcMem, hOld);
DeleteObject(hbmMem);
DeleteDC(hdcMem);
EndPaint(hwnd, &ps);
break;
If you guys need anything else please let me know.
Last edited by Senith; May 25th, 2012 at 05:19 PM.
Bookmarks