2015-02-27 7 views
0

Так у меня есть этот код, чтобы нарисовать прямоугольник на моем экране:Предотвращение Мерцание При рисовании

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); 
} 

Однако, когда вызывается несколько раз внутри цикла она мерцает на экране. Мне было интересно, есть ли способ предотвратить это мерцание?

Любая помощь будет оценена по достоинству.

Благодаря

+0

Двойная буферизация ... –

+0

Как бы я это сделал? – Steven

+0

Вам не нужно дублировать буфер. Вы не указали соответствующий код. Показать больше. Покажите полную программу, которая мерцает. –

ответ

0
/*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); 

    } 
    } 
1

Это не должно быть ответ, но я не могу отправить код в комментариях:

У вас есть много утечек 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 из вашего определения класса окна;
  • return 1L в вашей процедуре окна (или TRUE в процедуре вашего диалогового окна) в ответ на WM_ERASEBKGND;
  • нарисовать все на растровом изображении, а затем BitBlt в ваш m_hDC -> это называется двойной буферизацией (вы можете найти много примеров в Интернете);
+0

Двойная буферизация редко необходима. Если вы все сделаете правильно, это не понадобится. –

+0

@DavidHeffernan: В этом случае, может быть, и не совсем. Предположим, он имеет синий фон и называет его «DrawBox». При изменении размера окна «WM_ERASEBKGND» заполняет фон синим цветом и только затем рисует красный прямоугольник. Это будет восприниматься пользователем в том же порядке, как я описал его. Он мог бы удвоить буфер, чтобы уклониться от этого, или он каким-то образом может закрепить красный прямоугольник. Чем ему не нужна двойная буферизация, но я не верю, что он может это сделать -> пожалуйста, поправьте меня, если я ошибаюсь. С наилучшими пожеланиями. – AlwaysLearningNewStuff

Смежные вопросы