How to create an image buffer in MFC
Hello everyone,
I'm new to codeguru and beginner with MFC.
Can anyone please explain, or point out to an internet resource that explains how to create, initialize, and maintain a memory device context that works as a local buffer for images? The idea is to maintain some large images in local DCs and bitmaps, and only bitblt them to screen in OnDraw().
What I did so far was was to define CDC and CBitmap objects as members of my View class, and then tried to initialize them with the sequence that begins at "// Initialize buffer". I placed that sequence in either OnInitialUpdate, or PreCreateWindow, or OnPrepareDC, or the view constructor, to no avail. The code always crashes in OnDraw, and I've noticed that the m_hDC member of myDevice is zero at that point.
Obviously, the initialization is wrong and MFC does (too many) things in the background which I'm not aware of.... My question was where can I read about that?
Code:
class CMyView : public CScrollView
{
// ...
CDC myDevice;
CBitmap bmp;
CBitmap *oldbmp;
};
// Initialize buffer
CDC* pdc = GetDC();
myDevice.CreateCompatibleDC(pdc);
bmp.CreateCompatibleBitmap(pdc,XMAX,YMAX);
oldbmp = myDevice.SelectObject(&bmp);
myDevice.SetBkColor(BLK);
// Initialize buffer - end
Thank you,
Cris.
Re: How to create an image buffer in MFC
Re: How to create an image buffer in MFC
Thank you D_Drmmr.
The solution described in that example creates the DC object (CMemDC) and its bitmap within OnDraw, so they only exist and have to be updated within that scope. I'm looking for a solution that creates a persistent bitmap (and/or DC) that can be updated asynchronously between the calls to OnDraw.
Thanks, Cris.
Re: How to create an image buffer in MFC
Quote:
Originally Posted by
Cristi
Thank you D_Drmmr.
The solution described in that example creates the DC object (CMemDC) and its bitmap within OnDraw, so they only exist and have to be updated within that scope. I'm looking for a solution that creates a persistent bitmap (and/or DC) that can be updated asynchronously between the calls to OnDraw.
Thanks, Cris.
You can save the DC and bitmap as class members instead of as local variables. You can initialize them the first time OnDraw is called. It's really just a matter of copy-pasting some code from the example.
Re: How to create an image buffer in MFC
Yes, I did that, and I'm afraid it isn't just a matter of copy-pasting.
Here is my OnDraw() code, right now just five lines of code:
Code:
void CMyView::OnDraw(CDC* pDC)
{
// CBitmap bmp;
// CDC myDevice;
ASSERT_VALID(pDC);
myDevice.CreateCompatibleDC(pDC);
bmp.CreateCompatibleBitmap(pDC,XMAX,YMAX);
CBitmap *oldbmp = myDevice.SelectObject(&bmp);
myDevice.SetBkColor(BLK);
}
The execution crashes at CreateCompatibleDC(pDC); if I remove that line it crashes at CreateCompatibleBitmap(...).
This happens ONLY when bmp and myDevice are defined as members of CMyView class, as in my first post.
If I use local variables (insert the two lines commented out above ASSERT_VALID(pDC)) everything WORKS fine.
There are other forces at work here....
With best regards,
Cris.
Re: How to create an image buffer in MFC
Quote:
Originally Posted by
Cristi
Yes, I did that, and I'm afraid it isn't just a matter of copy-pasting.
The link I posted contains a lot more code than what you posted now, so you did not just copy-paste.
Quote:
Originally Posted by
Cristi
Here is my OnDraw() code, right now just five lines of code:
Code:
void CMyView::OnDraw(CDC* pDC)
{
// CBitmap bmp;
// CDC myDevice;
ASSERT_VALID(pDC);
myDevice.CreateCompatibleDC(pDC);
bmp.CreateCompatibleBitmap(pDC,XMAX,YMAX);
CBitmap *oldbmp = myDevice.SelectObject(&bmp);
myDevice.SetBkColor(BLK);
}
The execution crashes at CreateCompatibleDC(pDC); if I remove that line it crashes at CreateCompatibleBitmap(...).
This happens ONLY when bmp and myDevice are defined as members of CMyView class, as in my first post.
If I use local variables (insert the two lines commented out above ASSERT_VALID(pDC)) everything WORKS fine.
There are other forces at work here....
OnDraw will be called hundreds of times. You don't need to create a DC and bitmap each time, but only once (since you keep them as member variables). So, the first thing is to check if the DC has been created already. You can simply do that using
Code:
if (!myDevice) {
// initialize DC and bitmap
myDevice.CreateCompatibleDC(pDC);
// etc.
}
Then you can copy the rest of the initialization from the CMemDC constructor in the link I posted, as well as the bit blitting from the destructor.