To speed up a draw I have used the double buffering technique (i.e. drawing on a CDC in memory then copying it to the appropriate application CDC). However the background is always black. Can anyone tell me how this might be changed.
Cheers
Scott
Printable View
To speed up a draw I have used the double buffering technique (i.e. drawing on a CDC in memory then copying it to the appropriate application CDC). However the background is always black. Can anyone tell me how this might be changed.
Cheers
Scott
Try "FillRect" on your memory-DC
Remember that if you use a background DC to render your client area, that windows will still draw to the real device in WM_ERASEBKGND if you haven't trapped or disabled that (which you should). You need to assume that your memory DC is complete garbage every time you render and make sure to draw every pixel. I usually start with a PatBlt() or FillRect() if the background is going to be some solid color.
cheers both :)
FillRect sorted it.
I had the same problem and solved it by FillRect as well... But now when i resize the client area, the color set to the background doesn't resize... They rest of the area becomes black... I understand i may need to GetClientRect on WM_SIZE and call FillRect with these new coordinates... But my back-buffer doesn't get updated on repaint, so this wouldn't make a difference.. Any ideas?
The WM_SIZE message does give you the latest client area dimensions, but you are changing the bitmap selected into your memory DC right?
When you create a memory dc, GDI automatically selects a monochrome bitmap for it. How ever if you wish to have some colors in it, you have to select an appropriate bitmap and update it every time your client area changes its size. This is what I would do
//Member variables goes into your class .h file
CDC m_pDCBack;
CBitmap m_pBitBack;
//Constructor
{
...
m_pDCBack = NULL;
m_pBitBack = NULL;
...
}
//OnInitDialog
{
...
CClientDC dc(this);
m_pDCBack = new CDC;
m_pDCBack->CreateCompatibleDC(&dc);
...
}
//on WM_SIZE
{
...
//Skip if no size(always happens atleast once)
if((NULL == cx) ||
(NULL == cy))
{
return;
}
//Create a new bitmap for the memory dc
m_pBitBack= new CBitmap;
m_pBitBack->CreateCompatibleBitmap(m_pDCBack, cx, cy);
//Select this bitmap into background dc and delete old bitmap
delete (CBitmap *)m_pDCBack->SelectObject(m_pBitBack);
//you might want to repaint the background here
}
//Destructor
{
...
//The order of delleting is important... guess why
if(NULL != m_pDCBack)
{
delete m_pDCBack;
}
if(NULL != m_pBitBack)
{
delete m_pBitBack;
}
...
}
Shishyan, you should do all the graphic updates in the WM_PAINT message handler, not in the WM_SIZE.
When a window grows, not just a WM_SIZE, but also a WM_PAINT message is sent to that window. (If the window becomes smaller, no WM_PAINT message is sent.)
Hi srelu.. I chose to create and select the bitmap to dc in WM_SIZE since if I start doing it in WM_PAINT I may end up creating and selecting bitmaps a lot many times though the size of the window may not have changed.
I assumed that "moppy" is trying to drawing a static image, so when the window's size changes, he can prepare and keep a memory dc with his image and use BitBlt in WM_PAINT to bring it on screen
WM_PAINT not sent when window's size reduces? thats something new for me.. thanks for the info srelu
No doubt: WM_PAINT is sent also when window size reduces!
Doesn’t it depend on CS_HREDRAW and CS_VREDRAW styles of that window’s class?Quote:
Originally Posted by Bornish
Sorry Vladimir for the incomplete reply; if you need to be that precise, than also depends if a custom implementation is made in erase background event (WM_ERASEBKGND message)... in fact, also depends which region of the client area needs repainting... the best way to go about painting a window on every resize is to handle WM_SIZE and call InvalidateWindow() with no region, meaning the whole client area needs repainting, thus a WM_PAINT will be sent accordingly!Quote:
Originally Posted by VladimirF
Regards,
I simply wanted to point that when the window is resized up - it will always get WM_PAINT message for newly added area; when it's resized down - WM_PAINT will only be sent if you have CS_VREDRAW or CS_HREDRAW styles. In a wizard-generated Win32 app, try to remove CS_HREDRAW style and resize your window down horizonally - you will NOT get WM_PAINT.Quote:
Originally Posted by Bornish
Sorry, I don't see how handling of WM_ERASEBKGND can affect WM_PAINT message...Quote:
Originally Posted by Bornish
That would REALLY depend on your app! Consider Google's map, for example. Why would you paint anything when window's size is decreased?Quote:
Originally Posted by Bornish
Validate your window's client area on WM_ERASEBKGND and return zero...Quote:
Originally Posted by VladimirF
Google Maps has a legend, scalebar... and, the source of imagery displayed as separate controls!!! ...but Google Earth supports much more features (like rotation) that require repaint on sizing-down (the N indicator). What I'm trying to say is: YES, would REALLY depend on your app... you can have an application that doesn't require a window at all! :pQuote:
Originally Posted by VladimirF