title: C2011 'CMemDC':'class' type redefinition in Visual Studio 2019
body: <p>First of all, I would like you to know that the code that I'm using are the same codes that can be found in GitHub. Second, I have tried various solutions online such as setting header blocks or placing <code>#pragma once</code> on top of the cpp file, but still produce the same errors to be mentioned below.</p>
  
  <p>What I'm confused about is how this code is found in various repositories, but I can't build it using VS 2019.</p>
  
  <p>My guess is that I need to install VS 2010 for this to build properly, but I'm considering it as a last resort to solve this problem.</p>
  
  <p>Any ideas will be greatly appreciated. Thank you.</p>
  
  <h3>TextProgressCtrl.cpp</h3>
  
  <pre class="lang-cpp prettyprint-override"><code>// TextProgressCtrl.cpp : implementation file
  //
  // Written by Chris Maunder (chrismaunder@codeguru.com)
  // Copyright 1998.
  //
  // Modified : 26/05/98 Jeremy Davis, jmd@jvf.co.uk
  //              Added colour routines
  //
  // TextProgressCtrl is a drop-in replacement for the standard 
  // CProgressCtrl that displays text in a progress control.
  //
  // This code may be used in compiled form in any way you desire. This
  // file may be redistributed by any means PROVIDING it is not sold for
  // profit without the authors written consent, and providing that this
  // notice and the authors name is included. If the source code in 
  // this file is used in any commercial application then an email to
  // the me would be nice.
  //
  // This file is provided "as is" with no expressed or implied warranty.
  // The author accepts no liability if it causes any damage to your
  // computer, causes your pet cat to fall ill, increases baldness or
  // makes you car start emitting strange noises when you start it up.
  //
  // Expect bugs.
  // 
  // Please use and enjoy. Please let me know of any bugs/mods/improvements 
  // that you have found/implemented and I will fix/incorporate them into this
  // file. 
  #ifndef _MEMDC_H_        // changed location from original code
  #define _MEMDC_H_        // added for header blocks
  #include "stdAfx.h"
  #include "TextProgressCtrl.h"
  
  #ifdef _DEBUG
  #define new DEBUG_NEW
  #undef THIS_FILE
  static char THIS_FILE[] = __FILE__;
  #endif
  
  
  
  //////////////////////////////////////////////////
  // CMemDC - memory DC
  //
  // Author: Keith Rule
  // Email:  keithr@europa.com
  // Copyright 1996-1997, Keith Rule
  //
  // You may freely use or modify this code provided this
  // Copyright is included in all derived versions.
  //
  // History - 10/3/97 Fixed scrolling bug.
  //                   Added print support.
  //
  // This class implements a memory Device Context
  
  class CMemDC : public CDC
  {
  public:
  
      // constructor sets up the memory DC
      CMemDC(CDC* pDC) : CDC()
      {
          ASSERT(pDC != NULL);
  
          m_pDC = pDC;
          m_pOldBitmap = NULL;
          m_bMemDC = !pDC-&gt;IsPrinting();
  
          if (m_bMemDC)    // Create a Memory DC
          {
              pDC-&gt;GetClipBox(&amp;m_rect);
              CreateCompatibleDC(pDC);
              m_bitmap.CreateCompatibleBitmap(pDC, m_rect.Width(), m_rect.Height());
              m_pOldBitmap = SelectObject(&amp;m_bitmap);
              SetWindowOrg(m_rect.left, m_rect.top);
          }
          else        // Make a copy of the relevent parts of the current DC for printing
          {
              m_bPrinting = pDC-&gt;m_bPrinting;
              m_hDC = pDC-&gt;m_hDC;
              m_hAttribDC = pDC-&gt;m_hAttribDC;
          }
      }
  
      // Destructor copies the contents of the mem DC to the original DC
      ~CMemDC()
      {
          if (m_bMemDC)
          {
              // Copy the offscreen bitmap onto the screen.
              m_pDC-&gt;BitBlt(m_rect.left, m_rect.top, m_rect.Width(), m_rect.Height(),
                  this, m_rect.left, m_rect.top, SRCCOPY);
  
              //Swap back the original bitmap.
              SelectObject(m_pOldBitmap);
          }
          else {
              // All we need to do is replace the DC with an illegal value,
              // this keeps us from accidently deleting the handles associated with
              // the CDC that was passed to the constructor.
              m_hDC = m_hAttribDC = NULL;
          }
      }
  
      // Allow usage as a pointer
      CMemDC* operator-&gt;() { return this; }
  
      // Allow usage as a pointer
      operator CMemDC* () { return this; }
  
  private:
      CBitmap  m_bitmap;      // Offscreen bitmap
      CBitmap* m_pOldBitmap;  // bitmap originally found in CMemDC
      CDC* m_pDC;         // Saves CDC passed in constructor
      CRect    m_rect;        // Rectangle of drawing area.
      BOOL     m_bMemDC;      // TRUE if CDC really is a Memory DC.
  };
  
  #endif
  
  
  
  /////////////////////////////////////////////////////////////////////////////
  // CTextProgressCtrl
  
  CTextProgressCtrl::CTextProgressCtrl()
  {
      m_nPos = 0;
      m_nStepSize = 1;
      m_nMax = 100;
      m_nMin = 0;
      m_bShowText = TRUE;
      m_strText.Empty();
      m_colFore = ::GetSysColor(COLOR_HIGHLIGHT);
      m_colBk = ::GetSysColor(COLOR_WINDOW);
      m_colTextFore = ::GetSysColor(COLOR_HIGHLIGHT);
      m_colTextBk = ::GetSysColor(COLOR_WINDOW);
  
      m_nBarWidth = -1;
  }
  
  CTextProgressCtrl::~CTextProgressCtrl()
  {
  }
  
  BEGIN_MESSAGE_MAP(CTextProgressCtrl, CProgressCtrl)
      //{{AFX_MSG_MAP(CTextProgressCtrl)
      ON_WM_ERASEBKGND()
      ON_WM_PAINT()
      ON_WM_SIZE()
      //}}AFX_MSG_MAP
      ON_MESSAGE(WM_SETTEXT, OnSetText)
      ON_MESSAGE(WM_GETTEXT, OnGetText)
  END_MESSAGE_MAP()
  
  /////////////////////////////////////////////////////////////////////////////
  // CTextProgressCtrl message handlers
  
  LRESULT CTextProgressCtrl::OnSetText(WPARAM wParam, LPARAM lParam)
  {
      LPCTSTR szText = (LPCTSTR)lParam;
      LRESULT result = Default();
  
      if ((!szText &amp;&amp; m_strText.GetLength()) ||
          (szText &amp;&amp; (m_strText != szText)))
      {
          m_strText = szText;
          Invalidate();
      }
  
      return result;
  }
  
  LRESULT CTextProgressCtrl::OnGetText(WPARAM cchTextMax, LPARAM szText)
  {
      if (!_tcsncpy((LPTSTR)szText, m_strText, cchTextMax))
          return 0;
      else
          return min(cchTextMax, (UINT)m_strText.GetLength());
  }
  
  BOOL CTextProgressCtrl::OnEraseBkgnd(CDC* /*pDC*/)
  {
      return TRUE;
  }
  
  void CTextProgressCtrl::OnSize(UINT nType, int cx, int cy)
  {
      CProgressCtrl::OnSize(nType, cx, cy);
  
      m_nBarWidth = -1;   // Force update if SetPos called
  }
  
  void CTextProgressCtrl::OnPaint()
  {
      if (m_nMin &gt;= m_nMax)
          return;
  
      CRect LeftRect, RightRect, ClientRect;
      GetClientRect(ClientRect);
  
      double Fraction = (double)(m_nPos - m_nMin) / ((double)(m_nMax - m_nMin));
  
      CPaintDC PaintDC(this); // device context for painting
      CMemDC dc(&amp;PaintDC);
      //CPaintDC dc(this);    // device context for painting (if not double buffering)
  
      LeftRect = RightRect = ClientRect;
  
      LeftRect.right = LeftRect.left + (int)((LeftRect.right - LeftRect.left) * Fraction);
      dc.FillSolidRect(LeftRect, m_colFore);
  
      RightRect.left = LeftRect.right;
      dc.FillSolidRect(RightRect, m_colBk);
  
      if (m_bShowText)
      {
          CString str;
          if (m_strText.GetLength())
          {
              if (m_strText.ReverseFind(L'%') &lt; 0)
              {
                  str.Format(_T("%s (%d %%)"), m_strText, (int)(Fraction * 100.0));
              }
              else
              {
                  str = m_strText;
              }
          }
          else
          {
              str.Format(_T("%d%%"), (int)(Fraction * 100.0));
          }
  
          dc.SetBkMode(TRANSPARENT);
  
          CRgn rgn;
          rgn.CreateRectRgn(LeftRect.left, LeftRect.top, LeftRect.right, LeftRect.bottom);
          dc.SelectClipRgn(&amp;rgn);
          dc.SetTextColor(m_colTextBk);
  
          dc.DrawText(str, ClientRect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  
          rgn.DeleteObject();
          rgn.CreateRectRgn(RightRect.left, RightRect.top, RightRect.right, RightRect.bottom);
          dc.SelectClipRgn(&amp;rgn);
          dc.SetTextColor(m_colTextFore);
  
          dc.DrawText(str, ClientRect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
      }
  }
  
  void CTextProgressCtrl::SetForeColour(COLORREF col)
  {
      m_colFore = col;
  }
  
  void CTextProgressCtrl::SetBkColour(COLORREF col)
  {
      m_colBk = col;
  }
  
  void CTextProgressCtrl::SetTextForeColour(COLORREF col)
  {
      m_colTextFore = col;
  }
  
  void CTextProgressCtrl::SetTextBkColour(COLORREF col)
  {
      m_colTextBk = col;
  }
  
  COLORREF CTextProgressCtrl::GetForeColour()
  {
      return m_colFore;
  }
  
  COLORREF CTextProgressCtrl::GetBkColour()
  {
      return m_colBk;
  }
  
  COLORREF CTextProgressCtrl::GetTextForeColour()
  {
      return m_colTextFore;
  }
  
  COLORREF CTextProgressCtrl::GetTextBkColour()
  {
      return m_colTextBk;
  }
  /////////////////////////////////////////////////////////////////////////////
  // CTextProgressCtrl message handlers
  
  void CTextProgressCtrl::SetShowText(BOOL bShow)
  {
      if (::IsWindow(m_hWnd) &amp;&amp; m_bShowText != bShow)
          Invalidate();
  
      m_bShowText = bShow;
  }
  
  
  void CTextProgressCtrl::SetRange(int nLower, int nUpper)
  {
      m_nMax = nUpper;
      m_nMin = nLower;
  }
  
  int CTextProgressCtrl::SetPos(int nPos)
  {
      if (!::IsWindow(m_hWnd))
          return -1;
  
      int nOldPos = m_nPos;
      m_nPos = nPos;
  
      CRect rect;
      GetClientRect(rect);
  
      double Fraction = (double)(m_nPos - m_nMin) / ((double)(m_nMax - m_nMin));
      int nBarWidth = (int)(Fraction * rect.Width());
  
      if (nBarWidth != m_nBarWidth)
      {
          m_nBarWidth = nBarWidth;
          RedrawWindow();
      }
  
      return nOldPos;
  }
  
  int CTextProgressCtrl::StepIt()
  {
      return SetPos(m_nPos + m_nStepSize);
  }
  
  int CTextProgressCtrl::OffsetPos(int nPos)
  {
      return SetPos(m_nPos + nPos);
  }
  
  int CTextProgressCtrl::SetStep(int nStep)
  {
      int nOldStep = m_nStepSize;
      m_nStepSize = nStep;
      return nOldStep;
  }
  </code></pre>
  
  <h3>TextProgressCtrl.h</h3>
  
  <pre><code>#if !defined(AFX_TEXTPROGRESSCTRL_H__4C78DBBE_EFB6_11D1_AB14_203E25000000__INCLUDED_)
  #define AFX_TEXTPROGRESSCTRL_H__4C78DBBE_EFB6_11D1_AB14_203E25000000__INCLUDED_
  
  #if _MSC_VER &gt;= 1000
  #pragma once
  #endif // _MSC_VER &gt;= 1000
  
  // TextProgressCtrl.h : header file
  //
  // Written by Chris Maunder (chrismaunder@codeguru.com)
  // Copyright 1998.
  //
  // Modified : 26/05/98 Jeremy Davis, jmd@jvf.co.uk
  //              Added colour routines
  //
  // TextProgressCtrl is a drop-in replacement for the standard 
  // CProgressCtrl that displays text in a progress control.
  //
  // This code may be used in compiled form in any way you desire. This
  // file may be redistributed by any means PROVIDING it is not sold for
  // profit without the authors written consent, and providing that this
  // notice and the authors name is included. If the source code in 
  // this file is used in any commercial application then an email to
  // the me would be nice.
  //
  // This file is provided "as is" with no expressed or implied warranty.
  // The author accepts no liability if it causes any damage to your
  // computer, causes your pet cat to fall ill, increases baldness or
  // makes you car start emitting strange noises when you start it up.
  //
  // Expect bugs.
  // 
  // Please use and enjoy. Please let me know of any bugs/mods/improvements 
  // that you have found/implemented and I will fix/incorporate them into this
  // file. 
  
  /////////////////////////////////////////////////////////////////////////////
  // CTextProgressCtrl window
  
  class CTextProgressCtrl : public CProgressCtrl
  {
  // Construction
  public:
      CTextProgressCtrl();
  
  // Attributes
  public:
  
  // Operations
  public:
      int         SetPos(int nPos);
      int         StepIt();
      void        SetRange(int nLower, int nUpper);
      int         OffsetPos(int nPos);
      int         SetStep(int nStep);
      void        SetForeColour(COLORREF col);
      void        SetBkColour(COLORREF col);
      void        SetTextForeColour(COLORREF col);
      void        SetTextBkColour(COLORREF col);
      COLORREF    GetForeColour();
      COLORREF    GetBkColour();
      COLORREF    GetTextForeColour();
      COLORREF    GetTextBkColour();
  
      void        SetShowText(BOOL bShow);
  
  // Overrides
      // ClassWizard generated virtual function overrides
      //{{AFX_VIRTUAL(CTextProgressCtrl)
      //}}AFX_VIRTUAL
  
  // Implementation
  public:
      virtual ~CTextProgressCtrl();
  
      // Generated message map functions
  protected:
      int         m_nPos, 
                  m_nStepSize, 
                  m_nMax, 
                  m_nMin;
      CString     m_strText;
      BOOL        m_bShowText;
      int         m_nBarWidth;
      COLORREF    m_colFore,
                  m_colBk,
                  m_colTextFore,
                  m_colTextBk;
  
      //{{AFX_MSG(CTextProgressCtrl)
      afx_msg BOOL OnEraseBkgnd(CDC* pDC);
      afx_msg void OnPaint();
      afx_msg void OnSize(UINT nType, int cx, int cy);
      //}}AFX_MSG
      afx_msg LRESULT OnSetText(WPARAM wParam, LPARAM lParam);
      afx_msg LRESULT OnGetText(WPARAM wParam, LPARAM lParam);
  
      DECLARE_MESSAGE_MAP()
  };
  
  /////////////////////////////////////////////////////////////////////////////
  
  //{{AFX_INSERT_LOCATION}}
  // Microsoft Developer Studio will insert additional declarations immediately before the previous line.
  
  #endif // !defined(AFX_TEXTPROGRESSCTRL_H__4C78DBBE_EFB6_11D1_AB14_203E25000000__INCLUDED_)
  
  </code></pre>
  
  <h3>Errors found</h3>
  
  <pre><code>C2011 'CMemDC': 'class' type redefinition
  'dc' uses undefined class 'CMemDC'
  'initializing': cannot convert from 'CPaintDC*' to 'int'
  </code></pre>