3. Implementation/Windows API

ANSI 와 UNICODE 사이의 변환 클래스

SSKK 2008. 8. 21. 11:39
For a simple string conversion between ANSI and Unicode on a Pocket PC I have also written some C++ classes:
  • CTtoA for conversion from LPCTSTR to LPCSTR
  • CTtoW for conversion from LPCTSTR to LPCWSTR
  • CAtoT for conversion from LPCSTR to LPCTSTR
  • CWtoT for conversion from LPCWSTR to LPCTSTR
  • CAtoW for conversion from LPCSTR to LPCWSTR
  • CWtoA for conversion from LPCWSTR to LPCSTR

//////////////////////////////////////////////////////////////////////////
//
//  strconv.h - Some useful classes for string conversion.
//
//  Copyright (c) 2004-2007 by Daniel Strigl.
//
//  This code may be used in compiled form in any way you desire.
//  This file may be redistributed unmodified by any means PROVIDING
//  it is not sold for profit without the authors written consent,
//  and providing that this notice and the authors name is included.
//  By the way, if the source code in this file is used in any
//  application I would appreciate and enjoy hearing about them.
//
//  This file is provided "as is" with no expressed or implied warranty.
//  The author accepts no liability for any damage, in any form, caused
//  by this code. Use it at your own risk and as with all code expect
//  bugs! It's been tested, but I'm not perfect ;-)
//
//  Please use the contact page of my blog to report any
//  bug, comment or suggestion.
//
//  Contact:
//  --------
//
//    Daniel Strigl [http://geekswithblogs.net/dastblog]
//
//  History:
//  --------
//
//    21 Jul 2004 - Initial version.
//    20 Nov 2006 - Added class CAtoT, CWtoT, CAtoW and CWtoA.
//
//////////////////////////////////////////////////////////////////////////

#if !defined(_STRCONV_H_)
#define _STRCONV_H_

//////////////////////////////////////////////////////////////////////////
//
//  CTtoA
//
//      LPCTSTR to LPCSTR conversion.
//
class CTtoA
{
    LPSTR m_psz;

public:
    CTtoA(LPCTSTR ptsz) : m_psz(NULL)
    {
        ASSERT(ptsz != NULL);
#if defined(_UNICODE) // for UNICODE build
        const int size = WideCharToMultiByte(CP_ACP, 0, ptsz, -1,
            NULL, 0, NULL, NULL);
#ifdef _DEBUG
        if (size == 0) {
            ASSERT(!_T("Function \"WideCharToMultiByte\" failed."));
        }
#endif // _DEBUG
        ASSERT(size > 0);
        m_psz = (LPSTR) malloc(sizeof(CHAR)*size);
        ASSERT(m_psz != NULL);
#ifdef _DEBUG
        memset(m_psz, 0, sizeof(CHAR)*size);
#endif // _DEBUG
        VERIFY(WideCharToMultiByte(CP_ACP, 0, ptsz, -1,
            m_psz, size, NULL, NULL) != 0);
#else // for non-UNICODE build
        m_psz = _strdup(ptsz);
        ASSERT(m_psz != NULL);
#endif // defined(_UNICODE)
    }

    CTtoA(const CTtoA& rhs) : m_psz(_strdup(rhs.m_psz))
    {
        ASSERT(m_psz != NULL);
    }

    CTtoA& operator=(const CTtoA& rhs)
    {
        if (this != &rhs)
        {
            free(m_psz);
            m_psz = _strdup(rhs.m_psz);
            ASSERT(m_psz != NULL);
        }
        return *this;
    }

    ~CTtoA()
    {
        free(m_psz);
    }

    size_t GetLength() const { return strlen(m_psz); }

    operator LPCSTR() const { return m_psz; }
};

//////////////////////////////////////////////////////////////////////////
//
//  CTtoW
//
//      LPCTSTR to LPCWSTR conversion.
//
class CTtoW
{
    LPWSTR m_pwsz;

public:
    CTtoW(LPCTSTR ptsz) : m_pwsz(NULL)
    {
        ASSERT(ptsz != NULL);
#if defined(_UNICODE) // for UNICODE build
        m_pwsz = _wcsdup(ptsz);
        ASSERT(m_pwsz != NULL);
#else // for non-UNICODE build
        const int size = MultiByteToWideChar(CP_ACP, 0, ptsz, -1, NULL, 0);
#ifdef _DEBUG
        if (size == 0) {
            ASSERT(!_T("Function \"MultiByteToWideChar\" failed."));
        }
#endif // _DEBUG
        ASSERT(size > 0);
        m_pwsz = (LPWSTR) malloc(sizeof(WCHAR)*size);
        ASSERT(m_pwsz != NULL);
#ifdef _DEBUG
        memset(m_pwsz, 0, sizeof(WCHAR)*size);
#endif // _DEBUG
        VERIFY(MultiByteToWideChar(CP_ACP, 0, ptsz, -1, m_pwsz, size) != 0);
#endif // defined(_UNICODE)
    }

    CTtoW(const CTtoW& rhs) : m_pwsz(_wcsdup(rhs.m_pwsz))
    {
        ASSERT(m_pwsz != NULL);
    }

    CTtoW& operator=(const CTtoW& rhs)
    {
        if (this != &rhs)
        {
            free(m_pwsz);
            m_pwsz = _wcsdup(rhs.m_pwsz);
            ASSERT(m_pwsz != NULL);
        }
        return *this;
    }

    ~CTtoW()
    {
        free(m_pwsz);
    }

    size_t GetLength() const { return wcslen(m_pwsz); }

    operator LPCWSTR() const { return m_pwsz; }
};

//////////////////////////////////////////////////////////////////////////
//
//  CAtoT
//
//      LPCSTR to LPCTSTR conversion.
//
class CAtoT
{
    LPTSTR m_ptsz;

public:
    CAtoT(LPCSTR psz) : m_ptsz(NULL)
    {
        ASSERT(psz != NULL);
#if defined(_UNICODE) // for UNICODE build
        const int size = MultiByteToWideChar(CP_ACP, 0, psz, -1, NULL, 0);
#ifdef _DEBUG
        if (size == 0) {
            ASSERT(!_T("Function \"MultiByteToWideChar\" failed."));
        }
#endif // _DEBUG
        ASSERT(size > 0);
        m_ptsz = (LPWSTR) malloc(sizeof(WCHAR)*size);
        ASSERT(m_ptsz != NULL);
#ifdef _DEBUG
        memset(m_ptsz, 0, sizeof(WCHAR)*size);
#endif // _DEBUG
        VERIFY(MultiByteToWideChar(CP_ACP, 0, psz, -1, m_ptsz, size) != 0);
#else // for non-UNICODE build
        m_ptsz = _strdup(psz);
        ASSERT(m_ptsz != NULL);
#endif // defined(_UNICODE)
    }

    CAtoT(const CAtoT& rhs) : m_ptsz(_tcsdup(rhs.m_ptsz))
    {
        ASSERT(m_ptsz != NULL);
    }

    CAtoT& operator=(const CAtoT& rhs)
    {
        if (this != &rhs)
        {
            free(m_ptsz);
            m_ptsz = _tcsdup(rhs.m_ptsz);
            ASSERT(m_ptsz != NULL);
        }
        return *this;
    }

    ~CAtoT()
    {
        free(m_ptsz);
    }

    size_t GetLength() const { return _tcslen(m_ptsz); }

    operator LPCTSTR() const { return m_ptsz; }
};

//////////////////////////////////////////////////////////////////////////
//
//  CWtoT
//
//      LPCWSTR to LPCTSTR conversion.
//
class CWtoT
{
    LPTSTR m_ptsz;

public:
    CWtoT(LPCWSTR pwsz) : m_ptsz(NULL)
    {
        ASSERT(pwsz != NULL);
#if defined(_UNICODE) // for UNICODE build
        m_ptsz = _wcsdup(pwsz);
        ASSERT(m_ptsz != NULL);
#else // for non-UNICODE build
        const int size = WideCharToMultiByte(CP_ACP, 0, pwsz, -1,
            NULL, 0, NULL, NULL);
#ifdef _DEBUG
        if (size == 0) {
            ASSERT(!_T("Function \"WideCharToMultiByte\" failed."));
        }
#endif // _DEBUG
        ASSERT(size > 0);
        m_ptsz = (LPSTR) malloc(sizeof(CHAR)*size);
        ASSERT(m_ptsz != NULL);
#ifdef _DEBUG
        memset(m_ptsz, 0, sizeof(CHAR)*size);
#endif // _DEBUG
        VERIFY(WideCharToMultiByte(CP_ACP, 0, pwsz, -1,
            m_ptsz, size, NULL, NULL) != 0);
#endif // defined(_UNICODE)
    }

    CWtoT(const CWtoT& rhs) : m_ptsz(_tcsdup(rhs.m_ptsz))
    {
        ASSERT(m_ptsz != NULL);
    }

    CWtoT& operator=(const CWtoT& rhs)
    {
        if (this != &rhs)
        {
            free(m_ptsz);
            m_ptsz = _tcsdup(rhs.m_ptsz);
            ASSERT(m_ptsz != NULL);
        }
        return *this;
    }

    ~CWtoT()
    {
        free(m_ptsz);
    }

    size_t GetLength() const { return _tcslen(m_ptsz); }

    operator LPCTSTR() const { return m_ptsz; }
};

//////////////////////////////////////////////////////////////////////////
//
//  CAtoW
//
//      LPCSTR to LPCWSTR conversion.
//
class CAtoW
{
    LPWSTR m_pwsz;

public:
    CAtoW(LPCSTR psz) : m_pwsz(NULL)
    {
        ASSERT(psz != NULL);
        const int size = MultiByteToWideChar(CP_ACP, 0, psz, -1, NULL, 0);
#ifdef _DEBUG
        if (size == 0) {
            ASSERT(!_T("Function \"MultiByteToWideChar\" failed."));
        }
#endif // _DEBUG
        ASSERT(size > 0);
        m_pwsz = (LPWSTR) malloc(sizeof(WCHAR)*size);
        ASSERT(m_pwsz != NULL);
#ifdef _DEBUG
        memset(m_pwsz, 0, sizeof(WCHAR)*size);
#endif // _DEBUG
        VERIFY(MultiByteToWideChar(CP_ACP, 0, psz, -1, m_pwsz, size) != 0);
    }

    CAtoW(const CAtoW& rhs) : m_pwsz(_wcsdup(rhs.m_pwsz))
    {
        ASSERT(m_pwsz != NULL);
    }

    CAtoW& operator=(const CAtoW& rhs)
    {
        if (this != &rhs)
        {
            free(m_pwsz);
            m_pwsz = _wcsdup(rhs.m_pwsz);
            ASSERT(m_pwsz != NULL);
        }
        return *this;
    }

    ~CAtoW()
    {
        free(m_pwsz);
    }

    size_t GetLength() const { return wcslen(m_pwsz); }

    operator LPCWSTR() const { return m_pwsz; }
};

//////////////////////////////////////////////////////////////////////////
//
//  CWtoA
//
//      LPCWSTR to LPCSTR conversion.
//
class CWtoA
{
    LPSTR m_psz;

public:
    CWtoA(LPCWSTR pwsz) : m_psz(NULL)
    {
        ASSERT(pwsz != NULL);
        const int size = WideCharToMultiByte(CP_ACP, 0, pwsz, -1,
            NULL, 0, NULL, NULL);
#ifdef _DEBUG
        if (size == 0) {
            ASSERT(!_T("Function \"WideCharToMultiByte\" failed."));
        }
#endif // _DEBUG
        ASSERT(size > 0);
        m_psz = (LPSTR) malloc(sizeof(CHAR)*size);
        ASSERT(m_psz != NULL);
#ifdef _DEBUG
        memset(m_psz, 0, sizeof(CHAR)*size);
#endif // _DEBUG
        VERIFY(WideCharToMultiByte(CP_ACP, 0, pwsz, -1,
            m_psz, size, NULL, NULL) != 0);
    }

    CWtoA(const CWtoA& rhs) : m_psz(_strdup(rhs.m_psz))
    {
        ASSERT(m_psz != NULL);
    }

    CWtoA& operator=(const CWtoA& rhs)
    {
        if (this != &rhs)
        {
            free(m_psz);
            m_psz = _strdup(rhs.m_psz);
            ASSERT(m_psz != NULL);
        }
        return *this;
    }

    ~CWtoA()
    {
        free(m_psz);
    }

    size_t GetLength() const { return strlen(m_psz); }

    operator LPCSTR() const { return m_psz; }
};

//////////////////////////////////////////////////////////////////////////

#endif // !defined(_STRCONV_H_)


The usage of the classes are realy simple, here is an example:

...

#include "strconv.h"

BOOL IsWireless(LPCTSTR pszAdapter)
{
    ...
}

int _tmain(int argc, _TCHAR* argv[])
{
    char szAdapter[64];

    ...

    BOOL bIsWireless = IsWireless(CAtoT(szAdapter));

    ...

    return 0;
}

출처 : http://www.pocketpcdn.com/forum/viewtopic.php?t=11603