Passing arrays in messages (any datatypes)
(From CenturaPro september 1999)
To pass arrays using messages, use this nice trick to convert the address of any type of array
to a number and send them along as wParam or lParam.
At the source (sending side) do this to pass arrays to a window
! Construct an array with weekdays Set saWeekDay = "Monday" Set saWeekDay = "Tuesday" Set saWeekDay = "Wednesday" ! ! Construct an array with customer objects Set uaCustomer.sivCustomerName = "Brendan Perry" Set uaCustomer.nivCustomerID = 1 Set uaCustomer.sivCustomerName = "Lisa Gerrard" Set uaCustomer.nivCustomerID = 2 ! ! Get the address of the arrays as number Set nAddressStringArray = SalWindowHandleToNumber( saWeekDay ) Set nAddressUDVArray = SalWindowHandleToNumber( uaCustomer ) ! ! Send along the addresses as wParam and lParam Call SalPostMsg( frmMain, SAM_User, nAddressStringArray, nAddressUDVArray )
Now at the receiving side (frmMain), convert the array address back to an array variable
On SAM_User Call VisArrayCopy( SalNumberToWindowHandle( wParam ), saWeekDay, DT_String ) Call VisArrayCopy( SalNumberToWindowHandle( lParam ), uaCustomer, DT_Handle )
Here you can download a sample:
Single function to get number of elements in any array
Having an array (any type) the following piece of code will determine how many elements are in the array:
Local variables String: saMyArray[*] Actions ... If SalArrayIsEmpty( saMyArray ) Set nArrayCount = 0 Else Call SalArrayGetUpperBound( saMyArray, 1, nUpperBound ) Set nArrayCount = nUpperBound + 1 ...
This is a tedious task when you need to get the number elements spread over your sourcecode.
The code above does not even take into account the use of a different lower bound of the array (so not starting at zero index).
It would be simpler having a single function to do this, for any array you pass to it.
Local variables String: saMyArray[*] Number: naMyArray[1:*] Customer: uaMyCustomerArray[*,5] Number: nArrayCount Actions ... Set nArrayCount = PALArrayGetCount( saMyArray ) ! string array count Set nArrayCount = PALArrayGetCount( naMyArray ) ! number array count Set nArrayCount = PALArrayGetCount( uaMyCustomerArray ) ! object array count ...
Problem is you can have arrays of any type: strings, numbers, datetimes,objects etc.
So creating a function in which you pass any array, you need to specify the correct datatype of the parameter.
That would mean multiple functions, each predefined for a specific datatype. And this is not very convenient.
But we can use a trick which works for all datatypes and works on all TD versions (tested up to TD 6.2).
It is secretly known that the TD compiler accepts passing an array to a function which accepts it as Window Handle datatype.
Also the Sal/Vis functions on arrays (like SalArrayGetUpperBound) accept Window Handle datatype to reflect the array.
Have a look at this:
Function: TestArray Local variables String: saTest[*] Actions Call ArrayFunction( saTest ) Function: ArrayFunction Parameters Window Handle: phWndArray[*] Local variables Number: nUpperBound Actions Call SalArrayGetUpperBound( phWndArray, 1, nUpperBound ) ...
As can be seen, the ArrayFunction has a Window Handle array as parameter.
The TestArray function passes a string array to the ArrayFunction.
The compiler accepts this and also the passed array is treated as an array correctly.
BEWARE: maybe you have seen such a trick before, but it could be that the parameter is defined as Window Handle and not as a Window Handle array.
With TD 6.1 and up, the compiler does NOT accept a Window Handle parameter like "Window Handle: phWndArray", you must define it as a real array
like this: Window Handle: phWndArray[*]. Mind the brackets.
ANOTHER BEWARE: this trick does NOT work on .NET projects. The .NET compiler strictly forbids casting datatypes.
Using this "feature", a simple function can be created which is able to get the number of elements of ANY array.
The sample has these two globally defined functions:
PALArrayGetCount( Array ) -> gets the number of elements in Array for the first dimension only PALArrayDimGetCount( Array, nDimension ) -> gets the number of elements in Array for any dimension (1..n)
Here you can download the sample using these two functions: