| |
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).
| |