Announcement

Collapse
No announcement yet.

IMAGE/IMAGEX - how do I release them?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    IMAGE/IMAGEX - how do I release them?

    I have a bitmap in a resource file and want to show it, streched,
    in a secondary dialog. Okay, so I take the easy route and use
    DDT's IMAGEX statement, but no matter how I try, I get a memory
    leak each time I create/end the dialog window. The same goes for
    the IMAGE statement.

    I have found a solution that works fine, by using a LABEL and
    CONTROL SET IMAGEX instead, but it still would be fun to know
    how to release a bitmap loaded into DDT's IMAGEX "control".
    Is it even possible? I use numbered bitmaps in the resource file
    and in this case, the bitmap number is 3. The following leaks
    when I create/end the secondary dialog repeatedly:

    CONTROL ADD IMAGEX, hDlg, %IDABOUT_CAPT, "#3", 0, 0, 270, 50


    ..but this one works fine = does not leave any leaks:

    CONTROL ADD LABEL, hDlg, %IDABOUT_CAPT, "", 0, 0, 270, 50, %SS_BITMAP
    CONTROL SET IMAGEX hDlg, %IDABOUT_CAPT, "#3"


    Both with the following to remove the loaded bitmap in %WM_DESTROY:

    LOCAL hBmp AS LONG
    CONTROL SEND CBHNDL, %IDABOUT_CAPT, %STM_GETIMAGE, %IMAGE_BITMAP, 0 TO hBmp
    IF hBmp THEN DeleteObject hBmp

    #2
    Borje --
    I think, that you should use a method, described by Lance, something like this (there are two bitmaps in resource file - #1, #2)
    Code:
       #Compile Exe
       #Register None
       #Dim All
       #Include "Win32Api.Inc"
       $Resource "gt1.pbr"
    
       CallBack Function DlgProc
          Static nCall As Long
          Local hBmpOld As Long
          Select Case CbMsg
             Case %WM_INITDIALOG
                Control Add ImageX, CbHndl, 101, "#1", 10, 10, 580, 280: nCall = 1
                Control Add Button, CbHndl, 102, "&Change", 100, 360, 200, 20
             Case %WM_COMMAND
                If CbCtl = 102 Then
                   hBmpOld = SendMessage(GetDlgItem(CbHndl, 101), %STM_GETIMAGE, 0, 0)
                   Incr nCall: If nCall > 2 Then nCall = 1
                   Control Set ImageX CbHndl, 101, "#" + Format$(nCall)
                   SetWindowText CbHndl, Format$(DeleteObject(hBmpOld))               
                End If
          End Select
       End Function
    
       Function PbMain As Long
          Local hDlg As Long
          Dialog New %HWND_DESKTOP, "ImageX", , , 600, 400, %WS_SYSMENU Or %WS_CAPTION To hDlg
          Dialog Show Modal hDlg, Call DlgProc
       End Function
    BTW, strange, but I couldn't receive %EN_REQUESTRESIZE inside %WM_NOTIFY (I tried DDT, but even subclassing didn't help).
    Perhaps, I do something wrong. Can you post short sample ?


    ------------------

    Comment


      #3
      Thanks Semen, I'll have a look at it later on. I have posted a
      RichEdit auto-resize sample in the source code section. It's not
      at all complete, but at least it shows how to force and use the
      %EN_REQUESTRESIZE notification. I hope it can help.


      ------------------

      Comment


        #4
        <font face="courier new, courier" size="3"><pre>borje--

        for something relevant, see:

        http://www.powerbasic.com/support/pb...ead.php?t=2223

        i confess that i haven't yet performed the experiment that lance
        suggests in this posting.[/CODE]


        ------------------
        -- greg
        [email protected]

        Comment


          #5
          Thank you, yes, I searched through all messages but found no good
          answer. Played around a bit with Semen's code and see that switching
          between two bitmaps works fine, but when I create/end a sub-dialog,
          with an IMAGEX control, something simply isn't released properly.

          Seems like IMAGE/IMAGEX creates a new DC (or something), each time
          they are created within a program - but how do we delete it without
          exiting the program?

          Oh well, it's not really a problem for me anymore, because using
          a common LABEL with %SS_BITMAP and CONTROL SET IMAGEX works fine
          the way I describe it in my first posting above. Just thought it
          would be fun to know why this happens and what to do about it..


          ------------------

          Comment


            #6
            Here is what you need to do to change an image in a DDT IMAGE/IMAGEX/IMGBUTTON/IMGBUTTONX control:

            Code:
            DIM hBmp AS LONG
            ...
            CONTROL SEND CBHNDL, %ImageCtl, %STM_GETIMAGE, %IMAGE_BITMAP, 0 TO hBmp  ' get handle to current image
            CONTROL SET IMAGE CBHNDL, %ImageCtl, "#31"  ' Set new image from resource file
            DeleteObject hBmp ' release the original bitmap image
            Now, when you say you get a leak, we have to be sure what you mean here. As the DDT image is coming from a resource file, you'll be seeing the effect of Windows loading a copy of the resource into memory.

            If you can describe the *exact* amount memory loss, the size of your image file, whether the "loss" builds with each DIALOG SHOW, or what...

            ------------------
            Lance
            PowerBASIC Support
            mailto:[email protected][email protected]</A>
            Lance
            mailto:[email protected]

            Comment


              #7
              Thank you Lance. Maybe I'm doing something wrong, I don't know,
              but here's a sample to show you what I mean. In case you don't
              want to recompile it all, you can also download the code and a
              compiled exe from: http://www.tolken99.com/program/Leaktest.zip

              Code:
              '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
              ' Leak test sample for IMAGEX, by Borje Hagsten - just to prove my point.
              ' The resource file, Leaktest.rc contains one bitmap and looks like:
              ' 1 BITMAP SMTP.BMP
              '
              ' I have used the SMTP.BMP that's included in the SMTP sample here.
              ' When I flash the second dialog with the IMAGEX control repeatedly,
              ' showing the bitmap, the resources drops slowly after 5-10 times and
              ' then keeps on falling each time the new dialog is loaded/ended.
              '
              ' I have also included code that works fine in "NewDialog" - by using
              ' a common LABEL, SS_BITMAP and CONTROL SET IMAGEX instead. Uncomment
              ' and test it, if you like..  :-)
              '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
               
              #COMPILE EXE
              $RESOURCE "LEAKTEST.PBR"
              #INCLUDE "WIN32API.INC"
               
              %ID_LABEL  = 10
              %ID_IMAGEX = 20
               
              DECLARE CALLBACK FUNCTION DlgCallback()
              DECLARE CALLBACK FUNCTION NewDlgCallback()
              DECLARE FUNCTION GetSysInfo () AS STRING
              DECLARE SUB NewDialog(BYVAL hWnd AS LONG)
               
              'Constants and declare for the system resurce meter
              %RCRS32_SYSTEMRESOURCES = 0
              %RCRS32_GDIRESOURCES    = 1
              %RCRS32_USERRESOURCES   = 2
               
              DECLARE FUNCTION GetFreeResources LIB "rsrc32.dll" ALIAS "_MyGetFreeSystemResources32@4" (BYVAL WhichResource AS LONG) AS LONG
               
              '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
              ' Main dialog
              '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
              FUNCTION PBMAIN
                LOCAL hDlg AS LONG
               
                DIALOG NEW 0, "Leak test",,, 122, 90, %WS_SYSMENU TO hDlg
                CONTROL ADD BUTTON, hDlg, %IDOK, "Click me repeatedly..", 4,   4,  110, 14
                CONTROL ADD BUTTON, hDlg, %IDCANCEL, "&Close",            4,  20,  110, 14
                CONTROL ADD LABEL,  hDlg, %ID_LABEL, "",                  4,  40,  110, 36, %SS_CENTER
               
                CONTROL SET TEXT hDlg, %ID_LABEL, GetSysInfo
               
                DIALOG SHOW MODAL hDlg CALL DlgCallback
               
              END FUNCTION
               
              '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
              ' Callback for main dialog
              '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
              CALLBACK FUNCTION DlgCallback()
               
                SELECT CASE CBMSG
                   CASE %WM_COMMAND
                      SELECT CASE CBCTL
               
                         CASE %IDOK  'Show a second dialog and then show available resources
                            NewDialog CBHNDL
                            CONTROL SET TEXT CBHNDL, %ID_LABEL, GetSysInfo
               
                         CASE %IDCANCEL : DIALOG END CBHNDL, 0
               
                      END SELECT
                END SELECT
               
              END FUNCTION
               
              '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
              ' NewDialog - load and show a sub-dialog with an IMAGEX control
              '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
              SUB NewDialog(BYVAL hWnd AS LONG)
                LOCAL hDlg AS LONG
               
                DIALOG NEW hWnd, "About me..",,, 100, 70, %WS_SYSMENU TO hDlg
                CONTROL ADD BUTTON, hDlg, %IDCANCEL, "&Close", 4,  4, 88, 14
               
                CONTROL ADD IMAGEX,  hDlg, %ID_IMAGEX, "#1",    4, 22, 87, 28, %WS_BORDER
               
                'Rem out the line above and use the following two instead -> no leaks!
                'CONTROL ADD LABEL, hDlg, %ID_IMAGEX, "", 4, 22, 87, 28, %SS_BITMAP
                'CONTROL SET IMAGEX hDlg, %ID_IMAGEX, "#1"
               
                DIALOG SHOW MODAL hDlg CALL NewDlgCallback
               
              END SUB
               
              '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
              ' Callback for new dialog
              '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
              CALLBACK FUNCTION NewDlgCallback()
               
                SELECT CASE CBMSG
                   CASE %WM_COMMAND
                      IF CBCTL = %IDCANCEL THEN DIALOG END CBHNDL, 0
               
                   CASE %WM_DESTROY
                     LOCAL hBmp AS LONG, lRes AS LONG  'Get the loaded bitmaps handle
                     CONTROL SEND CBHNDL, %ID_IMAGEX, %STM_GETIMAGE, %IMAGE_BITMAP, 0 TO hBmp
                     IF hBmp THEN
                        lRes = DeleteObject(hBmp)      'Delete it and beep, just to show it worked
                        IF lRes THEN BEEP
                     END IF
               
                END SELECT
               
              END FUNCTION
               
              '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
              ' GetSysInfo - must have Windows System resource meter installed to work -> rsrc32.dll
              ' (I guess most have it installed - or is there a better way to get these numbers?)
              '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
              FUNCTION GetSysInfo () AS STRING
               
                FUNCTION = "System Resources: " + FORMAT$(GetFreeResources(%RCRS32_SYSTEMRESOURCES)) + "%" + CHR$(10) + _
                           "User Resources:     " + FORMAT$(GetFreeResources(%RCRS32_USERRESOURCES)) + "%" + CHR$(10) + _
                           "GDI Resources:      " + FORMAT$(GetFreeResources(%RCRS32_GDIRESOURCES)) + "%"
               
              END FUNCTION
              ------------------

              Comment


                #8
                Borje --
                I cut a little your code.
                Code:
                   #Compile Exe
                   #Register None
                   #Resource "LEAKTEST.PBR"
                   #Include "WIN32API.INC"
                
                   %ID_IMAGEX = 20
                
                   CallBack Function NewDlgCallback
                      Select Case CbMsg
                         Case %WM_COMMAND: If CbCtl = %IDCANCEL Then Dialog End CbHndl, 0
                         Case %WM_DESTROY
                            Local hBmp As Long
                            Control Send CbHndl, %ID_IMAGEX, %STM_GETIMAGE, %IMAGE_BITMAP, 0 To hBmp
                            If hBmp Then
                               If IsFalse(DeleteObject(hBmp)) Then MsgBox "Can't delete hBmp"
                            Else
                               MsgBox "hBmp is not found"
                            End If
                      End Select
                   End Function
                
                   Sub NewDialog(ByVal hWnd As Long)
                      Local hDlg As Long
                      Dialog New hWnd, "About me..",,, 100, 70, %WS_SYSMENU To hDlg
                      Control Add Button, hDlg, %IDCANCEL, "&Close", 4,  4, 88, 14
                      Control Add ImageX,  hDlg, %ID_IMAGEX, "#1", 4, 22, 87, 28, %WS_BORDER
                      Dialog Show Modal hDlg Call NewDlgCallback
                   End Sub
                
                   CallBack Function DlgCallback
                      Select Case CbMsg
                         Case %WM_COMMAND
                            Select Case CbCtl
                               Case %IDOK:  NewDialog CbHndl
                               Case %IDCANCEL : Dialog End CbHndl, 0
                            End Select
                      End Select
                   End Function
                   
                   Function PbMain
                      Local hDlg As Long
                      Dialog New 0, "Leak test",,, 122, 90, %WS_SYSMENU To hDlg
                      Control Add Button, hDlg, %IDOK, "Click me repeatedly..", 4,   4,  110, 14
                      Control Add Button, hDlg, %IDCANCEL, "&Close",            4,  20,  110, 14
                      Dialog Show Modal hDlg Call DlgCallback
                   End Function
                NT (Win2000) Task manager (and returned API functions' values) doesn't show any leaks.

                ------------------

                Comment


                  #9
                  Interesting. Could it be Win95/98 "feature"? I still get a resource
                  leak with your stripped version of the code in both Win95 and 98.
                  NT handles many things better than the DOS/Win versions, so maybe
                  that could be the case here.

                  Ah well, as long as the LABEL/SET IMAGEX trick works, I don't
                  really care. Just thought I'd mention it, in case someone from
                  the PB Dev team had some spare time to waiste on it..


                  ------------------

                  Comment


                    #10
                    It is of interest, and I'll be persuing the issue with R&D. Thanks for bringing it to our attention!


                    ------------------
                    Lance
                    PowerBASIC Support
                    mailto:[email protected][email protected]</A>
                    Lance
                    mailto:[email protected]

                    Comment

                    Working...
                    X
                    😀
                    🥰
                    🤢
                    😎
                    😡
                    👍
                    👎