Zugg MASTER

Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Sun Mar 27, 2005 11:55 pm
zApp and VBScript arrays |
Wow, what a mess. I never thought this would take a whole day to deal with.
Here is what I wanted to be able to do with zApp grids:
Code: |
Dim A
A = Array("Item 1", "Item 2", "Item 3", "Item 4")
Grid.Data = A
A(0) = "New Item 1"
Grid.DataChanged |
In other words, I want to point the Grid at a Variant Array in VBScript, and have changes made to this array get updated in the grid. In addition, if the user edits the value of the grid, I want the new value to show up in the VB array.
Well, this turns out to be a real pain. Delphi treats Variant Arrays from VBScript as OleVariant objects, rather than COM SafeArrays. While this works for most applications, what it does is force Delphi to make a copy of the entire array. So, when you assign the array to the grid, you end up with a duplicate array, and changes to the array in the script are not reflected in the grid, and edits of the grid are not reflected in the VBscript array.
I thought this would be easy to fix since I have full control over how parameters gets passed to my proxy COM objects. But Delphi is apparently hard-coded to *always* treat a variant array by reference, and always makes a copy of it no matter what you try to do.
After tearing my hair out for a while on this, I finally came up with a pretty clean solution. I created a COM object for handling array references. When I see a variant array passed from VBScript, I convert this to one of my array reference COM objects. Now that it's a COM object instead of a variant array, Delphi doesn't touch it.
Then, when the Grid accesses the data, I check to see if it points to one of my array reference COM objects, and if so, I ask the COM object to handle the Get and Put of the data in the array. The COM object has a pointer to the original VBScript array, so it can modify the original without making a copy.
Obviously this would never work for *REAL* COM objects, since real COM objects can exist in different process spaces (which is why Delphi needs to copy the data). But in the case of zApp, we know that the VBScript code is *always* being executed in the same process space as zApp, so passing a pointer to the array data works fine.
So, this is all working now. I'm now extending this to work on a 2-dimensional array so that you can Get and Put cells in the grid with a direct cell reference.
Yet another one of the cool features that zApp enables with your scripting language that nobody else does  |
|