CRect rcClient;
GetClientRect(rcClient);
HDC hdc = ::GetDC(m_hWnd) ;
// 定义一个内存显示设备上下文对象
HDC MemDC;
// 定义一个GDI位图对象
HBITMAP MemBitmap;
// 创建一个与指定设备(这里是屏幕)兼容的内存设备上下文环境(DC)
MemDC = ::CreateCompatibleDC(hdc);
// 建立一个与屏幕显示兼容的位图,位图的大小可选用窗口客户区的大小
MemBitmap= ::CreateCompatibleBitmap(hdc, rcClient.Width(), rcClient.Height());
// 将位图对象选入到内存显示设备上下文中,只有选择了才能进行绘图
//CBitmap *pOldBit = MemDC.SelectObject(&MemBitmap);
HGDIOBJ pOldBit = ::SelectObject(MemDC,MemBitmap);
// 先用白色背景色将位图清除干净,否则是黑色。
::FillRect(MemDC,rcClient, (HBRUSH)GetStockObject(WHITE_BRUSH));
// 定义画笔,颜色为灰色
CPen pen(PS_SOLID, 1, RGB(178,178,178));
CPen* pOldPen = NULL;
// 把画笔对象选定到指定的设备上下文环境中
HGDIOBJ hOldPen= ::SelectObject(MemDC,pen);
//-----------------------------------------绘图操作
// 需放在BitBlt函数前
// 画椭圆
::Ellipse(MemDC,rcClient.left,rcClient.top,rcClient.right,rcClient.bottom);
// 画对角线,循环次数多,没有双缓冲会卡顿
for(int i=0;i<1000;i++)
{
::MoveToEx(MemDC,0,0,NULL);
::LineTo(MemDC,rcClient.Width(), rcClient.Height());
::MoveToEx(MemDC,rcClient.Width(), 0,NULL);
::LineTo(MemDC,0, rcClient.Height());
}
//-----------------------------------------绘图操作
CString strText ;
strText = "将内存中的图拷贝到屏幕上进行显示";
DrawText(MemDC,strText,strText.GetLength(),&rcClient,DT_CENTER|DT_VCENTER);
// 将内存中的图拷贝到屏幕上进行显示
BitBlt(hdc,0, 0, rcClient.Width(), rcClient.Height(), MemDC, 0, 0, SRCCOPY);
// 绘图完成后的清理
::SelectObject(MemDC,pOldPen);
::SelectObject(MemDC,pOldBit);
//使用GetDC()要用ReleaseDC
::ReleaseDC(this->m_hWnd, MemDC);
::DeleteObject(hOldPen);
::DeleteObject(MemBitmap);
这篇博客详细介绍了如何利用内存设备上下文(DC)和兼容位图进行无闪烁的图形绘制,通过创建内存DC,绘图到内存位图,然后使用BitBlt函数将内容复制到屏幕,避免了多次屏幕重绘导致的闪烁问题。示例中包括了填充背景、绘制椭圆和线条等操作。
3295

被折叠的 条评论
为什么被折叠?



