06 March 2009

The Collection Ocx (part 1)

My first serious entry in this blog concerns the intrinsic Ocx object Collection. It is supposed to be the mother of all collections used throughout the Ocx implementations in GFA-BASIC 32. These collections include Panels, Buttons, ListItems, ListImages, etc. I will come to speak about these collection in the near future many times. However, as we will see, the Collection object itself isn't primary base of these other collections, it is the Hash data type that lies at the basis of each collection. Like VB(A), GFA-BASIC 32 features the generic Collection COM object type, which is simply a container for data. Although typically it is used with other objects (Panels, Buttons, etc.) it can in fact hold data of any type and stores the data in a Variant. Everything that can be stored in a Variant can be stored in a collection, including other collection objects (Variants can hold COM objects). The Collection object is a kind-of object-oriented version (Ocx) of the array. The Collection object is internally implemented as a hashed 'linked list', and as such provides good performance for access either by an item's key, index (yes GFA-BASIC 32 does), or through enumeration. In particular, I would emphasize the feature to access the hash elements by index. This is an extension on a 'normal' implementation of a hashed 'linked list'. In fact the GFA-BASIC 32 Hash data type is not implemented as a linked list, although the name of the data type suggests it does. The GFA-BASIC 32 Hash data type has been optimized extensively because it is used as storage for almost everything that GFA-BASIC does. Later more on this. Sufficient is to say that the compiler, which is very fast, uses many hash tables to store variable and type information. Let's look into the Collection type for now. You create a Collection as you would any other object: using Dim and the New declaration. Dim MyColl As New Collection The New keyword creates a new object of the specified type. It actually allocates memory for the COM object and sets its reference count to 1. The variable points to the allocated memory, which it wouldn't if the New clause was omitted. Remember, control Ocx objects are created using the Ocx or OcxOcx keywords. These keywords implicitly execute the Global Dim ... New command. (Each variable introduced with Ocx and OcxOcx is global and the control is actually created.) You cannot create a control Ocx object using a Dim statement, the compiler is instructed hard coded to explicitly check for New in combination with only a few COM types (Collection, DisAsm, StdFont, StdPicture). New in combination with any other type is rejected by the compiler. A COM object always comes with a set of functions (procedures) that are collected into an array, this is called an interface. The first element of a COM object always points to this array with functions, this element is always called lpVtbl. The first 7 entries in the interface contain the mandatory IUnknow functions (3) followed by the (optional) IDispatch functions (4). These standard OLE functions are then followed by the functions that make up the functionality of the Collection COM object: Item, Add, Count, Remove, and the hidden _NewEnum functions, respectively. Some of the interface functions are labeled 'get' or 'put', others aren't. When a function is labeled get or put the compiler is instructed to accept those functions as if they are used as variables using the assignment operator =. For instance, the Count function is a 'property get' function, so the syntax in which the Count property is used is like: i% = MyColl.Count As it turns out all other functions of the Collection object are 'methods' (the type library doesn't label them as either get or put) and are to be used as procedure calls. Here is a short overview (all variables are Variants): v = MyColl.Item(vIndex) MyColl.Add( vItem [, vKey, vBefore, vAfter] ) MyColl.Remove(vIndex) Add adds an item to the collection. Along with the data itself, you can specify a key value by which the member can be retrieved from the collection. The key is a Variant and converted to a string when the item is stored. Count returns the number of items in the collection. Item rretrieves a member from the collection either by its index (ordinal position in the collection) or by its key (assuming that one was provided when the item was added to the collection). The index and key argument are always converted to a Variant before they are passed to the Item method. Remove deletes a member from the collection either by its index or its key. For example, the following code fragment defines a collection object, colLanguages, to hold programming language information, and adds two members to it that can later be accessed by their key, which in this case happens to be their abbreviation: Dim colLangauges As New Collection colLanguages.Add "GFA-BASIC32", "GB32" colLanguages.Add "Visual Basic", "VB" Using Collections Given the similarity to arrays, why use collection objects, rather than arrays, in your code? Using collections, you can group related items together. Collections can be heterogeneous, that is, members of a collection don't have to share the same data type (Variant), and that can be very useful, because life doesn't always present you with collections made up of items of the same type. So the major reason is ease of access and ease of maintenance:
  • Members can be added before or after an existing member based on the latter’s key value as well as its index value.
  • Members can be retrieved based on either their key value or their index value.
  • Members can be deleted based on either their key value or their index value.
Collections are very useful and are one of the high points of (Visual) BASIC. However, because of the heterogeneous nature of their contents, they don't necessarily lend themselves to tight and uniform coding practices, which makes some C and C++ programmers look down their noses at BASIC. Since this is the first entry in the blog I explicitly invite you to comment!

No comments:

Post a Comment