Results 1 to 6 of 6

Thread: Out of Memory

  1. #1

    Thread Starter
    Hyperactive Member
    Join Date
    Jun 1999
    Location
    ma,usa
    Posts
    485

    Out of Memory

    'I'm using the following example and put it in my mousemove event. I am continually getting an "Out of Memory" error. Any Idea's?

    'VB code:

    Option Explicit

    Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
    Private Declare Function CreateCompatibleBitmap Lib "gdi32" (ByVal hdc As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long
    Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long
    Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
    Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long
    Private Const SRCCOPY = &HCC0020 ' (DWORD) dest = source

    Dim memdc As Long
    Dim membmp As Long
    Dim i As Single, j As Single





    Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
    'create a memory DC for this form
    memdc = CreateCompatibleDC(Me.hdc)
    'create a bitmap for this form
    membmp = CreateCompatibleBitmap(Me.hdc, Picture1.ScaleWidth, Picture1.ScaleHeight)
    'select that bitmap into the memory dc
    SelectObject memdc, membmp
    'paste the picture from the picture onto the memory DC.
    'Because we selected the bitmap in the memory DC, it'll
    'be pasted on the bitmap
    BitBlt memdc, 0, 0, Picture1.ScaleWidth, Picture1.ScaleHeight, Picture1.hdc, 0, 0, SRCCOPY
    'now paste the contents of the memory DC on this form
    Refresh
    BitBlt Me.hdc, 0, 0, Picture1.ScaleWidth, Picture1.ScaleHeight, memdc, i, j, SRCCOPY
    i = i + 1
    If i > 320 Then
    j = j + 1
    i = 0
    Picture1.Refresh
    End If
    DeleteObject memdc
    DeleteObject membmp

    End Sub

  2. #2
    PowerPoster Fox's Avatar
    Join Date
    Jan 2000
    Location
    *afk*
    Posts
    2,088
    you must not create the memory dc every time mousemove is called

    i dont know if this is the problem, but you shouldnt do so at all

  3. #3

    Thread Starter
    Hyperactive Member
    Join Date
    Jun 1999
    Location
    ma,usa
    Posts
    485
    Thanks!

    This seems to work:

    'VB code:

    Option Explicit

    Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
    Private Declare Function CreateCompatibleBitmap Lib "gdi32" (ByVal hdc As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long
    Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long
    Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
    Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long
    Private Const SRCCOPY = &HCC0020 ' (DWORD) dest = source

    Dim memdc As Long
    Dim membmp As Long
    Dim i As Single, j As Single





    Private Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
    If Button = vbLeftButton Then
    'create a memory DC for this form
    memdc = CreateCompatibleDC(Me.hdc)
    'create a bitmap for this form
    membmp = CreateCompatibleBitmap(Me.hdc, Picture1.ScaleWidth, Picture1.ScaleHeight)
    'select that bitmap into the memory dc
    SelectObject memdc, membmp
    End If
    End Sub

    Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
    If Button = vbLeftButton Then
    'paste the picture from the picture onto the memory DC.
    'Because we selected the bitmap in the memory DC, it'll
    'be pasted on the bitmap
    BitBlt memdc, 0, 0, Picture1.ScaleWidth, Picture1.ScaleHeight, Picture1.hdc, 0, 0, SRCCOPY
    'now paste the contents of the memory DC on this form
    Refresh
    BitBlt Me.hdc, 0, 0, Picture1.ScaleWidth, Picture1.ScaleHeight, memdc, i, j, SRCCOPY
    i = i + 1
    If i > 320 Then
    j = j + 1
    i = 0
    Picture1.Refresh
    End If
    End If
    End Sub

    Private Sub Form_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
    DeleteObject memdc
    DeleteObject membmp
    End Sub

  4. #4
    Fanatic Member PsychoMark's Avatar
    Join Date
    Feb 2001
    Location
    Netherlands
    Posts
    540
    The SelectObject and DeleteObject problem seems to come back every once in a while and everybody has a different solution. In my opinion, your method is wrong. After studying the GDI API's for a while now, I came to the conclusion you have to select the old object back into the DC before freeing it.

    It doesn't matter that much with only one DC, but if you miss any call or place it at the wrong position, you've got yourself a memory leak.

    Correct me if I'm wrong here, but this is how I think it should be:


    VB Code:
    1. Dim hMemDC As Long
    2. Dim hOldBMP As Long
    3.  
    4. ' Create memory DC
    5. hMemDC = CreateCompatibleDC(Me.hdc)
    6.  
    7. ' Select bitmap into it, storing the previous value
    8. ' (SelectObject returns the previous bitmap which
    9. ' was selected into the DC)
    10. hOldBMP = SelectObject(hMemDC, CreateCompatibleBitmap(Me.hdc, Width, Height))
    11.  
    12. '
    13. ' Now you can draw...
    14. '
    15.  
    16. ' First, select the old bitmap back into the DC and delete our bitmap
    17. DeleteObject(SelectObject(hMemDC, hOldBMP))
    18.  
    19. ' Now delete the DC
    20. DeleteDC(hMemDC)


    I've also seen ReleaseDC being used, therefore I quote from the SDK help files:

    Remarks

    The application must call the ReleaseDC function for each call to the GetWindowDC function and for each call to the GetDC function that retrieves a common device context.

    An application cannot use the ReleaseDC function to release a device context that was created by calling the CreateDC function; instead, it must use the DeleteDC function.
    Teaudirenopossum.Musasapientumfixaestinaure.
    (I can't hear you. There's a banana in my ear)

  5. #5

    Thread Starter
    Hyperactive Member
    Join Date
    Jun 1999
    Location
    ma,usa
    Posts
    485
    Thanks! This should save some poor unexpecting downloaders a crash or two - and I learned something too!

  6. #6
    jim mcnamara
    Guest
    You really should use a DeleteDC call at ther end. And restoring the objects back to the DC is good programming practice, even if as in this case it doesn't make too much difference.

    All of the api I've used & seen has this general scheme:

    GetDC -> restore objects as they were -> ReleaseDC

    or

    CreateDC (or CreateCompatibleDC) -> DeleteDC.

    Doing otherwise causes problems. If it's good enough for MS, it's good enough for me.

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