Click here to Skip to main content
15,879,326 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
Hello everyone

I'm trying to resolve the problem with image blinking and I almost get it ,but I got some problems.

I want to redraw all the rest of the window except only the image. I'm trying to throw the Image's rectangle(i.e.coordinates) into ValidateRect and perform rendering but somehow it doesn't work

If I just overriding OnEraseBkgnd(CDC* pDC) {return false;}
It gives me a workable code,without any flickering(especially it looks great with high-definition images like 1680x1050) . But with small pictures where all the rest window is free when I begin resize it, it lefts remains(thats why I need to redraw it)
I've tried a lot of different ways and can't make it work
All the code is in OnDraw(CDC* pDC/*pDC*/) function
1)
if(oldpathName!=pathName){
	memDC.DeleteDC();
	memDC.CreateCompatibleDC(pDC);
	cImg.Destroy();
	if(cImg.Load((LPCTSTR)pathName)!=S_OK)
		AfxMessageBox(L"Error");
	memDC.SelectObject(cImg);
	pDC->BitBlt(0, 0, cImg.GetWidth(), cImg.GetHeight(), &memDC, 0, 0, SRCCOPY);
	oldpathName=pathName;erase=true;}
	else{
		CRect s(0,0,tmpImg->width,tmpImg->height);
		////InvalidateRect(s,FALSE);
		//RedrawWindow(s,NULL,RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE);
		ValidateRect(&s);
		pDC->BitBlt(0, 0, cImg.GetWidth(), cImg.GetHeight(), &memDC, 0, 0, SRCCOPY);
		//RedrawWindow(s,NULL,RDW_VALIDATE | RDW_UPDATENOW | RDW_ERASENOW);


If I run the program,the area where the image hangs (I validated it) begins blinking when I resize the borders.With small images I almost see nothing , but when I do it with the large ones some blinks occurs. It means that the function didn't fix the image

Maybe I should carry my code from OnDraw() into OnPaint(),than (maybe) OnPaint()'d call ->WM_PAINT->and then OnEraseBkgnd() would redraw the window or smth like that? It may look stupidly but I dont see any way now.Where is the mistake???

Please gimme a clue what I should change

After many efforts I at last got What I need
To resolve my problem I dragged all drawing operations from OnDraw() to OnPaint()
But somehow I noticed on GPU widget, that my video accelerator(i.e. videocard) sustains some load when I begin load\reload some amount of images. If I operate with resizing on MsPaint all look fine. I assume maybe I somewhere have some unnecessary overheads.
Now my code looks that way:
void CMicrofilmOfficeView::OnPaint()
{
if(tmpImg){
	CClientDC aDC(this);
    CDC* pDC =&aDC;
	if(oldpathName!=pathName){
	memDC.DeleteDC();
	memDC.CreateCompatibleDC(pDC);
	cImg.Destroy();
	if(cImg.Load((LPCTSTR)pathName)!=S_OK)
		AfxMessageBox(L"Error");
	memDC.SelectObject(cImg);
	pDC->BitBlt(0, 0, cImg.GetWidth(), cImg.GetHeight(), &memDC, 0, 0, SRCCOPY);
	oldpathName=pathName;}
	else{
		pDC->BitBlt(0, 0, cImg.GetWidth(), cImg.GetHeight(), &memDC, 0, 0, SRCCOPY);
		ValidateRect(&CRect(0,0,tmpImg->width,tmpImg->height));
	}
}


Please gimme plz an advice how to maximum optimize my code /
Posted
Updated 9-Oct-12 6:11am
v12

Allocate an empty bitmap the size of your display area.
Make a memdc for this image.
Call CDC::FillSolidRect(&ClientRect, 0x00FFFFFF); to clear it to the back ground color.
BitBlt your bitmap to this DC.
Bitblt this DC to your window.
 
Share this answer
 
I don't think you can avoid flicker without double buffering. The flicker occurs because memory associated with the image on the display is updated at the same time as the hardware pushes pixels to the screen. Have a look at:
Don't Flicker! Double Buffer![^]
 
Share this answer
 
Comments
JOHN 602 9-Oct-12 7:46am    
Don't you see that this code
pDC->BitBlt(0, 0, cImg.GetWidth(), cImg.GetHeight(), &memDC, 0, 0, SRCCOPY);

is the approach to realization of so-called double-buffering? (Or maybe am I wrong ?)
And why do you offer me a solution for .NET. As you can see I use Native C++( +MFC). That solution where a half of work is done by CLR.
JOHN 602 9-Oct-12 7:50am    
Only I want to fix the area where the image is. If I do it therefore no flicker won't occur.
michaelmel 9-Oct-12 19:48pm    
1) The link was intended as a general reference to some of the issues involved. Sorry if you think it is irrelevant to your immediate issue - you are probably right. I think it is a well written article though;
2) The term "double buffering" is actually ambiguous. What most people understand by it these days is preparing the complete image outside the actual screen memory (e.g. memDC in your case) before very efficiently copying it to the actual screen DC. Hence two buffers. But even with this, flicker is possible as physical display memory is modified whilst the display hardware controller is simultaneously using the same memory to blast pixels to the screen.

True double-buffering is done using 2 or more screen buffers and switching them on hardware driver level. In particular this was relevant for CRT monitors where buffer swap had to occur during retrace (e.g. whilst display is not being updated).

The bottom line is, with your BitBlt you have no control over flicker. You will have greatly reduced flicker and appearance of smooth rendering if you fully prepare the image "offline" and then quickly copy it to physical DC, but you cannot guarantee it will be completely flicker free on all monitors and refresh rates.

Sorry for long-winded response and if is irrelevant to what you were actually asking- my bad.
Well, loading again and again the CImage doesn't help the overall performance, in my opinion.
 
Share this answer
 
Comments
JOHN 602 9-Oct-12 13:36pm    
Do I need use ValidateRect() every time I need to redraw the window? Maybe there is another way once fix it and than sometime unfix it ? (in may way unfix picture when I need to load a new image)
CPallini 9-Oct-12 13:43pm    
Quite the opposite:
http://msdn.microsoft.com/en-us/library/windows/desktop/dd145194(v=vs.85).aspx
JOHN 602 9-Oct-12 13:54pm    
yeah exactly
owing to my efforts to optimization I ain't see some evident things
tnx

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900