MFC Support for Direct2D – Part 2

A previous article shows how to use D2D MFC classes for easily make a simple image viewer. As said there, it can be made even easier.

Enabling D2D support in MFC

  1. In the WM_CREATE message handler call CWnd::EnableD2DSupport.
    int CDemoView::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
        if (CScrollView::OnCreate(lpCreateStruct) == -1)
            return -1;
    
            EnableD2DSupport(); // Enable D2D support for this window:
    
        return 0;
    }
    
  2. In the overridden CView::OnUpdate load the bitmap from the current document’s file.
    void CDemoView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
    {
        CDemoDoc* pDoc = GetDocument();
        ASSERT_VALID(pDoc);
    
        CSize sizeImage(100, 100);
        delete m_pBitmap;
        m_pBitmap = NULL;
    
        const CString& strFile = pDoc->GetPathName();
        if(! strFile.IsEmpty())
        {
            CHwndRenderTarget* pRenderTarget = this->GetRenderTarget();
            ASSERT_VALID(pRenderTarget);
    
            m_pBitmap = new CD2DBitmap(pRenderTarget, strFile);
            HRESULT hr = m_pBitmap->Create(pRenderTarget);
            if(m_pBitmap->IsValid())
            {
                CD2DSizeF size = m_pBitmap->GetSize();
                sizeImage.SetSize(static_cast<int>(size.width), static_cast<int>(size.height));
            }
        }
       SetScrollSizes(MM_TEXT, sizeImage);
       ScrollToPosition(CPoint(0, 0));
    }
    
  3. Map AFX_WM_DRAW2D registered message which is sent by the framework if D2D support is enabled. Perform all Direct2D painting in the AFX_WM_DRAW2D message handler.
    LRESULT CDemoView::OnDrawUsingDirect2D(WPARAM wParam, LPARAM lParam)
    {
        CHwndRenderTarget* pRenderTarget = (CHwndRenderTarget*)lParam;
        ASSERT_VALID(pRenderTarget);
    
        if(pRenderTarget->IsValid())
        {
            D2D1_COLOR_F color = {1.f, 1.f, 1.f, 1.f}; // r, g, b, a
            pRenderTarget->Clear(color);
            if((nullptr != m_pBitmap) && m_pBitmap->IsValid())
            {
                // apply translation transform according to view's scroll position
                CPoint point = GetScrollPosition();
                D2D1_MATRIX_3X2_F matrix = D2D1::Matrix3x2F::Translation((float)-point.x, (float)-point.y);
                pRenderTarget->SetTransform(matrix);
                // draw the bitmap
                CD2DSizeF size = m_pBitmap->GetSize();
                pRenderTarget->DrawBitmap(m_pBitmap, CD2DRectF(0, 0, size.width, size.height));
            }
        }
        return TRUE;
    }
    

That’s all. No need to create a render target, resize it, recreating it when nesessary, calling BeginDraw, EndDraw, etc. All is done in the MFC framework if D2D support is enabled for a window.

Demo project

Download: Image VIewer - Enabling D2D Support for MFC.zip (2111 downloads)

Resources and related articles

Leave a Comment