Results 1 to 3 of 3

Thread: Problems with GDI using API

  1. #1

    Thread Starter
    Member
    Join Date
    Dec 2001
    Location
    ny
    Posts
    38

    Problems with GDI using API

    I wrote a menu system from scratch using a class module, and everything works fairly well. I used API functions to do 95% of the drawing. The only problem is that if you move your mouse back and forth over the menus and keep clicking down on different ones, after a while, it causes the program to sort of stop responding. The menu turns white, and any attempts to move or resize the window causes the whole desktop to be drawn on.
    I have been unable to figure out if I am doing anything wrong (i.e. not deleting an object). Here's the code that seems to be causing the problem:

    VB Code:
    1. Public Sub DrawMenu()
    2.  
    3.     Dim intMenus As Integer, j As Integer, intWidth As Integer, I As Integer
    4.     Dim textWidth As Integer, textHeight As Integer, curX As Integer, intHeight As Integer
    5.     Dim tBrush As Long, BMP As BitmapStruc, hFont As Long, theSize As Size
    6.     Dim offset As Integer, ly As Integer, lx As Integer
    7.     offset = 2
    8.    
    9.     Static bDrawing As Boolean
    10.    
    11.     If bDrawing Then Exit Sub
    12.    
    13.     bDrawing = True
    14.    
    15.     '* Create the fonts to be used
    16.     hFont = CreateFont(13, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Tahoma")
    17.     If hFont = 0 Then Exit Sub
    18.    
    19.     '* Set the Area
    20.     BMP.Area.Left = 0
    21.     BMP.Area.Top = 0
    22.     BMP.Area.Right = picMenu.ScaleWidth
    23.     BMP.Area.Bottom = picMenu.ScaleHeight
    24.    
    25.     '* Create bitmap
    26.     BMP.hDcMemory = CreateCompatibleDC(picMenu.hdc)
    27.     BMP.hDcBitmap = CreateCompatibleBitmap(picMenu.hdc, picMenu.ScaleWidth, picMenu.ScaleHeight)
    28.     BMP.hDcPointer = SelectObject(BMP.hDcMemory, BMP.hDcBitmap)
    29.            
    30.     If BMP.hDcMemory = 0 Or BMP.hDcBitmap = 0 Then
    31.         DeleteObject BMP.hDcBitmap
    32.         DeleteDC BMP.hDcMemory
    33.         DeleteObject hFont
    34.         Exit Sub
    35.     End If
    36.        
    37.     '* Copy the background of picMenu into the DC
    38.     tBrush = CreateSolidBrush(clrBackground)
    39.     SelectObject BMP.hDcMemory, tBrush
    40.     tBrush = CreatePen(0, 0, clrBackground)
    41.     SelectObject BMP.hDcMemory, tBrush
    42.     Rectangle BMP.hDcMemory, 0, 0, picMenu.ScaleWidth + 1, picMenu.ScaleHeight + 1
    43.     DeleteObject tBrush
    44.    
    45.     '* Draw the uh..thing on the left
    46.     tBrush = CreateSolidBrush(clrLines)
    47.     SelectObject BMP.hDcMemory, tBrush
    48.     tBrush = CreatePen(0, 1, clrLines)
    49.     SelectObject BMP.hDcMemory, tBrush
    50.     lx = 3
    51.     For ly = 5 To 17 Step 2
    52.         Rectangle BMP.hDcMemory, 4, ly, 4 + lx, ly + 1
    53.     Next ly
    54.     DeleteObject tBrush
    55.    
    56.     '* Set The Font
    57.     Call SelectObject(BMP.hDcMemory, hFont)
    58.    
    59.     '* background of text transparent
    60.     SetBkMode BMP.hDcMemory, 0
    61.    
    62.     intMenus = UBound(MenuArray) + 1
    63.     If intMenus <= 0 Then GoTo fini****
    64.    
    65.     I = 0
    66.        
    67.     textHeight = picMenu.textWidth("gW")
    68.     intHeight = textHeight + (YM_Buffer * 2)
    69.    
    70.     curX = XStart
    71.    
    72.     On Error Resume Next
    73.     For j = 1 To intMenus
    74.         'textWidth = picMenu.textWidth(MenuArray(j - 1))
    75.         Call GetTextExtentPoint32(BMP.hDcMemory, MenuArray(j - 1), Len(MenuArray(j - 1)), theSize)
    76.         textWidth = theSize.cx
    77.         'intHeight = theSize.cy + (YM_Buffer * 2)
    78.         intWidth = textWidth + (XM_Buffer * 2)
    79.    
    80.         MenuYPos(j - 1) = curX + 4
    81.         If mnuOverWhich = j Then
    82.             If bPopupShown Then
    83.                 tBrush = CreateSolidBrush(RGB(150, 150, 150)) 'clrButtonOver)
    84.                 SelectObject BMP.hDcMemory, tBrush
    85.                 tBrush = CreatePen(0, 1, RGB(150, 150, 150)) 'clrBorderOver)
    86.                 SelectObject BMP.hDcMemory, tBrush
    87.             Else
    88.                 tBrush = CreateSolidBrush(clrButtonOver)
    89.                 SelectObject BMP.hDcMemory, tBrush
    90.                 tBrush = CreatePen(0, 1, clrBorderOver)
    91.                 SelectObject BMP.hDcMemory, tBrush
    92.             End If
    93.         Else
    94.             tBrush = CreateSolidBrush(clrButtonOff)
    95.             SelectObject BMP.hDcMemory, tBrush
    96.             tBrush = CreatePen(0, 1, clrBorderOff)
    97.             SelectObject BMP.hDcMemory, tBrush
    98.         End If
    99.         Rectangle BMP.hDcMemory, curX, YStart, curX + intWidth, YStart + intHeight
    100.         DeleteObject tBrush
    101.        
    102.         TextOut BMP.hDcMemory, curX + XM_Buffer, (picMenu.ScaleHeight - textHeight) \ 2 + 1, MenuArray(j - 1), Len(MenuArray(j - 1))
    103.         curX = curX + intWidth + 1
    104.         I = I + 1
    105.     Next
    106.    
    107. fini****:
    108.     'picMenu.Picture = picMenuBuffer.Image
    109.     BitBlt picMenu.hdc, BMP.Area.Left, BMP.Area.Top, BMP.Area.Right, BMP.Area.Bottom, BMP.hDcMemory, 0, 0, SRCCOPY
    110.    
    111.     DeleteObject hFont
    112.     DeleteObject BMP.hDcBitmap
    113.     BMP.hDcMemory = 0
    114.     BMP.hDcBitmap = 0
    115.     DeleteDC BMP.hDcMemory
    116.    
    117.     bMenuDrew = True
    118.     bDrawing = False
    119.  
    120. End Sub

    Some quick notes: The picMenu picturebox's AutoRedraw property is set to false, and ScaleMode to 3.

  2. #2
    Frenzied Member
    Join Date
    Aug 2001
    Posts
    1,075
    Sounds like a GDI resource problem. Somewhere you are not deleting an object that you created and releasing those resources. Eventually your PC runs out of resources and is unable to redraw properly.

    I only glanced at your code, and I'm far from an expert of GDI, but I did notice soemthing I would do differntly.

    Here you create a pen and a brush using the same variable but you only delete the object once when it is the pen but not the brush.
    VB Code:
    1. tBrush = CreateSolidBrush(RGB(150, 150, 150)) 'clrButtonOver)
    2. SelectObject BMP.hDcMemory, tBrush
    3. tBrush = CreatePen(0, 1, RGB(150, 150, 150)) 'clrBorderOver)
    4. SelectObject BMP.hDcMemory, tBrush
    5. lx = 3
    6. For ly = 5 To 17 Step 2
    7.      Rectangle BMP.hDcMemory, 4, ly, 4 + lx, ly + 1
    8. Next ly
    9. DeleteObject tBrush

    I would write this as

    VB Code:
    1. tBrush = CreateSolidBrush(RGB(150, 150, 150)) 'clrButtonOver)
    2. SelectObject BMP.hDcMemory, tBrush
    3. tPen = CreatePen(0, 1, RGB(150, 150, 150)) 'clrBorderOver)
    4. SelectObject BMP.hDcMemory, tPen
    5. lx = 3
    6. For ly = 5 To 17 Step 2
    7.      Rectangle BMP.hDcMemory, 4, ly, 4 + lx, ly + 1
    8. Next ly
    9. DeleteObject tBrush
    10. DeleteObject tPen


    You can run the resource monitor that comes with Windows to track your resource usage and make sure you are returning all of the resources you program uses.

    Start/Programs/Accessories/System Tools/Resource Meter

    Greg
    Free VB Add-In - The Reference Librarian
    Click Here for screen shot and download link.

  3. #3

    Thread Starter
    Member
    Join Date
    Dec 2001
    Location
    ny
    Posts
    38
    Yep, already got that figured out. Someone pointed it out to me.

    Thing is, the problem still occurs, and I notice each time I move the mouse over a new menu item, resources that my program is using jump 4k.

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