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
Permalink
Reply