Results 1 to 29 of 29

Thread: Right Device context CleanUp

  1. #1

    Thread Starter
    Hyperactive Member
    Join Date
    Jan 2002
    Location
    Palermo, Italy
    Posts
    325

    Right Device context CleanUp

    While working on my project I got 0% GDI resource!!!
    I think my cleanup is not good...
    The following is the code I use to create and clean Device Context resources:

    Code:
        ' Let's suppose picture1 on my form...
        
        Dim hBitMap As Long
        DCSprite = CreateCompatibleDC(0)
        
        hBitMap = CreateCompatibleBitmap(picture1.hdc, lWidth, lHeight)
        DeleteObject SelectObject(DCSprite, hBitMap)
        DeleteObject hBitMap
        
    
        'when I finished using sprite
        DeleteDC DCSprite
    Maybe I'm missing something... Every time I run my project in the IDE I get a loss of 2% about of GDI resources...
    When I close the IDE GDI values returns to the "normal" value of 70% about...

    Thnx Xmas.

  2. #2
    Good Ol' Platypus Sastraxi's Avatar
    Join Date
    Jan 2000
    Location
    Ontario, Canada
    Posts
    5,134
    Here's the 'right' code to use:
    VB Code:
    1. ' Let's suppose picture1 on my form...
    2.    
    3.     Dim hBitMap As Long
    4.     Dim hOldBitMap As Long
    5.  
    6.     DCSprite = CreateCompatibleDC(0)
    7.    
    8.     hBitMap = CreateCompatibleBitmap(picture1.hdc, lWidth, lHeight)
    9.     hOldBitMap = SelectObject(DCSprite, hBitMap)    
    10.  
    11.     'when I finished using sprite
    12.     DeleteObject SelectObject(DCSprite, hOldBitMap)
    13.  
    14.     ReleaseDC Me.hDC, DCSprite
    15.     DeleteDC DCSprite
    16.  
    17.     DeleteObject hBitmap 'I'm not sure if this line is necessary
    Unfortunately, obscene amounts of cleanup for GDI functions are almost always necessary.
    All contents of the above post that aren't somebody elses are mine, not the property of some media corporation.
    (Just a heads-up)

  3. #3
    Addicted Member
    Join Date
    Oct 2002
    Location
    Somewhere out in space
    Posts
    151
    I've had a similar problem problem once, i had to draw several rectangle of different color to represent a palette and my code was creating /selecting lots of brush. Even if I was deleting my brushes, if I ran my code couple of time in a row, I would run out of ressources. I found that the problem was caused because I was trying to delete them will they were still selected in the dc and, well, since you can't do that. My brushes were never deleted. However, the MSDN says that this (the not delete while selected in dc) is only applicable for brushes and pens... but, from the look of your code, it would appear that it is the case for hBitmaps also. I suggest you try this
    VB Code:
    1. dim hBitmap as long
    2. dim hPrevBitmap as long
    3.  
    4. DCSprite = CreateCompatibleDC(0)
    5.  
    6. hBitMap = CreateCompatibleBitmap(picture1.hdc,lWidth,lHeight)
    7. 'Keep the handle of the original dc's bitmap object
    8. hPrevBitmap = selectobject(DCSprite,hBitmap)
    9.  
    10. 'Now before you delete your bitmap, put back the original one in the dc.  I think think this one will be deleted when you delete the DC.  (well, this method worked for my brush thing)
    11. hBimap = SelectObject(DCSprite,hPrevBitmap)
    12. DeleteObject hBitmap
    13. DeleteDC DCSprite

    Good luck

    - Valkan
    'You keep creatures in cages and release them to fight? That's sick!'

  4. #4
    Addicted Member
    Join Date
    Oct 2002
    Location
    Somewhere out in space
    Posts
    151
    hehehe... damn you Sastraxi... you've beated me to it

    just one thing, I don't think you should put ReleaseDC. This functin is there to free a dc (retreived by GetDC or GetWindowDC) for the use of other apps and cannot be used on dc created by a createdc... functions. Also... isn't the first parameter of release dc a hWnd and not a hDC?

    - Valkan
    'You keep creatures in cages and release them to fight? That's sick!'

  5. #5
    Good Ol' Platypus Sastraxi's Avatar
    Join Date
    Jan 2000
    Location
    Ontario, Canada
    Posts
    5,134
    Yeah, I made a mistake, it should've been .hWnd. I'm just not sure about the entire thing... I mean, which do I use? I've heard ReleaseDC is better, but not sure...
    All contents of the above post that aren't somebody elses are mine, not the property of some media corporation.
    (Just a heads-up)

  6. #6
    Good Ol' Platypus Sastraxi's Avatar
    Join Date
    Jan 2000
    Location
    Ontario, Canada
    Posts
    5,134
    Unfortunately, there's still a damned memory leak.. I tried it, and all of the memory goes down the drain... this is a 16x16 bitmap being created and destroyed 200 times.

    Here's how it goes:
    87044 kB free
    86804 kB free
    86508 kB free
    85844 kB free
    85248 kB free
    ...

    At this point, the program is EXTREMELY sluggish. So is the VB IDE...
    All contents of the above post that aren't somebody elses are mine, not the property of some media corporation.
    (Just a heads-up)

  7. #7
    Addicted Member
    Join Date
    Oct 2002
    Location
    Somewhere out in space
    Posts
    151
    here are some quote from MSDN:
    Display Device Contexts
    An application obtains a display DC by calling the BeginPaint, GetDC, or GetDCEx function and identifying the window in which the corresponding output will appear. Typically, an application obtains a display DC only when it must draw in the client area. When the application is finished drawing, it must release the DC by calling the EndPaint or ReleaseDC function.

    There are three types of DCs for video displays:

    Class
    Common
    Private
    Class Device Contexts
    Class device contexts are supported strictly for compatibility with 16-bit versions of Windows. When writing your application, avoid using the class device context; use a private device context instead.

    Common Device Contexts
    Common device contexts are display DCs maintained in a special cache by the system. Common device contexts are used in applications that perform infrequent drawing operations. Before the system returns the DC handle, it initializes the common device context with default objects, attributes, and modes. Any drawing operations performed by the application use these defaults unless one of the GDI functions is called to select a new object, change the attributes of an existing object, or select a new mode.

    Because only a limited number of common device contexts exist, an application should release them after it has finished drawing. When the application releases a common device context, any changes to the default data are lost.

    Private Device Contexts
    Private device contexts are display DCs that, unlike common device contexts, retain any changes to the default data—even after an application releases them. Private device contexts are used in applications that perform numerous drawing operations such as computer-aided design (CAD) applications, desktop-publishing applications, drawing and painting applications, and so on. Private device contexts are not part of the system cache and therefore need not be released after use. The system automatically removes a private device context after the last window of that class has been destroyed.

    An application creates a private device context by first specifying the CS_OWNDC window-class style when it initializes the style member of the WNDCLASS structure and calls the RegisterClass function. (For more information about window classes, see Window Classes.)

    After creating a window with the CS_OWNDC style, an application can call the GetDC, GetDCEx, or BeginPaint function once to obtain a handle identifying a private device context. The application can continue using this handle (and the associated DC) until it deletes the window created with this class. Any changes to graphic objects and their attributes, or graphic modes are retained by the system until the window is deleted.

    Memory Device Contexts
    To enable applications to place output in memory rather than sending it to an actual device, use a special device context for bitmap operations called a memory device context. A memory DC enables the system to treat a portion of memory as a virtual device. It is an array of bits in memory that an application can use temporarily to store the color data for bitmaps created on a normal drawing surface. Because the bitmap is compatible with the device, a memory DC is also sometimes referred to as a compatible device context.

    The memory DC stores bitmap images for a particular device. An application can create a memory DC by calling the CreateCompatibleDC function.

    The original bitmap in a memory DC is simply a placeholder. Its dimensions are one pixel by one pixel. Before an application can begin drawing, it must select a bitmap with the appropriate width and height into the DC by calling the SelectObject function. To create a bitmap of the appropriate dimensions, use the CreateBitmap, CreateBitmapIndirect, or CreateCompatibleBitmap function. After the bitmap is selected into the memory DC, the system replaces the single-bit array with an array large enough to store color information for the specified rectangle of pixels.

    When an application passes the handle returned by CreateCompatibleDC to one of the drawing functions, the requested output does not appear on a device's drawing surface. Instead, the system stores the color information for the resultant line, curve, text, or region in the array of bits. The application can copy the image stored in memory back onto a drawing surface by calling the BitBlt function, identifying the memory DC as the source device context and a window or screen DC as the target device context.

    When displaying a DIB or a DDB created from a DIB on a palette device, you can improve the speed at which the image is drawn by arranging the logical palette to match the layout of the system palette. To do this, call GetDeviceCaps with the NUMRESERVED value to get the number of reserved colors in the system. Then call GetSystemPaletteEntries and fill in the first and last NUMRESERVED/2 entries of the logical palette with the corresponding system colors. For example, if NUMRESERVED is 20, you would fill in the first and last 10 entries of the logical palette with the system colors. Then fill in the remaining 256-NUMRESERVED colors of the logical palette (in our example, the remaining 236 colors) with colors from the DIB and set the PC_NOCOLLAPSE flag on each of these colors.

    For more information about color and palettes, see Colors. For more information about bitmaps and bitmap operations, see Bitmaps.

    and a link to an interesting article on GDI objects : GDI Objects
    'You keep creatures in cages and release them to fight? That's sick!'

  8. #8
    Good Ol' Platypus Sastraxi's Avatar
    Join Date
    Jan 2000
    Location
    Ontario, Canada
    Posts
    5,134
    Can you post what that one says, Valkan? The MSDN simply won't let me look at it >_<.
    All contents of the above post that aren't somebody elses are mine, not the property of some media corporation.
    (Just a heads-up)

  9. #9
    Addicted Member
    Join Date
    Oct 2002
    Location
    Somewhere out in space
    Posts
    151
    too big to post text... i'll try something.
    Attached Files Attached Files
    'You keep creatures in cages and release them to fight? That's sick!'

  10. #10
    Good Ol' Platypus Sastraxi's Avatar
    Join Date
    Jan 2000
    Location
    Ontario, Canada
    Posts
    5,134
    Thanks But it didn't really explain what I'm looking for.. and what I'm looking for is the reason why that code up there creates a memory leak.
    All contents of the above post that aren't somebody elses are mine, not the property of some media corporation.
    (Just a heads-up)

  11. #11
    Addicted Member
    Join Date
    Oct 2002
    Location
    Somewhere out in space
    Posts
    151
    what is the code used for creating/deleting 200 time? i've tried running the code you posted earlier 1000 time and I didn't notice any performance drop. Am I missing something here? i did this:
    VB Code:
    1. Private Sub Command2_Click()
    2. Dim x As Integer
    3.  
    4. Dim DCSprite As Long
    5. Dim hBitMap As Long
    6. Dim hOldBitMap As Long
    7.        
    8.     For x = 1 To 1000
    9.    
    10.     DCSprite = CreateCompatibleDC(0)
    11.     hBitMap = CreateCompatibleBitmap(Picture1.hdc, 32, 32)
    12.     hOldBitMap = SelectObject(DCSprite, hBitMap)
    13.     'when I finished using sprite
    14.     DeleteObject SelectObject(DCSprite, hOldBitMap)
    15.     ReleaseDC Me.hwnd, DCSprite
    16.     DeleteDC DCSprite
    17.     DeleteObject hBitMap 'I'm not sure if this line is necessary
    18.    
    19.     Next x
    20.  
    21. end sub
    'You keep creatures in cages and release them to fight? That's sick!'

  12. #12
    Good Ol' Platypus Sastraxi's Avatar
    Join Date
    Jan 2000
    Location
    Ontario, Canada
    Posts
    5,134
    Holy crap, there ISN'T!

    Wow... I must go and apply this to my module, and then it will be COMPLETE! MWAHHAA... ahem.
    All contents of the above post that aren't somebody elses are mine, not the property of some media corporation.
    (Just a heads-up)

  13. #13
    Good Ol' Platypus Sastraxi's Avatar
    Join Date
    Jan 2000
    Location
    Ontario, Canada
    Posts
    5,134
    I found out what it was! Instead of using a different DC to create the compatible bitmap, I was using the one I was creating at the time... resulting in a bitmap that pointed back to the original one... jesus! Let me go see if it all works out.
    All contents of the above post that aren't somebody elses are mine, not the property of some media corporation.
    (Just a heads-up)

  14. #14
    Good Ol' Platypus Sastraxi's Avatar
    Join Date
    Jan 2000
    Location
    Ontario, Canada
    Posts
    5,134
    IT WORKED
    I've been working on this for so long, it finally works, thank god for that!!
    All contents of the above post that aren't somebody elses are mine, not the property of some media corporation.
    (Just a heads-up)

  15. #15
    Addicted Member
    Join Date
    Oct 2002
    Location
    Somewhere out in space
    Posts
    151
    Great!

    and btw, if you are still unsure about ReleaseDc, i've tried without it to the same result.

    oh, and can I see the completed module?

    - Valkan
    'You keep creatures in cages and release them to fight? That's sick!'

  16. #16
    Good Ol' Platypus Sastraxi's Avatar
    Join Date
    Jan 2000
    Location
    Ontario, Canada
    Posts
    5,134
    In a second. It SEEMS, even through my exhaustive testing of my new Make/DestroyDC functions, that there's still a memory leak (not necessarily in those, but in the SmoothIconBlt function). I'm just trying to solve it through the process of elimination..
    All contents of the above post that aren't somebody elses are mine, not the property of some media corporation.
    (Just a heads-up)

  17. #17
    Good Ol' Platypus Sastraxi's Avatar
    Join Date
    Jan 2000
    Location
    Ontario, Canada
    Posts
    5,134
    Here is the completed module (I've still got doubts about TextBlt, CropTextBlt, SmoothIconBlt, and SmoothMaskFast, but I'm pretty sure SmoothMaskFast is OK).
    Attached Files Attached Files
    All contents of the above post that aren't somebody elses are mine, not the property of some media corporation.
    (Just a heads-up)

  18. #18
    Addicted Member
    Join Date
    Oct 2002
    Location
    Somewhere out in space
    Posts
    151
    thanks, i'll go take a look at it
    'You keep creatures in cages and release them to fight? That's sick!'

  19. #19
    Frenzied Member cyborg's Avatar
    Join Date
    May 2000
    Location
    Sweden
    Posts
    1,755
    ok...i got the "subscript out of range" error in SmoothMaskFast on this line:
    ReDim Preserve xPic(0 To (.biWidth * .biHeight) - 1) As mRGB

    cant create autoredraw image on theese lines:
    AlphaBltFast Dest.hdc, 4, 0, 12, 25, Src(1).hdc, Src(2).hdc, 0, 0
    AlphaBltFast Dest.hdc, 504, 0, 12, 25, Src(1).hdc, Src(11).hdc, 0, 0

    it was really hard to see if those were the lines, because everything was f***ed up, so some lines were mixed together and such...
    Check out the FAQ and do a search before you post.
    My tutorials: Anti-Alias Pixels, Accurate Game Loop, Resource File

  20. #20
    Addicted Member
    Join Date
    Oct 2002
    Location
    Somewhere out in space
    Posts
    151
    I get an error in the same function... but mine is an overflow

    VB Code:
    1. With xPic(Morph2D(I, hHeight - j, hWidth))
    2.     .R = Base '<-- right there base = 6569
    3.     .G = Base
    4.     .B = Base
    5. End With

    but if i go in debug, close the program and start it again... it works

    weird...
    'You keep creatures in cages and release them to fight? That's sick!'

  21. #21
    Good Ol' Platypus Sastraxi's Avatar
    Join Date
    Jan 2000
    Location
    Ontario, Canada
    Posts
    5,134
    I've got the Subscript out of Range error before (that means it didn't have enough memory to create the DC and thus there is no height/width). The can't create AutoRedraw image is new to me, though.

    And Valkan, do you get this EVERY time, or just after calling it a whole darn lot? Like I said, memory leaks...
    All contents of the above post that aren't somebody elses are mine, not the property of some media corporation.
    (Just a heads-up)

  22. #22
    Addicted Member
    Join Date
    Oct 2002
    Location
    Somewhere out in space
    Posts
    151
    no... Well at least everytime i start your code for the first time (after opening your project). But then, i just got to press debug, close with the stop button, run it again and what!... no overflows...
    'You keep creatures in cages and release them to fight? That's sick!'

  23. #23
    Frenzied Member cyborg's Avatar
    Join Date
    May 2000
    Location
    Sweden
    Posts
    1,755
    the very same thing happend to me with another project....cant remember which though...i

    i only got the error message a few times..
    Check out the FAQ and do a search before you post.
    My tutorials: Anti-Alias Pixels, Accurate Game Loop, Resource File

  24. #24
    Good Ol' Platypus Sastraxi's Avatar
    Join Date
    Jan 2000
    Location
    Ontario, Canada
    Posts
    5,134
    That's really odd. Does the compiled EXE in the other thread work for you? Because if it does, really odd, because it's the same code...
    All contents of the above post that aren't somebody elses are mine, not the property of some media corporation.
    (Just a heads-up)

  25. #25
    Addicted Member
    Join Date
    Oct 2002
    Location
    Somewhere out in space
    Posts
    151
    I've compiled the code i have into an .exe... now it happens all the time.

    and now i've got to go. Good luck, i'll come back later to check on progress

    - Valkan
    'You keep creatures in cages and release them to fight? That's sick!'

  26. #26

    Thread Starter
    Hyperactive Member
    Join Date
    Jan 2002
    Location
    Palermo, Italy
    Posts
    325
    Yes... After posting I found out that before deleting DC I had to put the original bitmap into it, then delete... But you know that then you discover an important thing on VB programming there's always something else that you must do, for example go at lunch, go to the girlfriend, go to study, go to do I don't know how many other things, and you don't have time to post !!!!
    Tonight I open my post for posting it and what??!??
    I found 24 replies!!!!
    Great!
    You guys are great!

    But now it's time for question:

    Valkan:

    VB Code:
    1. DCSprite = CreateCompatibleDC(0)
    2. hBitMap = CreateCompatibleBitmap(Picture1.hdc, 32, 32)
    3. hOldBitMap = SelectObject(DCSprite, hBitMap)
    4. 'when I finished using sprite
    5. DeleteObject SelectObject(DCSprite, hOldBitMap)
    6. [B]ReleaseDC Me.hwnd, DCSprite[/B]
    7. DeleteDC DCSprite
    8. DeleteObject hBitMap 'I'm not sure if this line is necessary

    Why this instruction? Should not be called only when you get a DC with GetDC?
    My code was without this instruction and I found no memory leak... I looked at it very fast... Maybe I'm wrong...
    And it seems to be the same code Sastraxi posted... But he had memory leak...
    I'm too tired to have a look and test them... Please do you guys for me

    Thx for all,
    Xmas

  27. #27
    Addicted Member
    Join Date
    Oct 2002
    Location
    Somewhere out in space
    Posts
    151
    Just happy to try to help.
    I found 24 replies!!!!
    that's what can happen when you post an interesting problem (seems like the GDI can really be a pain ... ! )

    about the code with the release dc, I did just used it to test, it was taken from Sastraxi's first post and yes you are right, it should be used after a getdc call.

    Sastraxi: How is you module comming up?
    'You keep creatures in cages and release them to fight? That's sick!'

  28. #28
    Good Ol' Platypus Sastraxi's Avatar
    Join Date
    Jan 2000
    Location
    Ontario, Canada
    Posts
    5,134
    I'm so mad, the exact same code isn't working now, lol.
    All contents of the above post that aren't somebody elses are mine, not the property of some media corporation.
    (Just a heads-up)

  29. #29
    Good Ol' Platypus Sastraxi's Avatar
    Join Date
    Jan 2000
    Location
    Ontario, Canada
    Posts
    5,134
    It worked. Want to know what the problem was? Using GetDC(GetDesktopWindow) as opposed to 0 for the CreateCompatibleDC/Bitmap calls.
    All contents of the above post that aren't somebody elses are mine, not the property of some media corporation.
    (Just a heads-up)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width