Export (0) Print
Expand All

Breaking Changes in ATL 7.0 and MFC 7.0 Since Visual C++ 6.0

Many improvements have been made to the ATL and MFC libraries since Visual C++ 6.0. Some of these changes may break existing code, and examples are listed below:

DLL Incompatibilities

The ATL and MFC DLL files shipping as part of Visual C++ .NET 2003 have been renamed to ATL71.dll and MFC71.dll, respectively.

The Visual C++ .NET ATL and MFC classes are not binary compatible with the same classes from previous releases, and therefore any source code built using mfc42.dll must be rebuilt with Visual Studio .NET. Any DLL or LIB files used by your application must also be rebuilt with Visual Studio .NET.

For example, a library containing an exported function taking CString as a parameter that has been built using Visual C++ 6.0 will give an unresolved external during linking with a Visual C++ .NET project.

ATL Module Classes

ATL 3.0 provided the class CComModule. In ATL 7.1, the functionality previously provided by CComModule is handled by several new classes. See ATL Module Classes for more information.

String Conversions

In versions of ATL up to and including ATL 3.0 in Visual C++ 6.0, string conversions using the macros in atlconv.h were always performed using the ANSI code page of the system (CP_ACP). Starting with ATL 7.0 in Visual C++ .NET, string conversions are performed using the default ANSI code page of the current thread, unless _CONVERSION_DONT_USE_THREAD_LOCALE is defined, in which case the ANSI code page of the system is used as before.

Note that the string conversion classes, such as CW2AEX, allow you to pass a code page to use for the conversion to their constructors. If a code page is not specified, the classes use the same code page as the macros.

For more information, see ATL and MFC String Conversion Macros.

CException Is Now an Abstract Base Class

CException is the base class for all exceptions in the Microsoft Foundation Class Library. Because CException is now an abstract base class, you cannot create CException objects directly; you must create objects of derived classes. If you do create an object directly, you will receive an error. For more information, see CException.

Converting from BSTR to CString

In Visual C++ 6.0, it was acceptable to use the following code:

BSTR bstr = SysAllocString(L"Hello");
CString str = bstr;

With new projects under Visual C++ .NET, this will cause the following error under ANSI builds:

error C2440: 'initializing' : cannot convert from 'BSTR' to 

There are now UNICODE and ANSI versions of CString (CStringW and CStringA). To flag any unnecessary overhead incurred by implicit conversions, constructors that take the inverse type (for example, CStringA taking a UNICODE argument, or CStringW taking an ANSI argument) are now tagged as explicit using the following entry in stdafx.h:


To work around this error, do one of the following:

  • Use CStringW to avoid conversion:
    BSTR bstr = SysAllocString(L"Hello");
    CStringW str = bstr;
  • Explicitly call the constructor:
    BSTR bstr = SysAllocString(L"Hello");
    CString str = CString(bstr);
  • Remove the line #define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS from stdafx.h.

CComEnumImpl::Skip Changes

The CComEnumImpl::Skip method in versions before ATL 7.0 would not return the correct error code for an input value of 0. It would also handle large input values in an inconsistent manner. These behaviors were fixed in ATL 7.0.

CWnd::DestroyWindow Assertions

When a tooltip was displayed in CWnd::DestroyWindow, an assertion error would occur. As a result, in MFC 7.0, the following member variables were moved from AFX_THREAD_STATE to AFX_MODULE_THREAD_STATE:

  • CToolTipCtrl* m_pToolTip
  • CWnd* m_pLastHit
  • int m_nLastHit
  • TOOLINFO m_lastInfo
  • int m_nLastStatus
  • CControlBar* m_pLastStatus

LNK2001 Unresolved External Symbol Error

When calling a function in a static library or DLL that takes a wchar_t type (note that BSTR and LPWSTR resolve to wchar_t*), you may get an LNK2001 unresolved external symbol error.

This error is caused by the /Zc:wchar_t compiler option, which is set to on by default in new MFC projects. This option causes the compiler to treat wchar_t as a native type. Prior to Visual C++ .NET, wchar_t was treated as an unsigned short.

If the main project and library don't use the same setting for /Zc:wchar_t, this will cause a mismatch of function signatures. To avoid this problem, rebuild the library with the /Zc:wchar_t compiler option, or turn it off in the main project using the Treat wchar_t as Built-in Type setting on the Language property page in the Property Pages dialog box.

Boolean Expressions Are Now of Type bool, Not BOOL

Consider the following class:

class CMyClass : public CObject
   BOOL bFlag;

   void Serialize (CArchive& ar))
      if (ar.IsStoring())
         ar << (bFlag != FALSE); // breaking change
         ar >> bFlag;

Prior to Visual C++ .NET, the expression bFlag != FALSE evaluated as a BOOL and four bytes were written; in Visual C++ .NET, it evaluates as a bool and one byte is written. This means that programs compiled with different versions of the compiler may produce mutually incompatible data files.

To avoid the problem, cast the expression to BOOL:

ar << (BOOL)(bFlag != FALSE);

See Also

Upgrading Your Program | ATL and Visual C++ Version Numbers | MFC and Visual C++ Version Numbers | Changes from ATL Version 2.1 | Changes in MFC Versions

CColorPropPage and CFontPropPage Have Been Removed

In previous versions of MFC, and ActiveX control displayed property pages for color or font properties by specifying the GUID CLSID_CColorPropPage or CLSID_CFontPropPage, respectively. These GUIDs pointed to the classes CColorPropPage and CFontPropPage, which are no longer implemented. Instead, use the GUIDs CLSID_StockColorPage and CLSID_StockFontPage. These are implemented by msstkprp.dll, so you must redistribute that DLL with your application.

© 2014 Microsoft