メッセージ内容に全角がうまく表示されません。
ソースはMSDNのヘルプをちょっといじりました。(試行錯誤中)
問題の箇所は//*****ここの全角文字の表示がうまくいきません。
の次のコードです。
参考http
http://support.microsoft.com/default.aspx?scid=kb;ja;410837
test.c
#include <windows.h>
#include <stdlib.h>
#include <TCHAR.H>
#define APPNAME "test"
#define FOOBUFSIZE 1024
__declspec(dllexport) int __stdcall foo(VARIANT *v);
__declspec(dllexport) int __stdcall bar(VARIANT *v);
__declspec(dllexport) int __stdcall foo(VARIANT *v)
{
SAFEARRAY *psa = *(v->pparray);
wchar_t **ps;
static char buf[FOOBUFSIZE];
long i, j, lb, ub;
/* VariantのサブタイプとしてArrayかつString以外はエラーにする */
if (v->vt != (VT_ARRAY | VT_BSTR | VT_BYREF)) {
#ifdef _DEBUG
wsprintf(buf, "VT:%x\n", v->vt);
OutputDebugString(buf);
#endif
return 1;
/* 1次元配列以外はエラーにする */
} else if (psa->cDims != 1) {
return 1;
}
SafeArrayLock(psa);
ps = psa->pvData;
SafeArrayGetLBound(psa, 1, &lb);
SafeArrayGetUBound(psa, 1, &ub);
for (i = 0, j = lb; j <= ub; i++, j++) {
wcstombs(buf, ps[i], FOOBUFSIZE);
//*****ここの全角文字の表示がうまくいきません。
MessageBox(NULL, (char *)(wchar_t*)buf, APPNAME, MB_OK);
}
SafeArrayUnlock(psa);
return 0;
}
__declspec(dllexport) int __stdcall bar(VARIANT *v)
{
SAFEARRAY *psa = *(v->pparray);
wchar_t **ps;
int lb, ub;
if (v->vt != (VT_ARRAY | VT_BSTR | VT_BYREF)) return 1;
if (psa->cDims != 1) return 1;
SafeArrayLock(psa);
ps = psa->pvData;
SafeArrayGetLBound(psa, 1, &lb);
SafeArrayGetUBound(psa, 1, &ub);
if (ub - lb >= 1) {
SysFreeString(ps[1]);
ps[1] = SysAllocString(L"変換しました。END");
}
SafeArrayUnlock(psa);
return 0;
}
test.def
LIBRARY test
EXPORTS
foo
bar
VBのフォーム内容
Option Explicit
Private Declare Function foo Lib "test.dll" (v As Variant) As Long
Private Declare Function bar Lib "test.dll" (v As Variant) As Long
Private Sub Command1_Click()
Dim s(2) As String
s(0) = "Hello こんにちは"
s(1) = "Visual Basic "
s(2) = "world! だね"
foo s
bar s
Print s(0) & s(1) & s(2)
End Sub
以上、よろしくお願いいたします。
> MessageBox(NULL, (char *)(wchar_t*)buf, APPNAME, MB_OK);
wchar_t* でキャストして、さらに char* でキャストして…
一体ナニしたいんです?
UnicodeからAnsiに変換したいのであれば、キャストではムリ。
変換を試みず、MessageBoxW ではダメですか?
setlocale( LC_ALL, "Japanese" );
を入れてもダメでしょうか?
>setlocale( LC_ALL, "Japanese" );
で確認できました。(VC6/Excel 2003 VBA(VB6環境が手元にないため))
ちなみに SafeArrayGetElement を使えばもう少しシンプルにかけます。
(C++でもいいならcomdef.hの_bstr_tが便利なんですけどね)
一応試したコード)
void WINAPI Sample( VARIANT* v )
{
SAFEARRAY* psa;
BSTR wcs;
long i, lb, ub;
static char mbs[ 256 ];
if ( v->vt != ( VT_ARRAY | VT_BSTR | VT_BYREF ) ) return;
psa = *( v->pparray );
if ( psa->cDims != 1 ) return;
SafeArrayLock( psa );
SafeArrayGetLBound( psa, 1u, &lb );
SafeArrayGetUBound( psa, 1u, &ub );
setlocale( LC_ALL, "Japanese" );
for ( i = lb; i <= ub; i++ )
{
SafeArrayGetElement( psa, &i, ( void* )&wcs );
wcstombs( mbs, wcs, 256 );
MessageBox( NULL, mbs, NULL, MB_OK );
// MessageBoxW( NULL, wcs, NULL, MB_OK );
}
SafeArrayUnlock( psa );
}
それと、VB側でEXEを作ってしまえば、DLLのデバッグをすることが出来ます。
#include <locale.h>を追加して、setlocale( LC_ALL, "Japanese" ); で
出来ました。ローカルをJapaneseにしなければいけなかったのですね。
BSTRをどう表示できるのかしか、考えていませんでした。。
ありがとうございました。
ツイート | ![]() |