Difference between revisions of "Arrays"
DaveRabelink (Talk | contribs) m (Added sample download link for "Passing arrays in messages" in section Arrays) |
DaveRabelink (Talk | contribs) (Added tip on getting array elements for any type of array) |
||
Line 41: | Line 41: | ||
Here you can download a sample: | Here you can download a sample: | ||
*[http://samples.tdcommunity.net/index.php?dir=&file=WIKI_PassingArraysInMessages.zip WIKI_PassingArraysInMessages.zip]<br> | *[http://samples.tdcommunity.net/index.php?dir=&file=WIKI_PassingArraysInMessages.zip WIKI_PassingArraysInMessages.zip]<br> | ||
+ | <br> | ||
+ | |||
+ | <!------------------------------------------------------------------------------------------------------------------------------> | ||
+ | {{TipHeader|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:<br> | ||
+ | <br> | ||
+ | <pre> | ||
+ | Local variables | ||
+ | String: saMyArray[*] | ||
+ | Actions | ||
+ | ... | ||
+ | If SalArrayIsEmpty( saMyArray ) | ||
+ | Set nArrayCount = 0 | ||
+ | Else | ||
+ | Call SalArrayGetUpperBound( saMyArray, 1, nUpperBound ) | ||
+ | Set nArrayCount = nUpperBound + 1 | ||
+ | ... | ||
+ | </pre> | ||
+ | <br> | ||
+ | This is a tedious task when you need to get the number elements spread over your sourcecode.<br> | ||
+ | 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).<br> | ||
+ | It would be simpler having a single function to do this, for any array you pass to it.<br> | ||
+ | <br> | ||
+ | <pre> | ||
+ | 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 | ||
+ | ... | ||
+ | </pre> | ||
+ | <br> | ||
+ | Problem is you can have arrays of any type: strings, numbers, datetimes,objects etc.<br> | ||
+ | <br> | ||
+ | So creating a function in which you pass any array, you need to specify the correct datatype of the parameter.<br> | ||
+ | That would mean multiple functions, each predefined for a specific datatype. And this is not very convenient.<br> | ||
+ | <br> | ||
+ | But we can use a trick which works for all datatypes and works on all TD versions (tested up to TD 6.2).<br> | ||
+ | <br> | ||
+ | It is secretly known that the TD compiler accepts passing an array to a function which accepts it as Window Handle datatype.<br> | ||
+ | Also the Sal/Vis functions on arrays (like SalArrayGetUpperBound) accept Window Handle datatype to reflect the array.<br> | ||
+ | <br> | ||
+ | Have a look at this:<br> | ||
+ | <br> | ||
+ | <pre> | ||
+ | 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 ) | ||
+ | ... | ||
+ | </pre> | ||
+ | <br> | ||
+ | As can be seen, the ArrayFunction has a Window Handle array as parameter.<br> | ||
+ | The TestArray function passes a string array to the ArrayFunction.<br> | ||
+ | The compiler accepts this and also the passed array is treated as an array correctly.<br> | ||
+ | <br> | ||
+ | <span style="color:red">BEWARE</span>: 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.<br> | ||
+ | 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<br> | ||
+ | like this: Window Handle: phWndArray[*]. Mind the brackets.<br> | ||
+ | <br> | ||
+ | <span style="color:red">ANOTHER BEWARE</span>: this trick does NOT work on .NET projects. The .NET compiler strictly forbids casting datatypes.<br> | ||
+ | <br> | ||
+ | Using this "feature", a simple function can be created which is able to get the number of elements of ANY array.<br> | ||
+ | <br> | ||
+ | The sample has two globally defined functions:<br> | ||
+ | <br> | ||
+ | <pre> | ||
+ | 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) | ||
+ | </pre> | ||
+ | <br> | ||
+ | Here you can download the sample using these two functions: | ||
+ | *[http://samples.tdcommunity.net/index.php?dir=&file=WIKI_PALArrayGetCount.zip WIKI_PALArrayGetCount.zip]<br> | ||
<br> | <br> |
Revision as of 08:36, 5 July 2013
This page covers Arrays from any datatype tips & tricks.
Contents |
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[0] = "Monday" Set saWeekDay[1] = "Tuesday" Set saWeekDay[2] = "Wednesday" ! ! Construct an array with customer objects Set uaCustomer[0].sivCustomerName = "Brendan Perry" Set uaCustomer[0].nivCustomerID = 1 Set uaCustomer[1].sivCustomerName = "Lisa Gerrard" Set uaCustomer[1].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 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: