??xml version="1.0" encoding="utf-8" standalone="yes"?>
http://www.codediscuss.com
]]>
下面的代码,当用AfxBeginThread开始一个线E时Q实际上是有内存泄漏?/p>
Q : | MFCq回的时对象指针成? | ||
主要解答? | QunKangLi | 提交? | QunKangLi |
感谢: | oldforest、yu_hl、QunKangLi | ||
审核? | happyparrot | C对应贴子: | 查看 |
A : | |||
msdn在介lGetDlgItem的时候,明确指出Q? The returned pointer may be temporary and should not be stored for later use. 如果真是q样那我不惨了!在我的一个Y件中Q因为常常要使切换按钮的可用与不可用以及改变按钮文字Q所以我用DetDlgItem把它们存了v来,用的时候直接到数组里面取,q样的话q个软g不是犯了一个重大的错误了?可是用这么久也没出错? 另外Q它也是说可能是临时的,那一定在某种情况下不是时的Q高手能不能解释一下这个问题? --------------------------------------------------------------- // Most Windows objects are represented with a HANDLE, including // the most important ones, HWND, HDC, HPEN, HFONT etc. // We want C++ objects to wrap these handle based objects whenever we can. // Since Windows objects can be created outside of C++ (eg: calling // ::CreateWindow will return an HWND with no C++ wrapper) we must // support a reasonably uniform mapping from permanent handles // (i.e. the ones allocated in C++) and temporary handles (i.e. // the ones allocated in C, but passed through a C++ interface. // We keep two dictionaries for this purpose. The permanent dictionary // stores those C++ objects that have been explicitly created by // the developer. The C++ constructor for the wrapper class will // insert the mapping into the permanent dictionary and the C++ // destructor will remove it and possibly free up the associated // Windows object. // When a handle passes through a C++ interface that doesn't exist in // the permanent dictionary, we allocate a temporary wrapping object // and store that mapping into the temporary dictionary. // At idle time the temporary wrapping objects are flushed (since you better // not be holding onto something you didn't create). // 在CWinThread::OnIdle里调用AfxUnlockTempMapsQAfxUnlockTempMaps会释放temporary maps. 所以不要保留GetDlgItem{返回的临时指针Q可以直接保存HWND objectsQ然后CWnd::FromHandle获取临时指针来用? --------------------------------------------------------------- 临时包装对象会在I闲旉删除.在同一函数中多ơ用是没用问题?不同函数中用先前保存下来的指针有可能出错,特别是对话框初化时候存下来的指? 在MFC层次上的函数使用CWnd对象,而本地Windows代码(API)使用句柄.?当Windowspȝ调用一个窗口过E时传递一个HWND参数,而MFC本n的消息机制用CWndc?Z更好更高效的实现,MFC需要与Windowspȝ合作,句柄与CWnd对象q行兌---它用CHandleMap完成兌. CHandleMap有两个CMapPtrToPtr的成员变?m_permanentMap(怹映射?E序q行q程中对?句柄之间的关p?,m_temporaryMap(临时映射?在消息存在的q程中才存在).怹表保存显式创建的CWnd对象,当对象创建时在怹目录下插入一个条?在CWnd::OnNcDestrory时删除对应条?但是Windows有时会传入某些不是由开发h员显式创建的H口的句?此时MFC会分配一个时对象来包装q个句柄q将它们的映保存到临时映射表中,q些临时对象会在I闲旉被删除ƈU走相应的时映表条目.cM的MFC对象与Windows句柄的映表? m_pmapHWND: H口句柄与CWnd对象 m_pampHMENU: 菜单句柄与CMenu对象 m_pmapHDC: 讑֤环境句柄与CDC对象 m_pmapHGDIOBJ: GDI句柄与CGDI对象 m_mapHIMAGELIST: 囑փ链表句柄到CImageList对象 当给定句?如HWND?MFC单调用CWnd* PASCAL CWnd::FromHandle(HWND hWnd), 此函数内部用CHandleMap::FromHandle(hWnd)获取相关联的CWnd对象.在CHandleMap::FromHandle(h)内部(源代码在WinHand.cpp),先用CObject* pObject = LookupPermanent(h); if (pObject != NULL)return pObject; 查永久表;如永久表中不存在,使用pObject = LookupTemporary(h)) != NULL查时表,都不存在?使用pTemp = = m_pClass->CreateObject();if (pTemp == NULL)AfxThrowMemoryException();m_temporaryMap.SetAt((LPVOID)h, pTemp);创徏临时对象q将其插入到临时表中?同时q回该时对? void CHandleMap::RemoveHandle(HANDLE h)的注释说明时对象将在空闲时由O(jin)nIdel释放: // remove only from permanent map -- temporary objects are removed // at idle in CHandleMap::DeleteTemp, always! 如果想不自动释放临时对象,使用void AFXAPI AfxLockTempMaps()/BOOL AFXAPI AfxUnlockTempMaps(BOOL bDeleteTemps)q行锁定. |
如果不是unicode,某些中文字符会在不同?/span>codepage上出Cؕ?/span>;如果当前codepage为韩文时,某些中文字会变成韩文的样?/span>,奇?/span>.
宏定?/span>UNICODE, _UNICODE定义两个也可?/span>,定义一个也可以,windows的头文g会保证两个都会被定义.
比如
char -> TCHAR
但是
,q不是说所有的charcd都不能用?/span>.如果需要用,q且函数的参?/span>/q回g么的都不冲突,charcdq是可以用的.
"
abc
" -> _T("
abc
")
因ؓ开始写E序时没有注?/span>
,造成q样的常量字W串形式非常?/span>,一个个改v来很?/span>,我写了个插?/span>,可以?/span>
?/span>
abc
?/span>
选中后点一?/span>
buttonp变成_T(
?/span>
abc
?/span>
),有点?/span>,代码也非常的?/span>.
比如atoi -> _ttoi
在这里遇C个问?/span>,是atof的替?/span>.
按照msdn, atof应该?/span>_ttof替换
TCHAR.H routine
|
_UNICODE & _MBCS not defined
|
_MBCS defined
|
_UNICODE defined
|
_tstof
|
atof
|
atof
|
_wtof
|
但是奇怪的?/span>,VC6里面不认?/span>_tstofq个函数,VC.net 2003可?/span>.
有两个解决的办法:
1) 因ؓatof只是替换为QҎ(gu),所以这里用WideCharToMultiByte转化一下之后再调用atof也是可行?/span>
2) 呵呵,?/span>strtod的替换函?/span>_tcstod,哈哈,当然参数要变一?我觉得这个方法不?不要被msdn限制M
因ؓ目q用了另外一?/span>dll,其中有些接口需?/span>char*参数,q个时候就必须?/span>WideCharToMultiByte转换一下了.
VC里面的设|?
1) {把所有的~译error改完了之后一~译,除了个link错误,不过msdn有解?
If you are using Unicode and MFC, you will get an unresolved external on _WinMain@16 if you don’t create an entrypoint to wWinMainCRTStartup. Use the /ENTRY option or type this value in the Project Settings dialog box. (To find this option in the development environment, click Settings on the Project menu, then click the Link tab, and click Output in the Category box.)
2)l于~译成功?调试的时候却发现CString的g能在QuickWatchH口中显CZ
tools->option->
in the debug tab u can find a check box Labeled "Display unicode strings"
Check it.
在?/span>dll的时?/span>,需要直接?/span>dll中的一个变?/span>,?/span>CStringcd,因ؓq个dllq没有改?/span>unicode,所以在直接使用其变量时有点问题,使得g?/span>.(是不是这个原因还没有完全验证,应该是的)
/*补充Q?br />l果是失败,但是基本UL代码的所有步骤都有了。而且Q也指出了如果需要调用的dll不是unicodeQ每ơ调?传递参数时Q都要{换,很烦?br />后来我把dll的代码也UL了下Q现在运行的很好Q韩文、中文都可以昄Q不你当前语言是什么?br />*/
q有一讲UL步骤?更全?适合更复杂的情况:
Cheat Sheet:Unicode-enabling Microsoft C/C++ Source Code (http://www.i18nguy.com/unicode/c-unicode.html)
现在好了Q自己写了个E序Q快速切换:当前是右手习惯就换到左手习惯Q反之换到右手习?br />E序很小Q只?行代码:
但是看文章的样子Q也不像是粗制滥造的Q心里很是疑惑?BR>后来再打开VC7的源码看Q果Ӟ
看来微Y在不知不觉中做了q么大的变化?BR>
2
“string是方便的Q可以从几乎所有的字符串构造而来Q包括CString和char*Q?nbsp;
CStringơ之Q可以从基本的一些字W串变量构造而来Q包括char*{; ?BR>的确Q如下的代码是可以编译的Q?BR>
但是q是表明string比CString方便吗?
实际上,在string sTest(strTest);中有一个函数被调用Q就是:
然后才是string构造生成,q能说是string比CString方便吗?应该说是CString比string方便才好?BR>虽然可以?BR>
来初始化CStringQ但是CString没有参数为string的构造函敎ͼ也是一个小的遗憾Q毕竟string是c++标准库的一部分了?/STRONG>
遇到好几个h说CMap在用CString做keycd时有问题Q说用int和DWORD可以,用CString׃行。因此很多h推荐使用MFC中的CMapStringToPtr之类?/p>
看下面的代码Q?br />//.h
CMap<CString, LPCTSTR, int, int> typeMap;
//.cpp
typeMap.SetAt(_T("ONE"),1);
typeMap.SetAt(_T("TWO"),2);
int nValue = 0;
BOOL ret = typeMap.Lookup(_T("ONE"), nValue);
ret = typeMap.Lookup(_T("THREE"), nValue);
ret = typeMap.Lookup(_T("TWO"), nValue);
我的代码q行的很好,我觉得关键是ARG_KEY要选LPCTSTR