WINDOWS CE下ANSI 与 Unicode 字符相互转换

一直在VC下做管了 ANSI 字符处理!在EVC下写出的字符处理程序老有问题!虽然知道是字符问题,但总是有些晕!~所以写一下以免自己再晕!同时也以免初学者晕!~~

在EVC中的字符都是宽(Unicode )字符的!例如,一个EDIT控件的对象m_Info要设置其中的内容要写成以下形式:m_Info.SetWindowText(_T("Hello"));才可以!要使用宏_T()。

但是宏_T()在使用中可能会出现问题(我已经遇到了!我现在还不能判断是我程序的问题还是这个宏有一定的局限性),微软还提供了ANSI 到 Unicode 字符串和 Unicode 字符串转换为 ANSI 的函数MultiByteToWideChar 和 WideCharToMultiByte。我以前在WINDOWS 2000下做驱动时用到过这两个函数!当时是这样处理的!


//宽字符串转换为普通字符串
PCHAR WideStrToMultiStr (PWCHAR WideStr)
{
    ULONG nBytes;
    PCHAR MultiStr;
    // 得到宽字符串的长度
    nBytes = WideCharToMultiByte(
                 CP_ACP,
                 0,
                 WideStr,
                 -1,
                 NULL,
                 0,
                 NULL,
                 NULL);
    if (nBytes == 0)
    {
        return NULL;
    }

    // 为转换后的字符串分配空间
    MultiStr = (PCHAR)GlobalAlloc(GPTR,nBytes);
    if (MultiStr == NULL)
    {
        return NULL;
    }
    // 转换字符串
    nBytes = WideCharToMultiByte(
                 CP_ACP,
                 0,
                 WideStr,
                 -1,
                 MultiStr,
                 nBytes,
                 NULL,
                 NULL);
    if (nBytes == 0)
    {
        GlobalFree(MultiStr);
        return NULL;
    }

    return MultiStr;
}

//普通字符串转换为宽字符串
PWCHAR MultiStrToWideStr (PCHAR MultiStr)
{
    ULONG nBytes;
    PWCHAR WideStr;
    // 得到宽字符串的长度
    nBytes = MultiByteToWideChar(
                 CP_ACP,
                 0,
                 MultiStr,
                 -1,
                 NULL,
                 0
                 );
    if (nBytes == 0)
    {
        return NULL;
    }

    // 为转换后的字符串分配空间
    WideStr = (PWCHAR)GlobalAlloc(GPTR,nBytes);
    if (WideStr == NULL)
    {
        return NULL;
    }
    // 转换字符串
    nBytes = MultiByteToWideChar(
                 CP_ACP,
                 0,
                 MultiStr,
                 -1,
                 WideStr,
                 nBytes
     );
    if (nBytes == 0)
    {
        GlobalFree(WideStr);
        return NULL;
    }

    return WideStr;
}

这两个函数分别实现宽字符串转换为普通字符串和普通字符串转换为宽字符串,我以前在WINDOWS 2000下用的时侯没有问题!现在在WINDOWS CE下用的时候出现异常!最后在微软网站中找到一篇“从 ANSI 到 Unicode & Unicode 到 ANSI 用于 OLE 如何转换”()其中是这样处理的:

/*
* AnsiToUnicode converts the ANSI string pszA to a Unicode string
* and returns the Unicode string through ppszW. Space for the
* the converted string is allocated by AnsiToUnicode.
*/

HRESULT __fastcall AnsiToUnicode(LPCSTR pszA, LPOLESTR* ppszW)
{

    ULONG cCharacters;
    DWORD dwError;

    // If input is null then just return the same.
    if (NULL == pszA)
    {
        *ppszW = NULL;
        return NOERROR;
    }

    // Determine number of wide characters to be allocated for the
    // Unicode string.
    cCharacters =  strlen(pszA)+1;

    // Use of the OLE allocator is required if the resultant Unicode
    // string will be passed to another COM component and if that
    // component will free it. Otherwise you can use your own allocator.
    *ppszW = (LPOLESTR) CoTaskMemAlloc(cCharacters*2);
    if (NULL == *ppszW)
        return E_OUTOFMEMORY;

    // Covert to Unicode.
    if (0 == MultiByteToWideChar(CP_ACP, 0, pszA, cCharacters,
                  *ppszW, cCharacters))
    {
        dwError = GetLastError();
        CoTaskMemFree(*ppszW);
        *ppszW = NULL;
        return HRESULT_FROM_WIN32(dwError);
    }

    return NOERROR;

}
/*
* UnicodeToAnsi converts the Unicode string pszW to an ANSI string
* and returns the ANSI string through ppszA. Space for the
* the converted string is allocated by UnicodeToAnsi.
*/

HRESULT __fastcall UnicodeToAnsi(LPCOLESTR pszW, LPSTR* ppszA)
{

    ULONG cbAnsi, cCharacters;
    DWORD dwError;

    // If input is null then just return the same.
    if (pszW == NULL)
    {
        *ppszA = NULL;
        return NOERROR;
    }

    cCharacters = wcslen(pszW)+1;
    // Determine number of bytes to be allocated for ANSI string. An
    // ANSI string can have at most 2 bytes per character (for Double
    // Byte Character Strings.)
    cbAnsi = cCharacters*2;

    // Use of the OLE allocator is not required because the resultant
    // ANSI  string will never be passed to another COM component. You
    // can use your own allocator.
    *ppszA = (LPSTR) CoTaskMemAlloc(cbAnsi);
    if (NULL == *ppszA)
        return E_OUTOFMEMORY;

    // Convert to ANSI.
    if (0 == WideCharToMultiByte(CP_ACP, 0, pszW, cCharacters, *ppszA,
                  cbAnsi, NULL, NULL))
    {
        dwError = GetLastError();
        CoTaskMemFree(*ppszA);
        *ppszA = NULL;
        return HRESULT_FROM_WIN32(dwError);
    }
    return NOERROR;

}
在WINDWOS CE 下使用正常!

 

你可能感兴趣的:(技术)