No announcement yet.

Resource Leak in Toolbar ??????

  • Filter
  • Time
  • Show
Clear All
new posts

  • Resource Leak in Toolbar ??????

    I have found a quirk with the Common control - Toolbar.

    I have a program where I create a Toolbar on a Window, then later destroy the Toolbar, and then create a Toolbar again (it is a Visual Designer for Designing Dialogs).

    If I use my own Bitmap for the Toolbar and after I destroy the Toolbar, I delete the Bitmap and then recreate the Toolbar again from scratch, I have no problem.

    My problem is when I create a Toolbar using the "builtin" Bitmaps in the Common Control DLL. There are 4 builtin Bitmaps, available in the Common control DLL, for use with the Toolbar. If you use the correct constant, instead of a Bitmap handle, when creating the Toolbar, it will automatically use one of the Builtin Bitmaps.

    When I use a Builtin Bitmap and then create, destroy, create , destroy the Toolbar over and over again, I get a very bad Resource leak. Even if you use one Toolbar in a program (where it remains until app terminates) and then run the program many times (run it, quit it, run it, quit it), the same Resource Leak occurs.

    Has anyone every experienced a problem with a Resource Leak, when using the Toolbar control with the Builtin Bitmaps ????

    Chris Boss
    Computer Workshop
    Developer of "EZGUI"

  • #2
    Did you try using MemCheck? It often suggests possible remedies for resource leaks. Also, did you search MSDN or MSKB for relevant information?

    PowerBASIC Support
    ( mailto:[email protected][email protected]</A> )
    mailto:[email protected]


    • #3
      I did some testing.

      I tried using the PBNote sample that comes with PB 5.0 and it displays the same behavior. So I gutted the PBNote program and left only the window and Toolbar to create the following "Test" program and it also displays the same behavior of a memory leak.

      This is how you will see the Resource leak:

      (1) Compile the program below:
      (2) Create an Icon on your Desktop to run the program
      (3) Run the "Resource Meter" (On the Start menu under "Accessories"/"System Tools"/"Resource Meter" )
      (4) Move the Resource Meter to Bottom Right corner of desktop out of the way
      (5)Now run the test by Running the Test program (below) over and over again. Simple run it, then click the X (close) icon and quit and run it again.

      The Resource leak will NOT show up until you have run the program 30 times.
      At this point it will progressively leak more and more resources. When you get to 70 times, you will start to get to a point where resources will drop low enough to cause problems for the system (below 80%)

      Now, you may say, "big deal" since nobody is going to run your program 70 times at one sitting, but the problem appears to grow exponentially with the more programs running simultaneously with Toolbars that use the BuiltIn Bitmaps. If you were to create a Test program with multiple windows, with a Toolbar on each window, then you will begin to see Resource problems as soon after running your program 10 times.

      The reason, I found this problem is that in my "Visual Designer" for EZGUI (for PB DLL) it is possible to create and destroy a window many times while developing Dialogs. Since I make the BuiltIn Bitmaps for Toolbars available, the problem showed up.

      My code has been tested on Win 95 only. I do not know if Win 98/NT/2000 has the same problem.

      ' ** Eliminate unnecessary macros
      %NOANIMATE    = 1
      %NODRAGLIST   = 1
      %NOHEADER     = 1
      %NOIMAGELIST  = 1
      %NOLISTVIEW   = 1
      %NOTRACKBAR   = 1
      %NOTREEVIEW   = 1
      %NOUPDOWN     = 1
      GLOBAL hInst      AS LONG
      GLOBAL hToolbar   AS LONG
      GLOBAL hWndMain   AS LONG
      FUNCTION WinMain (BYVAL hInstance     AS LONG, _
                        BYVAL hPrevInstance AS LONG, _
                        lpCmdLine           AS ASCIIZ PTR, _
                        BYVAL iCmdShow      AS LONG) AS LONG
        LOCAL Msg         AS tagMsg
        LOCAL wndclass    AS WndClassEx
        LOCAL szClassName AS ASCIIZ * 80
        LOCAL hWnd        AS LONG
        LOCAL hMenu       AS LONG
        LOCAL hAccel      AS LONG
        LOCAL hRichEd     AS LONG
        LOCAL vi          AS OSVERSIONINFO
        hInst                  = hInstance
      ' ** Register Main Window Class
        szClassName            = "TBUG32"
        wndclass.cbSize        = SIZEOF(WndClass)         = %CS_HREDRAW OR %CS_VREDRAW
        wndclass.lpfnWndProc   = CODEPTR( WndProc )
        wndclass.cbClsExtra    = 0
        wndclass.cbWndExtra    = 0
        wndclass.hInstance     = hInstance
        wndclass.hIcon         = %NULL
        wndclass.hCursor       = LoadCursor( %NULL, BYVAL %IDC_ARROW )
        wndclass.hbrBackground = %COLOR_APPWORKSPACE + 1
        wndclass.lpszMenuName  = %NULL
        wndclass.lpszClassName = VARPTR( szClassName )
        wndclass.hIconSm       = LoadIcon( hInstance, BYVAL %IDI_APPLICATION )
        RegisterClassEx wndclass
        ' Create a window using the registered class
        hWndMain = CreateWindow("TBUG32", _                  ' window class name
                                "Test Toolbar Bug", _                  ' window caption
                                %WS_OVERLAPPEDWINDOW, _      ' window style
                                %CW_USEDEFAULT, _            ' initial x position
                                %CW_USEDEFAULT, _            ' initial y position
                                %CW_USEDEFAULT, _            ' initial x size
                                %CW_USEDEFAULT, _            ' initial y size
                                %NULL, _                     ' parent window handle
                                %NULL, _                     ' window menu handle
                                hInstance, _                 ' program instance handle
                                BYVAL %NULL)                 ' creation parameters
        ShowWindow hWndMain, iCmdShow
        UpdateWindow hWndMain
      ' ** Message handler loop
        WHILE ISTRUE(GetMessage(Msg, BYVAL %NULL, 0, 0))
              TranslateMessage Msg
              DispatchMessage Msg
        FUNCTION = msg.wParam
      END FUNCTION  ' WinMain
                        BYVAL wParam AS LONG, BYVAL lParam AS LONG) AS LONG
        LOCAL dwProc      AS DWORD
        LOCAL tbab        AS TBADDBITMAP
        LOCAL hMdi        AS LONG
        LOCAL Style       AS LONG
        LOCAL f           AS STRING
        LOCAL Buffer      AS STRING
        LOCAL Path        AS STRING
        LOCAL RetVal      AS LONG
        LOCAL hFile       AS LONG
        STATIC tRect      AS RECT
        STATIC zText      AS ASCIIZ * 255
        STATIC ToolHeight AS LONG
        STATIC StatHeight AS LONG
        STATIC hEdit      AS LONG
        SELECT CASE wMsg
          CASE %WM_CREATE
            DIM tbb(0 to 6) AS STATIC TBBUTTON
            ' Initialize the common controls
            ' Fill the TBBUTTON array with button information
            tbb(0).iBitmap   = %STD_FILENEW
            tbb(0).idCommand = 1000
            tbb(0).fsState   = %TBSTATE_ENABLED
            tbb(0).fsStyle   = %TBSTYLE_BUTTON
            tbb(0).dwData    = 0
            tbb(0).iString   = 0
            tbb(1).iBitmap   = %STD_FILEOPEN
            tbb(1).idCommand = 1010
            tbb(1).fsState   = %TBSTATE_ENABLED
            tbb(1).fsStyle   = %TBSTYLE_BUTTON
            tbb(1).dwData    = 0
            tbb(1).iString   = 0
            tbb(2).iBitmap   = %STD_FILESAVE
            tbb(2).idCommand = 1020
            tbb(2).fsState   = %TBSTATE_ENABLED
            tbb(2).fsStyle   = %TBSTYLE_BUTTON
            tbb(2).dwData    = 0
            tbb(2).iString   = 0
            tbb(3).iBitmap   = 0
            tbb(3).idCommand = 0
            tbb(3).fsState   = %TBSTATE_ENABLED
            tbb(3).fsStyle   = %TBSTYLE_SEP
            tbb(3).dwData    = 0
            tbb(3).iString   = 0
            tbb(4).iBitmap   = %STD_CUT
            tbb(4).idCommand = 1030
            tbb(4).fsState   = %TBSTATE_ENABLED
            tbb(4).fsStyle   = %TBSTYLE_BUTTON
            tbb(4).dwData    = 0
            tbb(4).iString   = 0
            tbb(5).iBitmap   = %STD_COPY
            tbb(5).idCommand = 1040
            tbb(5).fsState   = %TBSTATE_ENABLED
            tbb(5).fsStyle   = %TBSTYLE_BUTTON
            tbb(5).dwData    = 0
            tbb(5).iString   = 0
            tbb(6).iBitmap   = %STD_PASTE
            tbb(6).idCommand = 1050
            tbb(6).fsState   = %TBSTATE_ENABLED
            tbb(6).fsStyle   = %TBSTYLE_BUTTON
            tbb(6).dwData    = 0
            tbb(6).iString   = 0
            ' Create the toolbar window
            hToolbar = CreateToolbarEx(hWnd, %WS_CHILD, _
                                       900, 12, %HINST_COMMCTRL, %IDB_STD_LARGE_COLOR, _
                                       tbb(0), 7, 0, 0, 100, 30, LEN(TBBUTTON))
            ' Display the toolbar
            SendMessage hToolbar, %TB_AUTOSIZE, 0, 0
            ShowWindow hToolbar, %SW_SHOW
            EXIT FUNCTION
          CASE %WM_SIZE
            IF wParam <> %SIZE_MINIMIZED THEN
              SendMessage hToolbar, wMsg, wParam, lParam
             END IF
            EXIT FUNCTION
          CASE %WM_DESTROY
            PostQuitMessage 0
            FUNCTION = 0
            EXIT FUNCTION
        END SELECT
        FUNCTION = DefWindowProc(hWnd, wMsg, wParam, lParam)
      Chris Boss
      Computer Workshop
      Developer of "EZGUI"