Variant型からCStringArray型へ変換するには?


しょん  2004-11-16 22:00:59  No: 55206

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);

        <省略>

}


HIRO  2004-11-17 21:23:39  No: 55207

こんな感じでできるかも

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;
}


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加