Thread: Drawing Bitmaps

  1. #1
    Registered User filler_bunny's Avatar
    Join Date
    Feb 2003
    Posts
    87

    Drawing Bitmaps

    Hi - quick couple of questions regarding drawing bitmaps...

    1. MSDN says.. "After painting with a common DC, the ReleaseDC function must be called to release the DC. " - Does this mean it must absolutely be released within the one WM_PAINT message? In otherwords, it is not OK to keep the DC around until the end of the program?

    2. In the following code I want to draw two bitmaps, I can see a number of problems with the code below, i.e. I am not reinstating the old bitmap. How do I go about rewriting this properly - so I can draw both images in the window without causing any resource leaks?
    Code:
    PAINTSTRUCT ps;
    			
    dc = BeginPaint(hwnd, &ps);
    dcMem = CreateCompatibleDC(NULL);
    SelectObject(dcMem, hBucket);
    BitBlt(dc, 0, 200, 140, 160, dcMem, 0, 0, SRCCOPY);
    SelectObject(dcMem, hBubble);
    BitBlt(dc, 0, 0, 400, 160, dcMem, 0, 0, SRCCOPY);
    DeleteDC(dcMem);
    EndPaint(hwnd, &ps);
    Cheers.
    Visual C++ .net
    Windows XP profesional

  2. #2
    Registered User Dante Shamest's Avatar
    Join Date
    Apr 2003
    Posts
    970
    I recommend using a class like this to manage your bitmaps. Its hard to keep track of all those HDCs and HBITMAPs .

  3. #3
    Registered User filler_bunny's Avatar
    Join Date
    Feb 2003
    Posts
    87
    Hey, thanks - that is really quite useful
    Visual C++ .net
    Windows XP profesional

  4. #4
    train spotter
    Join Date
    Aug 2001
    Location
    near a computer
    Posts
    3,868
    To fix the leaks

    hOriginalBMP = SelectObject(dcMem, hBucket);
    //use, then return to original state
    SelectObject(dcMem,hOriginalBMP);
    //now delete DC

    // on close delete the bitmaps

    The way you are doing the paint will be slow if the drawing get more complex. Look at double buffering, plenty of examples here.

    or simply

    Create the DC in the WM_INIT / CREATE or when you load the bitmaps. Use a global or static local in the callback.

    Delete the DC in the WM_CLOSE or when you free the bitmaps.
    "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

  5. #5
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Does this mean it must absolutely be released within the one WM_PAINT message? In otherwords, it is not OK to keep the DC around until the end of the program?
    In your case, yes. But you can get a HDC from a call to GetDC(hWnd) at the start of the program, then use that for drawing until you call ReleaseDC(hWnd) at the end of the program. Then, you can also create a back-buffer and bitmap-holding buffer after you get the main HDC, and keep those too until you decide to quit the program.

    An added advantage of this method is that you aren't limited to drawing within the WM_PAINT message; you can redraw everything that needs redrawing at any time you choose. There are probably drawbacks to this method too, but I've successfully used it in 3 or 4 games already, and plan to use it in more (although I have a DirectDraw7 wrapper written too, with pretty much the same features).
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  6. #6
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    About Window Classes

    If no device-context style is explicitly given, the system assumes each window uses a device context retrieved from a pool of contexts maintained by the system. In such cases, each window must retrieve and initialize the device context before painting and free it after painting.

    To avoid retrieving a device context each time it needs to paint inside a window, an application can specify the CS_OWNDC style for the window class. This class style directs the system to create a private device context — that is, to allocate a unique device context for each window in the class. The application need only retrieve the context once and then use it for all subsequent painting.

    Windows 95/98/Me: Although the CS_OWNDC style is convenient, use it carefully, because each device context uses a significant portion of 64K GDI heap.
    GetDC() documentation

    Windows 95/98/Me: There are only 5 common DCs available per thread, thus failure to release a DC can prevent other applications from accessing one.
    If you want to keep a DC handy, use the either CS_CLASSDC or CS_OWNDC when you register the window class.

  7. #7
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    >>only 5 common DCs available per thread
    >>can prevent other applications from accessing one.
    Don't other applications run in separate threads?

    Besides which, I don't think my method uses more than 1 common DC (by 'common', I'm assuming it means one that you don't create yourself).
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Drawing HBITMAP into CWnd, Acquired from "screenshot"
    By DeusAduro in forum Windows Programming
    Replies: 6
    Last Post: 07-02-2009, 03:41 PM
  2. Drawing bitmaps efficiently
    By scwizzo in forum Windows Programming
    Replies: 28
    Last Post: 06-30-2009, 08:25 PM
  3. drawing on bitmaps
    By eth0 in forum Windows Programming
    Replies: 2
    Last Post: 03-24-2006, 05:56 PM
  4. DX9 Not Displaying Bitmaps
    By Sentral in forum Game Programming
    Replies: 9
    Last Post: 01-31-2006, 05:35 AM
  5. Interesting problem with bmp drawing
    By Victor in forum C++ Programming
    Replies: 3
    Last Post: 04-12-2005, 10:39 AM