Come visualizzare i valori da questa istanza VARIANT e salvarlo in un TStringLi st?
Il COM VARIANT
struttura ha parray
e pparray
membri dati che sono puntatori a un SAFEARRAY
, per esempio:
VARIANT V;
LPSAFEARRAY sa = V_ISBYREF(&V) ? V_ARRAYREF(&V) : V_ARRAY(&V);
La classe VCL Variant
, d'altra parte, ha un operatore LPSAFEARRAY
conversione definito, in modo da poterlo assegnare direttamente (ma solo se il campo Variant.VType
non ha il flag varByRef
presente), ad esempio:
Variant V;
LPSAFEARRAY sa = V;
In entrambi i casi, una volta che si ha il puntatore SAFEARRAY
, utilizzare l'API SafeArray per accedere ai valori BSTR
, ad esempio:
bool __fastcall VariantToStrings(const Variant &V, TStrings *List)
{
// make sure the Variant is holding an array
if (!V_ISARRAY(&V)) return false;
// get the array pointer
LPSAFEARRAY sa = V_ISBYREF(&V) ? V_ARRAYREF(&V) : V_ARRAY(&V);
// make sure the array is holding BSTR values
VARTYPE vt;
if (FAILED(SafeArrayGetVartype(sa, &vt))) return false;
if (vt != VT_BSTR) return false;
// make sure the array has only 1 dimension
if (SafeArrayGetDim(sa) != 1) return false;
// get the bounds of the array's sole dimension
LONG lBound = -1, uBound = -1;
if (FAILED(SafeArrayGetLBound(sa, 0, &lBound))) return false;
if (FAILED(SafeArrayGetUBound(sa, 0, &uBound))) return false;
if ((lBound > -1) && (uBound > -1))
{
// access the raw data of the array
BSTR *values = NULL;
if (FAILED(SafeArrayAccessData(sa, (void**)&values))) return false;
try
{
List->BeginUpdate();
try
{
// loop through the array adding the elements to the list
for (LONG idx = lBound; l <= uBound; ++idx)
{
String s;
if (values[idx] != NULL)
s = String(values[idx], SysStringLen(values[idx]));
List->Add(s);
}
}
__finally
{
List->EndUpdate();
}
}
__finally
{
// unaccess the raw data of the array
SafeArrayUnaccessData(sa);
}
}
return true;
}
VarClear (V); TVarData (V) .VType = varOleStr;
Non hai bisogno di quelli a tutti. La classe VCL Variant
si inizializza in uno stato vuoto e non è necessario assegnare lo VType
poiché si assegna immediatamente un nuovo valore all'intero Variant
.
V = ComFunction-> GetValues (); // < < < < ----- V è vuoto
Se V è vuota, allora GetValues()
restituisce un vuoto Variant
per cominciare.
mystr = (wchar_t *) (TVarData (V) .VString);
TVarData::VString
è un riferimento AnsiString&
, non un puntatore wchar_t*
. Per convertire un VCL Variant
(non un COM VARIANT
) per un String
, basta assegnarlo così com'è e lasciare che il RTL funziona dettaglio per voi:
String mystr = V;