Newsgroups: bit.listserv.win3-l
Date:         Tue, 25 Aug 1992 21:29:08 EST
From:         macphil <IQTI400@INDYCMS.IUPUI.EDU>
Subject:      X-post: "Baffled By Bitmaps"
X-To:         win3-l@uicvm.uic.edu, pascal-l@yalevm.ycc.yale.edu

I've tried to strip this down as far as possible to keep it short (so
pardon the size) and keep all of the pertinent stuff here.  I'm
trying to scoot a loaded bitmap around the screen and somehow I've
sprung a leak as the first five or six runs it's great then it
gets slower and slooower and slooooower.  I have a feeling I'm orphaning
some resource that begins to accumlate out in memory but don't know how
to track down such a beast.  I've even saved off more bitmap handles
than necessary just to make sure I don't have any stray away.

This is TPW 1.5 in Windows 3.1.

Type
    PCribWindow = ^PlayWindow ;
    PlayWindow = Object( TWindow )
        SaveDC:       hDC ;
        ImageBM:      tBitMap ;
        Image:        hBitMap ;
        Where:        tPoint ;
        SaveDCBitmap: hBitmap ;
{ ------------------------------------------------------------------------- }
Constructor PlayWindow.Init ;
Begin
    Image := LoadBitMap( HInstance, PChar( 'APPLE' ) ) ;
    Where.X := 70 ;
    Where.Y := 70 ;
End ;
{ ------------------------------------------------------------------------- }
Procedure PlayWindow.Paint ;
Var
    I : Integer ;
Begin ;
    SaveBackground ;
    ShowIt ;
    For I := 1 To 20 Do
         NewSite( 70 + ( I * 8 ), 70 ) ;
End ;
{ ------------------------------------------------------------------------- }
Procedure PlayWindow.SaveBackground ;
Var
    DC: hDC ;
Begin ;
    DC := GetDC( hWindow ) ;
    GetObject( Image, SizeOf( ImageBM ), @ImageBM ) ;
    SaveDC := CreateCompatibleDC( DC ) ;
    SaveDCBitmap := SelectObject( SaveDC,
                           CreateCompatibleBitmap( DC, ImageBM.bmWidth,
                                                         ImageBM.bmHeight ) );
    BitBlt( SaveDC, 0, 0, ImageBM.bmWidth, ImageBM.bmHeight,
              DC, Where.X, Where.Y, SrcCopy ) ;
    ReleaseDC( hWindow, DC ) ;
End ;
{ ------------------------------------------------------------------------- }
Procedure PlayWindow.ShowIt ;
Var
    DC:          hDC ;
    MemDC:       hDC ;
    MemDCBitmap: hBitmap ;
Begin ;
    DC := GetDC( hWindow ) ;
    MemDC := CreateCompatibleDC( DC ) ;
    MemDCBitmap := SelectObject( MemDC, Image ) ;
    BitBlt( DC, Where.X, Where.Y, ImageBM.bmWidth, ImageBM.bmHeight,
              MemDC, 0, 0, SrcCopy ) ;
    SelectObject( MemDC, MemDCBitmap ) ;
    DeleteDC( MemDC ) ;
    ReleaseDC( hWindow, DC ) ;
End ;
{ ------------------------------------------------------------------------- }
Procedure PlayWindow.NewSite ;
Var
    BM:              tPoint ;
    Origin:          tPoint ;
    DC:              hDC ;
    NewScreen:       hDC ;
    NewScreenBitmap: hBitmap ;
    MemDC:           hDC ;
    MemBitmap:       hBitmap ;
Begin ;
    { determine boundaries, etc. }
    If Where.X > NewX
    Then Begin ;
         Origin.X := NewX ;
         BM.X := Where.X + ImageBM.bmWidth - NewX ;
    End
    Else Begin ;
         Origin.X := Where.X ;
         BM.X := NewX + ImageBM.bmWidth - Where.X ;
    End ;
    If Where.Y > NewY
    Then Begin ;
         Origin.Y := NewY ;
         BM.Y := Where.Y + ImageBM.bmHeight - NewY ;
    End
    Else Begin ;
         Origin.Y := Where.Y ;
         BM.Y := NewY + ImageBM.bmHeight - Where.Y ;
    End ;
    { extract the area to be updated }
    DC := GetDC( hWindow ) ;
    NewScreen := CreateCompatibleDC( DC ) ;
    NewScreenBitmap := SelectObject( NewScreen,
                                   CreateCompatibleBitmap( DC, BM.X, BM.Y ) );
    BitBlt( NewScreen, 0, 0, BM.X, BM.Y, DC, Where.X, Where.Y, SrcCopy ) ;
    { restore the old background }
    BitBlt( NewScreen, Where.X - Origin.X, Where.Y - Origin.Y,
              ImageBM.bmWidth, ImageBM.bmHeight, SaveDC, 0, 0, SrcCopy ) ;
    { new coordinates }
    Where.X := NewX ;
    Where.Y := NewY ;
    { get a new "underneath" }
    BitBlt( SaveDC, 0, 0, ImageBM.bmWidth, ImageBM.bmHeight, NewScreen,
              Where.X - Origin.X, Where.Y - Origin.Y, SrcCopy ) ;
    { put the image in its new location }
    MemDC := CreateCompatibleDC( DC ) ;
    MemBitmap := SelectObject( MemDC, Image ) ;
    BitBlt( NewScreen, Where.X - Origin.X, Where.Y - Origin.Y,
              ImageBM.bmWidth, ImageBM.bmHeight, MemDC, 0, 0, SrcCopy ) ;
    SelectObject( MemDC, MemBitmap ) ;
    DeleteObject( MemBitmap ) ;
    DeleteDC( MemDC ) ;
    { refresh the real screen }
    BitBlt( DC, Origin.X, Origin.Y, BM.X, BM.Y, NewScreen, 0, 0, SrcCopy ) ;
    { relinquish our resources }
    SelectObject( NewScreen, NewScreenBitmap ) ;
    DeleteObject( NewScreenBitmap ) ;
    DeleteDC( NewScreen ) ;
    ReleaseDC( hWindow, DC ) ;
End ;
{ ------------------------------------------------------------------------- }
Destructor PlayWindow.Done ;
Begin ;
    SelectObject( SaveDC, SaveDCBitmap ) ;
    DeleteDC( SaveDC ) ;
    DeleteObject( Image ) ;
    TWindow.Done ;
End ;
{ ------------------------------------------------------------------------- }
Comments: Gated by NETNEWS@AUVM.AMERICAN.EDU