| By Arthur Hefti | Article Rating: |
|
| May 19, 2006 11:15 AM EDT | Reads: |
11,818 |
In the first article we presented a some theories about the ClassDefinition object and were able to show the libraries of a PB application in a treeview control. This month we'll read the objects from the libraries and inspect their content.
When a user expands an entry in the treeview, we check to see if it was expanded once already. If it was, we don't take any action. We code this in the itemexpanding event of the treeview control, where we get the clicked treeviewitem by calling This.GetItem.
If it wasn't expanded already, we check to see if the level of the treeviewitem is equal to two, which means we're expanding a library name. We could create an NVO to include all the logic for parsing, but for demonstration purposes, I want to keep things simple. We define all the functions we need on the window itself, but use arguments to refer to the controls. This will let you move the logic to an NVO quite easily later.
The next function we create is called of_ShowLibraryItems. It's used to read the PB objects from a PBL. I use the function LibraryDirectoryEx to extract the objects. Compared to the function LibraryDirectory, it provides the date/time modified and the comment as well as the name and type of the objects. Since I want the objects sorted, I use a DataWindow with an external datasource. See Figure 1 for the definition of a DataWindow. Set the sorting to the column objtype and save it as d_libobj.
The string returned byLibrary-DirectoryEx will be imported into the datastore by the ImportString. After sorting the data, the script loops through the objects and adds them to the treeview. You can find the code for this function in Listing 1. Call the of_ShowLibraryItems function in the itemexpanding event of the treeview control when the level is 2, whereas the ll_TviCurrent is the treeviewitem identified by the handle argument.
Parent.of_ShowLibraryItems( This, handle, ltvi_Current.Data )
On to Class Details
The application so far shows the libraries and the PB objects located in them. Now it's time for the classdefinitionobject object and its descendants. As you saw last month, we'll display the information in various child entries. The first part is called Variables where we list all the variables of this object. In the second section we have the scripts and in the third section the nested classes. Finally the last section includes a reference to the ancestor of the class. The idea behind the functions we create is that they can be called recursive and be used for each type of PB object.
It's impossible to loop through the variable list of the ClassDefinition object of a PB object and display all the information about it nicely. So the next step is creating two helper functions. The first is called of_ValueString and translates the enumerated values to strings (see Listing 2). The arguments of this function are the type of a variable (e.g., Cardinality or InitialValue) and the value itself. It returns both as a readable string. Converting the value to a string is simple with, say, Boolean values; however if we have enumerated data types we have to handle them individually. If the variable is an enumerated datatype we use the FindTypeDefinition get all the possible enumerations of this datatype.
The second function is called of_FormatInfo (See Listing 3) and takes a classdefinitionobject as its argument. Its purpose is to create a formatted string out of the classdefinitionobject information. The argument is a classdefinitionobject type, which lets us pass variables of type classdefinition, scriptdefinition, and variabledefinition.
Display the Information about a Class
Having set up the helper functions, let's go back to the treeview. When we expand a PB object in the treeview, we have to call the function of_ShowClassDefinition. The definition of the function is available online in Listing 4. It takes three arguments: the treeview control, the handle of the clicked item, and a ClassDefinition object. For the first level of information the ClassDefinition object is determined by a call to the FindClassDefinition function where the argument equals the label of the treeview item. Here is the code in the itemexpanding event of the treeview when the level is greater than two. The variable lcd_Temp is a ClassDefinition type and ll_Child is a long type:
ll_Child = This.FindItem( ChildTreeItem!, handle )
IF ll_Child = -1 THEN // No children yet
lcd_Temp= FindClassDefinition (&
ltvi_Current.Label,il_LibList )
IF NOT IsNull(lcd_Temp) THEN
Parent.of_ShowClassDefinition(&
tv_1,handle,lcd_Temp)
END IF
END IF
The variable section is filled by looping through the VariableList property of the ClassDefinition, using the IsControl properties to prevent adding controls and IsUserDefined to set the picture of the treeviewitem. For each variable the of_ShowVarible function (see Listing 5) is called to fill the variable information into the data property of the treeviewitem. After handling the variables, the function goes on to the scripts. For each entry in the ScriptList property of the ClassDefinition, the function of_ShowScript (Listing 6) is called. Here we use the properties IsLocallyScripted and IsScripted to set the picture of the treeviewitem. The data property of the treeviewitem is used for general information about the script. For each script we add, there is an entry Source (saving the source of the script) called ArgumentList and another one called LocalVariableList. We add each argument variable and each local variable including their definitions under the appropriate entry by calling the function of_ShowVariable with each variable. To compile you have to define of_ShowVariableFirst, then of_ShowScript, and then of_ShowClassDefinition.
Then the nested classes are shown. The naming convention of a nested class is objectname`nestedclassname. We need the whole name to find more information about the nested class when calling FindClassDefinition. For nested classes we check the property ParentClass. If this is null we don't add the class. Further the NestedClassList returns not only the controls on an object, but also the controls on the ancestor of the object. We prevent showing ancestor data by comparing the name of the ParentClass of the NestedClass with the name of the current object. If they don't match, the control is inherited from the ancestor. At the end of this list we add an entry for the ancestor object if there is one.
To display the additional information stored in the data property of the treeview items you have to put the following code in the selectionchanged event of the treeview:
treeviewitem ltvi_Current
This.Getitem(newhandle,ltvi_Current)
IF ClassName(ltvi_Current.data)="string"THEN
mle_1.Text=ltvi_Current.Data
ELSE
mle_1.Text=""
END IF
RETURN
When running the application and expanding a library entry, all the information of the entry itself is loaded at once. We don't parse information about nested classes and no information about possible ancestors is retrieved (except its name). On large objects this might take some time. To drill down on an entry you have to expand the item in the treeview. If it's a nested class or ancestor class and the data isn't loaded, the ClassDefinition object of the chosen entry is retrieved by FindClassDefiniton and the function of_ShowClassDefinition is called, passing the ClassDefinition object as an argument. Since the ClassDefinition object is available to all PB classes, no further coding is required and our application is ready to browse. Browsing PFC-based applications is quite interesting and lets you drill down many levels.
You can download the source code of the application from the PBDJ Web site or from the download section of the CATsoft Web site at www.catsoft.ch.
Conclusion
I hope this gives you a basic understanding of the ClassDefinition object and related objects. Creating a browser for PB objects is one possible use of these objects. Maybe you can make use of it in an application, where you need to get information about an object's inheritance or the availability of a certain function (see the function FindMatchingFunction). Another possible use might be the dynamic creation of WSDL files for a Web Service.
Published May 19, 2006 Reads 11,818
Copyright © 2006 SYS-CON Media, Inc. — All Rights Reserved.
Syndicated stories and blog feeds, all rights reserved by the author.
More Stories By Arthur Hefti
Arthur Hefti is CEO of CATsoft Development GmbH in Zurich. He has been working with PowerBuilder since version 3 and taught dozens of PowerBuilder training classes. He and his team create custom-made client/server and Web applications using XML, Web Services, and encryption.
![]() |
PBDJ News Desk 05/19/06 10:42:08 AM EDT | |||
In the first article we presented a some theories about the ClassDefinition object and were able to show the libraries of a PB application in a treeview control. This month we'll read the objects from the libraries and inspect their content. When a user expands an entry in the treeview, we check to see if it was expanded once already. If it was, we don't take any action. |
||||
- Why SOA Needs Cloud Computing - Part 1
- Cloud Expo and The End of Tech Recession
- The Transition to Cloud Computing: What Does It Mean For You?
- A Rules Engine Built in PowerBuilder
- Sybase Named “Silver Sponsor” of iPhone Developer Summit
- How PowerBuilder Got Its Groove Back
- The Cloud Has Cross-Border Ambitions
- Ulitzer Names The World's 30 Most Influential Virtualization Bloggers
- Ulitzer Named "New Media" Partner of Greatly Anticipated iStrategy Event in Berlin
- Risks and Enterprise Mobility?
- Steps for Success in Enterprise Mobility?
- Are Mobile Luddites Resisting Mobility?
- The Difference Between Web Hosting and Cloud Computing
- Sybase CTO to Speak at 4th International Cloud Computing Expo
- Why SOA Needs Cloud Computing - Part 1
- Cloud Expo and The End of Tech Recession
- The Transition to Cloud Computing: What Does It Mean For You?
- Five Reasons to Choose a Private Cloud
- Seeding The Cloud: The Future of Data Management
- The Threat Behind the Firewall
- Economy Drives Adoption of Virtual Lab Technology
- Tips for Efficient PaaS Application Design
- A Rules Engine Built in PowerBuilder
- Sybase Named “Silver Sponsor” of iPhone Developer Summit
- Where Are RIA Technologies Headed in 2008?
- PowerBuilder History - How Did It Evolve?
- The Top 250 Players in the Cloud Computing Ecosystem
- Custom Common Dialogs Using SetWindowsHookEx
- DDDW Tips and Tricks
- OLE - Extending the Capabilities of PowerBuilder
- DataWindow.NET How To: Data Entry Form
- Book Excerpt: Sybase Adaptive Server Anywhere
- Sybase ASE 12.5 Performance and Tuning
- Working with SOA & Web Services in PowerBuilder
- Office 2003 Toolbar: A New Look For Your Old PowerBuilder App
- Dynamically Creating DataWindow Objects

































