c++winapigdi

FillRect disappears after some time


Outline
I'm trying to build a waveform visualizer using FillRect but after some time the rectangles disappear. I'm not sure if its related but I'm also met with a few visual glitches after they have disappeared such as color bleeding and a number 6 appearing on one of my combo boxes.

Code
To do this I have 3 functions each invoked in the WM_CREATE call using SetTimerSetTimer(window, ID, 1, (TIMERPROC) FUNCTION);); LOOP, PROCESS, PAINT

PAINT runs this code;

RECT* r = new RECT {x, 0, 500, 500};
InvalidateRect(hwnd, r, TRUE);

PROCESS runs this code;

// data_buffer is queue<queue<int>> data_buffer
if (data_buffer.size() < 100){
    data_buffer.push(data); // data is queue<int> data
}

and LOOP runs this code;

// if we have atleast 1 step entry
if (data_buffer.size() > 0){ 
    // count the steps  
    int steps = data_buffer.front().size();

    // if we have steps
    if (steps > 0){
        
        // add and delete item for each step
        for (int i = 0; i < steps; i++){
            // get first step data
            int v = data_buffer.front().front();

            if (v == 0) {
                v = 1;
            } else {
                v = (int)((double)v / (2000000000.0) * 50);
            }

            // add a data point using the first step data
            scroll.push_back(v); 

            // remove the leftmost data point
            scroll.erase(scroll.begin());
            
            // remove first step data
            data_buffer.front().pop();
        }
    }

    // delete first step entry
    data_buffer.pop();
}

Then using WM_PAINT I draw to the display;

case WM_PAINT: {
    // paint
    PAINTSTRUCT ps;
    HDC hdc = BeginPaint(window, &ps);
    //FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW+1));
    
    // brush color
    HBRUSH brush;
    
    // draw rects
    for (int i = 0; i < scroll.size(); i++){
        if (i == 0){ 
            brush = CreateSolidBrush(RGB(0, 255, 0)); 
        } else {
            brush = CreateSolidBrush(RGB(255, 0, 0));
        }
    
        RECT* r = new RECT {
            x + (i * scroll_mult), 
            75 - scroll[i], 
            y + (i * scroll_mult), 
            75 + scroll[i]
        };
    
        FillRect(hdc, 
            r,
            brush
        );
    
        delete r;
    }
    
    // finish
    EndPaint(window, &ps); // end window paint
    DeleteObject(brush); // delete brush object
    
    return 0;
}

Theory

I think my code may be drawing over itself multiple times and reaching the object limit for GDI or I'm drawing/invalidating too frequently and something is "tripping" the code to force the rectangles to be deleted.

Tried and tested


Solution

  • The issue is the leaked GDI objects. Brushes are created like brush = CreateSolidBrush(...) in the loop, but only the last one is deleted after the loop.

    Firstly, you should check CreateSolidBrush() results. When the limit of GDI objects is reached, the function fails.

    Secondly, you should delete brushes in the loop.