title: C++ MFC: Draw a bitmap into a CFrame
body: <p>I am trying to draw a bitmap (stored as an array of bytes) to a window.</p>
  
  <p>Typical procedure follows:</p>
  
  <p>Get the device context in the OnPaint() handler.</p>
  
  <pre><code>CPaintDC dc(this);
  </code></pre>
  
  <p>Create a compatible device context from it,</p>
  
  <pre><code>CDC pMemDC-&gt;CreateCompatibleDC(&amp;dc);
  </code></pre>
  
  <p>Create a compatible bitmap that is the size of the client area (<code>GetClientRect(&amp;WinRect)</code>).</p>
  
  <pre><code>CBitmap pNewBitmap-&gt;CreateCompatibleBitmap(&amp;dc, WinRect.Width(), WinRect.Height());
  </code></pre>
  
  <p>Now, if the window client size is exactly the same size as the bitmap, I can simply make a call to <code>pNewBitmap-&gt;SetBitmapBits</code> to "feed" my array into the bitmap.</p>
  
  <p>Follow this with a <code>BitBlt</code> and the bitmap appears on the window.</p>
  
  <pre><code>dc-&gt;BitBlt(0, 0, WinRect.Width(), WinRect.Height(), pMemDC, 0, 0, SRCCOPY);
  </code></pre>
  
  <p>If you want the window size to vary independent of the image size, then first you must make sure <code>pNewBitmap</code> is the right size (the client rectangle), but now you cannot simply shove the array into the bitmap.</p>
  
  <p>In this situation, I have found a solution by repeating the above procedure to create a bitmap the exact size of the image so I can "shove" my bits into it, and then <code>BitBlt</code> that into the larger, client-sized bitmap, which then gets <code>BitBlt</code>'ed into the window.</p>
  
  <p>Is there another way to do this? Actual code follows.</p>
  
  <pre><code>void CAnimateWnd::OnPaint() 
  {
      CPaintDC dc(this); // device context for painting
  
      DrawScene(&amp;dc);
  
      // Do not call CWnd::OnPaint() for painting messages
  }
  
  void CAnimateWnd::DrawScene(CDC *pDrawDC)
  {
      CRect WinRect;
      GetClientRect(&amp;WinRect);
  
      if (pNewBitmap == NULL)
      {
          pMemDC = new CDC();
          pMemDC-&gt;CreateCompatibleDC(pDrawDC);
          pNewBitmap = new CBitmap();
          pNewBitmap-&gt;CreateCompatibleBitmap(pDrawDC, WinRect.Width(), WinRect.Height());
          pMemDC-&gt;SelectObject(pNewBitmap);
      }
  
      CRect BMPRect;
      GetBitmapDrawSize(&amp;BMPRect);
      if (BMPRect != NULL)
      {
          if (!(BMPRect.Width() &gt;= WinRect.Width() &amp;&amp; BMPRect.Height() &gt;= WinRect.Height()))
          {
              //The bitmap is smaller than the window, so fill the window with the background color.
              CBrush BackBrush(BackGndColor);
              CPen BackPen(PS_SOLID, 1, BackGndColor);
              pMemDC-&gt;SelectObject(&amp;BackBrush);
              pMemDC-&gt;SelectObject(&amp;BackPen);
              pMemDC-&gt;Rectangle(&amp;WinRect);
              BackBrush.DeleteObject();
              BackPen.DeleteObject();
          }
      }
  
      OverrideAndDrawInHere(pMemDC, resize);
      pDrawDC-&gt;BitBlt(0,0,WinRect.right,WinRect.bottom,pMemDC,0,0,SRCCOPY);
  }
  
  template &lt;class T&gt;
  void ImageWindow&lt;T&gt;::OverrideAndDrawInHere(CDC *pDC, int resize)
  {
      if (this-&gt;sourceImage == NULL) return;
  
      CRect clientRect;
      GetClientRect(&amp;clientRect);
  
      if (this-&gt;dispBMP == NULL)
      {
          this-&gt;dispDC = new CDC();
          this-&gt;dispDC-&gt;CreateCompatibleDC(pDC);
          this-&gt;dispBMP = new CBitmap();
          this-&gt;dispBMP-&gt;CreateCompatibleBitmap(pDC, this-&gt;sourceImage-&gt;GetWidth(), this-&gt;sourceImage-&gt;GetHeight());
          this-&gt;dispDC-&gt;SelectObject(this-&gt;dispBMP);
      }
  
      this-&gt;dispBMP-&gt;SetBitmapBits(this-&gt;sourceImage-&gt;GetArea() * 4, this-&gt;translatedImage);
      pDC-&gt;BitBlt(0, 0, this-&gt;sourceImage-&gt;GetWidth(), this-&gt;sourceImage-&gt;GetHeight(), this-&gt;dispDC, 0, 0, SRCCOPY);
  }
  </code></pre>