Revision: 7318 http://sourceforge.jp/projects/ttssh2/scm/svn/commits/7318 Author: zmatsuo Date: 2018-12-11 00:01:30 +0900 (Tue, 11 Dec 2018) Log Message: ----------- utf8文字列考慮 Modified Paths: -------------- branches/cmake/teraterm/common/i18n.c branches/cmake/teraterm/common/i18n.h branches/cmake/teraterm/common/ttlib.c branches/cmake/teraterm/common/ttlib.h Added Paths: ----------- branches/cmake/teraterm/common/codeconv.cpp branches/cmake/teraterm/common/codeconv.h -------------- next part -------------- Added: branches/cmake/teraterm/common/codeconv.cpp =================================================================== --- branches/cmake/teraterm/common/codeconv.cpp (rev 0) +++ branches/cmake/teraterm/common/codeconv.cpp 2018-12-10 15:01:30 UTC (rev 7318) @@ -0,0 +1,150 @@ + +#include <stdio.h> +#include <windows.h> +#include <memory> + +#include "codeconv.h" + +/** + * wchar_t文字列をマルチバイト文字列へ変換 + * @param[in] *wstr_ptr wchar_t文字列 + * @param[in] wstr_len wchar_t文字列長(0のとき自動) + * @param[in] code_page 変換先コードページ + * @param[out] *mb_len_ mb文字列長(NULLのとき内部エラー) + * @retval mb文字列へのポインタ(NULLの時変換エラー) + */ +char *_WideCharToMultiByte(const wchar_t *wstr_ptr, size_t wstr_len, int code_page, size_t *mb_len_) +{ + const DWORD flags = 0; + char *mb_ptr; + if (mb_len_ != NULL) { + *mb_len_ = 0; + } + if (wstr_len == 0) { + wstr_len = wcslen(wstr_ptr) + 1; + } + int len = ::WideCharToMultiByte(code_page, flags, + wstr_ptr, (DWORD)wstr_len, + NULL, 0, + NULL, NULL); + if (len == 0) { + return NULL; + } + mb_ptr = (char *)malloc(len); + if (mb_ptr == NULL) { + return NULL; + } + len = ::WideCharToMultiByte(code_page, flags, + wstr_ptr, (DWORD)wstr_len, + mb_ptr, len, + NULL,NULL); + if (len == 0) { + free(mb_ptr); + return NULL; + } + if (mb_len_ != NULL) { + *mb_len_ = len - 1; + } + return mb_ptr; +} + +/** + * マルチバイト文字列をwchar_t文字列へ変換 + * @param[in] *str_ptr mb(char)文字列 + * @param[in] str_len mb(char)文字列長(0のとき自動) + * @param[in] code_page 変換先コードページ + * @param[out] *w_len_ wchar_t文字列長 + * @retval mb文字列へのポインタ(NULLの時変換エラー) + */ +wchar_t *_MultiByteToWideChar(const char *str_ptr, size_t str_len, int code_page, size_t *w_len_) +{ + const DWORD flags = MB_ERR_INVALID_CHARS; + wchar_t *wstr_ptr; + if (w_len_ != NULL) { + *w_len_ = 0; + } + if (str_len == 0) { + str_len = strlen(str_ptr) + 1; + } + int len = ::MultiByteToWideChar(code_page, flags, + str_ptr, (int)str_len, + NULL, 0); + if (len == 0) { + return NULL; + } + wstr_ptr = (wchar_t *)malloc(len*sizeof(wchar_t)); + if (wstr_ptr == NULL) { + return NULL; + } + len = ::MultiByteToWideChar(code_page, flags, + str_ptr, (int)str_len, + wstr_ptr, len); + if (len == 0) { + free(wstr_ptr); + return NULL; + } + if (w_len_ != NULL) { + *w_len_ = len - 1; + } + return wstr_ptr; +} + +const TCHAR *ToTcharA(const char *strA) +{ +#if defined(UNICODE) + wchar_t *strW = _MultiByteToWideChar(strA, 0, CP_ACP, NULL); + return strW; +#else + return _strdup(strA); +#endif +} + +const TCHAR *ToTcharU8(const char *strU8) +{ + const wchar_t *strW = _MultiByteToWideChar(strU8, 0, CP_UTF8, NULL); +#if defined(UNICODE) + return strW; +#else + const char *strA = _WideCharToMultiByte(strW, 0, CP_ACP, NULL); + free((void *)strW); + return strA; +#endif +} + +const TCHAR *ToTcharW(const wchar_t *strW) +{ +#if defined(UNICODE) + return _wcsdup(strW); +#else + char *strA = _WideCharToMultiByte(strW, 0, CP_ACP, NULL); + return strA; +#endif +} + +#if defined(UNICODE) +const char *ToCharW(const wchar_t *strW) +{ + const char *strA = _WideCharToMultiByte(strW, 0, CP_ACP, NULL); + return strA; +} +#endif + +const char *ToCharA(const char *strA) +{ + return _strdup(strA); +} + +const char *ToU8W(const wchar_t *strW) +{ + const char *strU8 = _WideCharToMultiByte(strW, 0, CP_UTF8, NULL); + return strU8; +} + +const char *ToU8A(const char *strA) +{ + const wchar_t *strW = _MultiByteToWideChar(strA, 0, CP_ACP, NULL); + const char *strU8 = _WideCharToMultiByte(strW, 0, CP_UTF8, NULL); + free((void *)strW); + return strU8; +} + Added: branches/cmake/teraterm/common/codeconv.h =================================================================== --- branches/cmake/teraterm/common/codeconv.h (rev 0) +++ branches/cmake/teraterm/common/codeconv.h 2018-12-10 15:01:30 UTC (rev 7318) @@ -0,0 +1,35 @@ + +#include <tchar.h> + +#ifdef __cplusplus +extern "C" { +#endif + +char *_WideCharToMultiByte(const wchar_t *wstr_ptr, size_t wstr_len, int code_page, size_t *mb_len_); +wchar_t *_MultiByteToWideChar(const char *str_ptr, size_t str_len, int code_page, size_t *w_len_); +const TCHAR *ToTcharA(const char *strA); +const TCHAR *ToTcharU8(const char *strU8); +const TCHAR *ToTcharW(const wchar_t *strW); +const char *ToCharW(const wchar_t *strW); +const char *ToCharA(const char *strA); +const wchar_t *ToWcharA(const char *strA); +const char *ToU8A(const char *strA); +const char *ToU8W(const wchar_t *strW); + +#if defined(_UNICODE) +#define ToCharT(s) ToCharW(s) +#define ToU8T(s) ToU8W(s) +#else +#define ToCharT(s) ToCharA(s) +#define ToU8T(s) ToU8A(s) +#endif + +#ifdef __cplusplus +} +#endif + +#ifdef __cplusplus +TCHAR *ToTchar(const char *strA); +TCHAR *ToTchar(const wchar_t *strW); +#endif + Modified: branches/cmake/teraterm/common/i18n.c =================================================================== --- branches/cmake/teraterm/common/i18n.c 2018-12-10 15:01:12 UTC (rev 7317) +++ branches/cmake/teraterm/common/i18n.c 2018-12-10 15:01:30 UTC (rev 7318) @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2006-2018 TeraTerm Project * All rights reserved. * @@ -48,6 +48,31 @@ RestoreNewLine(buf); } +DllExport void GetI18nStrU8(const char *section, const char *key, char *buf, int buf_len, const char *def, const char *iniFile) +{ +#if defined(UNICODE) + wchar_t tmp[MAX_UIMSG]; + wchar_t defW[MAX_UIMSG]; + MultiByteToWideChar(CP_UTF8, 0, def, -1, defW, _countof(defW)); + GetI18nStrW(section, key, tmp, _countof(tmp), defW, iniFile); + WideCharToMultiByte(CP_UTF8, 0, + tmp, _countof(tmp), + buf, buf_len, + NULL, NULL); +#else + // ANSI -> Wide -> utf8 + char strA[MAX_UIMSG]; + wchar_t strW[MAX_UIMSG]; + GetI18nStr(section, key, strA, _countof(strA), def, iniFile); + MultiByteToWideChar(CP_ACP, 0, strA, -1, strW, _countof(strW)); + WideCharToMultiByte(CP_UTF8, 0, + strW, -1, + buf, buf_len, + NULL, NULL); +#endif +} + + DllExport int GetI18nLogfont(const char *section, const char *key, PLOGFONTA logfont, int ppi, const char *iniFile) { static char tmp[MAX_UIMSG]; @@ -63,7 +88,7 @@ GetNthNum(tmp, 3, &charset); strncpy_s(logfont->lfFaceName, sizeof(logfont->lfFaceName), font, _TRUNCATE); - logfont->lfCharSet = charset; + logfont->lfCharSet = (BYTE)charset; logfont->lfHeight = MulDiv(hight, -ppi, 72); logfont->lfWidth = 0; Modified: branches/cmake/teraterm/common/i18n.h =================================================================== --- branches/cmake/teraterm/common/i18n.h 2018-12-10 15:01:12 UTC (rev 7317) +++ branches/cmake/teraterm/common/i18n.h 2018-12-10 15:01:30 UTC (rev 7318) @@ -55,6 +55,7 @@ DllExport void GetI18nStrW(const char *section, const char *key, wchar_t *buf, int buf_len, const wchar_t *def, const char *iniFile); #endif DllExport void GetI18nStr(const char *section, const char *key, PCHAR buf, int buf_len, const char *def, const char *iniFile); +DllExport void GetI18nStrU8(const char *section, const char *key, char *buf, int buf_len, const char *def, const char *iniFile); DllExport int GetI18nLogfont(const char *section, const char *key, PLOGFONTA logfont, int ppi, const char *iniFile); #if defined(_UNICODE) Modified: branches/cmake/teraterm/common/ttlib.c =================================================================== --- branches/cmake/teraterm/common/ttlib.c 2018-12-10 15:01:12 UTC (rev 7317) +++ branches/cmake/teraterm/common/ttlib.c 2018-12-10 15:01:30 UTC (rev 7318) @@ -1031,6 +1031,11 @@ GetI18nStr(lang_section, key, buf, buf_len, def, iniFile); } +void get_lang_msgU8(const char *key, PCHAR buf, int buf_len, const char *def, const char *iniFile) +{ + GetI18nStrU8(lang_section, key, buf, buf_len, def, iniFile); +} + int get_lang_font(PCHAR key, HWND dlg, PLOGFONTA logfont, HFONT *font, const char *iniFile) { if (GetI18nLogfont(lang_section, key, logfont, Modified: branches/cmake/teraterm/common/ttlib.h =================================================================== --- branches/cmake/teraterm/common/ttlib.h 2018-12-10 15:01:12 UTC (rev 7317) +++ branches/cmake/teraterm/common/ttlib.h 2018-12-10 15:01:30 UTC (rev 7318) @@ -85,6 +85,7 @@ void GetOnOffEntryInifile(char *entry, char *buf, int buflen); DllExport void set_lang_section(const char *section); DllExport void get_lang_msg(const char *key, PCHAR buf, int buf_len, const char *def, const char *iniFile); +DllExport void get_lang_msgU8(const char *key, PCHAR buf, int buf_len, const char *def, const char *iniFile); #if defined(UNICODE) DllExport void get_lang_msgW(const char *key, wchar_t *buf, int buf_len, const wchar_t *def, const char *iniFile); #endif