Home   |   Products   |   Documentation
 

dev net revision
29 July 2008
 

 
 

Unified CMarkup for STL and MFC

As of CMarkup release 9.0, CMarkup can be compiled for either MFC or STL strings. Prior to this release, the CMarkupSTL class was separate from CMarkup.

STL goes prime time!

The primary result of merging these classes has been a lot more functionality for the STL version including UNICODE support and text encoding conversion functions.

CMarkupSTL customers who are upgrading to 9.0 should do the following:

  • change places where you use the "CMarkupSTL" class name to "CMarkup"
  • include Markup.cpp and Markup.h in the project instead of MarkupSTL.cpp and MarkupSTL.h
  • put MARKUP_STL in your project compiler defines
  • The free Express edition of Microsoft Visual Studio 2005 does not include MFC or plain C++/Win32 Windows programming (Express only supports .NET and console apps), but it does include Microsoft's best STL support yet.

    CMarkup 9.0 for STL has been tested in Visual C++ 2005 Express, and the free Dev-C++ IDE Mingw compiler 2.95.

    See also: CMarkup STL Platforms.

    Pre-compiled headers in Visual Studio

    Markup.cpp no longer calls #include "stdafx.h" which was specifically done for Visual Studio before CMarkup release 9.0. This means that now in Visual Studio, whether you are using MFC or STL, you must go into the project file precompiled headers settings for Markup.cpp and specify "not using" precompiled headers.

    See also: Pre-compiled Header Issue.

    Platform differences

    Since release 7.0, the only dependency on STL or MFC has been the corresponding string class std::string for STL, and CString for MFC. The most obvious difference between the two versions of CMarkup was the string class, but equally important was the text encoding support which was geared towards Visual C++ in the MFC version, and tried to adhere to standard C++ string functions in the STL version.

    The new unified class pulls the string and text differences into a series of defines in the Markup.h header file. This allows you to control the way it is compiled on different platforms, and increases your build options. It even potentially shows you what would be required to use another string class instead of STL or MFC string classes!

    Text defines

    Markup.h comes with text settings for Visual C++ (#if _MSC_VER > 1000), and standard C++ non-UNICODE and C++ UNICODE. In other words, whenever it is not Microsoft Visual C++, it will use the standard C++ settings (with or without UNICODE) that are intended to be compatible with as many C++ compilers as possible. You can force it to use the standard C++ settings in Visual C++ by defining MARKUP_STDC.

    Default Text Defines
    Define Visual C++ standard C++ C++ UNICODE
    MCD_CHAR _TCHAR char wchar_t
    MCD_PCSZ const _TCHAR* const char* const wchar_t*
    MCD_PSZCPY _tcscpy strcpy wcscpy
    MCD_PSZLEN (int)_tcslen (int)strlen (int)wcslen
    MCD_PSZCHR _tcschr strchr wcschr
    MCD_PSZSTR _tcsstr strstr wcsstr
    MCD_PSZNCPY _tcsncpy strncpy wcsncpy
    MCD_PSZTOL _tcstol strtol wcstol
    MCD_PSZNCMP _tcsncmp strncmp wcsncmp
    MCD_PSZNICMP _tcsnicmp strnicmp _wcsnicmp
    MCD_SPRINTF _stprintf sprintf swprintf
    MCD_FOPEN _tfopen fopen _wfopen
    MCD_STRERROR strerror(errno) wcserror(errno)
    _T(s) s L s
    MCD_CLEN(p) (int)_tclen(p) 1 1

    If MCD_STRERROR is not defined (Windows CE doesn't have it), CMarkup calls the Win32 FormatMessage (see Markup.cpp).

    String defines

    Markup.h comes with string settings for MFC and STL. To use STL you must define MARKUP_STL, otherwise it will default to MFC. It was not necessary to define MARKUP_STL prior to CMarkup release 9.0 because the STL version was in the separate CMarkupSTL class, but now that STL has been merged into CMarkup, the STL preprocessor define is needed.

    Default String Defines
    Define MFC STL
    MCD_STR CString std::string or
    std::wstring
    MCD_2PCSZ(s) ((MCD_PCSZ)s) s.c_str()
    MCD_STRLENGTH(s) s.GetLength() (int)s.size()
    MCD_STRCLEAR(s) s.Empty() s.erase()
    MCD_STRISEMPTY(s) s.IsEmpty() s.empty()
    MCD_STRMID(s,n,l) s.Mid(n,l) s.substr(n,l)
    MCD_STRASSIGN(s,p,n) s=CString(p,n) s.assign(p,n)
    MCD_STRCAPACITY(s) (((CStringData*)((MCD_PCSZ)s)-1)
    ->nAllocLength)
    (int)s.capacity()
    MCD_STRINSERTREPLACE(d,i,r,s) d.replace(i,r,s)
    MCD_GETBUFFER(s,n) s.GetBuffer(n) new MCD_CHAR[n+1]
    MCD_RELEASEBUFFER(s,p,n) s.ReleaseBuffer(n) s.assign(p,n); delete[]p
    MCD_BLDRESERVE(s,n) MCD_CHAR*pD=s.GetBuffer(n);
    int nL=0
    s.reserve(n)
    MCD_BLDCHECK(s,n,d) if(nL+d>n){
    s.ReleaseBuffer(nL);
    n<<=2;
    pD=s.GetBuffer(n);}
    MCD_BLDRELEASE(s) s.ReleaseBuffer(nL)
    MCD_BLDAPPENDN(s,p,n) MCD_PSZNCPY(&pD[nL],p,n);nL+=n s.append(p,n)
    MCD_BLDAPPEND(s,p) MCD_PSZCPY(&pD[nL],p);
    nL+=MCD_PSZLEN(p)
    s.append(p)
    MCD_BLDAPPEND1(s,c) pD[nL++]=(MCD_CHAR)(c) s+=(MCD_CHAR)(c)

    In the case where MFC MCD_STRINSERTREPLACE is not defined (CString doesn't have it), CMarkup uses MCD_GETBUFFER and MCD_RELEASEBUFFER with a memmove/memcpy implementation (see Markup.cpp).

     
     

    Question or comment about this article?

    ©Copyright 2008 First Objective Software, Inc. All rights reserved.