绘制时防止闪烁
Prevent Flickering When Drawing
所以我有这个代码在屏幕上画一个矩形:
LOGBRUSH m_LogBrush;
HBRUSH m_hBrush;
HPEN m_hPen;
HDC m_hDC;
void DrawBox(int x, int y, int r, int g, int b, int size, int thickness)
{
// Brush style to hollow
m_LogBrush.lbStyle = BS_NULL;
// Create a logical brush and select into the context
m_hBrush = CreateBrushIndirect(&m_LogBrush);
SelectObject(m_hDC, m_hBrush);
// Create a logical pen and select into the context
m_hPen = CreatePen(PS_SOLID, thickness, RGB(r, g, b));
SelectObject(m_hDC, m_hPen);
// Draw the rectangle
Rectangle(m_hDC, (x - size / 2), (y - size / 2), (x + size / 2), (y + size / 2));
// Remove the object
DeleteObject(m_hBrush);
DeleteObject(m_hPen);
}
然而,当在循环中被反复调用时,它会在屏幕上闪烁。我想知道是否有办法防止这种闪烁?
如有任何帮助,我们将不胜感激。
感谢
这不应该是一个答案,但我不能在评论中发布代码:
您的代码中有许多GDI泄漏。
复制/粘贴以下代码,如果闪烁减少,则向我们报告:
void DrawBox(int x, int y, int r, int g, int b, int size, int thickness)
{
// Brush style to hollow
m_LogBrush.lbStyle = BS_NULL;
// Create a logical brush and select into the context
m_hBrush = CreateBrushIndirect(&m_LogBrush);
HBRUSH hbrOldBrush = SelectObject(m_hDC, m_hBrush);
// Create a logical pen and select into the context
m_hPen = CreatePen(PS_SOLID, thickness, RGB(r, g, b));
HPEN hpOldPen = SelectObject(m_hDC, m_hPen);
// Draw the rectangle
Rectangle(m_hDC, (x - size / 2), (y - size / 2), (x + size / 2), (y + size / 2));
// Remove the object
SelectObject(m_hDC, hbrOldBrush); // first you must restore DC to original state
SelectObject(m_hDC, hpOldPen); // same here
DeleteObject(m_hBrush);
DeleteObject(m_hPen);
}
在MSDN上阅读有关GDI泄漏的信息。
这应该会减少闪烁,但要完全消除闪烁,您应该执行以下操作:
- 从窗口类定义中删除
CS_VREDRAW | CS_HREDRAW
- 在窗口过程中返回
1L
(或在对话框过程中返回TRUE
)以响应WM_ERASEBKGND
- 在内存位图上绘制所有内容,然后将其
BitBlt
写入m_hDC
->,这称为双缓冲(您可以在网上找到许多示例)
/*Hi You May Change Your Code To This*/
LOGBRUSH m_LogBrush;
//HBRUSH m_hBrush;
//HPEN m_hPen;
//HDC m_hDC;
HWND m_hWND; //Your WindowHandle instead of your DC
//
void DrawBox(int x, int y, int r, int g, int b, int size, int thickness)
{
// Lock & Get Forground DC From m_hWND
HDC m_hDC = GetDC(m_hWND);
if (m_hDC != 0) //Make Sure It's ok
{
// Double Buffering Begins Here
// Create Background DC From m_hDC
HDC mem_m_hDC = CreateCompatibleDC(m_hDC);
// Calculate Window Bounds
RECT ClientRect = { 0 };
GetClientRect(m_hWND, &ClientRect);
// Create Background Buffer Frame
BITMAPINFO bmi = { 0 };
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = ClientRect.right - ClientRect.left;
bmi.bmiHeader.biHeight = ClientRect.bottom - ClientRect.top;
bmi.bmiHeader.biBitCount = 32;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biPlanes = 1;
HBITMAP memBMP = CreateDIBSection(mem_m_hDC, &bmi, DIB_RGB_COLORS, 0, 0, 0);
// Select Background Buffer Frame
SelectObject(mem_m_hDC, memBMP);
// Brush style to hollow
m_LogBrush.lbStyle = BS_NULL;
// Create a logical brush and select into the context
HBRUSH m_hBrush = CreateBrushIndirect(&m_LogBrush);
HGDIOBJ oldHGDIOBJ1 = SelectObject(m_hDC, m_hBrush); //Save Old Seleteed GDI Object To oldHGDIOBJ1
// Create a logical pen and select into the context
HPEN m_hPen = CreatePen(PS_SOLID, thickness, RGB(r, g, b));
HGDIOBJ oldHGDIOBJ2 = SelectObject(m_hDC, m_hPen); //Save Old Seleteed GDI Object To oldHGDIOBJ2
// Draw the rectangle in Background Memory DC
Rectangle(mem_m_hDC, (x - size / 2), (y - size / 2), (x + size / 2), (y + size / 2));
// Copy Background DC To Forground DC
BitBlt(m_hDC, 0, 0, bmi.bmiHeader.biWidth, bmi.bmiHeader.biHeight, mem_m_hDC, 0, 0, SRCCOPY);
// Delete Background Buffer Frame
DeleteObject(memBMP);
// Delete Background DC
DeleteDC(mem_m_hDC);
// Double Buffering Ends Here
// Unlock Forground DC
ReleaseDC(m_hWND, m_hDC);
// Remove the objects
DeleteObject(m_hBrush);
DeleteObject(m_hPen);
}
}
相关文章:
- QuadTree只在窗口的右上角绘制
- 绘制旋转的三角形
- flutter:即使shouldRepaint()返回true,自定义画家也不会重新绘制
- 处理闪烁窗口事件
- 如何在QT中的自定义视频小工具t上绘制矩形
- 如何在Visual Basic中使用矩形函数OpenGL绘制矩形
- 无法使用VAO和EBO(openGL)绘制多个对象
- 为什么我的点没有在 OpenGL 中绘制鼠标所在的位置?
- 绘制顺时针三角形,重新排序点
- 在顶点着色器中使用 OpenGl 的未声明标识符,我在顶点着色器中绘制三角形时遇到问题
- 如何避免LED在循环状态变化中闪烁?
- SFML 文本未绘制在窗口上
- 如何在快板的屏幕中显示子位图的绘制?
- 如何绘制自定义形状的元素?
- QPainter 将 QBrush 设置为 在 QT/C++ 中绘制文本
- 除非重新绘制大小,否则SDL_Texture在调整大小后呈现黑色
- 对话框窗体快速闪烁,但之后未正确绘制
- 绘制时防止闪烁
- 在主循环之外绘制背景时闪烁
- 绘制无闪烁