上一版本链接:https://blog.csdn.net/u012156872/article/details/104966445,近期做窗口自绘,发现用该方法绘制非客户区仍存在问题,于是进行了功能简化和补充。
定义和声明:
#pragma once
namespace sw {
class CMemDC : public CDC
{
public:
//构造函数可应用于非客户区窗口绘制
CCacheDC(CDC& dc, CWnd* pWnd) :
m_dc(dc), m_hOldBmp(NULL), m_hBmp(NULL), m_hWnd(NULL)
{
ASSERT_VALID(pWnd);
Attach(::GetWindowDC(m_hWnd = pWnd->GetSafeHwnd()));
pWnd->GetWindowRect(m_rect);
m_rect.OffsetRect(-m_rect.TopLeft());
m_dcMem.Attach(m_hDC);
//BITMAPINFO bi;
//bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
//bi.bmiHeader.biBitCount = 32;
//bi.bmiHeader.biHeight = m_rect.Height();
//bi.bmiHeader.biWidth = m_rect.Width();
//bi.bmiHeader.biPlanes = 1;
//bi.bmiHeader.biCompression = BI_RGB;
//bi.bmiHeader.biXPelsPerMeter = 0;
//bi.bmiHeader.biYPelsPerMeter = 0;
//bi.bmiHeader.biClrUsed = 0;
//bi.bmiHeader.biSizeImage = ((m_rect.Width() * 32 + 31) & (~31)) >> 3 * m_rect.Height();
//PVOID pvBits = NULL;
//m_hBmp = ::CreateDIBSection(NULL, &bi, DIB_RGB_COLORS, &pvBits, 0, 0);
m_hBmp = ::CreateCompatibleBitmap(m_dc.GetSafeHdc(), m_rect.Width(), m_rect.Height());
m_hOldBmp = (HBITMAP)m_dcMem.SelectObject((HBITMAP)m_hBmp);
}
//构造函数只能应用于客户区窗口绘制
CMemDC(CDC& dc, const CRect& rect) :
m_dc(dc), m_hOldBmp(NULL), m_rect(rect), m_hBmp(NULL), m_hWnd(NULL)
{
ASSERT(!m_rect.IsRectEmpty());
m_dcMem.CreateCompatibleDC(&m_dc);
//BITMAPINFO bi;
//bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
//bi.bmiHeader.biBitCount = 32;
//bi.bmiHeader.biHeight = m_rect.Height();
//bi.bmiHeader.biWidth = m_rect.Width();
//bi.bmiHeader.biPlanes = 1;
//bi.bmiHeader.biCompression = BI_RGB;
//bi.bmiHeader.biXPelsPerMeter = 0;
//bi.bmiHeader.biYPelsPerMeter = 0;
//bi.bmiHeader.biClrUsed = 0;
//bi.bmiHeader.biSizeImage = ((m_rect.Width() * 32 + 31) & (~31)) >> 3 * m_rect.Height();
//PVOID pvBits = NULL;
//m_hBmp = ::CreateDIBSection(NULL, &bi, DIB_RGB_COLORS, &pvBits, 0, 0);
m_hBmp = ::CreateCompatibleBitmap(m_dc.GetSafeHdc(), m_rect.Width(), m_rect.Height());
m_hOldBmp = (HBITMAP)m_dcMem.SelectObject((HBITMAP)m_hBmp);
}
virtual ~CMemDC()
{
CRect rcClip;
int nClipType = m_dc.GetClipBox(rcClip);
if (nClipType != NULLREGION)
{
if (nClipType != SIMPLEREGION)
rcClip = m_rect;
BLENDFUNCTION blend;
blend.AlphaFormat = AC_SRC_ALPHA;
blend.BlendFlags = 0;
blend.BlendOp = AC_SRC_OVER;
blend.SourceConstantAlpha = 255;
::AlphaBlend(m_dc.GetSafeHdc(), rcClip.left, rcClip.top, rcClip.Width(), rcClip.Height(), m_dcMem.GetSafeHdc(), rcClip.left, rcClip.top, rcClip.Width(), rcClip.Height(), blend);
}
m_dcMem.SelectObject((HBITMAP)m_hOldBmp);
if (m_hWnd)
::ReleaseDC(m_hWnd, Detach());
}
CMemDC* operator->()
{
return this;
}
operator CMemDC*()
{
return this;
}
CDC& GetDC() { return m_dcMem; }
protected:
CDC& m_dc;
HBITMAP m_hBmp;
HBITMAP m_hOldBmp;
CDC m_dcMem;
CRect m_rect;
HWND m_hWnd;
};
}