用内存dc和bitblt 给你一个封装好的内存dc class CMemDC : public CDC { public: //constructor sets up the memory DC CMemDC(CDC* pDC) : CDC() { ASSERT(pDC != NULL); m_pDC = pDC; m_pOldBitmap = NULL;
#ifndef WCE_NO_PRINTING m_bMemDC = !pDC->IsPrinting(); #else m_bMemDC = FALSE; #endif if (m_bMemDC) // Create a Memory DC { pDC->GetClipBox(&m_rect); CreateCompatibleDC(pDC); m_bitmap.CreateCompatibleBitmap(pDC, m_rect.Width(), m_rect.Height()); m_pOldBitmap = SelectObject(&m_bitmap); #ifndef _WIN32_WCE SetWindowOrg(m_rect.left, m_rect.top); #endif // EFW - Bug fix - Fill background in case the user has overridden // WM_ERASEBKGND. We end up with garbage otherwise. // CJM - moved to fix a bug in the fix.
FillSolidRect(m_rect, (COLORREF)GetSysColor( COLOR_WINDOW ) ); } else // Make a copy of the relevent parts of the current DC for printing { #if !defined(_WIN32_WCE) || ((_WIN32_WCE > 201) && !defined(WCE_NO_PRINTING)) m_bPrinting = pDC->m_bPrinting; #endif m_hDC = pDC->m_hDC; m_hAttribDC = pDC->m_hAttribDC; } } // Destructor copies the contents of the mem DC to the original DC ~CMemDC() { if (m_bMemDC) { // Copy the offscreen bitmap onto the screen. m_pDC->BitBlt(m_rect.left, m_rect.top, m_rect.Width(), m_rect.Height(), this, m_rect.left, m_rect.top, SRCCOPY); //m_pDC->DrawState( CPoint( 10 ,10 ) , CSize( m_rect.right , m_rect.bottom ), &m_bitmap , DST_BITMAP | DSS_DISABLED ); //Swap back the original bitmap. SelectObject(m_pOldBitmap); } else { // All we need to do is replace the DC with an illegal value, // this keeps us from accidently deleting the handles associated with // the CDC that was passed to the constructor. m_hDC = m_hAttribDC = NULL; } } // Allow usage as a pointer CMemDC* operator->() {return this;}
// Allow usage as a pointer operator CMemDC*() {return this;} void DrawDisabled() { CPen pen; pen.CreatePen( PS_DOT , 1 , RGB( 192 , 192 , 192 ) ); SelectObject( &pen ); for( int y = 0 ; y < m_rect.bottom ; y++ ) { MoveTo( ( ! (y % 2) ) ? 0 : 3 , y ); LineTo( m_rect.right , y ); }; //for pen.DeleteObject();
} CRect m_rect; // Rectangle of drawing area.private: CBitmap m_bitmap; // Offscreen bitmap CBitmap* m_pOldBitmap; // bitmap originally found in CMemDC CDC* m_pDC; // Saves CDC passed in constructor BOOL m_bMemDC; // TRUE if CDC really is a Memory DC. };
dcMem.CreateCompatibleDC(&dc);
CBitmap * pSaveBack = dcMem.SelectObject(&bmPicture);
dc.BitBlt(0,0,PICWIDTH,PICHEIGHT,&dcMem,0,0,SRCCOPY);
dcMem.SelectObject(pSaveBack);
给你一个封装好的内存dc
class CMemDC : public CDC
{
public: //constructor sets up the memory DC
CMemDC(CDC* pDC) : CDC()
{
ASSERT(pDC != NULL); m_pDC = pDC;
m_pOldBitmap = NULL;
#ifndef WCE_NO_PRINTING
m_bMemDC = !pDC->IsPrinting();
#else
m_bMemDC = FALSE;
#endif if (m_bMemDC) // Create a Memory DC
{
pDC->GetClipBox(&m_rect);
CreateCompatibleDC(pDC);
m_bitmap.CreateCompatibleBitmap(pDC, m_rect.Width(), m_rect.Height());
m_pOldBitmap = SelectObject(&m_bitmap);
#ifndef _WIN32_WCE
SetWindowOrg(m_rect.left, m_rect.top);
#endif
// EFW - Bug fix - Fill background in case the user has overridden
// WM_ERASEBKGND. We end up with garbage otherwise.
// CJM - moved to fix a bug in the fix.
FillSolidRect(m_rect, (COLORREF)GetSysColor( COLOR_WINDOW ) ); }
else // Make a copy of the relevent parts of the current DC for printing
{
#if !defined(_WIN32_WCE) || ((_WIN32_WCE > 201) && !defined(WCE_NO_PRINTING))
m_bPrinting = pDC->m_bPrinting;
#endif
m_hDC = pDC->m_hDC;
m_hAttribDC = pDC->m_hAttribDC;
} } // Destructor copies the contents of the mem DC to the original DC
~CMemDC()
{
if (m_bMemDC)
{
// Copy the offscreen bitmap onto the screen.
m_pDC->BitBlt(m_rect.left, m_rect.top, m_rect.Width(), m_rect.Height(),
this, m_rect.left, m_rect.top, SRCCOPY); //m_pDC->DrawState( CPoint( 10 ,10 ) , CSize( m_rect.right , m_rect.bottom ), &m_bitmap , DST_BITMAP | DSS_DISABLED ); //Swap back the original bitmap.
SelectObject(m_pOldBitmap);
} else {
// All we need to do is replace the DC with an illegal value,
// this keeps us from accidently deleting the handles associated with
// the CDC that was passed to the constructor.
m_hDC = m_hAttribDC = NULL;
}
} // Allow usage as a pointer
CMemDC* operator->() {return this;}
// Allow usage as a pointer
operator CMemDC*() {return this;}
void DrawDisabled() { CPen pen; pen.CreatePen( PS_DOT , 1 , RGB( 192 , 192 , 192 ) );
SelectObject( &pen ); for( int y = 0 ; y < m_rect.bottom ; y++ ) {
MoveTo( ( ! (y % 2) ) ? 0 : 3 , y );
LineTo( m_rect.right , y );
}; //for
pen.DeleteObject();
} CRect m_rect; // Rectangle of drawing area.private:
CBitmap m_bitmap; // Offscreen bitmap
CBitmap* m_pOldBitmap; // bitmap originally found in CMemDC
CDC* m_pDC; // Saves CDC passed in constructor
BOOL m_bMemDC; // TRUE if CDC really is a Memory DC.
};
------------------->
弟一个问题,我觉得一定是你的程序问题。因为你还可以看到你的程序在闪烁。估计是重复调用刷新引起的。或大量计算。第二个问题,如楼上几位所说。用内存DC可解决
我刚刚做了一个,
也不会占用特别大的资源,是否你重复调用但是没有释放?
1,OnPaint中重复调用OnPaint刷新,导致资源占用过大。
2,OnPaint中没有释放GDI资源,导致效率低,维护占用CPU。看任务管理器里程序运行是不是内存不断增多。
3,使用某些MFC状态量,而且OnPaint调用频繁。比如构造CString等,这些状态量资源在程序空闲的时候由MFC回收的,如果程序占CPU多,那么很有可能导致内存泄露.建议使用双缓存,OnPaint里只用一句话:
pDC->BitBlt(***); // 将内存dc显示到设备上