「文字列操作は ATL::CStringが良さそう」という結論になったのですが、よく考えると標準関数の多くは文字列といえばchar *を期待しているわけです。
取得したデータもANSIコードページだったりするので、UNICODEに変換してやらないとまともに表示することはできません。
で、文字列の変換にはMultiByteToWideChar()を使用する必要があるようです。
void ShowMessage(HWND hWnd) { WSADATA wsaData; CString msg = _T(""); char hostname[256]; _TCHAR * buf; int len; WSAStartup(MAKEWORD(2,2), &wsaData); gethostname(hostname, 256); WSACleanup(); len = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, hostname, -1, NULL, 0); if (len > 0) { buf = (_TCHAR *)calloc( len, sizeof(_TCHAR)); if (buf != NULL) { MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, hostname, -1, buf, len); msg.Format(_T("host=%s"), buf); free(buf); } } MessageBox(hWnd, msg, _T("ホスト名"), MB_OK); }
面度くせぇ(笑
せっかくATL::CStringで行こうと思ってるのに、char *やら _TCHAR *やらの方が目立ってます。
その後 ATL::CStringのヘルプを見ていると CSimpleStringT::GetBufferなるものを発見。
void ShowMessage(HWND hWnd) { WSADATA wsaData; CString msg = _T(""); char hostname[256]; CString buf; int len; WSAStartup(MAKEWORD(2,2), &wsaData); gethostname(hostname, 256); WSACleanup(); len = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, hostname, -1, NULL, 0); if (len > 0) { MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, hostname, -1, buf.GetBuffer(len) , len); msg.Format(_T("host=%s"), buf); buf.ReleaseBuffer(); } MessageBox(hWnd, msg, _T("ホスト名"), MB_OK); }
ちょっとだけスッキリしましたね。
gethostname()に渡す部分もATL::CStringにしてみます。
void ShowMessage(HWND hWnd) { WSADATA wsaData; CString msg = _T(""); CString hostname; CString buf; int len; char * pszHostname; WSAStartup(MAKEWORD(2,2), &wsaData); pszHostname = (char *)hostname.GetBuffer(256); gethostname(pszHostname, 256); WSACleanup(); len = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pszHostname, -1, NULL, 0); if (len > 0) { MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pszHostname, -1, buf.GetBuffer(len) , len); msg.Format(_T("host=%s"), buf); buf.ReleaseBuffer(); } pszHostname = NULL; hostname.ReleaseBuffer(); MessageBox(hWnd, msg, _T("ホスト名"), MB_OK); }
冗長になっただけのような気もしますが、ANSI->UNICODE変換部分を別関数に持っていけばこれでもいいのかな?
0 件のコメント:
コメントを投稿