September 21, 2009 A header file to directly write wide string literal | ||||
---|---|---|---|---|
| ||||
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 |
November 20, 2009 Re: A header file to directly write wide string literal | ||||
---|---|---|---|---|
| ||||
Posted in reply to hirofield | > 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 |
Copyright © 1999-2021 by the D Language Foundation