Home > Programming > A Comprehensive comparison of the MFC & ATL changes in VS 2015 RC compared to Visual Studio 2013 Update 4 (Part 1)

A Comprehensive comparison of the MFC & ATL changes in VS 2015 RC compared to Visual Studio 2013 Update 4 (Part 1)

May 7, 2015

As my area of expertise is in libraries rather than new language features, I thought it would be useful to see what has been changed in MFC and ATL in Visual Studio 2015. If you want to review what’s new in the C++ language in VS 2015, please take a look at https://www.visualstudio.com/en-us/news/vs2015-vs.aspx. Please note that this review is based on the VS 2015 Release Candidate which was released at Build 2015 which took place from April 29th to May 1st. and as such you might expect some further changes at RTM time.

  • afx.h
    • Line 44: The #error line has been updated to mention that MFC is supported on ARM64 platforms. What I have noticed is in VC 2015 you can now compile native mode ARM binaries out of the box without getting the “error MSB8022: Compiling Desktop applications for the ARM platform is not supported. “ compiler error which you previously got in VC 2013. This in part is the enabling work to support Windows IoT and other upcoming 64 bit ARM processors which MFC looks like will be targeting. I was able to successfully compile my DtWinVer code for ARM in VS 2015 with relatively little changes (The compiler flag /ZI does not seem to be supported on ARM yet). Any migrated projects also get a new “_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE” pre-processor value. Here’s a screen capture of it running taken from my Windows 10 VM which connected to the Pi using PowerShell and Windows Remote Management:

    DtWinVer on Raspberry Pi 2

    • I will be officially updating DtWinVer to support Visual Studio 2015, ARM and Windows IoT in the next few weeks. These changes make for some very interesting developments and times ahead for Microsoft desktop development on non x86/x64 chips.
    • Line 327: AfxAssertFailedLine has been made inline and looks like it has a bug fix around WM_QUIT handling
    • Multiple locations: TRACE calls have been updated to use a %Ts format specifier instead of %s. This looks like an interesting and breaking change for client code which uses printf, CString::Format functionality and which support Unicode. It turns out that %s in VC 2015 will map to narrow string (char*) always unless you define _CRT_STDIO_LEGACY_WIDE_SPECIFIERS. Check out http://stackoverflow.com/questions/10000723/visual-studio-swprintf-is-making-all-my-s-formatters-want-wchar-t-instead-of for the issue. It looks like this change is going to be the most upsetting change to migrate your existing MFC code to VS 2015.
    • Line 1476: AfxAllocMemoryDebug has been decorated with a __declspec(allocator) value. This looks like part of the new Memory Diagnostics tools in VC 2015. Check out http://blogs.msdn.com/b/vcblog/archive/2014/06/04/native-memory-diagnostic-tools-for-visual-studio-14-ctp1.aspx
  • Afxanimationhelper.h
    • Line 88: The declaration of IID_IUnknown has been fixed.
  • afxbasepane.h
    • Line 41 and 52: Removal of unnecessary C style enum declarations. This and similar changes were done probably from the static code analysis fixes suggested by a fellow C++ MVP: Andrey Karpov and his commercial product PVS-Studio
  • afxbasetabctrl.h
    • Throughout: Inclusion of new header file and new code to support active accessibility in CMFCBaseTabCtrl
  • afxcmn.h
    • Line 743 & 2151: Fixes to SAL annotation in CTreeCtrl::SetImageList & CReBarCtrl::SetImageList
  • afxcontrolbarutil.h
    • Line 118: Removal of unnecessary C style enum declarations
  • afxcontrolrenderer.h
    • Line 89: Removal of an unused rectImage local variable.
  • afxctl.rc
    • Line 173: More %Ts changes
  • afxdisp.h
    • Line 34: Suppression of compiler error C4091 while including shlobj.h
  • afxdlgs.h
    • Line 489: CFileDialog::m_szFileTitle is now allocated using MAX_FNAME rather than the value 64
    • Line 1082-1083: Addition of two new virtual functions CFileDialog::IsLeftNavigationPane and CFIleDialog::CanAddPageToDynamicLaout. This is part of the support for the new dynamic dialog layout feature described later
    • Line 1091: Addition of a CSize m_SizeMin member variable
    • Line 1101: Addition of a OnGetMinMaxInfo message handler
  • afxeditbrowsectrl.h
    • Line 57 & 67: New parameter to the CMFCEditBrowseCtrl::EnableFileBrowseButton which gets stored in the m_dwFileDialogFlags member variable already discussed. This allows the flags passed to CFileDialog to be customized for CMFCEditBrowseCtrl. For an alternative implementation which already supports this check out http://www.naughter.com/ddxgetfile.html
  • afxext.h
    • Line 806 and 812: A new IsIntDlgCompleted method and associated m_bInitDlgCompleted member variable in CFormView. This is probably a bug fix to ensure OnInitialUpdate only fires once. This issue affected the CDialog class in previous versions of MFC.
  • afxglobals.h
    • Line 34: Removal of unnecessary C style enum declarations
    • Line 317: Addition of a new ResetCheckCompositionFlag method to AFX_GLOBAL_DATA struct
  • afxhtml.h
    • Line 826 & 959: More %Ts changes
  • afxlayout.h
  • afxmdichildwndex.h
    • Line 206: Addition of a new CanShowOnMDITabs method to CMDIChildWndEx
  • afxmultidoctemplateex.h
    • Line 26: Fix up suppression of C4510 & C4610 compiler errors
  • afxolecl.rc
    • Line 53-54: More %Ts changes
  • afxpane.h
    • Line 42: Removal of unnecessary C style enum declarations
  • afxpanedivider.h
    • Line 28: New forward declaration of CPaneTrackingWnd class
    • Line 158: The CPaneDivider classes contains a new CPaneTrackingWnd pointer member variable
  • afxpaneframewnd.h
    • Line 43: Removal of unnecessary C style enum declarations
  • afxplex_.h
    • Line 28-43: Tidy up of the CPlex class declaration and memory layout
  • afxpropertygridctrl.h
    • Line 164: The CMFCPropertyGridProperty::SetOrginalValue method has been made virtual
    • Line 264: A new derived CMFCPropertyGridColorProperty::SetOriginalValue method has been implemented
  • afxpropertysheet.h
    • Line 126: Addition of a new CMFCPropertySheet:GetNavBarWidth method
    • Line 171-172: Addition of new IsLeftNavigationPane and CanAddPageToDynamicLayout methods. Again part of the support for the new MFC dynamic dialogs
  • afxrendertarget.h
    • Line 13-23: Inclusion of a new header file d3d9types.h and correct suppression of C4458 compiler error
  • afxres.h
    • Line 26: Definition of the new MFC version number of 140
  • afxres.rc
    • Line 69-70, 100, 160: More %Ts changes
  • afxribbon.rc
    • Line 601, 621, 624 & 632: More %Ts changes
  • afxribbonpalettegallery.h
    • Line 123: Addition of a new virtual CMFCRibbonGallery::PreClickPaletteIcon method
  • afxsmartdockingguide.h
    • Line 218: The template function GetSmartDockingWndClassName has been simplified
  • afxtempl.h
    • Line 164: The template function HashKey now supresses the C4311 compiler error
  • afxtooltipctrl.h
    • Line 38: Addition of a comment to indicate that CMFCToolTipInfo::m_bRoundedCorners is Obsolete
    • Line 115: Addition of a new CToolTipCtrl::m_sizeCornerRadius member variable.
  • afxv_cpu.h:
    • This header file has been removed from MFC in VC 2015
  • afxv_w32.h
    • Line 149-151 & 184-187: Changes to correctly save and restore packing settings
  • afxver_h
    • Line 20, 24, : The version number of MFC has been incremented from 12.00 to 14.00
    • Line 87-90: Changes to handle removal of defunct afxv_cpu.h module around the area of packing.
  • afxwin.h
    • Line 216: Forward declaration of the new CMFCDynamicLayout class.
    • Line 1361-1363, 1702-1704: Changes to specific some ARM64 structs
    • Line 1840-1848: Changes to handle stack pushing changes in CCmdTarget for ARM64.
    • Line 2970-2991: Addition of new EnableDynamicLayout, IsDynamicLayout and GetDynamicLayout methods to CWnd. Again this is part of the new dynamic dialogs feature.
    • Line 3084-3092: Addition of new member variable m_pDynamicLayout, ResizeDynamicLayout, InitDynamicLayout and LoadDynamicLaoutResource methods to CWnd. Again this is part of the new dynamic dialogs feature.
    • Line 3259-3285: Changes to the D2D methods in CWnd to support DC render targets in addition to HWND render targets
    • Line 6615: Inclusion of the new afxlayout.h header file
  • afxwin1.inl
    • Line 71-79: Fix up suppression of C6271 & C6273 compiler errors in CGdiObject destructor
  • afxwin2.inl
    • Line 1087-1095: Fix up suppression of C6271 & C6273 compiler errors in CWaitCursor destructor
  • afxwinforms.h
    • Line 42 & 46: Updates to MFC version numbers
  • afxwinforms.inl
    • Line 15 & 16: Updates to calling convention for AfxmEnsureManagedInitialization and AfxmReleaseManagedReferences functions
  • atlacc.h
    • Line 1253: Updates to declaration of names static table in AtlIAccessibleGetIDsOfNamesHelper function
  • atlalloc.h
  • atlbase.h
    • Line 3084: GetAppIdT is now declared as returning a const TCHAR* instead of TCHAR.
    • Line 4014: nShowCmd parameter to CAtlServiceModuleT::PreMessageLoop is not marked as an unreferenced parameter.
    • Line 4017: #ifdef code in CAtlServiceModuleT::PreMessageLoop has been expanded in scope to include local variables which are only used inside the #ifdef block of code. Again this was probably fixed as the results of some static analysis results
    • Line 5031-5033: The return value from CoInitialize is now checked. This is probably the result of making the code /analyze clean when used with used with newer versions of the Windows SDK which now have SAL annotations on the CoInitialize API.
    • Line 6308: The return value from StringFromGUID2 is checked in CRegKey::SetGUIDValue. Again the result of /analyze clean work.
    • Line 6348, 6466, 6518, 6889, 6922: More %Ts changes.
    • Line 7276: The return value from StringFromGUID2 is checked in AtlRegisterClassCategoriesHelper. Again the result of /analyze clean work.
  • atlbuild.h
    • Line 4-16: Updates to the build numbers of ATL. It is now 14.00.22816.
  • atlcoll.h
    • Line 19, 38-40: Changes to handle removal of defunct afxv_cpu.h module and packing of CAtlPlex class.
  • atlcom.h
    • Line 2397, 4518: Changes to support ARM64 as a valid compilation platform
    • Line 3933: Additional SAL annotations to CComClassFactorySingleton::CreateInstance parameter
    • Line 4328: More %Ts changes.
    • Line 4694: Additional SAL annotations to IDispEventSimpleImpl::Invoke parameter
    • Line 5208: Additional SAL annotations to IProvideClassInfoImpl::GetClassInfo parameter
    • Line 5232: Additional SAL annotations to IProvideClassInfo2Impl::GetClassInfo parameter
    • Line 6650: Replacement of the constant 3 with SEVERITY_ERROR in AtlSetErrorInfo.
    • Line 6949 & 6957: More %Ts changes.
  • atlcomcli.h
    • Line 525: Addition of a C style cast in CComPtr::InvokeN on a parameter. This is probably due to improvements in the Prefast static analyser in VC 2015
    • Line 544-591: Changes to the name of an IDispatch parameter to CComPtr::PutProperty and CComPtr::GetProperty methods
    • Line 795-797: The return value from StringFromGUID2 is checked in a in a CComBSTR constructor. Again the result of /analyze clean work.
  • ATLComMem.h
  • atlconv.h
  • atlcore.h
    • Line 592-603: Changes to the AtlPrintfT function to handle the new %Ts changes. The comments in the modified code in this function are quite interesting and might be worth covering in a future VC blog post about breaking changes VS 2015 before it gets to RTM
  • atlctrl.h
    • Line 188-206: member variables in CComControlBase constructor are now explicitly initialized rather than relying on a memset call. Again this change is probably the result of static code analysis.
    • Line 776: Removal of a “HWND* m_phWndCD” member variable from CComControlBase. It looks like an unused member variable which static code analysis spotted.
    • Line 4055, 4076, 4091, 4112, 4127 & 4151: More %Ts changes
  • atldb.h
    • Line 230-234: More %Ts changes
    • Line 687-689: The return value from StringFromGUID2 is checked in AtlTraceErrorRecords. Again the result of /analyze clean work.
    • Line 691: More %Ts changes
    • Line 6232: m_bIsParent method uses COLUMN_ENTRY_TYPE instead of COLUMN_ENTRY in CEnumeratorAccessor column map
    • Line 6354: More %Ts changes
  • atldbgmem.h
  • atldbsch.h
    • Throughout: Changes to various Boolean member variables of ATL DB accessor classes to use COLUMN_ENTRY_TYPE instead of COLUMN_ENTRY
  • atldef.h
    • Line 122, 385: Change to support ARM64 compilation and packing
    • Line 511-522: Updates to the build numbers of ATL
    • Line 583 & 584: Updates to Window Class names used by ATL
    • Line 633-637: Defines to support __declspec(allocator) support in ATL
  • atlevent.h
    • SAL annotations added to _EventingCriticalSectionAuto::Lock and Unlock to indicating locking semantics of class
  • atlhost.h
    • Line 366-397: All member variables in CAXHostWindow constructor are now explicitly initialized. Again this change is probably the result of static code analysis.
    • Line 2474, 2483, 2593 & 2602: Updates to CAxHostWindow::AtlAxWindowProc and CAxHostWindow::AtlAxWindowProc2 to compile cleanly using /analyze
    • Line 2498, 2499, 2622 & 2623: More %Ts changes
  • atlimage.h
    • Line 36-43: Fix up suppression of C4458 compiler errors
  • atlmem.h
  • atlplus.h
    • Line 334, 431, 592, 615, 724, 787 & 903: More %Ts changes
  • atlsecurity.h
    • Line 585, 589, 4072, 4075, 4080 & 4086: “bInheritHandle” parameter name in CSecurityAttributes constructor and CSecurityAttributes::Set method has been renamed
    • Line 5147-5159: The return value from CoRevertToSelf is checked in CAccessToken::OpenCOMClientToken. Again the result of /analyze clean work.
  • atlsimpcoll.h
    • Line 164: Additional SAL annotations to CSimpleArray::Add
    • Line 193: Additional SAL annotations to CSimpleArray::Remove
    • Line 202: Additional SAL annotations to CSimpleArray::RemoveAt
    • Line 259: Additional SAL annotations to CSimpleArray::SetAtIndex
  • atlstdthunk.h
    • Some of this modules functionality has been refactored into a new atlthunk.h header file
    • Line 221-254, 314-347: The ATL thunk to map HWND to CWindow instances has been implemented for ARM64
    • Line 357-428: The CDynamicStdCallThunk2 class has been significantly reworked. This is probably in light of the ARM64 support added to this module.
  • atlstr.h
    • Line 172-228: Addition of new functions in an AtlUtil namespace to handle varargs sprint functionality. These change look like they are related to the %Ts changes
    • Line 565-574, 1066-1075: The ChTraitsOS has been updated to use the new AtlUtil methods instead of calling wvspringfA directly.
    • Line 792: ChTraitsOS::lstrcmpiW now calls wsccmp instead of lstrcmpiW.
    • Line 1230-1240: CHTraits::strstrT has been updated to use C++ typename keyword
  • atlsync.h
    • Line 514: Fix up suppression of C4311 compiler errors
  • atlthunk.h
    • New module which implements some of the ATL HWND to CWindow instance thunk.
  • atltime.h
    • Line 377-391: Addition of a new CTime::GetAsDBTIMESTAMP method
    • Line 505-516: The CTime constructor which takes a FILETIME& parameter now uses the SystemTimeToTZSpecificLocalTime API.
    • Line 693 & 694: More %Ts changes
  • atltrace.h
    • Line 21: The tchar.h system header file is now included
    • Line 144, 226, 269: Removal of redundant class name from CTrace::TraceV method
    • Line 161 – 198, 282-320: Changes throughout CTrace::TraceV method to use more correct printf format specifiers
    • Line 346-350: Changes in CTrace::RegisterCategory to use more correct printf format specifiers
    • Line 387-402: Addition of a new CPreserveLastError which preserves the Win32 GetLastError value across a scope instance of itself.
    • Line 422-463: The CTraceFileAndLineInfo now use the new CPreserveLastError class to preserve the Win32 GetLastError value across its operator() methods.
    • Line 567-609: All AtlTrace* functions now use the new CPreserveLastError class to preserve the Win32 GetLastError value.
    • Line 617: More %Ts changes
  • atltransactionmanager.h
    • line 25: __uncaught_exception is now declared as extern “C”
  • atlutil.h
    • Line 29-34: Fix up suppression of C4091 compiler errors
    • Line 365: A local variable in CStackDumper::ResolveSymbol is now declared as const char* instead of LPSTR.
    • Line 449-451: The _AtlThreadContextInfo is now aligned correctly for ARM64
    • Line 545-548: _AtlThreadContextInfo::DoDumpStack now supports ARM64
    • Line 2433: The CUrl::SetScheme method now includes a static_cast of its input parameter in its body
    • Line 2XXX: The Curl::Parse method has had some code which calls goto removed as it could never be reached
  • atlwin.h
    • Line 2837: The ATL END_MSG_MAP macro now includes a static_cast when calling ATLTRACE
    • Line 4216-4218: The return value from CreateStramOnHGlobal in CAxDialogImpl:: CreateActiveXControls is now checked
    • Line 5275: More %Ts changes
  • atlwinverapi.h
    • Throughout: This module has been significantly reworked with new structs, functions and tables to map LCID to and from locale names. This is to support Windows XP targeting which does not support Locale.
    • Line 724-738: _AtlInitializeCriticalSectionEx has been updated to use newer style SAL annotations
  • cstringt.h
    • Line 448: ChTraitsCRT::ReallocSysString has been updated to only call MultiByteToWideChar if the input parameter length is greater than zero
    • Line 678-738: Changes throughout ChTraitsCRT::GetFormattedLength & ChTraitsCRT::Format to use more correct printf format specifiers
  • statreg.h
    • Line 270: Removal of unnecessary int construction from CParserBuffer::Append
    • Line 473, 483,484,677,815,982,995,1000,1064,1354,1367,1377,1494,1533,1568,1570,16020 & 1634: More %Ts changes

I plan to produce a follow-up blog post where I post the details of the MFC source code diff of VS 2015 compared to VS 2013. I would expect most of the changes to be similar to the differences as described above in the corresponding header files but I would expect to find a few unrelated bug fixes also. I might also do a blog post on the new dynamic dialog mechanism if people are interested also.

Hopefully this review was useful for those developers thinking of migrating their large ATL / MFC code base to the latest version of Visual Studio. Happy coding.

Advertisements
Categories: Programming
  1. Mathias
    May 7, 2015 at 9:52 pm

    One think with MFC that currently is broken in VS2015RC is if you have
    #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS
    in stdafx.h

    (It is defined if you do not use new MFC controls and want to avoid a bloated exe if you do static linking of MFC)

    You will get link error because some functions is already defined.
    Hope they fix it before release.

    • May 7, 2015 at 10:19 pm

      I’ve heard about this one. I’d thought the VC group has fixed this in VS 2012 but I was unaware that they had broken this again in VS 2015. I have only started looking at VS 2015 myself just this week so I was unaware of this (In fact I have not run any of my MFC code through VS 2015 yet). I’d make sure you create a connect bug report for this so that it gets fixed for VS 2015 RTM

  2. Mathias
    May 8, 2015 at 4:44 am

    I created a bug report for them a couple of days ago
    http://connect.microsoft.com/VisualStudio/feedback/details/1305097/project-with-static-linked-mfc-with-no-enhanced-mfc-controls-define-set-cant-be-build

    With 2015RC I’m now able to build all of my old (but still active) projects. (CTP releases gave me a lot of strange issues but they are now all fixed) This is the last issue I have.
    For the moment I build without that constant define. But I would prefer not to ship like that since exes are bloated.. each EXE is 2.5MB extra in size, and that is code that is not even used.

  3. July 29, 2015 at 5:59 am

    As someone:

    1. who is really interested in SAL

    2. doesn’t yet have VS2015

    3. opened the Connect bug for CSimpleArray’s annotations

    …I’d love to hear what new annotations were added. Elaborate?

    • August 12, 2015 at 3:49 pm

      Just taken a look and all that has been added to CSimpleArray is _Success_(return != FALSE) for the “Add”, “Remove”, “RemoveAt” and “SetAtIndex” methods. This would correspond to the following Connect bug: https://connect.microsoft.com/VisualStudio/feedback/details/1052983/sal-success-annotations-missing-for-csimplearray. I once used this class in my CSortedArray class when it is compiled in non-MFC mode but replaced its usage with “CAtlArray” back in 2009. I would suggest you do the same for any ATL code still using this class as the CAtlArray class is a bit more flexible.

      • October 15, 2015 at 9:57 pm

        Well, if you’re going to refactor ay code that uses MFC/ATL containers, I’d always prefer their STL counterparts, which are better in many (i.e. every) way(s) 😉

  1. May 13, 2015 at 9:12 pm
Comments are closed.
%d bloggers like this: