MFC工程转Win32总结Word格式文档下载.docx
- 文档编号:17397442
- 上传时间:2022-12-01
- 格式:DOCX
- 页数:24
- 大小:247.48KB
MFC工程转Win32总结Word格式文档下载.docx
《MFC工程转Win32总结Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《MFC工程转Win32总结Word格式文档下载.docx(24页珍藏版)》请在冰豆网上搜索。
2)ASSERT是MFC的,可以用小写的assert替代,要包含#include<
assert.h>
3)“_T”:
找不到标识符,添加头文件tchar.h
4)LPCSTR:
找不到标识符,添加头文件windows.h
5)VERIFY:
改成assert
例如:
VERIFY(FindClose(hFind));
--》
BOOLbRet=FindClose(hFind);
assert(bRet);
6)AfxIsValidAddress改为CString头文件中的IsValidAddress
AfxIsValidAddress改为CString头文件中的IsValidAddress
7)TRY...CATCH....换为try...catch...
(5)新建一个mfc工程和一个win32工程,对比一下testwin32.vcxproj文件,对比testwin32.rc文件,参照区别手动修改,以win32工程为准
2、网络库头文件的包含问题
1>
c:
\programfiles\microsoftsdks\windows\v7.0a\include\winsock2.h(1619):
errorC2375:
“closesocket”:
重定义;
不同的链接
c:
\programfiles\microsoftsdks\windows\v7.0a\include\winsock.h(752):
参见“closesocket”的声明
\programfiles\microsoftsdks\windows\v7.0a\include\winsock2.h(1638):
“connect”:
\programfiles\microsoftsdks\windows\v7.0a\include\winsock.h(754):
参见“connect”的声明
\programfiles\microsoftsdks\windows\v7.0a\include\winsock2.h(1659):
“ioctlsocket”:
\programfiles\microsoftsdks\windows\v7.0a\include\winsock.h(759):
参见“ioctlsocket”的声明
\programfiles\microsoftsdks\windows\v7.0a\include\winsock2.h(1680):
“getpeername”:
\programfiles\microsoftsdks\windows\v7.0a\include\winsock.h(764):
参见“getpeername”的声明
但凡在Windows平台下用C++做网络开发很多时候都会同时包含这两个头文件,如若顺序不当(windows.h先于winsock2.h)就会出现很多莫名其妙的错误。
要注意先后顺序,如下:
winsock2.h>
3、MFC的CImage文件引起的CString不明确的问题
e:
\svn_dir\20140519_truelink_v2r6_sp1\90-truelink\common\include\picture.h(40):
errorC2872:
“CImage”:
不明确的符号
可能是“e:
\svn_dir\20140519_truelink_v2r6_sp1\90-truelink\kdvp_pcmtim\minimfc\include\cimage.h(85):
CImage”
或“d:
\programfiles\microsoftvisualstudio10.0\vc\atlmfc\include\atlimage.h(68):
ATL:
:
CImage”
\svn_dir\20140519_truelink_v2r6_sp1\90-truelink\common\include\imtcpicmanager.h(36):
“CString”:
\svn_dir\20140519_truelink_v2r6_sp1\90-truelink\kdvp_pcmtim\minimfc\include\cstring.h(33):
CString”
是因为使用到CImage的地方包含了mfc的atlimage.h的头文件,而atlimage.h中包含了atlstr.h的头文件,所以出现CImage和CString不明确的符号的问题。
所以不能包含atlimage.h,minimfc中既实现了CString,也实现了CImage,直接包含minimfc.h即可。
4、duilib包含minimfc.h头文件问题
(1)duilib中使用到了CImage,改为依赖minimfc,会出现Cimage不明确问题。
包含的是atlimage.h,将值改为cimage.h后,CString还是不明确。
(2)是因为duilib中使用到了atl中的CTime,包含了atltime.h,这个头文件又包含了atlstr.h即atl的CString的头文件,所以出现CString不明确问题。
Minimfc中也实现了CTime,所以不用使用ATL的CTime。
(3)但是CImage还会报错,因为stdafx.h中包含了uilib.h,后包含了minimfc.h,应该将顺序调整一下,先包含minimfc.h。
5、ATL的CString与MFC的CString区别
(1)ATL的CString对应的是atlstr.h头文件:
D:
\ProgramFiles\MicrosoftVisualStudio10.0\VC\atlmfc\include\atlstr.h,定义如下:
#ifndef_ATL_CSTRING_NO_CRT
typedefCStringT<
wchar_t,StrTraitATL<
wchar_t,ChTraitsCRT<
wchar_t>
>
CAtlStringW;
char,StrTraitATL<
char,ChTraitsCRT<
char>
CAtlStringA;
TCHAR,StrTraitATL<
TCHAR,ChTraitsCRT<
TCHAR>
CAtlString;
#else//_ATL_CSTRING_NO_CRT
#endif//_ATL_CSTRING_NO_CRT
#ifndef_AFX
typedefCAtlStringWCStringW;
typedefCAtlStringACStringA;
typedefCAtlStringCString;
(2)MFC的CString对应的是afxstr.h头文件:
\ProgramFiles\MicrosoftVisualStudio10.0\VC\atlmfc\include\afxstr.h,定义如下:
#endif//_MFC_DLL_BLD
typedefATL:
CStringT<
wchar_t,StrTraitMFC_DLL<
CStringW;
char,StrTraitMFC_DLL<
CStringA;
TCHAR,StrTraitMFC_DLL<
CString;
#else
wchar_t,StrTraitMFC<
char,StrTraitMFC<
TCHAR,StrTraitMFC<
#endif//!
_WIN64&
&
_AFXDLL
(3)由于两种CString的实现都在头文件中,即函数的实现都放在类的头文件中,所以可以直接包含头文件来引用。
这两种CString的相互关系可以参考如下的链接:
6、静态变量定义执行先后顺序问题
(1)相关说明
1)进程启动后,要执行一些初始化代码(如一些全局及静态变量的空间分配和赋初值、全局及静态对象的构造等等),然后跳转到相关main函数执行。
2)对于MFC工程,如果要看从初始化的操作,到main函数的执行,到CWinThread如何将App的InitInstance、Run与win32的工程的执行步骤对应起来的(窗口类的注册、窗口的创建、消息循环读取并分发消息),直接在App的InitInstance中添加断点,然后调试运行查看调用堆栈即可看出。
(2)问题说明并解决
1)但是多个静态对象都存在时,在构造时,由于相互的依赖关系,必须要有个先后顺序,否则可能会产生异常。
2)通过调试运行发现,duilib中的CSkinShadow类定义了CImage静态对象,运行时会优先于CImage:
s_initGDIPlus,进入CImage的构造函数,进而调用s_initGDIPlus.IncreaseCImageCount函数,访问到未经初始化的关键代码段对象m_sect,从而引起崩溃。
由于都是静态变量定义,执行的先后顺序无法预料,正是CSkinShadow类定义了CImage静态对象定义先执行,CImage:
s_initGDIPlus的定义后执行,导致上面的问题。
所以要保证代码正常执行,要使CImage:
s_initGDIPlus的定义先执行。
所以此处参考MFC中的处理办法,使用#pragmainit_seg(lib),保证先执行。
3)MFC中的Cimage类的代码都放置在对应的头文件中,即成员函数都以内联的方式放置在头文件中。
Cimage类中使用到两个static对象,在头文件中只有声明,好像找不到静态对象的定义。
在构造函数中打上断点,通过查看调用堆栈,找到了定义处,也找到了本问题的解决办法:
#include"
StdAfx.H"
#pragmawarning(disable:
4073)//initializersputinlibraryinitializationarea
namespaceATL
{
#pragmainit_seg(lib)
CImage:
CDCCacheCImage:
s_cache;
};
//namespaceATL
使用了#pragmainit_seg(lib),就能保证CImage:
s_cache的构造在CImage对象构造之前构造,保证了构造顺序,从而能够正常执行。
相关代码及注释如下所示:
(3)MFC源码查看
如果直接能Go过去就比较好。
如果Go不过去如何查看呢?
通过添加断点,查看调用堆栈。
如果是一个类的话,要查看CPP相关源码,可以先定义一个对象,通过构造时要调用构造函数的特性,在构造的语句上添加断点,查看调用堆栈,进入对应的CPP文件,进而找到相关的函数实现。
7、友元函数也需要导出
(1)minimf工程从VC6的MFC中抽出了CString类,类中定义了友元函数,是重载了加号操作符,重载函数就是友元函数,如下所示:
friendCStringAFXAPIoperator+(constCString&
string1,
constCString&
string2);
string,TCHARch);
friendCStringAFXAPIoperator+(TCHARch,constCString&
string);
#ifdef_UNICODE
string,charch);
friendCStringAFXAPIoperator+(charch,constCString&
string,LPCTSTRlpsz);
friendCStringAFXAPIoperator+(LPCTSTRlpsz,constCString&
但在外部调用时,即
CStringstrTest=strPath+strName;
链接时提示错误,找不到operate+函数。
(2)友元用的比较少,后经查阅资料才知道,友元函数是可以直接访问类的私有成员的非成员函数。
它是定义在类外的普通函数,它不属于任何类,但需要在类的定义中加以声明,声明时只需在友元的名称前加上关键字friend。
类似于全局函数,外部如果要使用需要单独导出(虽然CString类导出了,但是友元函数不属于类,所以需要单独导出)。
所以上述函数都是要导出的。
8、updateinstall在链接libminimfc库时老是出现无法解析的外部符号的问题
是因为链接路径弄错了,导致链接的是老的libminimfc.lib库,出现链接异常问题。
9、去除changelang对minimfc的依赖,尽量使changelang独立
(1)尽量减少库与库之间的耦合,之前处理imageoleex工程时也是这么个想法,能做到相互独立的,尽量做到相互独立,不相互依赖。
(2)工程中使用到了两个MFC类:
CString和CFile类,对于CString直接使用stl的string类替换;
对于CFile,则使用API替换,具体API的参数设置,可参见CFile相关函数内部实现。
1)使用stl的string:
string>
usingnamespacestd;
typedefwstringtstring;
typedefstringtstring;
在使用时,调用c_str()函数来得到LPCTSTR类型的数据。
再就是string不支持format格式化,可以使用C函数_stprintf()来格式化。
2)用API函数替换CFile:
(之所以替代CFile,目的是不想依赖minimfc库)
HANDLEhFile=:
CreateFile(strPathName.c_str(),GENERIC_READ,0,NULL,
OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if(hFile==INVALID_HANDLE_VALUE)
{
returnFALSE;
}
DWORDdwSize;
dwSize=:
GetFileSize(hFile,NULL);
u8*pBuf=newu8[dwSize];
DWORDdwReadBytes=0;
:
ReadFile(hFile,pBuf,dwSize,&
dwReadBytes,NULL);
if(dwReadBytes==0)
delete[]pBuf;
CloseHandle(hFile);
:
(3)在添加stl的string的头文件包含后,出现如下的错误:
对于extent,有两处都定义了,出现冲突。
在zip.cpp中,定义了:
typedefsize_textent;
解决办法有两种:
1)直接将zip.cpp中的extent类型直接换成size_t;
2)是stdafx.h中包含了#include<
引起的,由于zip.cpp是开源拷贝过来的文件,不需
要包含stdafx.h,所以可以在工程中设置:
.c(或.cpp)文件点右键选择Properties,在PrecompiledHeaders项下设置NotUsingPrecompiledHeaders即可,如下所示:
具体原理说明参见:
(4)pcdvdll使用stl的string/wstring引起的TL的崩溃(2014/08/08)
1)需要将pcdvdll改造成win32的工程,但其中使用到了CString类,为了不引入对minimfc的依赖,让pcdvdll尽量独立,决定使用stl的string/wstring。
修改了一些全局函数的返回值为tstring,结果就是因为这样引起了pcdvdll的崩溃,从而引起TL的崩溃。
如下所示:
tstringGetPcdvEventName(u16wEvent);
tstringGetErrorCodeDes(u16wError);
2)在使用string中存放的字符串内容时,都要调用.c_str()方法。
一般我们不会逐一去检查,而是通过编译器去检查(参数类型检查),如有问题则会报错,在报错的地方去修改。
但是对于使用可变长参数的函数,则不进行类型检测,如果直接调用,则可能引起崩溃。
Pcdvdll的崩溃代码如下:
voidCMtInst:
NotifyUI(u16wMsg)
HWNDhWnd=g_cMtSsn.GetMainWnd();
if(hWnd!
=NULL&
IsWindow(hWnd))
dvPrint("
[NotifyUI]msg%s(%d),errcode=%d(%s),len=%d\n"
OspEventDesc(wMsg),
wMsg,
g_cUIMsg.GetErrorCode(),
GetErrorCodeDes(g_cUIMsg.GetErrorCode()),
g_cUIMsg.GetMsgBodyLen());
SendMessage(g_cMtSsn.GetMainWnd(),wMsg,(WPARAM)&
g_cUIMsg,NULL);
//清空缓存
g_cUIMsg.SetMsgBody();
}
}
voidCPcdvCfg:
SendMsgToMtSsnDaemon(u16wEvent,constu8*constpbyMsg,u16wLen)
dvPrint("
[CPcdvCfg:
SendMsgToMtSsnDaemon]wEvent%s(%d),wLen=%d\n"
GetPcdvEventName(wEvent),wEvent,wLen);
OspPost(MAKEIID(AID_MT_PCDUALVIDEO,CInstance:
DAEMON),wEvent,pbyMsg,wLen);
voiddvPrint(s8*pszFmt,...)//可变长参数,不进行类型检测
s8achPrintBuf[255];
s32nBufLen=sprintf(achPrintBuf,"
[dvPrint]"
);
va_listtArgptr;
va_start(tArgptr,pszFmt);
vsprintf(achPrintBuf+nBufLen,pszFmt,tArgptr);
va_end(tArgptr);
if(g_cMtSsn.IsPrintf())
OspPrintf(TRUE,FALSE,achPrintBuf);
dvLog(achPrintBuf);
所以,在使用到stl的string的工程中,一方面通过编译器去检测,另一方要特别小心可变长参数的函数,要对
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- MFC 工程 Win32 总结