正拿着牛刀正砍 MFC 呢,来看看是不是很变态?
nbb01 2002-06-21 12:56:11 我以前用MFC写了一套监控系统,C/S模式,程序中的类封装都从CObject继承,
还大量用了MFC的链表,map等。此外,程序中的描述参数(矢量化的图形、系统的配置描述等),都序列化成MFC的文档。
现在,想在这套系统中支持B/S模式,即在intranet或internet上运行,具体设想是:server端运行IIS,同时运行我的后台服务(计划将我的后台写成NT的service),非实时内容用asp提供,实时内容由我的后台服务通过socket提供;客户端准备写一个ActiveX,嵌在IE中接收实时数据,以及完成同server交互。
现在问题来了:由于这套系统还在运行中,原来的参数结构不允许大幅度变更,原来的C/S模式要求继续保留,而要在internet上运行,用MFC写ActiveX肯定不行,否则要带一大堆DLL,没发用;server端的服务用MFC写也不合适吧。于是我准备用ATL来写,问题是,改写原来的代码,工作量巨大,同时,要保留原来的参数,以及MFC实现的RTTI等。
于是我研读了VC7中MFC和ATL的实现,发现microsoft已经将很多原MFC中的代码改写,可以在MFC和ATL中共用,同时ATL中也有了很多新的封装,如DC,PEN,Brush、各种链表等。我想,如果将MFC中的部分代码抠出来,将会在满足上面的条件下,实现新的模式。
于是乎,拿起牛刀,狂砍MFC......
目前,应该说大部分迁移基本完成,包括CObject及所需的类,MFC的RTTI、
序列化、动态生成、CArchive、CFile、部分链表等。
现在的疑惑是:
1. 这样做是不是很变态?我是不是正在做着前无古人,后无来者的工作?有没有更好的实现方法?
2.还有一个难点,我对迁移中CString的序列化总是不对(也就是对>>和<<的重载),可能是我对C++的template用法还不熟吧?哪位大虾帮着看看:
以下是MFC的实现
typedef ATL::CStringT< wchar_t, StrTraitMFC< wchar_t > > CStringW;
typedef ATL::CStringT< char, StrTraitMFC< char > > CStringA;
typedef ATL::CStringT< TCHAR, StrTraitMFC< TCHAR > > CString;
template< typename BaseType, class StringTraits >
CArchive& AFXAPI operator<<(CArchive& ar,
const ATL::CStringT<BaseType, StringTraits>& str)
{
AfxWriteStringLength(ar, str.GetLength(), sizeof(BaseType) == sizeof(wchar_t));
ar.Write(str, str.GetLength()*sizeof(BaseType));
return ar;
}
template< typename BaseType, class StringTraits >
CArchive& AFXAPI operator>>(CArchive& ar,
ATL::CStringT<BaseType, StringTraits>& str)
{
int nCharSize; // 1 = char, 2 = wchar_t
UINT nLength = UINT( AfxReadStringLength(ar, nCharSize) );
if (nCharSize == sizeof(char))
{
ATL::CTempBuffer< char > pszBufferA(nLength+1);
pszBufferA[nLength] = '\0';
UINT nBytesRead = ar.Read(pszBufferA, nLength*sizeof(char));
if (nBytesRead != (nLength*sizeof(char)))
AfxThrowArchiveException(CArchiveException::endOfFile);
str = pszBufferA;
}
else
{
ASSERT(nCharSize == sizeof(wchar_t));
ATL::CTempBuffer< wchar_t > pszBufferW( nLength+1 );
pszBufferW[nLength] = L'\0';
UINT nBytesRead = ar.Read(pszBufferW, nLength*sizeof(wchar_t));
if (nBytesRead != (nLength*sizeof(wchar_t)))
AfxThrowArchiveException(CArchiveException::endOfFile);
str = pszBufferW;
}
return ar;
}
以下是ATL的定义
#if !defined(_ATL_CSTRING_NO_CRT) && defined(_ATL_MIN_CRT)
#define _ATL_CSTRING_NO_CRT
#endif
#ifndef _ATL_CSTRING_NO_CRT
typedef CStringT< wchar_t, StrTraitATL< wchar_t, ChTraitsCRT< wchar_t > > > CAtlStringW;
typedef CStringT< char, StrTraitATL< char, ChTraitsCRT< char > > > CAtlStringA;
typedef CStringT< TCHAR, StrTraitATL< TCHAR, ChTraitsCRT< TCHAR > > > CAtlString;
#else // _ATL_CSTRING_NO_CRT
typedef CStringT< wchar_t, StrTraitATL< wchar_t > > CAtlStringW;
typedef CStringT< char, StrTraitATL< char > > CAtlStringA;
typedef CStringT< TCHAR, StrTraitATL< TCHAR > > CAtlString;
#endif // _ATL_CSTRING_NO_CRT
#ifndef _AFX
typedef CAtlStringW CStringW;
typedef CAtlStringA CStringA;
typedef CAtlString CString;
#endif
呵呵,够长了吧,劳您费眼了 :)
也不知道我这300分大餐,谁能吃到?
考,还不让放这么多,那就100分将就吧。