VC++を使うのは今回が初めての初心者です。
現在ActiveXコントロールを作成しているのですが、
Variant型からCStringArray型への変換方法がわからなくて困っています。
Variant型やSafeArrayの使い方がよくわからないまま、
コーディングをしてみたのですが(下記ソース)うまく変換できません。
メッセージボックスで引数の内容を表示させると件数分表示されるのですが
最初の1文字しか表示されません。
「A」
「B」
「C」
「D」
「E」
「F」
「G」 と7回表示されます。
どなたか詳しい方教えていただけないでしょうか
よろしくお願いします。
****************************
以下 のようにVB側で呼び出しています
Dim ArrayToken(7) As String
Dim value() As Variant
ArrayToken(0) = "AAAAAA"
ArrayToken(1) = "BBBBBB"
ArrayToken(2) = "CCCCCC"
ArrayToken(3) = "DDDDDD"
ArrayToken(4) = "EEEEEE"
ArrayToken(5) = "FFFFFF"
ArrayToken(6) = "GGGGGG"
lRet = TestOcx.Test1(ArrayToken, value)
****************************
以下 VC++側
short CTestCtrl::test1(const VARIANT FAR& Token, const VARIANT FAR& RetValues)
{
// TODO: ここにディスパッチ ハンドラ コードを追加してください。
long lnCode;
int i;
char *ptr;
VARIANT args = Token;
VARTYPE vt = V_VT(&args);
// VARIANT型 REFERENCE(参照渡し) のチェック
if (vt == (VT_VARIANT | VT_BYREF)) {
args = *args.pvarVal;
vt = V_VT(&args);
}
int bArray = vt & VT_ARRAY;
if (!bArray) // not array
return 0;
SAFEARRAY *psa = NULL;
HRESULT hr;
LONG cElements, lLBound, lUBound;
psa = V_ARRAY(&args);
// 配列の次元数をチェック.
if (SafeArrayGetDim(psa) != 1)
return 0;
// 配列のインデックスをチェック.
hr = SafeArrayGetLBound(psa, 1, &lLBound);
if (FAILED(hr))
return 0;
hr = SafeArrayGetUBound(psa, 1, &lUBound);
if (FAILED(hr))
return 0;
// 配列の要素へのポインタを取得.
hr = SafeArrayAccessData(psa, (LPVOID*)&ptr);
if (FAILED(hr))
return 0;
// 配列の要素数.
cElements = lUBound - lLBound + 1;
// メッセージボックスで内容確認!!
long saidx[2];
char szidx[MAX_DN_CHARS];
saidx[0] = 1;
for ( i = lLBound; i < lUBound; i++ ) {
saidx[1] = i;
hr = SafeArrayGetElement( psa, saidx, &ptr );
sprintf( szidx, "[%d]", saidx[0]);
MessageBox( ptr, NULL, MB_ICONINFORMATION);
}
hr = SafeArrayUnaccessData(psa);
<省略>
}
こんな感じでできるかも
void GetStringArrayFromVARIANT( const VARIANT* psarrayItemData, CStringArray &csa )
{
USES_CONVERSION;
COleSafeArray sarrayItemList( *psarrayItemData );
long nItemCnt;
sarrayItemList.GetUBound( 1, &nItemCnt );
++nItemCnt; // array size = upper bound of array + 1
for (long i = 0; i < nItemCnt; ++i)
{
CComVariant comVar;
sarrayItemList.GetElement( &i, &comVar );
if( comVar.vt == VT_BSTR )
{
CString str = OLE2T( comVar.bstrVal );
csa.Add( str );
}
}
return;
}
ツイート | ![]() |