Dynamically Load Components From Packages at Run Time (cont'd)


Adding New Properties and Methods
So now you know how to use a component T42Edit, but what if you add a new property called 'About' and a new method called 'AboutBox'? How can we attempt to read/write this property, and how can we call this method during runtime? Fortunately, Delphi fully supports RunTime Type Information (RTTI), so classes contain a lot of information about themselves, including which properties, methods, and events are part of the components.

To access the new property named 'About', we should first call the IsPublishedProp function, which returns true if the property name is indeed part of the object instance we pass it:

  if IsPublishedProp(Obj, 'About') then
To get and set the value of a property, we can use the GetPropValue function and SetPropValue procedure as follows:
var
  Value: Variant;

  ...

  if IsPublishedProp(Obj, 'About') then
  begin
    Value := GetPropValue(Obj, 'About');
    SetPropValue(Obj, 'About', Value);
  end;
Value is a variant here, but if you know the specific type you can also use the type-specific Get and Set routines from the TypInfo unit (like GetStrProp or SetInt64Prop). Note that an event handler is just a property of a specific event handler "method of object" type.

Apart from access to previously unknown properties and events, we can also see if a method is part of the dynamically created component (using MethodAddress), and even call the method itself. The only rule is that RTTI works with "published" parts of a component, so the method must be published (and not just public) or we won't see it.

We must first declare a variable that has the exact signature of the procedure or function we wish to call. For example, for the simple procedure AboutBox with no arguments the variable declaration would be:

var
  pr: procedure;
Using the MethodAddress, we can obtain the address of a specified method and assign it to the previously declared procedure pointer:
  pr := Obj.MethodAddress('AboutBox');
The next step is simple. If the procedure pointer is assigned (i.e., it has a value), then we can call it. If we can't, we did not obtain a correct method pointer (for example, if the method didn't exist in the component Obj).
var
  pr: procedure;

  pr := Obj.MethodAddress('AboutBox');
  if Assigned(pr) then
    pr;
If the procedure pointer was declared with arguments, then we can pass the required arguments when we call it. Note that you even get Code Insight support from Delphi when you need to fill in the arguments to the dynamic method.

Bob Swart (aka Dr.Bob) is an IT Consultant for the Everest Delphi OplossingsCentrum (DOC), and he has spoken at the Inprise/Borland Conferences since 1993. He is a freelance technical author who has written chapters for The Revolutionary Guide to Delphi 2 (WROX), Delphi 4 Unleashed, C++Builder 4 Unleashed, and C++Builder 5 Developer's Guide (SAMS). He can be reached at drbob@chello.nl.



Previous: Create Run-Time Components
 
Back to Introduction


Introduction Create Run-Time Components
Anatomy of a Run-Time Package Adding Properties and Methods
Load Dynamic Run-Time Packages


Return to Get Help with Delphi Page

Return to Main Get Help Page
 
How do I dynamically load packages and use their components at run-time?




Write Delphi packages, dynamically load them, and create dynamic component instances in a way that can be the basis for a dynamic application plug-in architecture.


Find Out More
• The T42Edit and T42Label components are implemented on Bob Swart's Web site in the Tip-of-the-Hat section.

The Delphi Companion: Delphi Component

Delphi Components and Tools Developers and Their Products

TALK BACK
What are your experiences with getting components out of packages? Do you have a better way to build dynamic application plug-in architectures. Let us know in the database development discussion groups!
 





Sponsored Links