无论是GDI、GDI+还是DirectDraw还是Direct2D,如果不注意细节的话,都非常容易闪屏。
<code class="lang-cpp">// 错误的做法 void OnPaint() { using namespace Gdiplus; CPaintDC dc(this); Graphics graphics(dc); Image myImage(L"img1.jpg"); REAL srcWidth = (REAL)myImage.GetWidth(); REAL srcHeight = (REAL)myImage.GetHeight(); RectF srcRect(0.0f, 0.0f, srcWidth, srcHeight); Matrix myMatrix(1.0f, 0.0f, 0.0f, 1.0f, 200.0f, 20.0f); BlurParams myBlurParams; myBlurParams.expandEdge = TRUE; myBlurParams.radius = 3; Blur myBlur; myBlur.SetParameters(&myBlurParams); // Draw the image without the blur effect. graphics.DrawImage(&myImage, 20.0, 20.0, srcWidth, srcHeight); // Draw the image with the blur effect. graphics.DrawImage(&myImage, &srcRect, &myMatrix, &myBlur, NULL, UnitPixel); } // 正确的做法 void OnPaint() { using namespace Gdiplus; CPaintDC dc(this); Graphics graphics(dc); Image myImage(L"img1.jpg"); // 画出没有模糊效果的图片 graphics.DrawImage(&myImage, 20, 20); static Bitmap *g_bmp = NULL; if (g_bmp == NULL) { // 如果图片还没有被模糊处理过,那么就先处理它,否则直接显示 REAL srcWidth = (REAL)myImage.GetWidth(); REAL srcHeight = (REAL)myImage.GetHeight(); BlurParams myBlurParams; myBlurParams.expandEdge = TRUE; myBlurParams.radius = 3; Blur myBlur; myBlur.SetParameters(&myBlurParams); g_bmp = ::new Bitmap(srcWidth, srcHeight, &graphics); Graphics graphics2(g_bmp); // 在内存位图上画出高斯模糊过的图片 graphics2.DrawImage(&myImage, NULL, NULL, &myBlur, NULL, UnitPixel); } // 画出已经处理过的图片 graphics.DrawImage(g_bmp, 500, 20); }</code>
<code class="lang-cpp">BOOL CChildView::OnEraseBkgnd(CDC* pDC) { // 抗闪烁 - 不自动清空背景,务必在OnPaint中清空背景,否则易出现显示不正确! return TRUE; // 默认 - 自动清空背景,但是在某些情况下可能会闪烁 //return CWnd::OnEraseBkgnd(pDC); }</code>
<code class="lang-cpp">struct CFastDC : public CDC { CDC *m_phydc; CBitmap m_bitmap; CRect m_rc; CFastDC() { m_phydc = NULL; } CFastDC(CDC *phyDC, CRect rc, COLORREF cr = RGB(255, 255, 255)) { m_phydc = NULL; BeginFastDC(phyDC, rc, cr); } ~CFastDC() { if (m_phydc != NULL) EndFastDC(); } CDC *BeginFastDC(CDC *phyDC, CRect rc, COLORREF cr = RGB(255, 255, 255)) { ASSERT(m_phydc == NULL); m_phydc = phyDC; m_rc = rc; CreateCompatibleDC(phyDC); // 新建兼容DC m_bitmap.CreateCompatibleBitmap(phyDC, m_rc.right-m_rc.left, m_rc.bottom-m_rc.top); SelectObject(m_bitmap); // 新建承载图像的兼容位图并附着在兼容DC上 FillColor(cr); return this; } void FillColor(COLORREF cr) { CRect rc2; rc2.top = rc2.left = 0; rc2.right = m_rc.right - m_rc.left; rc2.bottom = m_rc.bottom - m_rc.top; FillSolidRect(rc2, cr); // 填充背景 } BOOL EndFastDC() { ASSERT(m_phydc != NULL); return m_phydc->BitBlt(m_rc.left, m_rc.top, m_rc.right-m_rc.left, m_rc.bottom-m_rc.top, this, 0, 0, SRCCOPY); } };</code>
<code class="lang-cpp">void OnPaint() { CRect rc; GetClientRect(rc); // 获取窗口大小 CPaintDC dc(this); // 获取绘图DC CFastDC memdc(&dc, rc, GetSysColor(COLOR_3DFACE)); // 新建一个指定背景色和大小的内存DC // TODO: 使用memdc而不是dc作图 // ... // 当CFastDC析构时,它会自动尝试将自己的图像映射到物理DC上 }</code>
[修改于 9年5个月前 - 2015/07/18 19:34:16]
时段 | 个数 |
---|---|
{{f.startingTime}}点 - {{f.endTime}}点 | {{f.fileCount}} |
200字以内,仅用于支线交流,主线讨论请采用回复功能。