Uniface Handles: Understanding the Power of References
If you’re delving into the world of Uniface development, you’ve likely encountered the handle data type. While it might seem a bit abstract initially, grasping its concept is crucial for building robust and interactive Uniface applications. Simply put, a handle acts as a direct reference or a unique identifier to an object within your application, allowing you to interact with it indirectly.
Imagine a remote control for your television: the remote isn’t the TV itself, but it provides the means to control it. Similarly, a Uniface handle doesn’t store the actual object; instead, it holds the precise “address” or reference to that object, enabling your code to manipulate it.
In Uniface, a handle can point to various elements, including:
* A specific instance of a component
* An entity within a component
* A particular occurrence (record or row of data)
* A field residing within an occurrence
* An external OCX object
Declaring a Handle in Your ProcScript
Declaring a handle is straightforward and can be done in two primary contexts within your ProcScript:
- As a Variable:
Within avariablesblock, you can define a handle that will be used locally within your component’s script.variables handle vMyComponentHandle endvariables - As a Parameter for an Operation:
This method is frequently used when one component needs to interact with or pass a reference to another component.operation doSomething params handle pComponentHandle : IN endparams ; ... your operational code ... end
An Illustrative Example
Let’s consider a practical scenario. Suppose you have a main component that needs to instruct a “Writer” component to begin drafting a document. You can achieve this by passing the handle of the Writer component to your main component.
operation exec
params
handle pWriter : IN
endparams
; Assign the incoming handle to a component variable for use
$hWriter$ = pWriter
; Utilize the handle to invoke an operation on the referenced component
$hWriter$->startdocument("true")
end; exec
In this example:
1. The exec operation receives pWriter, a handle, as an input parameter.
2. This pWriter handle is then stored in a component variable named $hWriter$.
3. Using the -> syntax, we can now call the startdocument operation on the component that $hWriter$ references, effectively controlling another component remotely.
Understanding public vs. partner Handles
When declaring a handle variable, you can specify its scope, impacting the level of access it has to the target component’s operations. This acts as a security mechanism:
public handle: Can only access operations that are also declared aspublicon the target component.partner handle: Provides broader access, capable of reaching bothpublicandpartneroperations.
A Crucial Warning: Do Not Convert Handles to Strings!
Uniface documentation strongly advises against converting a handle to a string and then attempting to convert it back. The reason is simple yet critical: a handle is a live, actively managed reference. When you convert it to a string, you’re merely capturing a textual representation of its internal ID at that specific moment—it ceases to be a functional pointer. Attempting to reverse this process by converting the string back will not restore the handle and will invariably lead to runtime errors. Always ensure handles are passed and stored purely as the handle data type to maintain their integrity and functionality.
Mastering the use of handle types will significantly enhance your ability to create interconnected and dynamic Uniface applications. Happy coding!