www.digitalmars.com         C & C++   DMDScript  

c++ - A header file to directly write wide string literal

reply hirofield <hi_ohta nifty.com> writes:
Hi,

I wrote a header file to resolve wide string literal issue.
Previously, when UNICODE is defined, wide string literals like L"foo" or
_T("foo") doesn't work correctly (garbled).   In this case, programmers must
write wide string literals in character codes by using \u.

e.g.)

// Garbled
::MessgaeBoxW(NULL, _T("Hello"), _T("Title"), MB_OK);


This header file resolve the problem (this requires STLPort).

// dmctchar.h

#ifndef DMCTCHAR_H
#define DMCTCHAR_H

#include <windows.h>
#include <tchar.h>
#include <string>

using namespace std;

namespace {     // nameless namespace
    // MBCS->UNICODE converting function
    wstring MultiByteToWstr(const char* mbChar, UINT cp)
    {
        // Get buffer size
        int numChars = ::MultiByteToWideChar(cp, 0, mbChar, -1, NULL, 0);
        wchar_t* pWst = new wchar_t[numChars];

        // Conversion
        numChars = ::MultiByteToWideChar(cp, 0, mbChar, -1, pWst, numChars);
        wstring result = wstring(pWst);
        delete[] pWst;
        return result;
    }
}

#ifdef UNICODE
    #undef _T
    #define _T(str) MultiByteToWstr(str, ::GetACP()).c_str()
#endif // UNICODE

#endif // DMCTCHAR_H


When UNICODE is defined, Include above header file after tchar.h in your
program, and you can write wide string literals directly as _T("foo").

Please feel free to use it if you faced with this problem.
Your bug reports are appreciated.


hirofield
Sep 21 2009
parent "Matthew Wilson" <matthew hat.stlsoft.dot.org> writes:
 Your bug reports are appreciated.

Haven't compiled it, but I can tell you that it's got issues wrt exception-safety and error-conditions. First, you don't check the return value of MultiByteToWideChar(). If it returns 0, you may want to just return wstring(). Second, if the expression wstring result = wstring(pWst); throws an exception, then the memory in the wide-char array will be leaked. (btw, you can just write wstring result(pWst); or, even better, wstring result(pWst, static_cast<size_t>(numChars)); ) Third, you might consider avoiding the (potentially unnecessary) explicit memory allocation, and use an auto_buffer instead; see www.ddj.com/cpp/184401740 and http://www.stlsoft.org/doc-1.9/classstlsoft_1_1auto__buffer.html wstring MultiByteToWstr(const char* mbChar, UINT cp) { // Get buffer size int numChars = ::MultiByteToWideChar(cp, 0, mbChar, -1, NULL, 0); stlsoft::auto_buffer<wchar_t> buff(numChars); // Conversion numChars = ::MultiByteToWideChar(cp, 0, mbChar, -1, &buff[0], numChars); wstring(&buff[0], numChars); return result; } // if any memory allocated in buff, will be freed here automatically btw, the second problem now disappears as well. Four, I'm not sure what you're doing with redefining _T(), but it looks suspicious. I'd need to hear more from you before commenting, but I think you're doing something that might screw up other code. HTH Matt "hirofield" <hi_ohta nifty.com> wrote in message news:h9810v$3bi$1 digitalmars.com...
 Hi,

 I wrote a header file to resolve wide string literal issue.
 Previously, when UNICODE is defined, wide string literals like L"foo" or
 _T("foo") doesn't work correctly (garbled).   In this case, programmers must
 write wide string literals in character codes by using \u.

 e.g.)

 // Garbled
 ::MessgaeBoxW(NULL, _T("Hello"), _T("Title"), MB_OK);


 This header file resolve the problem (this requires STLPort).

 // dmctchar.h

 #ifndef DMCTCHAR_H
 #define DMCTCHAR_H

 #include <windows.h>
 #include <tchar.h>
 #include <string>

 using namespace std;

 namespace {     // nameless namespace
     // MBCS->UNICODE converting function
     wstring MultiByteToWstr(const char* mbChar, UINT cp)
     {
         // Get buffer size
         int numChars = ::MultiByteToWideChar(cp, 0, mbChar, -1, NULL, 0);
         wchar_t* pWst = new wchar_t[numChars];

         // Conversion
         numChars = ::MultiByteToWideChar(cp, 0, mbChar, -1, pWst, numChars);
         wstring result = wstring(pWst);
         delete[] pWst;
         return result;
     }
 }

 #ifdef UNICODE
     #undef _T
     #define _T(str) MultiByteToWstr(str, ::GetACP()).c_str()
 #endif // UNICODE

 #endif // DMCTCHAR_H


 When UNICODE is defined, Include above header file after tchar.h in your
 program, and you can write wide string literals directly as _T("foo").

 Please feel free to use it if you faced with this problem.
 Your bug reports are appreciated.


 hirofield

Nov 20 2009