|
Toshihiro Shimizu |
890ddd |
#include "igs_resource_msg_from_err.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*------ localeを日本に設定し日本語を扱うことを指示
|
|
Toshihiro Shimizu |
890ddd |
(しないと日本語文字部分のみ処理しない)
|
|
Toshihiro Shimizu |
890ddd |
ただし数値カテゴリはC localeのままに
|
|
Toshihiro Shimizu |
890ddd |
(しないと3桁ごとにカンマが付く(1000-->1,000)) */
|
|
Toshihiro Shimizu |
890ddd |
void igs::resource::locale_to_jp(void)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
std::locale::global(
|
|
Toshihiro Shimizu |
890ddd |
std::locale(std::locale(), "japanese", std::locale::ctype));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/*------ マルチバイト文字列 --> ワイド文字文字列 ------*/
|
|
Toshihiro Shimizu |
890ddd |
void igs::resource::mbs_to_wcs(
|
|
Toshihiro Shimizu |
890ddd |
const std::string &mbs, std::wstring &wcs, const UINT code_page)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
/* 第4引数で -1 指定により終端文字を含む大きさを返す */
|
|
Toshihiro Shimizu |
890ddd |
/* int MultiByteToWideChar(
|
|
Toshihiro Shimizu |
890ddd |
UINT CodePage
|
|
Toshihiro Shimizu |
890ddd |
,DWORD dwFlags
|
|
Toshihiro Shimizu |
890ddd |
,LPCSTR lpMultiByteStr
|
|
Toshihiro Shimizu |
890ddd |
,int cbMultiByte
|
|
Toshihiro Shimizu |
890ddd |
,LPWSTR lpWideCharStr
|
|
Toshihiro Shimizu |
890ddd |
,int cchWideChar
|
|
Toshihiro Shimizu |
890ddd |
);
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
int length = ::MultiByteToWideChar(
|
|
Toshihiro Shimizu |
890ddd |
code_page, 0, mbs.c_str(), -1, 0, 0);
|
|
Toshihiro Shimizu |
890ddd |
if (length <= 1) {
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
} /* 終端以外の文字がないなら何もしない */
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*** std::vector<wchar_t> buf(length);</wchar_t>
|
|
Toshihiro Shimizu |
890ddd |
length = ::MultiByteToWideChar(
|
|
Toshihiro Shimizu |
890ddd |
code_page ,0 ,mbs.c_str() ,-1
|
|
Toshihiro Shimizu |
890ddd |
,&buf.at(0) ,static_cast<int>(buf.size())</int>
|
|
Toshihiro Shimizu |
890ddd |
);***/
|
|
Toshihiro Shimizu |
890ddd |
wcs.resize(length);
|
|
Toshihiro Shimizu |
890ddd |
length = ::MultiByteToWideChar(
|
|
Toshihiro Shimizu |
890ddd |
code_page, 0, mbs.c_str(), -1, const_cast<lpwstr>(wcs.data()), static_cast<int>(wcs.size()));</int></lpwstr>
|
|
Toshihiro Shimizu |
890ddd |
if (0 == length) {
|
|
Toshihiro Shimizu |
890ddd |
switch (::GetLastError()) {
|
|
Toshihiro Shimizu |
890ddd |
case ERROR_INSUFFICIENT_BUFFER:
|
|
Toshihiro Shimizu |
890ddd |
throw std::domain_error(
|
|
Toshihiro Shimizu |
890ddd |
"MultiByteToWideChar():insufficient buffer");
|
|
Toshihiro Shimizu |
890ddd |
case ERROR_INVALID_FLAGS:
|
|
Toshihiro Shimizu |
890ddd |
throw std::domain_error(
|
|
Toshihiro Shimizu |
890ddd |
"MultiByteToWideChar():invalid flags");
|
|
Toshihiro Shimizu |
890ddd |
case ERROR_INVALID_PARAMETER:
|
|
Toshihiro Shimizu |
890ddd |
throw std::domain_error(
|
|
Toshihiro Shimizu |
890ddd |
"MultiByteToWideChar():invalid parameter");
|
|
Toshihiro Shimizu |
890ddd |
case ERROR_NO_UNICODE_TRANSLATION:
|
|
Toshihiro Shimizu |
890ddd |
throw std::domain_error(
|
|
Toshihiro Shimizu |
890ddd |
"MultiByteToWideChar():no unicode translation");
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
//wcs = std::wstring(buf.begin() ,buf.end()-1); /* 終端以外を */
|
|
Toshihiro Shimizu |
890ddd |
wcs.erase(wcs.end() - 1); /* 終端文字を消す。end()は終端より先位置 */
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/*------ ワイド文字文字列 --> マルチバイト文字列 ------*/
|
|
Toshihiro Shimizu |
890ddd |
void igs::resource::wcs_to_mbs(
|
|
Toshihiro Shimizu |
890ddd |
const std::wstring &wcs, std::string &mbs, const UINT code_page)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
/* 第4引数で -1 指定により終端文字を含む大きさを返す */
|
|
Toshihiro Shimizu |
890ddd |
int length = ::WideCharToMultiByte(
|
|
Toshihiro Shimizu |
890ddd |
code_page, 0, wcs.c_str(), -1, 0, 0, 0, 0);
|
|
Toshihiro Shimizu |
890ddd |
if (length <= 1) {
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
} /* 終端以外の文字がないなら何もしない */
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*** std::vector<char> buf(length);</char>
|
|
Toshihiro Shimizu |
890ddd |
length = ::WideCharToMultiByte(
|
|
Toshihiro Shimizu |
890ddd |
code_page ,0 ,wcs.c_str() ,-1
|
|
Toshihiro Shimizu |
890ddd |
,&buf.at(0) ,static_cast<int>(buf.size()) ,0 ,NULL</int>
|
|
Toshihiro Shimizu |
890ddd |
);***/
|
|
Toshihiro Shimizu |
890ddd |
mbs.resize(length);
|
|
Toshihiro Shimizu |
890ddd |
length = ::WideCharToMultiByte(
|
|
Toshihiro Shimizu |
890ddd |
code_page, 0, wcs.c_str(), -1, const_cast<lpstr>(mbs.data()), static_cast<int>(mbs.size()), 0, NULL);</int></lpstr>
|
|
Toshihiro Shimizu |
890ddd |
if (0 == length) {
|
|
Toshihiro Shimizu |
890ddd |
switch (::GetLastError()) {
|
|
Toshihiro Shimizu |
890ddd |
case ERROR_INSUFFICIENT_BUFFER:
|
|
Toshihiro Shimizu |
890ddd |
throw std::domain_error(
|
|
Toshihiro Shimizu |
890ddd |
"WideCharToMultiByte():insufficient buffer");
|
|
Toshihiro Shimizu |
890ddd |
case ERROR_INVALID_FLAGS:
|
|
Toshihiro Shimizu |
890ddd |
throw std::domain_error(
|
|
Toshihiro Shimizu |
890ddd |
"WideCharToMultiByte():invalid flags");
|
|
Toshihiro Shimizu |
890ddd |
case ERROR_INVALID_PARAMETER:
|
|
Toshihiro Shimizu |
890ddd |
throw std::domain_error(
|
|
Toshihiro Shimizu |
890ddd |
"WideCharToMultiByte():invalid parameter");
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
//mbs = std::string(buf.begin() ,buf.end()-1); /* 終端以外を */
|
|
Toshihiro Shimizu |
890ddd |
mbs.erase(mbs.end() - 1); /* 終端文字を消す。end()は終端より先位置 */
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/*------ UNICODE宣言ならマルチバイト文字列をワイド文字文字列に変換 ------*/
|
|
Toshihiro Shimizu |
890ddd |
const std::basic_string<tchar> igs::resource::ts_from_mbs(</tchar>
|
|
Toshihiro Shimizu |
890ddd |
const std::string &mbs, const UINT code_page)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
#if defined UNICODE
|
|
Toshihiro Shimizu |
890ddd |
std::wstring wcs;
|
|
Toshihiro Shimizu |
890ddd |
igs::resource::mbs_to_wcs(mbs, wcs, code_page);
|
|
Toshihiro Shimizu |
890ddd |
return wcs;
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Toshihiro Shimizu |
890ddd |
code_page;
|
|
Toshihiro Shimizu |
890ddd |
/* MBCSの場合のsize()は文字数ではなくchar(byte)数,2bytes文字は2 */
|
|
Toshihiro Shimizu |
890ddd |
return mbs;
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/*------ UNICODE宣言ならワイド文字文字列をマルチバイト文字列に変換 ------*/
|
|
Toshihiro Shimizu |
890ddd |
const std::string igs::resource::mbs_from_ts(
|
|
Toshihiro Shimizu |
890ddd |
const std::basic_string<tchar> &ts, const UINT code_page)</tchar>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
#if defined UNICODE
|
|
Toshihiro Shimizu |
890ddd |
std::string mbs;
|
|
Toshihiro Shimizu |
890ddd |
igs::resource::wcs_to_mbs(ts, mbs, code_page);
|
|
Toshihiro Shimizu |
890ddd |
return mbs;
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Toshihiro Shimizu |
890ddd |
code_page;
|
|
Toshihiro Shimizu |
890ddd |
/* MBCSの場合のsize()は文字数ではなくchar(byte)数,2bytes文字は2 */
|
|
Toshihiro Shimizu |
890ddd |
return ts;
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/*------ cp932を含む文字列をutf-8に変換(マルチバイト文字列) ------*/
|
|
Toshihiro Shimizu |
890ddd |
const std::string igs::resource::utf8_from_cp932_mb(const std::string &text)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
std::wstring wcs;
|
|
Toshihiro Shimizu |
890ddd |
igs::resource::mbs_to_wcs(text, wcs);
|
|
Toshihiro Shimizu |
890ddd |
std::string mbs;
|
|
Toshihiro Shimizu |
890ddd |
igs::resource::wcs_to_mbs(wcs, mbs, CP_UTF8);
|
|
Toshihiro Shimizu |
890ddd |
return mbs;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/*------ utf-8を含む文字列をcp932に変換(マルチバイト文字列) ------*/
|
|
Toshihiro Shimizu |
890ddd |
const std::string igs::resource::cp932_from_utf8_mb(const std::string &text)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
std::wstring wcs;
|
|
Toshihiro Shimizu |
890ddd |
igs::resource::mbs_to_wcs(text, wcs, CP_UTF8);
|
|
Toshihiro Shimizu |
890ddd |
std::string mbs;
|
|
Toshihiro Shimizu |
890ddd |
igs::resource::wcs_to_mbs(wcs, mbs, 932);
|
|
Toshihiro Shimizu |
890ddd |
return mbs;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/*------ エラーメッセージ表示の元関数、直接呼び出すことはしない ------*/
|
|
Toshihiro Shimizu |
890ddd |
#include <sstream></sstream>
|
|
Toshihiro Shimizu |
890ddd |
const std::string igs::resource::msg_from_err_(
|
|
Toshihiro Shimizu |
890ddd |
const std::basic_string<tchar> &tit, const DWORD error_message_id, const std::basic_string<tchar> &file, const std::basic_string<tchar> &line, const std::basic_string<tchar> &funcsig, const std::basic_string<tchar> &comp_type, const std::basic_string<tchar> &msc_full_ver, const std::basic_string<tchar> &date, const std::basic_string<tchar> &time)</tchar></tchar></tchar></tchar></tchar></tchar></tchar></tchar>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
汎用データ型 ワイド文字(UNICODE)(※1) マルチバイト文字(_MBCS)(※2)
|
|
Toshihiro Shimizu |
890ddd |
TCHAR wchar_t char
|
|
Toshihiro Shimizu |
890ddd |
LPTSTR wchar_t * char *
|
|
Toshihiro Shimizu |
890ddd |
LPCTSTR const wchar_t * const char *
|
|
Toshihiro Shimizu |
890ddd |
※1 1文字を16ビットのワイド文字として表すUnicode を使う方法
|
|
Toshihiro Shimizu |
890ddd |
すべての文字が 16 ビットに固定されます。
|
|
Toshihiro Shimizu |
890ddd |
マルチバイト文字に比べ、メモリ効率は低下しますが処理速度は向上します
|
|
Toshihiro Shimizu |
890ddd |
※2 1文字を複数のバイトで表すマルチバイト文字
|
|
Toshihiro Shimizu |
890ddd |
MBCS(Multibyte Character Set) と呼ばれる文字集合を使う方法
|
|
Toshihiro Shimizu |
890ddd |
可変長だが、事実上、サポートされているのは 2 バイト文字までなので、
|
|
Toshihiro Shimizu |
890ddd |
マルチバイト文字の 1 文字は 1 バイトまたは 2 バイトとなります。
|
|
Toshihiro Shimizu |
890ddd |
Windows 2000 以降、Windows は内部で Unicode を使用しているため、
|
|
Toshihiro Shimizu |
890ddd |
マルチバイト文字を使用すると内部で文字列の変換が発生するため
|
|
Toshihiro Shimizu |
890ddd |
オーバーヘッドが発生します。
|
|
Toshihiro Shimizu |
890ddd |
UNICODEも_MBCSも未定義のときはこちらになる。
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
std::basic_string<tchar> errmsg;</tchar>
|
|
Toshihiro Shimizu |
890ddd |
errmsg += TEXT('\"');
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/* makefile-vc2008mdAMD64等でコンパイルすると
|
|
Toshihiro Shimizu |
890ddd |
フルパスで入ってくるのでファイル名だけにする
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
std::basic_string<tchar>::size_type index =</tchar>
|
|
Toshihiro Shimizu |
890ddd |
file.find_last_of(TEXT("/\\"));
|
|
Toshihiro Shimizu |
890ddd |
if (std::basic_string<tchar>::npos != index) {</tchar>
|
|
Toshihiro Shimizu |
890ddd |
errmsg += file.substr(index + 1);
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
errmsg += file;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
errmsg += TEXT(':');
|
|
Toshihiro Shimizu |
890ddd |
errmsg += line;
|
|
Toshihiro Shimizu |
890ddd |
errmsg += TEXT(':');
|
|
Toshihiro Shimizu |
890ddd |
errmsg += comp_type;
|
|
Toshihiro Shimizu |
890ddd |
errmsg += TEXT(":");
|
|
Toshihiro Shimizu |
890ddd |
errmsg += msc_full_ver;
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
std::basic_istringstream<tchar> ist(date);</tchar>
|
|
Toshihiro Shimizu |
890ddd |
std::basic_string<tchar> month, day, year;</tchar>
|
|
Toshihiro Shimizu |
890ddd |
ist >> month;
|
|
Toshihiro Shimizu |
890ddd |
ist >> day;
|
|
Toshihiro Shimizu |
890ddd |
ist >> year;
|
|
Toshihiro Shimizu |
890ddd |
errmsg += TEXT(':');
|
|
Toshihiro Shimizu |
890ddd |
errmsg += year;
|
|
Toshihiro Shimizu |
890ddd |
errmsg += TEXT(':');
|
|
Toshihiro Shimizu |
890ddd |
errmsg += month;
|
|
Toshihiro Shimizu |
890ddd |
errmsg += TEXT(':');
|
|
Toshihiro Shimizu |
890ddd |
errmsg += day;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
errmsg += TEXT(':');
|
|
Toshihiro Shimizu |
890ddd |
errmsg += time;
|
|
Toshihiro Shimizu |
890ddd |
errmsg += TEXT('\"');
|
|
Toshihiro Shimizu |
890ddd |
errmsg += TEXT(' ');
|
|
Toshihiro Shimizu |
890ddd |
errmsg += TEXT('\"');
|
|
Toshihiro Shimizu |
890ddd |
errmsg += funcsig;
|
|
Toshihiro Shimizu |
890ddd |
errmsg += TEXT('\"');
|
|
Toshihiro Shimizu |
890ddd |
errmsg += TEXT(' ');
|
|
Toshihiro Shimizu |
890ddd |
errmsg += TEXT('\"');
|
|
Toshihiro Shimizu |
890ddd |
if (0 < tit.size()) {
|
|
Toshihiro Shimizu |
890ddd |
errmsg += tit;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
if (NO_ERROR != error_message_id) {
|
|
Toshihiro Shimizu |
890ddd |
errmsg += TEXT(':');
|
|
Toshihiro Shimizu |
890ddd |
LPTSTR lpMsgBuf = 0;
|
|
Toshihiro Shimizu |
890ddd |
if (0 < ::FormatMessage(
|
|
Toshihiro Shimizu |
890ddd |
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
|
Toshihiro Shimizu |
890ddd |
FORMAT_MESSAGE_FROM_SYSTEM |
|
|
Toshihiro Shimizu |
890ddd |
FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
Toshihiro Shimizu |
890ddd |
NULL, error_message_id, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT) /* 既定言語 */
|
|
Toshihiro Shimizu |
890ddd |
,
|
|
Toshihiro Shimizu |
890ddd |
reinterpret_cast<lptstr>(&lpMsgBuf), 0, NULL)) { /* --- 成功 --- */</lptstr>
|
|
Toshihiro Shimizu |
890ddd |
errmsg += lpMsgBuf;
|
|
Toshihiro Shimizu |
890ddd |
::LocalFree(lpMsgBuf);
|
|
Toshihiro Shimizu |
890ddd |
std::string::size_type index =
|
|
Toshihiro Shimizu |
890ddd |
errmsg.find_first_of(TEXT("\r\n"));
|
|
Toshihiro Shimizu |
890ddd |
if (std::string::npos != index) {
|
|
Toshihiro Shimizu |
890ddd |
errmsg.erase(index);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
} else { /* エラー */
|
|
Toshihiro Shimizu |
890ddd |
errmsg += TEXT("FormatMessage() can not get (error)message");
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
errmsg += TEXT('\"');
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/* MBCSで返す */
|
|
Toshihiro Shimizu |
890ddd |
return igs::resource::mbs_from_ts(errmsg);
|
|
Toshihiro Shimizu |
890ddd |
}
|