EVC下UNICODE的字符串的输出问题

在开发PDA的测图系统中,EVC下的字符串的输出问题困扰了我好几天,在查阅网上相当一部分资料后,总算找到了个解决之道,但今天发现中文字符串却又出现问题,研究了一个下午,弄出了一个比较笨的方法,虽然效率不算高,但目前本人只能想到这样了。 以下是从网上摘抄资料EVC在某种意义上说,相当于VC的一个子集。因为大多EVC有的功能,VC也具备,而VC有的功能,EVC则不一定拥有。在VC中,操作字符串很方便,因为WINDOWS的字处理能力实在是很强大,它支持多种字符集。我们随便使用一个CString str=“你好”,就要以输入我们想要的中文字符串。在EVC中这种情况有所改变,因为WINCE的字处理能力不够强大,它在处理汉字里统一将它示为UNICODE编码,所以我们在EVC中片理中文字符串时需要用到UNICODE编码。下面结合WINDOWS 下VC字符串的处理,对比一下EVC中文字符串的片理方法。一、中文字符串定义1、在VC中我们如果定义一个中文字符串,可以使用CString str=“你好”或LPCTSTR str=“你好”。2、在EVC中我们如果想定义一个中文字符串,可以使用如下方法:CString str=_T(“你好”)或者LPCTSTR str=“你好”,这里LPCTSTR在EVC里就是表示UNICODE字符串。值得注意的是_T()宏中,括号中只能填写常量,不能填定变量。二、字符串操作1、在VC中我们想拷贝字符串,可以作如下操作:char s[20];CString str=“你好”;strcpy(s,str);在EVC中则不能这样做,首先定义中文数组应该用双字节指针wchar_t,而拷贝函数也不能用strcpy,而应该用:wchar_t * wcscpy(wchar_t * wDest,wchar_t wSource);函数,操作如下:wchar_t s[20];CString str=“你好”;wcscpy(s,(LPCTSTR)str); //前面没有转成UNICODE编码,所以这里需要强制转换2、在VC中我们想在一个字符串中查找某个子串,只需要作下面的操作:CString str=“你是一个好学生”;str.Find(“学生”);在EVC中不能这样做,因为中文字符串为UNICODE编码,我们必需在查找函数的参数里作如下修改:str.Find(_T(“学生”));了解上述基本知识后,先说说我的情况吧,本人的系统由于是个测图系统,设计到点线面的坐标存储和注记(也就是文本)的存储,因为要把已经有的二进制数据存为明码TXT文件,要进行文件操作,本人采用的WIN32的文件操作函数HANDLE hHandle =CreateFile(FileName,GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);CString str=L"LineBegin";WriteFile(hHandle,str,str.GetLength()*sizeof(TCHAR),&cb,NULL);注意上面的函数,str.GetLenth()*sizeof(TCHAR),因为unicode环境下是用的宽字符,写入的时候要占用双倍的空间,上面的函数本人在向文件写入数字和英文字符串时效果很好,运行也OK。但是在写入汉字时却发现生成的文件中汉字部分全市乱码,且原来格式优美的文本全成了每个字符之间都有一个小空格的情况。上网找了很多资料,原来EVC下向文件写入中文时必须得把宽字符变成普通的ANSI的字符,采用WideCharToMultiByte()函数能够很好的实现,用该函数将宽字符转换为普通的ANSI字符,不管是中文还是英文抑或是中英混合的都可以很好的写入文件。做到这一步,着实把本人高兴了一番,以为问题解决了,可运行程序发现,离成功的道路还很远啊,问题又出现了,因为程序中已经将很多非中文字符串的写入语句都写好了,都是采用的原先的将字符串长度乘以TCHAR的大小实现的,然后再加入后面转换后的中文字符串,发现文本格式还是乱套,虽然没出现乱码,但那格式还是出现那种每个字符间都有个小空格,这让别的程序读取那明码文件肯定会出现问题的。总结了下,也就是说EVC向TXT文件写入字符串时,不能同时写入UNICODE和ANSI字符咯,不知道是否这样。但本人在程序中却发现有点问题很诡异,一直也没弄明白其中缘故。CString str = L"剑张三丰张放房间打扫test" ;WriteFile(hHandle,str,str.GetLength()*sizeof(TCHAR),&cb,NULL);以上两行代码却能将上面的字符串很方便的写入TXT文件中,且格式正确也没有乱码,如果str变量全是汉字的话却又成了乱码,如果中文字符很多的话也变成了乱码,郁闷。这个问题害得我今天比较两个程序费了不少时间。最后实在没有办法,看样子只能把所有的字符都转为ANSI格式了,代码看样子得全改了,又要忙了,这个该死的EVC害死我了!void WriteString(HANDLE hHandle,CString str){//int len=str.GetLength();//wchar_t *wchar;//char* s;wchar_t wchar[40];char s[40];DWORD cb;wcscpy(wchar,str);int nLen=wcslen(wchar)+1;int len=WideCharToMultiByte(CP_ACP,0,wchar,-1,s,2*nLen,NULL,NULL);WriteFile(hHandle,s,len-1,&cb,NULL);}利用该函数就能方便的将一切格式的UNICODE字符转换为ANSI的了,明天开工。注:以上函数代码都是在VS2005 VC++开发智能设备MFC程序中运行通过转自:http://blog.sina.com.cn/s/blog_4c8b1bdd0100a8sj.html------------------------------------------------------------------------------------------《MultiByteToWideChar和WideCharToMultiByte用法详解》在进行ce的开发时,经常设计到字符的转换,特别是系统中包含网络通讯时,更是如此。ce中均是Unicode编码,而网络通讯一般都使用BYTE进行数据传输。以下是在网上找到的一篇文章,介绍的很详细。1.使用方法详解在本文开始之处,先简要地说一下何为短字符和宽字符.所谓的短字符,就是用8bit来表示的字符,典型的应用是ASCII码.而宽字符,顾名思义,就是用16bit表示的字符,典型的有UNICODE.关于windows下的ASCII和UNICODE的更多信息,可以参考这两本经典著作:《windows 程序设计》,《windows 核心编程》.这两本书关于这两种字符都有比较详细的解说.宽字符转换为多个短字符是一个难点,不过我们只要掌握到其中的要领,便可如鱼得水.好吧,那就让我们开始吧.这个是我们需要转化的多字节字符串: char sText[20] = {"多字节字符串!OK!"};我们需要知道转化后的宽字符需要多少个数组空间.虽然在这个里程里面,我们可以直接定义一个20*2宽字符的数组,并且事实上将运行得非常轻松愉快.但假如多字节字符串更多,达到上千个乃至上万个,我们将会发现其中浪费的内存将会越来越多.所以以多字节字符的个数的两倍作为宽字符数组下标的声明绝对不是一个好主意.所幸,我们能够确知所需要的数组空间.我们只需要将MultiByteToWideChar()的第四个形参设为-1,即可返回所需的短字符数组空间的个数:DWORD dwNum = MultiByteToWideChar (CP_ACP, 0, sText, -1, NULL, 0);接下来,我们只需要分配响应的数组空间:wchar_t *pwText;pwText = new wchar_t[dwNum];if(!pwText){ delete []pwText;}接着,我们就可以着手进行转换了.在这里以转换成ASCII码做为例子:MultiByteToWideChar (CP_ACP, 0, psText, -1, sText, dwSize);最后,使用完毕当然要记得释放占用的内存:delete []psText;同理,宽字符转为多字节字符的代码如下: wchar_t wText[20] = {L"宽字符转换实例!OK!"};DWORD dwNum = WideCharToMultiByte(CP_OEMCP,NULL,lpcwszStr,-1,NULL,0,NULL,FALSE);char *psText;psText = new char[dwNum];if(!psText){ delete []psText;}WideCharToMultiByte (CP_OEMCP,NULL,lpcwszStr,-1,psText,dwNum,NULL,FALSE);delete []psText; 如果之前我们已经分配好空间,并且由于字符串较短,可以不理会浪费的空间,仅仅只是想简单地将短字符和宽字符相互转换,那有没有什么简便的方法呢? WIN32 API里没有符合这种要求的函数,但我们可以自己进行封装: //-------------------------------------------------------------------------------------//Description:// This function maps a character string to a wide-character (Unicode) stringParameters:// lpcszStr: [in] Pointer to the character string to be converted // lpwszStr: [out] Pointer to a buffer that receives the translated string. // dwSize: [in] Size of the bufferReturn Values:// TRUE: Succeed// FALSE: Failed// //Example:// MByteToWChar(szA,szW,sizeof(szW)/sizeof(szW[0]));//---------------------------------------------------------------------------------------BOOL MByteToWChar(LPCSTR lpcszStr, LPWSTR lpwszStr, DWORD dwSize){ // Get the required size of the buffer that receives the Unicode // string. DWORD dwMinSize; dwMinSize = MultiByteToWideChar (CP_ACP, 0, lpcszStr, -1, NULL, 0); if(dwSize < dwMinSize) { return FALSE; } // Convert headers from ASCII to Unicode. MultiByteToWideChar (CP_ACP, 0, lpcszStr, -1, lpwszStr, dwMinSize); return TRUE;}//-------------------------------------------------------------------------------------//Description:// This function maps a wide-character string to a new character stringParameters:// lpcwszStr: [in] Pointer to the character string to be converted // lpszStr: [out] Pointer to a buffer that receives the translated string. // dwSize: [in] Size of the bufferReturn Values:// TRUE: Succeed// FALSE: Failed// //Example:// MByteToWChar(szW,szA,sizeof(szA)/sizeof(szA[0]));//---------------------------------------------------------------------------------------BOOL WCharToMByte(LPCWSTR lpcwszStr, LPSTR lpszStr, DWORD dwSize){ DWORD dwMinSize; dwMinSize = WideCharToMultiByte(CP_OEMCP,NULL,lpcwszStr,-1,NULL,0,NULL,FALSE); if(dwSize < dwMinSize) { return FALSE; } WideCharToMultiByte(CP_OEMCP,NULL,lpcwszStr,-1,lpszStr,dwSize,NULL,FALSE); return TRUE;}使用方法也很简单,示例如下:wchar_t wText[10] = {L"函数示例"};char sText[20]= {0};WCharToMByte(wText,sText,sizeof(sText)/sizeof(sText[0]));MByteToWChar(sText,wText,sizeof(wText)/sizeof(wText[0]));这两个函数的缺点在于无法动态分配内存,在转换很长的字符串时可能会浪费较多内存空间;优点是,在不考虑浪费空间的情况下转换较短字符串非常方便.2.MultiByteToWideChar()函数乱码的问题有的朋友可能已经发现,在标准的WinCE4.2或WinCE5.0 SDK模拟器下,这个函数都无法正常工作,其转换之后的字符全是乱码.及时更改MultiByteToWideChar()参数也依然如此.不过这个不是代码问题,其结症在于所定制的操作系统.如果我们定制的操作系统默认语言不是中文,也会出现这种情况.由于标准的SDK默认语言为英文,所以肯定会出现这个问题.而这个问题的解决,不能在简单地更改控制面板的"区域选项"的"默认语言",而是要在系统定制的时候,选择默认语言为"中文".系统定制时选择默认语言的位置于:Platform -> Setting... -> locale -> default language ,选择"中文",然后编译即可.转自:http://blog.youkuaiyun.com/Q_Jizi/archive/2009/02/25/3936629.aspxWideCharToMultiByte Function:http://msdn.microsoft.com/en-us/library/dd374130(VS.85).aspxMultiByteToWideChar Function:http://msdn.microsoft.com/en-us/library/dd319072(VS.85).aspx--------------------------------------------------------------------------------------《关于WinCE下通讯乱码及unicode转换》WinCE和WinNT一样,是UNICODE环境,尽管WinCE支持ASCII功能来进行文件交换,但是WinCE的本地文件格式是Unicode。所以,我们要将字符串转换为unicode才能使用。 在系统定义了_UNICODE 宏时,_T和TEXT宏都可以将一个ansi字符转换为一个宽字符的unicode字符。WideCharToMultiByte是将Unicode字符串转换为ASCII字符串,MultiByteToWideChar则相反。当WinCE和pc通信时,由于PC使用ASCII字符串在网络上传输,所以当Wince接收到内容时要转换为Unicode才能使用,而发送内容时,要转换为ASCII字符才能发送。那么如何判断转化后的字符大小呢?只要将这两个函数中的转换后的大小设为0,那么函数就会返回转换后的实际大小,然后利用这个返回值再调用这两个函数就可以实现转换了。WinCE还提供了几种专门用于Unicode字符的数据类型,如WCHAR,LPWSTR,LPCWSTR,对于ANSI字符函数如strcpy,strcmp等,WinCE提供了 wcscpy,wcscmp等于之对应。 纵所周知,WindowsCE下编程99%的问题都和Unicode有关.比如文件编辑,一般都保存为Ansi格式;无线通讯中控制Modem需要发送的 AT指令,必须是Ansi格式;网络通讯中,PC端一般都是Ansi的,为了和PC上协议兼容,在WindowsCE中必须把要发送的一个指令从 Unicode 转换成Ansi格式...等等.很多初学者对于这些问题总是感到很麻烦.其实WindowsCE中有标准的API实现了Unicode和Ansi字符间的互转. 在实际测试UDP接收过程中发现,可以通过两种方式: 1。通过CString str=buf,CString内部即可完成转换。 2。通过MultiByteToWideCharDWORD dwNum = MultiByteToWideChar (CP_ACP, MB_COMPOSITE, (char*)buf, -1, NULL, 0); wchar_t *pwText; pwText = new wchar_t[dwNum]; if(!pwText) { delete []pwText; } MultiByteToWideChar(CP_ACP,MB_COMPOSITE,(char*)buf,-1,pwText,dwNum); ::MessageBox(NULL,pwText,_T("Recvd:"),MB_OK);delete []pwText;//例子///发送函数片断void CClient1Dlg::OnButtonSend(){ // TODO: Add your control notification handler code here if (!m_psocket) //无Socket连接,退出 { MessageBox(TEXT("无连接!"),TEXT("信息")); return; } UpdateData(TRUE); //保存输入的字符串到m_snd unsigned char buf[129]; //发送缓冲区 ZeroMemory(buf,sizeof(buf)); //缓冲区清零 CString tmpstr(m_snd); //复制要发送的字符串 int multibytelen=WideCharToMultiByte( //计算从Unicode转换到Ansi后需要的字节数 CP_ACP, //根据ANSI code page转换 WC_COMPOSITECHECK | WC_DEFAULTCHAR, //转换出错用缺省字符代替 tmpstr.GetBuffer(m_snd.GetLength()), //要转换的字符串地址 m_snd.GetLength(), //要转换的个数 0, //转换后字符串放置的地址 0, //最多转换字符的个数,为0表示返回转换Unicode后需要多少个字节 0, //缺省的字符:"\0" 0 //缺省的设置); WideCharToMultiByte( //转换Unicode到Ansi CP_ACP, WC_COMPOSITECHECK | WC_DEFAULTCHAR, tmpstr.GetBuffer(m_snd.GetLength()), m_snd.GetLength(), (char *)buf, //转换到缓冲区中 128, //最多128个字节 0, 0); int sendcount=m_psocket->Send(buf,multibytelen+1); //发送转换后的缓冲区 CString statusstr; statusstr.Format(TEXT("共发送字节数:%d"),sendcount); m_status.SetWindowText(statusstr); //更新显示栏}程序接收到的字符串最后保存到CString tmpstr中.//接收函数片断void MyCeSocket::OnReceive(int nErrorCode){ // TODO: Add your specialized code here and/or call the base class unsigned char p[129]; //接受缓冲区 ZeroMemory(p,sizeof(p)); //接收缓冲区清零 this->Receive(p,128); //接收128个字节 int widecharlen=MultiByteToWideChar( //计算从Ansi转换到Unicode后需要的字节数 CP_ACP, MB_COMPOSITE, (char*)p, //要转换的Ansi字符串 -1, //自动计算长度 0, 0 ); CString tmpstr; tmpstr.GetBuffer(widecharlen); //为转换后保存Unicode字符串分配内存 MultiByteToWideChar( //从Ansi转换到Unicode字符 CP_ACP, MB_COMPOSITE, (char*)p, -1, tmpstr.GetBuffer(widecharlen), //转换到tmpstr widecharlen //最多转换widecharlen个Unicode字符 ); m_clientdlg->m_listbox.InsertString(0,tmpstr); //插入到listbox中显示 CCeSocket::OnReceive(nErrorCode);}转自:http://blog.youkuaiyun.com/liugy1126/archive/2007/11/02/1863350.aspx-----------------------------------------------------------------------------------Unicode与字符集函数近日闲来无事,前一阵子又被Unicode搞的焦头烂额,于是想看看MSDN吧!英文的看起来真费劲,为了以后省点劲,翻译总结了一下,备查。英文水平有限,如有出入,请参见MSDN。第一个就是宽字符到多字节字符转换函数,函数原型如下:int WideCharToMultiByte(UINT CodePage,DWORD dwFlags,LPCWSTR lpWideCharStr,int cchWideChar,LPSTR lpMultiByteStr,int cbMultiByte,LPCSTR lpDefaultChar,LPBOOL lpUsedDefaultChar);此函数把宽字符串转换成指定的新的字符串,如ANSI,UTF8等,新字符串不必是多字节字符集。参数:CodePage: 指定要转换成的字符集代码页,它可以是任何已经安装的或系统自带的字符集,你也可以使用如下所示代码页之一。CP_ACP 当前系统ANSI代码页 CP_MACCP 当前系统Macintosh代码页 CP_OEMCP 当前系统OEM代码页,一种原始设备制造商硬件扫描码 CP_SYMBOL Symbol代码页,用于Windows 2000及以后版本,我不明白是什么CP_THREAD_ACP 当前线程ANSI代码页,用于Windows 2000及以后版本,我不明白是什么 CP_UTF7 UTF-7,设置此值时lpDefaultChar和lpUsedDefaultChar都必须为NULLCP_UTF8 UTF-8,设置此值时lpDefaultChar和lpUsedDefaultChar都必须为NULL我想最常用的应该是CP_ACP和CP_UTF8了,前者将宽字符转换为ANSI,后者转换为UTF8。dwFlags: 指定如何处理没有转换的字符, 但不设此参数函数会运行的更快一些,我都是把它设为0。 可设的值如下表所示:WC_NO_BEST_FIT_CHARS 把不能直接转换成相应多字节字符的Unicode字符转换成lpDefaultChar指定的默认字符。也就是说,如果把Unicode转换成多字节字符,然后再转换回来,你并不一定得到相同的Unicode字符,因为这期间可能使用了默认字符。此选项可以单独使用,也可以和其他选项一起使用。WC_COMPOSITECHECK 把合成字符转换成预制的字符。它可以与后三个选项中的任何一个组合使用,如果没有与他们中的任何一个组合,则与选项WC_SEPCHARS相同。WC_ERR_INVALID_CHARS 此选项会致使函数遇到无效字符时失败返回,并且GetLastError会返回错误码ERROR_NO_UNICODE_TRANSLATION。否则函数会自动丢弃非法字符。此选项只能用于UTF8。WC_DISCARDNS 转换时丢弃不占空间的字符,与WC_COMPOSITECHECK一起使用WC_SEPCHARS 转换时产生单独的字符,此是默认转换选项,与WC_COMPOSITECHECK一起使用WC_DEFAULTCHAR 转换时使用默认字符代替例外的字符,(最常见的如’?’),与WC_COMPOSITECHECK一起使用。当指定WC_COMPOSITECHECK时,函数会将合成字符转换成预制字符。合成字符由一个基字符和一个不占空间的字符(如欧洲国家及汉语拼音的音标)组成,每一个都有不同的字符值。预制字符有一个用于表示基字符和不占空间字符的合成体的单一的字符值。当指定WC_COMPOSITECHECK选项时,也可以使用上表列出的最后3个选项来定制预制字符的转换规则。这些选项决定了函数在遇到宽字符串的合成字符没有对应的预制字符时的行为,他们与WC_COMPOSITECHECK一起使用,如果都没有指定,函数默认WC_SEPCHARS。对于下列代码页,dwFlags必须为0,否则函数返回错误码ERROR_INVALID_FLAGS。50220 50221 50222 50225 50227 50229 52936 54936 57002到57011 65000(UTF7) 42(Symbol)对于UTF8,dwFlags必须为0或WC_ERR_INVALID_CHARS,否则函数都将失败返回并设置错误码ERROR_INVALID_FLAGS,你可以调用GetLastError获得。lpWideCharStr: 待转换的宽字符串。cchWideChar: 待转换宽字符串的长度,-1表示转换到字符串结尾。lpMultiByteStr: 接收转换后输出新串的缓冲区。cbMultiByte: 输出缓冲区大小,如果为0,lpMultiByteStr将被忽略,函数将返回所需缓冲区大小而不使用lpMultiByteStr。lpDefaultChar: 指向字符的指针, 在指定编码里找不到相应字符时使用此字符作为默认字符代替。 如果为NULL则使用系统默认字符。对于要求此参数为NULL的dwFlags而使用此参数,函数将失败返回并设置错误码ERROR_INVALID_PARAMETER。lpUsedDefaultChar:开关变量的指针,用以表明是否使用过默认字符。对于要求此参数为NULL的dwFlags而使用此参数,函数将失败返回并设置错误码ERROR_INVALID_PARAMETER。lpDefaultChar和lpUsedDefaultChar都设为NULL,函数会更快一些。返回值: 如果函数成功,且cbMultiByte非0,返回写入lpMultiByteStr的字节数(包括字符串结尾的null);cbMultiByte为0,则返回转换所需字节数。函数失败,返回0。注意:函数WideCharToMultiByte使用不当,会给影响程序的安全。调用此函数会很容易导致内存泄漏,因为lpWideCharStr指向的输入缓冲区大小是宽字符数,而lpMultiByteStr指向的输出缓冲区大小是字节数。为了避免内存泄漏,应确保为输出缓冲区指定合适的大小。我的方法是先使cbMultiByte为0调用WideCharToMultiByte一次以获得所需缓冲区大小,为缓冲区分配空间,然后再次调用WideCharToMultiByte填充缓冲区,详见下面的代码。另外,从Unicode UTF16向非Unicode字符集转换可能会导致数据丢失,因为该字符集可能无法找到表示特定Unicode数据的字符。wchar_t* pwszUnicode = "Holle, word! 你好,中国!";int iSize;char* pszMultiByte;iSize = WideCharToMultiByte(CP_ACP, 0, pwszUnicode, -1, NULL, 0, NULL, NULL);pszMultiByte = (char*)malloc((iSize+1)/**sizeof(char)*/);WideCharToMultiByte(CP_ACP, 0, pwszUnicode, -1, pszMultiByte, iSize, NULL, NULL);第二个是多字节字符到宽字符转换函数,函数原型如下:> int MultiByteToWideChar(UINT CodePage,DWORD dwFlags,LPCSTR lpMultiByteStr,int cbMultiByte,LPWSTR lpWideCharStr,int cchWideChar);此函数把多字节字符串转换成宽字符串(Unicode),待转换的字符串并不一定是多字节的。此函数的参数,返回值及注意事项参见上面函数WideCharToMultiByte的说明,这里只对dwFlags做简单解释。dwFlags: 指定是否转换成预制字符或合成的宽字符,对控制字符是否使用像形文字,以及怎样处理无效字符。MB_PRECOMPOSED 总是使用预制字符,即有单个预制字符时,就不会使用分解的基字符和不占空间字符。此为函数的默认选项,不能和MB_COMPOSITE合用MB_COMPOSITE 总是使用分解字符,即总是使用基字符+不占空间字符的方式MB_ERR_INVALID_CHARS 设置此选项,函数遇到非法字符就失败并返回错误码ERROR_NO_UNICODE_TRANSLATION,否则丢弃非法字符MB_USEGLYPHCHARS 使用像形字符代替控制字符对于下列代码页,dwFlags必须为0,否则函数返回错误码ERROR_INVALID_FLAGS。50220 50221 50222 50225 50227 50229 52936 54936 57002到57011 65000(UTF7) 42(Symbol)对于UTF8,dwFlags必须为0或MB_ERR_INVALID_CHARS,否则函数都将失败并返回错误码ERROR_INVALID_FLAGS。以下函数我没用过,只简要说明之。int GetTextCharset( HDC hdc );此函数获取当前选进的设备描述表的字符集,等同于GetTextCharsetInfo(hdc, NULL, 0)。返回值: 成功返回字符集标识,失败返回DEFAULT_CHARSET。Windows定义的字符集标识有:ANSI_CHARSETBALTIC_CHARSETCHINESEBIG5_CHARSETDEFAULT_CHARSETEASTEUROPE_CHARSETGB2312_CHARSETGREEK_CHARSETHANGUL_CHARSETMAC_CHARSETOEM_CHARSETRUSSIAN_CHARSETSHIFTJIS_CHARSETSYMBOL_CHARSETTURKISH_CHARSETVIETNAMESE_CHARSETJOHAB_CHARSET(韩语版)ARABIC_CHARSET(中东版)HEBREW_CHARSET(中东版)THAI_CHARSET(泰国版)int GetTextCharsetInfo(HDC hdc,LPFONTSIGNATURE lpSig,DWORD dwFlags);此函数获取当前选进设备描述表的字体的字符集信息。参数:lpSig:指向FONTSIGNATURE结构的指针。如果当前选进设备的是TureType字体,函数会填充FONTSIGNATURE结构。否则FONTSIGNATURE结构被填充为0,而应使用TranslateCharsetInfo来获取一般字符集信息,如果你不需要字体标志信息,可将此参数设为NULL,此时相当于调用GetTextCharset。FONTSIGNATURE结构包括代码页和Unicode子域的信息,Unicode子域是指定字体的字型轮廓。该结构定义如下:typedef struct tagFONTSIGNATURE {DWORD fsUsb[4];DWORD fsCsb[2];} FONTSIGNATURE, *PFONTSIGNATURE; fsUsb 是一个128位的Unicode子集标志位(Unicode Subset Bitfield),用以标识最多126个Unicode子域。除了两个最高有效位外,每一位代表一个子域。最高位总是1,表示此位是一个字体标志,次高位保留,必须位0。Unicode子域根据ISO 10646标准制定。fsCsb 是一个64位的代码页标志位,用以标识制定的字符集或代码页。代码页由低32位标识,而高32位用于非Windows代码页。dwFlags:保留,必须为0。返回值:成功返回字符集标识,失败返回DEFAULT_CHARSET。BOOL TranslateCharsetInfo(DWORD* pSrc,LPCHARSETINFO lpCs,DWORD dwFlags);此函数根据指定字符集,代码页或字体标识转换并设置目标结体的值。参数:lpSrc:如果dwFlags是TCI_SRCFONTSIG,此参数是FONTSIGNATURE结构的fsCsb成员地址,否则是一个DWORD值。lpCs: 指向要填充的CHARSETINFO结构。CHARSETINFO结构定义如下:typedef struct {UINT ciCharset; // 字符集标识UINT ciACP; // ANSI代码页标识FONTSIGNATURE fs;} CHARSETINFO, *PCHARSETINFO;dwFlags: 指定如何转换。可以是下列标识之一:TCI_SRCCHARSET lpSrc的低字是字符集标识,高字为0TCI_SRCCODEPAGE lpSrc的低字是代码页标识,高字为0TCI_SRCFONTSIG lpSrc是FONTSIGNATURE的代码页标志位部分,即FONTSIGNATURE的fsCsb成员地址TCI_SRCLOCALE lpSrc是键盘布局的LCID或LANGID,如果是LANGID,其值存在lpSrc的低字BOOL IsDBCSLeadByte( BYTE TestChar );此函数使用当前WindowsANSI代码页判断指定字节是不是一个潜在的双字节字符(DBCS)的引导字节。若使用其他代码页,请用IsDBCSLeadByteEx函数。BOOL IsDBCSLeadByteEx(UINT CodePage,BYTE TestChar);此函数判断指定字节是不是一个潜在的双字节字符(DBCS)的引导字节。CodePage可用的值有:CP_ACP,CP_MACCP,CP_OEMCP,CP_THREAD_ACP。 BOOL IsTextUnicode(CONST VOID* pBuffer,int cb,LPINT lpi);此函数判断指定缓冲区里是否可能会有某种格式的Unicode文本。参数:lpi: 输入时指明测试项,输出时测试位返回各项测试结果:通过测试返回1,测试失败返回0。如果为NULL,则函数会测试所有可能的项。它可以是以下值的一个或多个:IS_TEXT_UNICODE_ASCII16 缓冲区文本是Unicode,并且仅有0扩展的ASCII字符IS_TEXT_UNICODE_REVERSE_ASCII16 同上,只是Unicode文本是字节翻转的(与BOM有关)IS_TEXT_UNICODE_STATISTICS 缓冲区文本可能是Unicode,由于它采用统计分析法,所以并不能确保准确IS_TEXT_UNICODE_REVERSE_STATISTICS 同上,只是可能的Unicode文本是字节翻转的IS_TEXT_UNICODE_CONTROLS 缓冲区文本含有Unicode表示的一个或多个非打印控制字符,如RETURN, LINEFEED, SPACE, CJK_SPACE, TAB。IS_TEXT_UNICODE_REVERSE_CONTROLS 同上,只是Unicode字符是字节翻转的IS_TEXT_UNICODE_BUFFER_TOO_SMALL 缓冲区里的文本太少,不足以作出有意义的分析IS_TEXT_UNICODE_SIGNATURE 缓冲区文本含有Unicode字节顺序码(BOM)0XFEFF作为他的第一个字符IS_TEXT_UNICODE_REVERSE_SIGNATURE 缓冲区文本含有Unicode反向字节顺序码0XFFFE作为他的第一个字符IS_TEXT_UNICODE_ILLEGAL_CHARS 缓冲区文本含有Unicode非法字符,如内嵌BOM,UNICODE_NUL,CRLF或0XFFFFIS_TEXT_UNICODE_ODD_LENGTH 缓冲区字符数为奇数,Unicode字符串长度都是偶数IS_TEXT_UNICODE_NULL_BYTES 缓冲区含有null字节,表示非ASCII文本IS_TEXT_UNICODE_UNICODE_MASK IS_TEXT_UNICODE_ASCII16 | IS_TEXT_UNICODE_STATISTICS | IS_TEXT_UNICODE_CONTROLS | IS_TEXT_UNICODE_SIGNATUREIS_TEXT_UNICODE_REVERSE_MASK IS_TEXT_UNICODE_REVERSE_ASCII16 | IS_TEXT_UNICODE_REVERSE_STATISTICS | IS_TEXT_UNICODE_REVERSE_CONTROLS | IS_TEXT_UNICODE_REVERSE_SIGNATURE.IS_TEXT_UNICODE_NOT_UNICODE_MASK IS_TEXT_UNICODE_ILLEGAL_CHARS | IS_TEXT_UNICODE_ODD_LENGTH和两个当前没有使用的标志位IS_TEXT_UNICODE_NOT_ASCII_MASK IS_TEXT_UNICODE_NULL_BYTES 和三个当前没有使用的标志位还有三个Windows不推荐使用的函数:NlsDllCodePageTranslation,UnicodeToBytes和BytesToUnicode,这里就不作介绍了。PS:在VC中编译定义了_UNICODE的代码时经常会出现如下连接错误:msvcrtd.lib(crtexew.obj) : error LNK2001: unresolved external symbol _WinMain @16 Debug/Test.exe : fatal error LNK1120: 1 unresolved externals解决办法如下:在Project->Settings->Link选项下选择Output, 然后在Entry里输入:wWinMainCRTStartup即可。转自:http://www.stubc.com/thread-2041-1-5.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值