Posts: 133
Threads: 15
Joined: Jun 2014
Is there anyway to differentiate between different array type?
Let's say I have 4 arrays with 4 different types:
Macro Macro132
ARRAY(int) aInt.create(3)
aInt[0]=1
aInt[1]=2
aInt[2]=3
ARRAY(double) aDouble.create(3)
aDouble[0]=1.0
aDouble[1]=2.0
aDouble[2]=3.0
ARRAY(str) aStr="abc[]def[]ghi"
ARRAY(lpstr) aLpstr.create(3)
aLpstr[0]="abc"
aLpstr[1]="def"
aLpstr[2]="ghi"
How to differentiate between aInt, aDouble, aStr and aLpstr in coding not just by simply looking at their names?
Posts: 12,073
Threads: 140
Joined: Dec 2002
Get array type at run time? Some types can be extracted from SAFEARRAY structure. For other types can only get size of elements. I'll try to create a function for it if you need.
Posts: 133
Threads: 15
Joined: Jun 2014
Yes, could you post your function?
Posts: 12,073
Threads: 140
Joined: Dec 2002
What types will need to recognize?
int, double, str, lpstr - possible. What other types?
Posts: 12,073
Threads: 140
Joined: Dec 2002
But cannot get type of empty arrays.
Posts: 133
Threads: 15
Joined: Jun 2014
Right now I just need 2 types: int and str only.
Yes these arrays are not empty at all.
Posts: 12,073
Threads: 140
Joined: Dec 2002
Function GetArrayType
;/
function# SAFEARRAY*a ;;Returns: str 256, lpstr 257, Acc 258, int VT_I4, byte VT_UI1, word VT_I2, long VT_I8, double VT_R8, other VT_, unknown -size, empty 0.
;Returns array type, if possible.
;If cannot get type, returns -size.
;Returns 0 if array not created or somehow invalid.
;For some types returns one of VT_ constants. Some listed above.
;For some other types returns >=256. See above. You can edit this function to add more known types.
;For COM interfaces returns either VT_UNKNOWN or VT_DISPATCH.
;For pointers returns VT_I4 (int).
word vt; IRecordInfo ri
if !SafeArrayGetVartype(a &vt)
,if(vt>255) ret iif(vt&0xff00=VT_BYREF VT_I4 0)
,if(vt!=VT_RECORD) ret vt
,if !SafeArrayGetRecordInfo(a &ri)
,,ARRAY(int)+ ___gat; int i
,,if !___gat.len
,,,lock
,,,if !___gat.len
,,,,ARRAY(str) a0.create
,,,,ARRAY(lpstr) a1.create
,,,,ARRAY(Acc) a2.create
,,,,;Here you can add more array types like the above 3 lines. Then restart QM or reopen file.
,,,,;Add only composite types, because simple types like RECT don't have IRecordInfo. Simple types have only size.
,,,,;Composite types are types and classes that have a destructor or contain str, BSTR, VARIANT, ARRAY, interface, another composite type.
,,,,
,,,,SAFEARRAY** k=&a0.psa
,,,,___gat.create(&k-&a0/4)
,,,,for(i 0 ___gat.len) SafeArrayGetRecordInfo(k[i] +&___gat[i])
,,
,,for(i 0 ___gat.len) if(ri=___gat[i]) ret 256+i
ret -SafeArrayGetElemsize(a)
test
Macro Macro2422
out
ARRAY(int) aInt.create
ARRAY(byte) aByte.create
ARRAY(word) aWord.create
ARRAY(long) aLong.create
ARRAY(double) aDouble.create
ARRAY(str) aStr.create
ARRAY(lpstr) aLpstr.create
ARRAY(BSTR) aBstr.create
ARRAY(VARIANT) aVariant.create
ARRAY(CURRENCY) aCurrency.create
ARRAY(FLOAT) aFloat.create
ARRAY(DECIMAL) aDecimal.create
ARRAY(DATE) aDate.create
ARRAY(RECT) aRect.create
ARRAY(Acc) aAcc.create
ARRAY(SmtpMail) aSmtpMail.create
ARRAY(IXml) aIXml.create
ARRAY(IAccessible) aIAccessible.create
ARRAY(double*) aPtr.create
ARRAY(int) aNotCreated
int t=GetArrayType(aInt)
if(t=0) out "array not created or invalid"
else if(t<0) out "type unknown, size=%i" -t
else
,sel t
,,case VT_I4; out "int or pointer"
,,case VT_UI1 out "byte"
,,case VT_I2 out "word"
,,case VT_I8 out "long"
,,case VT_R8 out "double"
,,case VT_BSTR out "BSTR"
,,case VT_VARIANT out "VARIANT"
,,case VT_CY out "CURRENCY"
,,case VT_R4 out "FLOAT"
,,case VT_DECIMAL out "DECIMAL"
,,case VT_DATE out "DATE"
,,case VT_UNKNOWN out "IUnknown or an interface that does not have IDispatch"
,,case VT_DISPATCH out "IDispatch or an interface that has IDispatch"
,,case 256 out "str"
,,case 257 out "lpstr"
,,case 258 out "Acc"
Posts: 133
Threads: 15
Joined: Jun 2014
You give me more than what I've asked for!
I really appreciate your fast response and great effort for this.
Thank you very much as always, Gintaras!
Posts: 1,031
Threads: 246
Joined: Jul 2022
01-24-2024, 06:17 AM
(This post was last modified: 01-24-2024, 06:21 AM by Davider.)
I need to get the type of the array variable passed in. Is this possible? Alternatively, are there any other solutions?
The following code will show an error
Macro Macro29
ARRAY(str) as; out sub.f(as)
ARRAY(str) ai; out sub.f(ai)
#sub f
function~ `arg
sel GetArrayType(arg)
,case VT_I4; ret "int[]"
,case 256; ret "string[]"
Posts: 1,336
Threads: 61
Joined: Jul 2006
Macro Macro29
ARRAY(str) as.create; out sub.f(as)
ARRAY(int) ai.create; out sub.f(ai)
#sub f
function~ SAFEARRAY*arg
sel GetArrayType(arg)
,case VT_I4; ret "int[91]]"
,case 256; ret "string[91]]"
Posts: 1,031
Threads: 246
Joined: Jul 2022
01-26-2024, 11:12 PM
(This post was last modified: 01-27-2024, 02:56 AM by Davider.)
Thanks for your help.
|