Tiling a Window With a Bitmap

Date: 16 March 1999
Author: Darryn Reid (darryn dot reid at dsto dot defence dot gov dot au)

The following method tiles the background of a window with a TDib. Because the virtual size of my window may be quite large and can change frequently, it was not appropriate to maintain a big TBitmap member to BitBlt to the window.

Instead, the background is tiled dynamically whenever the window is scrolled, resized, etc.

class TMyWindow : public TWindow {
      private:
         TDib  *tile;
      protected:
         void Paint(TDC&, bool, TRect&);
      public:
         ...
         }; 

void TMyWindow::Paint(TDC &dc, bool, TRect &rect)
     {
     if (tile)
       {
       TDibDC tiledc(*tile);
       int dsty = rect.top;
       int h;
       while ((h = rect.bottom - dsty) > 0)
         {
         int srcy = dsty % tile->Height();
         h = Min(tile->Height() - srcy, h);
         int dstx = rect.left;
         int w;
         while ((w = rect.right - dstx) > 0)
           {
           int srcx = dstx % tile->Width();
           w = Min(tile->Width() - srcx, w);
           dc.BitBlt(dstx, dsty, w, h, tiledc, srcx, srcy);
           dstx += w;
           }
         dsty += h;
         }
       }
     }

Some improvements to this method are possible, such as unrolling the loops a little to first tile the cut-off edges and corners before doing the middle with complete copies of the dib.

The method shown here was used with dibs that were fairly large, at least 200x200 pixels, so that the loops are only executed a few times. Smaller dibs will cause the method to execute more slowly.