![]() | ![]() |
Home |
|
|
ORCA Guide |
|
| Chapter 1: Using ORCA |
It explains the correspondence between tasks a PowerBuilder developer can do in the Library painter and tasks you want to do programmatically with ORCA for a PowerBuilder library.
It also explains the constraints involved in developing ORCA programs and who should and should not use ORCA, as well as the functions available in ORCA and how to conduct an ORCA session in your program.
ORCA lets your application do programmatically the same library and object management tasks that a developer does in the PowerBuilder development environment. ORCA covers most of the functionality of the Library painter, and some of that of the Application and Project painters.
You can:
ORCA is available with the Enterprise and Professional editions of PowerBuilder. Users of these editions of PowerBuilder can run programs that use ORCA.
ORCA is not available with the Desktop edition of PowerBuilder. Desktop users cannot run programs that call ORCA.
ORCA as a development tool is designed for tool vendors who want to provide tools for PowerBuilder developers. Tool vendors must be aware of the constraints described below.
ORCA as a development tool is not meant for a wider audience of PowerBuilder developers. If you are a PowerBuilder developer, you should not develop programs that call ORCA unless you understand and observe the constraints described next.
Constraints when using ORCA Both PowerBuilder and ORCA make use of the PowerBuilder compiler. However, the compiler is not reentrant and more than one program cannot use it simultaneously. Therefore, PowerBuilder cannot be running when your programs call ORCA.
Tool providers who use ORCA must code their programs carefully so that when a PowerBuilder developer calls their ORCA-based modules, their tool:
| Caution If the PowerBuilder development environment is not shut down while ORCA is running, your PowerBuilder libraries can become corrupted. For this reason, casual use of ORCA is not recommended. |
| What you need
| Where to find it on the PowerBuilder installation
CD
|
|---|---|
| This ORCA documentation
| In \pb\orca
|
| C development files (PBORCA.H and PBORCA.LIB)
| For 16-bit Windows
: in \orca\orca16
|
|
| For 32-bit Windows
: in \orca\orca32
|
You can find the sample application on the Powersoft ftp site in \pub2\pbuilder\samples\orc5smpl.zip.
The Library painter lets the PowerBuilder developer view and maintain the contents of a PBL. The painter lists the objects in a PBL with their properties, such as modification date and comments.
In the Library painter, the PowerBuilder developer can delete, move, compile, export, and import objects--and can use source control systems and create PowerBuilder dynamic libraries and DLLs.
From the Library painter, you can open objects in their own painters and view and modify the objects graphically.
When you open an object in a painter, PowerBuilder interprets the library entries and displays the object in a graphical format. The painter does not display the source code. If you change the object graphically and save it again in the PBL, PowerBuilder rewrites the source code to incorporate the changes and recompiles the object.
The Library painter lets you export source code, study and even modify it in any text editor, and import it back into the library. PowerBuilder compiles the imported object to check that the source code is valid. It will not import objects that fail to compile.
Source code exported to a file has two header lines before the source code. These header lines must not be included if you import the source using ORCA:
$PBExportHeader$w_about.srw$PBExportComments$Tell us about the
application level
You can view the exported source code in the PowerBuilder file editor:
Most ORCA functions have a counterpart in the Library painter, the Application painter, the Project painter, or the commands that start and stop a PowerBuilder session.
The next section identifies the ORCA functions, their purpose, and what they correspond to in the PowerBuilder development environment.
Just as you begin a session in the PowerBuilder development environment by running PowerBuilder and you end the session by exiting PowerBuilder, you need to open a session when using ORCA and close the session when finished.
ORCA functions that don't involve compiling objects or building applications do not require a library list and current application. These are the library management functions and source control functions.
| Function (prefix PBORCA_)
| Purpose
| Equivalent in PowerBuilder
|
|---|---|---|
| SessionOpen
| Opens an ORCA session and returns the
session handle
| Starting PowerBuilder
|
| SessionClose
| Closes an ORCA session
| Exiting PowerBuilder
|
| SessionSetLibraryList
| Specifies the libraries for the session
| Application painter: Entry>Properties, Libraries
tab
|
| SessionSetCurrentAppl
| Specifies the Application object for
the session
| Application painter: File>Open
or New
|
| SessionGetError
| Provides information about an error
| No correspondence
|
The library management functions are similar to commands in the Library painter. These functions allow you to create and delete libraries, modify library comments, and see the list of objects located within a library. They also allow you to examine objects within libraries, export their syntax, and copy, move, and delete entries.
These functions may be called outside the context of a library list and current application.
The library management functions (which all have the prefix PBORCA_) and their equivalents in the PowerBuilder Library painter are:
| Function (prefix PBORCA_)
| Purpose
| Equivalent in PowerBuilder
|
|---|---|---|
| LibraryCommentModify
| Modify the comments for a library
| Library>Properties
|
| LibraryCreate
| Create a new library file
| Library>Create
|
| LibraryDelete
| Delete a library file
| Library>Delete
|
| LibraryDirectory
| Get the library comments and a list of
its objects
| Main view
|
| LibraryEntryCopy
| Copy an object from one library to another
| Entry>Copy
|
| LibraryEntryDelete
| Delete an object from a library
| Entry>Delete
|
| LibraryEntryExport
| Get the source code for an object
| Entry>Export
|
| LibraryEntryInformation
| Get details about an object
| Main view
|
| LibraryEntryMove
| Move an object from one library to another
| Entry>Move
|
These functions allow you to import new objects into a library from a text listing of their source code and to compile entries that already exist in a library.
Entries in a library have both a source code representation and a compiled version. When you import a new object, PowerBuilder compiles it. If there are errors, it is not imported.
You must set the library list and current application before calling these functions.
The compilation functions (which all have the prefix PBORCA_) and their equivalents in the PowerBuilder Library painter are:
| Function (prefix PBORCA_)
| Purpose
| Equivalent in Library painter
|
|---|---|---|
| CompileEntryImport
| Imports an object and compiles it
| Entry>Import
|
| CompileEntryImportList
| Imports a list of objects and compiles
them
| No correspondence
|
| CompileEntryRegenerate
| Compiles an object
| Entry>Regenerate
|
| ApplicationRebuild
| Compiles all the objects in all the libraries
associated with an application
| Design>Incremental Rebuild or Design>Full
Rebuild
|
The object query functions get information about an object's ancestors and the objects it references.
The library list and current application must be set before calling these functions.
The object query functions (which all have the prefix PBORCA_) are listed below. There are no direct correspondences to PowerBuilder commands:
| Function (prefix PBORCA_)
| Purpose
|
|---|---|
| ObjectQueryHierarchy
| Gets a list of an object's ancestors
|
| ObjectQueryReference
| Gets a list of the objects an object
refers to
|
These functions allow you to create executables and PowerBuilder Dynamic Libraries (PBDs and DLLs). You can specify the same options for Pcode and machine code and tracing that you can specify in the Project painter.
Using ORCA, PBDs or DLLs must be created in a separate step from creating the executable.
The library list and current application must be set before calling these functions.
The functions for creating executables and libraries (which all have the prefix PBORCA_) and their equivalents in the PowerBuilder development environment are:
| Function (prefix PBORCA_)
| Purpose
| Equivalent in painter
|
|---|---|---|
| ExecutableCreate
| Creates an executable application using
ORCA's library list and current Application object
| Project painter
|
| DynamicLibraryCreate
| Creates a PowerBuilder dynamic library
from a PBL
| Project painter or Library painter: Library>Build
Runtime Library
|
The source control functions provide a way to check an object in to or out of a PowerBuilder library using PowerBuilder native source control. You can also find out an object's checkout status.
These functions allow you to implement version control using version control systems that don't have a PowerBuilder interface.
The library list and current application do not need to be set before calling these functions.
The source management functions (which all have the prefix PBORCA_) and their equivalents in the PowerBuilder Library painter are:
| Function (prefix PBORCA_)
| Purpose
| Equivalent in Library painter
|
|---|---|---|
| CheckInEntry
| Checks an object into a library
| Source>Check In or Source>Clear
Check Out Status
|
| CheckOutEntry
| Checks an object out of a library
| Source>Check Out
|
| ListCheckOutEntries
| Reports objects that are registered or
checked out
| Source>View Check Out Status
|
These functions (which all have the prefix PBORCA_) use a callback function:
| ORCA function call (prefix PBORCA_)
| Purpose of callback
|
|---|---|
| CompileEntryImport CompileEntryImportList CompileEntryRegenerate
| Called once for each compile error
|
| ExecutableCreate
| Called once for each link error
|
| LibraryDirectory
| Called once for each library entry name
|
| ObjectQueryHierarchy
| Called once for every ancestor name
|
| ObjectQueryReference
| Called once for every object referenced
in the entry
|
| ListCheckOutEntries
| Called once for each object that is registered
or checked out in a library
|
ORCA calls a callback function like this:
The processing that occurs in the callback function is entirely up to you. This section illustrates a simple way of handling it.
typedef struct ORCA_UserDataInfo { LPSTR lpszBuffer; // Buffer to
store data DWORD dwCallCount; // # of
messages in buffer DWORD dwBufferSize; // size
of buffer DWORD dwBufferOffset; // current offset
in buffer } ORCA_USERDATAINFO, FAR *PORCA_USERDATAINFO;
ORCA_USERDATAINFO UserDataBuffer;PORCA_USERDATAINFO lpUserDataBuffer;CHAR InfoBuffer[60000];lpUserDataBuffer = &UserDataBuffer;lpUserDataBuffer->dwCallCount = 0;lpUserDataBuffer->dwBufferOffset = 0;lpUserDataBuffer->dwBufferSize = 60000;lpUserDataBuffer->lpszBuffer = &InfoBuffer;// Initialize all of InfoBuffer to
0memset(lpUserDataBuffer->lpszBuffer, 0x00, (size_t)
lpUserDataBuffer->dwBufferSize);
Create Proc instance The calling program also needs to create a Proc instance of the callback function that it will pass to the ORCA function:
FARPROC lpCallbackProc;lpCallbackProc = MakeProcInstance((FARPROC)CallbackFunc,
hInst);
Call ORCA The calling program calls the ORCA function, passing the callback function pointer and the UserData buffer pointer. This example calls PBORCA_ExecutableCreate, whose callback type is PBORCA_LNKPROC:
rtn = PBORCA_ExecutableCreate(...,
(PBORCA_LNKPROC) lpCallbackProc, lpUserDataBuffer);
Free Proc instance When control returns from ORCA back to the calling program, the calling program can free the Proc instance:
FreeProcInstance(lpCallbackProc);
Process results Finally, the calling program can process or display information that the callback function stored in the UserData buffer.
Simple callback A simple callback might do the following:
This code implements a callback called LinkErrors for PBORCA_ExecutableCreate:
void WINAPI LinkErrors(PPBORCA_LINKERR lpLinkError, LPVOID lpUserData) { PORCA_USERDATAINFO lpData; LPSTR
lpCurrentPtr; int iNeededSize; lpData = (PORCA_USERDATAINFO)
lpUserData; // Keep track of number of link errors lpData->dwCallCount++; // Is buffer already full? if (lpData->dwBufferOffset
== lpData->dwBufferSize) return; // How long is the new message? // Message
length plus carriage rtn and newline iNeededSize = strlen(lpLinkError->lpszMessageText) + 2; // Set
pointer for copying message to buffer lpCurrentPtr = lpData->lpszBuffer + lpData->dwBufferOffset; // Check if there's room
for the message // plus the final message if ((iNeededSize + strlen("Buffer
full")) > (lpData->dwBufferSize - lpData->dwBufferOffset)) { // If
almost full, copy final message // and set offset
to end of buffer strcat(lpCurrentPtr, "Buffer full"); lpData->dwBufferOffset = lpData->dwBufferSize; } else { // If
not full, copy link error message, // CR and
LF, and update offset strcat(lpCurrentPtr, lpLinkError->lpszMessageText); strcat(lpCurrentPtr,
"\r\n"); lpData->dwBufferOffset += iNeededSize; } return;}
A more complex callback The ORCA sample application implements more elaborate buffer management. When the buffer is full, the callback allocates another, larger buffer, then copies the old data to the new buffer and adds the new message. It updates the pointer in the UserData buffer to the new message buffer. It also keeps track of handles to the buffers so that the globally allocated memory can be freed again.
To use the ORCA interface, your calling program will:
Before calling any other ORCA functions, you need to open a session. The PBORCA_SessionOpen function returns a handle that ORCA uses to manage this program's ORCA session. The handle type HPBORCA is defined as LPVOID, meaning that it can be a pointer to any type of data. This is because within ORCA it is mapped to a structure not available to the calling program.
HPBORCA WINAPI SessionOpen(){ HPBORCA hORCASession; hORCASession = PBORCA_SessionOpen(); return
hORCASession;}
The next step in writing an ORCA program depends on the intent of the program. The choices are:
In the PowerBuilder development environment, you select an Application object in the Application painter and then set the library search path on the Application object's property sheet. With ORCA, you set the library list first and then set the Application object.
Set once per session You can set the library list and current application only once in an ORCA session. To use another library list and application, close the ORCA session and open a new session.
nReturnCode WINAPI SetUpSession(HPBORCA hORCASession){ char szApplName[36]; int
nReturnCode; LPSTR lpLibraryNames[2] = {"c:\\pbfiles\\demo\\master.pbl", "c:\\pbfiles\\demo\\work.pbl"}; // Call the ORCA function nReturnCode = PBORCA_SessionSetLibraryList( hORCASession,
lpLibraryNames, 2); if (nReturnCode != 0) return nReturnCode;
// return if it failed // Set up the string containing the
appl name strcpy(szApplName, "demo"); // The appl object is in the first
library nReturnCode = PBORCA_SessionSetCurrentAppl( hORCASession,
lpLibraryName[0], szApplName)) return nReturnCode;}
After the library list and application are set, you can call any ORCA function using the handle returned by the PBORCA_SessionOpen function. Most of the function calls are fairly straightforward. Others, like those requiring callbacks, are a bit more complicated.
FOR INFO For information about callback functions, see "About ORCA callback functions" .
The last step in an ORCA program is to close the session. This allows the Library Manager to clean up and free all resources associated with the session.
This sample C function closes the session:
void WINAPI SessionClose(hORCASession){ PBORCA_SessionClose(hORCASession); return;}
Beginning with PowerBuilder 5.0, you can use ORCA to create the libraries for an entire application from object source code. You don't need to start with an existing PBL.
To import an object, ordinarily you need a library with an Application object that already exists. When you set the Application object to a NULL value during the bootstrap process, ORCA uses a temporary Application object so that you can import your own Application object. But your Application object doesn't become the current application until you close the session, start a new session, and set the current application.
Do not import other objects now .
| Why you should import only the Application object Although you can import additional objects into the library, it is not a good idea. In the bootstrap session, the default Application object is the current application. If the objects have any dependencies on your Application object (for example, if they reference global variables), they will cause errors and fail to be imported. |
You can only set the library list and current application once in a session, so you need to start a new ORCA session to finish the process. Since you now have a library with the Application object you want to use, the process is the same as any other ORCA session that imports objects.
| When to create the libraries You can create the additional libraries during the first bootstrap procedure. However, you should not import objects until the second procedure when the correct Application object is current. |
|
|