┌──────────────────────────────────────────────────────────────────────┐ │Basically, wide character based handling is used for an internal │ │process. When the application communicates with the other systems or │ │subsystems (e.g. DB2/2, PM, etc.), the communication is based on │ │multibyte. │ └──────────────────────────────────────────────────────────────────────┘
Most applications must communicate with the operating system, other subsystems or middle wares to input/output information. Even the famous "hello world!" program uses stdout to output the message.
At present, the interface between an application and these subsystems are byte-based. Thus, the application must convert all outbound wide strings to multibyte strings, and vice versa.
Note: The exception is stream I/O for which the conversion is done within the stream I/O functions implicitly.
The following conversion functions are provided by XPG4:
┌───────────────┬─────────────────────────────────────────────┐ │Function name │Description │ ├───────────────┼─────────────────────────────────────────────┤ │mbstowcs │Converts a multibyte string to a wide string.│ ├───────────────┼─────────────────────────────────────────────┤ │mbtowc │Converts a multibyte character to a wide │ │ │character. │ ├───────────────┼─────────────────────────────────────────────┤ │wcstombs │Converts a wide string to a multibyte string │ │ │(**). │ ├───────────────┼─────────────────────────────────────────────┤ │wctomb │Converts a wide character to a multibyte │ │ │character. │ └───────────────┴─────────────────────────────────────────────┘
When converting a multibyte string to a wide string, enough size of output
buffer should be prepared. Since the arguments of memory allocation functions
such as malloc() represent the number of bytes, an application programmer
must be careful when using these functions to prepare buffer for wide string
at run time.
initHelp() of XPRMMAIN.C
#include <stdlib.h> #include <limits.h> ... static void initHelp( char* pszResFile, size_t szLen ) { ... wchar_t *wcsTemp, *wcp; /* strchr() may misinterpret either byte of a DBCS as an SBCS, */ /* thus use wcschr() instead. */ wcsTemp = (wchar_t *)malloc( (strlen(pszResFile)+1)*sizeof(wchar_t) ); mbstowcs( wcsTemp, pszResFile, strlen(pszResFile) ); ... }
┌──────────────────────────────────────────────────────────────────────┐ │The memory allocation functions such as malloc() reserves a block of │ │storage of specified bytes. Therefore, when allocating buffer for │ │converting a multibyte string to a wide string (or vice versa), make │ │sure the size of the prepared buffer is sufficient. │ └──────────────────────────────────────────────────────────────────────┘
When converting a wide string to a multibyte string, the wcslen() function
can be used to determine the number of wide characters in a wide string.
Multiply macro MB_CUR_MAX to get the sufficient size of the destination
buffer. (If you'd like to prepare the buffer as a char array at the
compile time, you can use MB_LEN_MAX instead.) The following is a
wide character version of the WinSetDlgItemText() which allocates storage
for conversion dynamically.
setDlgItemWcs() and queryDlgItemWcs() of XPRMMAIN.C
#include <stdlib.h> #include <limits.h> &ellips. /**********************************************************************/ /* setDlgItemWcs() */ /* Wide string version of setDlgItemText(). */ /**********************************************************************/ void setDlgItemWcs( HWND hwnd, ULONG ulItemId, wchar_t* wcsText ) { char *pszBuf; int sz; sz = wcslen(wcsText)*MB_CUR_MAX; pszBuf = (char *)malloc(sz+1); wcstombs( pszBuf, wcsText, sz+1 ); WinSetDlgItemText( hwnd, ulItemId, pszBuf ); free( pszBuf ); }
When converting a multibyte string to a wide string, the mbstowcs functions
can be used to determine the number of elements required for the converted
wide characters. Multiply the returned value by sizeof(wchar_t) to
get the sufficient destination buffer. The following is a wide character
version of the WinQueryDlgItemText() which allocates storage for conversion
dynamically.
setDlgItemWcs() and queryDlgItemWcs() of XPRMMAIN.C
/**********************************************************************/ /* queryDlgItemWcs() */ /* Wide string version of queryDlgItemText(). */ /**********************************************************************/ size_t queryDlgItemWcs( HWND hwnd, ULONG ulItemId, wchar_t* wcsBuf, size_t szLen ) { char *pszBuf; LONG lLength; size_t szNumChar; lLength = WinQueryDlgItemTextLength( hwnd, ulItemId ); pszBuf = malloc( (size_t)lLength+1 ); WinQueryDlgItemText( hwnd, ulItemId, lLength+1, pszBuf ); szNumChar = mbstowcs( NULL, pszBuf, 0 ); szNumChar = (szNumChar > szLen)? szLen : szNumChar; szNumChar = mbstowcs( wcsBuf, pszBuf, szNumChar+1 ); free( pszBuf ); return( szNumChar ); }