最近刚换一工作,开发工具使用VS2008,于是我得从前一个公司熟悉的VC6编程环境转换到vs2008,,首当其重视是unicode编码的注意事项。查了下windows核心编程,总结了一下多字节和宽字节之间的一些相互转换。
最近写一个接口,接口字符串参数全都都是用char*形式传入的,所以在我的unicode编译环境下,首先得把传入的多字节参数转换成宽字节
int WriteIniFile(const char* szFileName) { CONST TCHAR* pFileFullName = NULL; #ifdef UNICODE //传入的参数进行多字节到宽字节的转换 wchar_t* pWStr; int unicodeLen = MultiByteToWideChar(CP_ACP, 0, szFileName, -1, NULL, 0); pWStr = new wchar_t[unicodeLen+1]; memset(pWStr,0,(unicodeLen+1)*sizeof(wchar_t)); ::MultiByteToWideChar( CP_ACP, 0, szFileName, -1, (LPWSTR)pWStr, unicodeLen); pFileFullName = pWStr; #else pFileFullName = szFileName; #endif
/*。。。。。后面代码与转换无关,省略。。。。。。。*/
<pre name="code" class="cpp">#ifdef UNICODE <span> </span>SAFE_DEL_PTR(pFileFullName) #endif}
在使用COPY_DATA消息的时候,发送方编译环境是宽字节,接收方这边是多字节,接受到的消息转换为字符串就只有第一个字符。
考虑到发送消息方和接收消息方可能编译环境会改变,所以在接收方这边修改代码如下:
BOOL CMainTestDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct) { if (pCopyDataStruct->dwData == 0xff01) { TCHAR recvData[MAX_PATH] = {0} ; CString sCopyData; if(IsTextUnicode(pCopyDataStruct->lpData, pCopyDataStruct->cbData, NULL)) //消息为UNICODE编码 { #ifndef UNICODE char* pElementText; int iTextLen = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)pCopyDataStruct->lpData, -1, NULL, 0, NULL, NULL); pElementText = new char[iTextLen+1]; memset((void*)pElementText, 0, sizeof(char)*(iTextLen+1)); WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)pCopyDataStruct->lpData, -1, pElementText, iTextLen, NULL, NULL); sCopyData.Format("%s",pElementText); delete []pElementText; #else sCopyData.Format(_T("%s"),pCopyDataStruct->lpData); #endif } else //消息为ANSI编码 { #ifdef UNICODE int unicodeLen = ::MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pCopyDataStruct->lpData, -1, NULL, 0); wchar_t * pUnicode; pUnicode = new wchar_t[unicodeLen+1]; memset(pUnicode,0,(unicodeLen+1)*sizeof(wchar_t)); ::MultiByteToWideChar( CP_ACP, 0, (LPCSTR)pCopyDataStruct->lpData, -1, (LPWSTR)pUnicode, unicodeLen); sCopyData.Format(_T("%s"), pUnicode); delete []pUnicode; #else sCopyData.Format("%s",pCopyDataStruct->lpData); #endif } MessageBox(sCopyData); } return CDialog::OnCopyData(pWnd, pCopyDataStruct); }
考虑到转换占代码行数太多,于是打算将转换写成几个函数,刚好在查阅多字节和宽字节转换的时候百度到一个哥们封装的函数
以下代码转自 http://www.cnblogs.com/gakusei/articles/1585211.html
1. ANSI to Unicode wstring ANSIToUnicode( const string& str ) { int len = 0; len = str.length(); int unicodeLen = ::MultiByteToWideChar( CP_ACP, 0, str.c_str(), -1, NULL, 0 ); wchar_t * pUnicode; pUnicode = new wchar_t[unicodeLen+1]; memset(pUnicode,0,(unicodeLen+1)*sizeof(wchar_t)); ::MultiByteToWideChar( CP_ACP, 0, str.c_str(), -1, (LPWSTR)pUnicode, unicodeLen ); wstring rt; rt = ( wchar_t* )pUnicode; delete pUnicode; return rt; } 2. Unicode to ANSI string UnicodeToANSI( const wstring& str ) { char* pElementText; int iTextLen; // wide char to multi char iTextLen = WideCharToMultiByte( CP_ACP, 0, str.c_str(), -1, NULL, 0, NULL, NULL ); pElementText = new char[iTextLen + 1]; memset( ( void* )pElementText, 0, sizeof( char ) * ( iTextLen + 1 ) ); ::WideCharToMultiByte( CP_ACP, 0, str.c_str(), -1, pElementText, iTextLen, NULL, NULL ); string strText; strText = pElementText; delete[] pElementText; return strText; } 3. UTF-8 to Unicode wstring UTF8ToUnicode( const string& str ) { int len = 0; len = str.length(); int unicodeLen = ::MultiByteToWideChar( CP_UTF8, 0, str.c_str(), -1, NULL, 0 ); wchar_t * pUnicode; pUnicode = new wchar_t[unicodeLen+1]; memset(pUnicode,0,(unicodeLen+1)*sizeof(wchar_t)); ::MultiByteToWideChar( CP_UTF8, 0, str.c_str(), -1, (LPWSTR)pUnicode, unicodeLen ); wstring rt; rt = ( wchar_t* )pUnicode; delete pUnicode; return rt; } 4. Unicode to UTF-8 string UnicodeToUTF8( const wstring& str ) { char* pElementText; int iTextLen; // wide char to multi char iTextLen = WideCharToMultiByte( CP_UTF8, 0, str.c_str(), -1, NULL, 0, NULL, NULL ); pElementText = new char[iTextLen + 1]; memset( ( void* )pElementText, 0, sizeof( char ) * ( iTextLen + 1 ) ); ::WideCharToMultiByte( CP_UTF8, 0, str.c_str(), -1, pElementText, iTextLen, NULL, NULL ); string strText; strText = pElementText; delete[] pElementText; return strText; }