DrawText buffering?

I have something really weird going on.
DrawText appears to be buffering.

I have a loop that's supposed to write "A" through "O" across the top of the screen. The first time through the loop nothing appears. Debugger shows the variables are correct. The second time through the loop, the "A" appears, but the text to be written is supposed to be "B", etc.

Everything appears correctly and in the right place, just one iteration late.

Problem is not unique to this particular loop. I also have a dialog window that's driven from a deque of messages. Iterating through the deque, the first time nothing appears. Second time, first message appears even though the text message attempting to be displayed is the second one.

What is going on?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void GAME::set_horiz_lbls()
{
    int top = TOP_MARGIN_TOP + 4;
    int bottom = TOP_MARGIN_BOTTOM;
    WTEXT   temp;
    string  lbl;

    for (int i = 0; i < NUM_COLS; i++)
    {
        int left = BOARD_LEFT + (i * CELL_SIZE) + 12;
        int right = left + CELL_SIZE;

        temp.set_rect(left, top, right, bottom);
        temp.set_color(CR_LIGHT_GREEN);
        lbl = I2L(i+1);     // Convert index to character
        temp.set_font("ARIAL", 12);
        temp.set_text(lbl);        
        temp.Paint();
    }
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void WTEXT::Paint()
{
    int     rslt;
    size_t  len;
    HFONT   hfont;   
 
    if (hdc == NULL)
        return;
    len = m_text.size();
    if (len == 0)
        return;
    
    SetTextColor(hdc, CR_BLACK);
    SetBkColor(hdc, get_color());
    hfont = g_fonts.find_font(m_face, m_size);  // Fonts are cached
    if (!hfont)
        throw EXC_FINDFONT;
    rslt = DrawTextA(hdc, m_text.c_str(), len, this, DT_NOCLIP);    
    if (!rslt)
        throw EXC_DRAWTEXT;    
    g_fonts.restore_font();
}

Note: I had an earlier thread where the problem was due to writing to an intermediate buffer. That double buffering is gone from the program.

Solved: Apparently GDI accumulates operations in a "batch".
Adding a call to GdiFlush() to flush the "batch" solved the problem.

MSDN wrote:
Batching enhances drawing performance by minimizing the amount of time needed to call GDI drawing functions that return Boolean values. The system accumulates the parameters for calls to these functions in the current batch and then calls the functions when the batch is flushed by any of the following means:

- Calling the GdiFlush function.
- Reaching or exceeding the batch limit set by the GdiSetBatchLimit function.
- Filling the batching buffers.
- Calling any GDI function that does not return a Boolean value.
Last edited on
Solved: Apparently GDI accumulates operations in a "batch".
I actually doubt that this is the problem. I used the GDI alot and never needed to call GdiFlush().

Did you call EndPaint(...) correctly and other cleanup functions? What is g_fonts?
Hi coder777, thanks for your thoughts.

I found this while I was debugging between BeginPaint and EndPaint calls.
I'd execute the DrawText() call and the text would not appear until the next time through the loop. I suspect in the broader view of things, the GDI buffer would get flushed implicitly by one
of the conditions I listed in my last message. Explicitly calling GdiFlush() solved the issue of text being displayed one iteration behind.

I was trying to debug a log window that involved overloading streambuf and ostream and queuing the messages in a deque. I really could not tell if it was working correctly since the window was displaying messages one behind. Rather than post that mess, I posted set_horiz_lbls() which displayed the same symptoms.

g_fonts is a class derived from std::set functioning as a font cache. Returns an HFONT.
Topic archived. No new replies allowed.