Announcement

Collapse
No announcement yet.

Stretch bitmap to dialog..

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

  • Stretch bitmap to dialog..

    I was playing around with this a bit and thought I'd ask: is following
    code safe? I load a bitmap in PBMAIN and store the handle globally so
    it can be used for stretching the bitmap in WM_ERASEBKGND. Somehow, I
    get a feeling there's something missing here, like - the global handle,
    shouldn't that one also be released? No leaks as far as I can tell, so
    maybe this is the way to do it.

    BTW, discovered that using BeginPaint in WM_PAINT doesn't work for this
    purpose. Picture becomes a mess of different sizes after a few resizing
    events and not even using FillRect on hDC helps. Think Semen found some
    strange things with BeginPaint a while ago too, maybe that was it?
    Following works though:
    Code:
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    ' Declares
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    #COMPILE EXE
    #INCLUDE "WIN32API.INC"
    GLOBAL hBitMap AS LONG 'keep this one globally to enable rezising
    DECLARE CALLBACK FUNCTION DlgProc() AS LONG
     
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    ' Create dialog and controls, etc
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    FUNCTION PBMAIN () AS LONG
     LOCAL hDlg AS LONG, txt AS STRING
     
      DIALOG NEW 0, "AutoStretch test",,, 195, 50, %WS_CAPTION OR %WS_OVERLAPPEDWINDOW, 0 TO hDlg
     
      'txt = "c:\pbdll60\samples\smtp\smtp.bmp" & CHR$(0) 'change to whatever picture you have..
      'txt = "c:\windows\suback.bin" & CHR$(0) 'found this one in Win98 - heaven background..
      txt = "c:\windows\logow.sys" & CHR$(0)   'Windows shutdown screen..
      hBitMap = LoadImage(0, BYVAL STRPTR(txt), %IMAGE_BITMAP, 0, 0, %LR_LOADFROMFILE) 'load with actual size
     
      DIALOG SHOW MODAL hDlg CALL DlgProc
    END FUNCTION
     
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    ' Main callback
    '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    CALLBACK FUNCTION DlgProc() AS LONG
     
      IF CBMSG = %WM_ERASEBKGND THEN
         LOCAL hDC AS LONG, memDC AS LONG, wRect AS RECT, bm AS BITMAP
         GetClientRect CBHNDL, wRect                  'get control's size
         GetObject hBitmap, SIZEOF(bm), bm            'get bitmap properties
     
         hDC = GetDc(CBHNDL)                          'get current DC
            memDC = CreateCompatibleDC(hDC)           'create temporary DC
            SelectObject memDC, hBitmap               'select bitmap in tmpDC
     
            StretchBlt hDC, 0, 0, wRect.nright, wRect.nbottom, _
                       memDC, 0, 0, bm.bmWidth, bm.bmHeight, %SRCCOPY
     
            DeleteObject SelectObject(memDC, hBitmap) 'delete bitmap object, but keep handle
            DeleteDC memDC                            'delete temporary DC
         ReleaseDC CBHNDL, hDC
         FUNCTION = 1
      END IF
     
    END FUNCTION

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

  • #2
    Borje --
    I approx. understood, how BeginPaint works.

    Below a corrected code (it seems to me works fine under Win2000)

    Code:
       #Compile Exe
       #Register None
       #Dim All
       #Include "WIN32API.INC"
    
       $Text = "c:\pb\pbdll60\samples\tcp\smtp.bmp" 'change to whatever picture you have..
       
       CallBack Function DlgProc() As Long
          Select Case CbMsg
             Case %WM_INITDIALOG
                Dim hBitMap As Static Long
                hBitMap = LoadImage(0, $Text, %IMAGE_BITMAP, 0, 0, %LR_LOADFROMFILE)
                
             Case %WM_DESTROY
                DeleteObject hBitMap
                
             Case %WM_SIZE ' EXITSIZEMOVE ' to reduce redrawing
                InvalidateRect CbHndl, ByVal 0, 1
                
             Case %WM_ERASEBKGND
                Dim MemDC As Long, rc As RECT, bm As BITMAP
                GetClientRect CbHndl, rc
                GetObject hBitmap, SizeOf(bm), bm     ' get bitmap properties
                MemDC = CreateCompatibleDC(CbWparam)  ' create temporary DC
                SelectObject MemDC, hBitmap           'select bitmap in tmpDC
                StretchBlt CbWparam, 0, 0, rc.nRight, rc.nBottom, MemDC, 0, 0, bm.bmWidth, bm.bmHeight, %SRCCOPY
                DeleteDC MemDC                        'delete temporary DC
                Function = 1
            End Select
       End Function
       
    
       Function PbMain
          Dim hDlg As Long
          Dialog New 0, "AutoStretch test",,, 195, 50, %WS_CAPTION Or %WS_OVERLAPPEDWINDOW, 0 To hDlg
          Dialog Show Modal hDlg Call DlgProc
       End Function

    ------------------
    E-MAIL: [email protected]

    Comment


    • #3
      Thanks, Semen. Yes, looks much better your way and of course - wParam
      gives handle to DC directly there. But why WM_SIZE? I get same result
      without. Isn't WM_ERASEBKGND always triggered at resizing? I get two
      WM_ERASE.. with your code. Add "BEEP : SLEEP 100" to WM_ERASE and see..

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

      Okay, just tested without WM_SIZE and understand. Exactly same problem
      I found with BeginPaint - old picture isn't cleared. Must be something
      with the bitmap handle after all, because the code I posted works
      without WM_SIZE and double WM_ERASE.. Weird.



      [This message has been edited by Borje Hagsten (edited May 02, 2001).]

      Comment


      • #4
        Nope, it's wParam. Try your code without WM_SIZE, but use GetDC instead.
        No problems and no double calls needed. So fault is in the DC Windows
        gives in message handler.

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

        Comment


        • #5
          Borje --
          GetDC works, because it's ignores Validate/Invalidate.
          Quick reconstruction (alternative)
          Code:
             #Compile Exe
             #Register None
             #Dim All
             #Include "WIN32API.INC"
             $Text = "c:\pb\pbdll60\samples\tcp\smtp.bmp" 'change to whatever picture you have..
             CallBack Function DlgProc() As Long
                Select Case CbMsg
                   Case %WM_INITDIALOG
                      Dim hBitMap As Static Long
                      hBitMap = LoadImage(0, $Text, %IMAGE_BITMAP, 0, 0, %LR_LOADFROMFILE)
                   Case %WM_DESTROY
                      DeleteObject hBitMap
                   Case %WM_ERASEBKGND
                      InvalidateRect CbHndl, ByVal 0, 0
                      Function = 1
                   Case %WM_PAINT
                      Dim MemDC As Long, rc As RECT, bm As BITMAP, ps As PAINTSTRUCT
                      BeginPaint CbHndl, ps
                      GetClientRect CbHndl, rc
                      GetObject hBitmap, SizeOf(bm), bm     ' get bitmap properties
                      MemDC = CreateCompatibleDC(ps.hDC)  ' create temporary DC
                      SelectObject MemDC, hBitmap           'select bitmap in tmpDC
                      StretchBlt ps.hDC, 0, 0, rc.nRight, rc.nBottom, MemDC, 0, 0, bm.bmWidth, bm.bmHeight, %SRCCOPY
                      DeleteDC MemDC                        'delete temporary DC
                      EndPaint CbHndl, ps
                      
                  End Select
             End Function
             Function PbMain
                Dim hDlg As Long
                Dialog New 0, "AutoStretch test",,, 195, 50, %WS_CAPTION Or %WS_OVERLAPPEDWINDOW, 0 To hDlg
                Dialog Show Modal hDlg Call DlgProc
             End Function


          [This message has been edited by Semen Matusovski (edited May 02, 2001).]

          Comment

          Working...
          X