Thread: InvalidateRect() + DrawText()

  1. #1
    Registered User
    Join Date
    Dec 2009
    Posts
    40

    InvalidateRect() + DrawText()

    Ok, so i've been trying to have a rectangle that fills with new text each time a button is pressed. I've got it all working except for it deleting the previous text before writing any new text, so I was wondering if anybody could help.

    I think it was Niara who suggested this method to me before, so thank you for that. The helps appreciated.

    Code:
             HDC dev = GetDC(hwnd);
                        GetClientRect(hwnd, &rec1);
    ///rec2 is a rectangle derived from the size of the parent window
                        rec2.left = rec1.left+50;
                        rec2.right = rec1.right - 50;
                        rec2.top = rec1.top + 25;
                        rec2.bottom = rec1.bottom - 90;
                        SetBkMode(dev, TRANSPARENT);
                        InvalidateRect(hwnd, &rec2, 0);
                        FillRect(dev, &rec2, NULL);
                        poem_func();
                        HDC dev2 = GetDC(hwnd);
                        DrawText(dev2, poem.c_str(), poem.length(), &rec2, DT_CENTER);
    EDIT:: oh i forgot to say, this compiles and runs ok, but it does not clear the rectangle/text. When i set the fourth parameter of InvalidateRect to 0, it clears it but then it will not display the text

    Hmm just another thought, do I need to create and destroy a handle to a device context each time I press the button?
    Last edited by ineedmunchies; 05-13-2010 at 11:51 AM.

  2. #2
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    you need to do this in response to a paint msg or double buffer, which requires a persistent DC.

    Some issues...(done without a complier so may not be 100% correct)
    Code:
    If you create a GDI object you must clear it (release if you used a 'Get'  or delete if you used a 'create')
    
    HDC dev = GetDC(hwnd);//here we 'get' a GDI object, allocating it memory (a copy) which must be 'release'd
    //create new GDI
    HPEN = Pen = CreatePen(...);//here we 'create' a new GDI object which must be 'delete'd
    
    //select objects into into DC for use, catching the default GDI object 'pushed' out
    HPEN *hOriginal = (HPEN*)SelectObject(dev , Pen);
    
    //use HDC
    
    //return to the same state original
    SelectObject(dev , hOriginal );//put any original objects back in, pushing out ones we created
    
    //clean up GDI objects
    ReleaseDC(dev);
    DeleteObject(Pen);
    Calling for a paint
    InvalidateRect() generates a WM_PAINT msg for the area in the rect.
    Follow InvalidateRect() with UpdateWindow()
    UpdateWindow() will make the paint msg non-queued (posted immediately to the windows callback, not sent to the OS msg queue, then app queue, then to the window, being ignored and concatinated along the way).

    in the buttons handler just call for a paint and set up the string to draw
    Code:
    //in teh buttons BN_CLICKED handler
    GetClientRect(hWnd, &ClientRect);
    InvalidateRect(hWnd, ClientRect);
    UpdateWindow(hWnd);
    So if painting speed is not required.

    Code:
    Case WM_PAINT:
    PAINTSTRUCT PS = {0};
    rect ClientRect;
    GetClientRect(hWnd, &ClientRect);
    
    ///fill in the paint details 
    BeginPaint(hWnd, &PS);can only be done in WM_PAINT and must have a EndPaint() call
    
    
    //paint client area white to clear last text
    FillRect(PS.hdc,  &ClientRect,  (HBRUSH)GetStockObject(WHITE_BRUSH));//easy as we dont have to clean up a stock object
    
    //set text background
    SetBkMode(PS.hdc, TRANSPARENT);
    
    //adjust rect and get string
    
    //paint text
    DrawText(PS.hdc, poem.c_str(), poem.length(), &rec2, DT_CENTER);
    
    //clean up
    EndPaint(hWnd, &PS);//this will clean up the PS.hdc
    To avoid flicker you will also probably want to return false from WM_ERASEBKGND msgs. (or is that true, been a few years and no IDE to check....)

    Search for code on double buffering, I have answered that one many times in the last 10 years
    Last edited by novacain; 05-13-2010 at 10:36 PM.
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

  3. #3
    Registered User
    Join Date
    Dec 2009
    Posts
    40
    Thank you novacain, I've tried as you have said but I still cannot get it to work properly.

    It does not clear the rectangle that the text is being displayed in.

    Code:
            case WM_COMMAND:
            {
                if (HIWORD(wParam) == BN_CLICKED)
                    {
                        poem_func();
                        RECT ClientRect;
                        GetClientRect(hwnd, &ClientRect);
                        InvalidateRect(hwnd, &ClientRect, 0);
                        UpdateWindow(hwnd);
                        
                    }
            }
            break;
    
            case WM_PAINT:
            {
                RECT ClientRect;
                GetClientRect(hwnd, &ClientRect);
                rec3.left = ClientRect.left+50;
                rec3.right = ClientRect.right - 50;
                rec3.top = ClientRect.top + 25;
                rec3.bottom = ClientRect.bottom - 90;
                PAINTSTRUCT PS = {0};
                BeginPaint(hwnd, &PS);
                FillRect(PS.hdc,  &rec3,  (HBRUSH)GetStockObject(WHITE_BRUSH));
                SetBkMode(PS.hdc, TRANSPARENT);
                DrawText(PS.hdc, poem.c_str(), poem.length(), &rec3, DT_CENTER);
                EndPaint(hwnd, &PS);
             }
    Where rec3 is the white rectangle for the text to be drawn in. This still leaves the previous text and prints the next string after the previous one. Am i missing something? Thank you again for your help its greatly appreciated

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    After the previous one, and not on top? I guess you can check that you're replacing the contents of poem and not concatenating to the end.

  5. #5
    Registered User
    Join Date
    Dec 2009
    Posts
    40
    Ah very good idea, I think I'm doing exactly that.

    Ha yip I was indeed, very silly little mistake. Thank you.

    Hmmm now to find if I can allign centrally in the middle of the rectangle!

    Hmmm vertical justification only works with single lines. Pity.
    Last edited by ineedmunchies; 05-14-2010 at 07:11 AM.

  6. #6
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    Currently all buttons on your window will redraw the poem as you have not 'switched' for the controls ID.

    Your WM_COMMAND handler should have three levels

    1 what type of msg [case WM_COMMAND] //is a command msg

    2 then the control's ID [case IDC_MY_BUTTON] //is from the re-draw text button

    3 then what happened to the control [case BN_CLICKED] //button was clicked


    Have a look at GetTextExtentPoint32().

    You can get the length and height of a particular/individual string.

    Divide length by display width to get lines (round up) then multi by height to find the min bounding rect to Drawtext() in.
    "Man alone suffers so excruciatingly in the world that he was compelled to invent laughter."
    Friedrich Nietzsche

    "I spent a lot of my money on booze, birds and fast cars......the rest I squandered."
    George Best

    "If you are going through hell....keep going."
    Winston Churchill

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problem with DrawText (DirectX9)
    By Diod in forum C++ Programming
    Replies: 2
    Last Post: 04-11-2006, 07:21 PM
  2. DrawText and different backgounr colors
    By stormbringer in forum Windows Programming
    Replies: 4
    Last Post: 05-09-2003, 03:34 AM
  3. DrawText()
    By DominicTrix in forum Windows Programming
    Replies: 1
    Last Post: 04-03-2003, 03:00 PM
  4. DrawText and backgrounds c++
    By AtomRiot in forum Windows Programming
    Replies: 1
    Last Post: 01-04-2003, 03:10 AM
  5. ValidateRect() and InvalidateRect()
    By Garfield in forum Windows Programming
    Replies: 6
    Last Post: 11-01-2001, 12:04 PM