|
|
|
This chapter offers guidelines to help you take advantage of the open and extensible development environment available in both Forms Developer and Reports Developer.
Section | Description |
---|---|
Section 6.1, "Working with OLE Objects and ActiveX Controls" |
Describes support for component technologies and provides steps and guidelines for creating applications that include OLE objects and ActiveX controls. |
Section 6.2, "Using Foreign Functions to Customize Your Applications" |
Describes how to customize and extend your applications with 3GL foreign functions. |
Section 6.3, "Using the Open API to Build and Modify Form Builder Applications" |
Introduces the Open API and explains how to use the Open API to build and modify Form Builder applications. |
Section 6.4, "Designing Applications to Run against ODBC Datasources" |
Discusses ODBC support and provides detailed steps and guidelines that describe how to run applications against ODBC datasources. |
This section describes what OLE and ActiveX are, and how you can exploit this technology. This section includes these topics:
Note: Support for OLE and ActiveX is limited to the Windows platform.
Object Linking and Embedding (OLE) is a Microsoft standard that allows you to integrate and reuse different software components within a single application.
Integrating an application with a Microsoft Excel document, for example, enables you to offer both Forms Developer (or Reports Developer) and Microsoft Excel features. Your users can format a Microsoft Excel document with any of the text processing features provided by Microsoft Excel, while using Forms Developer or Reports Developer features for displaying and manipulating data from the database.
By incorporating OLE objects within your application, you can seamlessly integrate a diverse group of specialized components to build full-fledged applications. You no longer have to build entire applications from the ground up. You can deliver applications in a shorter amount of time and at a lower cost.
Use OLE when:
For example, you can enhance your application's capabilities with word processor documents, spreadsheet documents, knob controls, video clips, sound, and so on.
On Microsoft Windows, most users are familiar with Microsoft Word and Microsoft Excel. Rather than creating word processing or spreadsheet functionality to your application, you could leverage and embed a Word or Excel document within your application.
OLE uses the concept of client and server. The client is an application that requests and uses the services of another application. The server is the one that provides these services.
An OLE server application creates OLE objects that are embedded or linked in OLE containers. The server application is responsible for the creation, storage, and manipulation of OLE objects. For example, the server decides how to repaint the object when certain portions are exposed.
Graphics Builder and Microsoft Word are examples of OLE servers.
Unlike OLE server applications, OLE container applications do not create documents for embedding and linking. Instead, OLE container applications provide a place to store and display objects that are created by OLE server applications.
Form Builder and Report Builder are examples of OLE container applications.
You can link or embed OLE objects within your application.
There is no functional difference between linking and embedding. The OLE container treats the objects equally, by executing the same code, whether they are linked or embedded. The only difference is that embedding an OLE object increases the size of your application. This could eventually lead to performance considerations (particularly on a file server), because the larger the application, the longer it will take to open and load into memory.
Each client machine contains an OLE registration database. The registration database stores a set of classes that categorize OLE objects. The information in the registration database determines the object classes that are available for embedding and linking in OLE containers.
OLE server applications export a set of classes that become members of the registration database. Each computer has a single registration database. If the registration database does not already exist when an OLE server application is installed, one is created.
A single OLE server application can add many OLE classes to the registration database. The process of adding classes to the registration database is transparent and occurs during the installation of an OLE server application. For example, when you install Microsoft Excel, several classes are added to the registration database; some of the classes that are installed in the registration database include Excel Application, Excel Application 5, Excel Chart, Excel Sheet, ExcelMacrosheet, and ExcelWorkSheet.
Activating an OLE object enables you to access features from the OLE server application. There are two ways to activate an OLE object: in-place activation or external activation.
During in-place activation, the activated object appears within a hatched border, and the toolbar, menu and other controls of the activated object temporarily replace standard menu options. The replacement menu options and toolbars provide access to features that are available from the OLE server application. Standard menu options and toolbars re-appear when you deactivate in-place activation. To deactivate in-place activation, you click anywhere outside the hatched border.
Note: In-place activation is available for embedded objects, but it is not available for linked objects.
External activation is available for both embedded and linked objects.
When the contents of a linked source file is modified with external activation, a linked object can be updated manually or automatically. Manual updates require an explicit instruction for an object to reflect changes from a linked source file. Automatic updates occur as soon as you modify a linked source file.
Note: Both in-place activation and external activation are dependent on the OLE activation property settings of the OLE container. If the OLE server application is accessible, the activation property settings of the OLE container determine whether in-place activation or external activation occurs when an embedded OLE object is activated. Linked objects can only be activated with external activation; in-place activation does not apply to linked objects, even if the in-place activation property is set to Yes.
Occasionally, you may want to interact with or manipulate the data within an OLE object. To do so, you use PL/SQL and OLE automation.
OLE automation enables the server application to expose a set of commands and functions that can be invoked from an OLE container application. By using these commands and functions, you can manipulate OLE objects from the OLE container environment.
In both Forms Developer and Reports Developer, you use PL/SQL to access any command or function that is exposed by an OLE server application. Built-ins provide a PL/SQL Application Programming Interface for creating, manipulating, and accessing OLE commands and functions.
Note: Many of the options available for manipulating an OLE object in an OLE container application are determined by the OLE server application. For instance, options from the OLE popup menu, also known as OLE verbs, are exposed by the OLE server application. The information contained in the registration database, such as object classes, is also dependent on the OLE server application.
Both Forms Developer and Reports Developer provide OLE server and container support as well as support for OLE automation.
As OLE container applications, Form Builder and Report Builder support the following:
In-place activation enables you to access menus and toolbars from OLE server applications to edit embedded OLE objects while you are in Form Builder.
Using PL/SQL, you can invoke commands and functions that are exposed by OLE servers.
You can save OLE objects to a database, as well as query OLE objects from a database. When linked objects are saved, only the image and the link information are retained in the database. The contents of a linked object remains in a linked source file. Saving an embedded object retains all the contents of an embedded object in the database.
Graphics Builder is an OLE server application. You can embed or link Graphics Builder displays within your Forms Developer or Reports Developer application.
Recommendation: If you want to add a Graphics Builder display to your application, don't embed or link it as an OLE object. Instead, use the Chart Wizard to add graphical displays to your applications.
OLE container properties determine OLE display attributes, OLE container interaction with the server, container storage, and so on.
Note: In addition to container properties, you can also set OLE object properties. Each OLE object can expose several properties. You access OLE object properties by clicking the right mouse button to display the popup menu.
This section lists the OLE container properties supported by both Forms Developer and Reports Developer.
This section lists the OLE and ActiveX built-ins supported by different components.
For detailed steps about how to add an OLE object to your application, refer to the online help.
OLE server applications expose a set of commands that allow you to manipulate an OLE object programmatically.
You can manipulate OLE objects by:
Note: Before you can call an OLE method, you must first import the OLE object's methods and properties into Forms Developer or Reports Developer. Importing OLE methods and properties enables you to interact with the OLE object within the native environment.
You can access OLE methods from your application by using the STANDARD (Form Builder only) and OLE2 built-in packages.
This section provides several examples to help you get started with OLE.
Within your form applications, you can use the :item('item_name').ocx.server_name.property bind variable syntax to assign or retrieve property values.
For example:
:item('OLEitem').OCX.SpreadSheet.CellForeGroundColor:=:item('OLEitem').OCX.SpreadSheet.CellForeGroundColor + 1;
OLEitem is the name of the item, SpreadSheet is the name of the OLE control server, and CellForeGroundColor is the name of the property.
Within your form applications, you can also use property assessor functions and procedures to get and set property values.
For example:
Variant OleVar; Variant := EXCEL_WORKSHEET.ole_Range(:CTRL.interface, To_variant('A1'));
EXCEL_WORKSHEET is the name of the program unit created from the OLE Importer. OLE_RANGE is the name of the property accessor.
This example gets and sets cell values in an Excel spreadsheet.
PACKAGE spreadsheet IS procedure setcell(trow number, col number, val number); function getcell(trow number, col number) return number; END; PACKAGE BODY spreadsheet IS obj_hnd ole2.obj_type; /* store the object handle */ FUNCTION get_object_handle return ole2.obj_type IS BEGIN /* If the server is not active, activate the server and get the object handle. */ if not forms_ole.server_active ('spreadsheet') then forms_ole.activate_server('spreadsheet'); obj_hnd := forms_ole.get_interface_pointer('spreadsheet'); end if; return obj_hnd; END; /* Excel cells are accessed with the following syntax in Visual Basic: ActiveSheet.Cells(row, column).Value In PL/SQL, we need to first get the active sheet using the forms_ole.get_interface_pointer built-in. We can then use that to call the Cells method with the row and column in an argument list to get a handle to that specific cell. Lastly, we access the value of that cell. */ PROCEDURE SETCELL (trow number, col number, val number) IS d ole2.obj_type; c ole2.obj_type; n number; lst ole2.list_type; BEGIN /* Activate the server and get the object handle to the spreadsheet. */ d := get_object_handle; /* Create an argument list and insert the specified row and column into the argument list. */ lst := ole2.create_arglist; ole2.add_arg(lst,trow); ole2.add_arg(lst,col); /* Call the Cells method to get a handle to the specified cell. */ c := ole2.invoke_obj(d,'Cells',lst); /* Set the value of that cell. */ ole2.set_property(c,'Value',val); /* Destroy the argument list and the cell object handle. */ ole2.destroy_arglist(lst); ole2.release_obj(c); END; FUNCTION GETCELL(trow number, col number) return number IS c ole2.obj_type; d ole2.obj_type; n number; lst ole2.list_type; BEGIN /* Activate the server and get the object handle to the spreadsheet. */ d := get_object_handle; /* Create an argument list and insert the specified row and column into the argument list. */ lst := ole2.create_arglist; ole2.add_arg(lst,trow); ole2.add_arg(lst,col); /* Call the Cells method to get the value in the specified cell. */ c := ole2.invoke_obj (d,'Cells',lst); n := ole2.get_num_property (c, 'Value'); /* Destroy the argument list. */ ole2.destroy_arglist(lst); ole2.release_obj(c); return n; END; END;
To access a cell, use the following code:
spreadsheet.setcell(3, 5, 91.73); :block1.item1 := spreadsheet.getcell(2, 4);
ActiveX controls (originally known as OLE or OCX controls) are stand-alone software components that you embed within your application to provide light-weight user interface controls.
ActiveX controls differ from OLE objects in several ways:
ActiveX controls are typically used to enhance an application by providing some additional, self-contained functionality.
For example, you can enhance your application with a tabbed property sheet, a spin control, a calendar control, a help control, and so on.
A significant amount of effort is required to develop your own ActiveX controls or OLE servers. It is recommended that you use ActiveX controls and OLE servers developed and distributed by third party vendors.
Each ActiveX control exposes a set of properties, methods, and events. Properties define the ActiveX control's physical and logical attributes, methods define actions that the ActiveX control can perform, and events denote some change in status in the ActiveX control.
You can manipulate an ActiveX control by:
Note: Before you can invoke an ActiveX control method, you must first import its methods and events into Forms Developer. Importing ActiveX methods and events enables you to interact with the ActiveX control within the native Forms Developer environment.
To manipulate an ActiveX control, you use the STANDARD and OLE2 (both within Forms Developer) built-in packages.
You can respond to an ActiveX event by writing your own code within an ActiveX event package or within the On-Dispatch-Event trigger.
Each ActiveX event is associated with a PL/SQL procedure defined in the events' package. When the control fires an event, the code in the procedure is automatically executed.
Procedure names are determined by an internal number that represents the corresponding event. The restricted procedure produced by an event has an application programming interface similar to the following:
PROCEDURE /*Click*/ event4294966696(interface OleObj);
Note: ActiveX procedures run in restricted mode. When calling the event procedure within an On-Dispatch-Event trigger, you can explicitly define whether the procedure is run in restricted or unrestricted mode by using the FORMS4W.DISPATCH_EVENT call. When defining a restricted procedure, OUT parameters are not observed.
Deploying an application that contains an ActiveX control requires that you deploy the ActiveX control.
To deploy an ActiveX control, you must:
If you install an ActiveX control by using the installation program supplied with the ActiveX control, registration occurs automatically.
For manual registration, use regActiveX32.exe or regsvr32.exe; both are available with Microsoft development tools and from ActiveX control vendors.
Most ActiveX controls require a supporting DLL, such as the Microsoft Foundation Class runtime library (MFC40.DLL). The DLL must be in the \WINDOWS\SYSTEM directory or in the search path. If the DLL is out of date or missing, your ActiveX control will not register properly.
Note: ActiveX controls, whether distributed by third party ActiveX control vendors or bundled with application development tools, may require that you pay additional fees or obtain additional licenses prior to distributing the ActiveX control.
Support means the ability to create, manipulate, and communicate with ActiveX controls.
Component | Container |
---|---|
Form Builder |
Yes |
Graphics Builder |
No |
Procedure Builder |
No |
Project Builder |
No |
Query Builder |
No |
Report Builder |
No |
Schema Builder |
No |
Translation Builder |
No |
This section lists the ActiveX properties supported by Forms Developer.
Refer to Section 6.1.1.7.4 for a list of the ActiveX and OLE built-ins supported by different components.
For information about how to add an ActiveX control to your application, refer to the online help.
This section provides several examples to help you get started with ActiveX controls.
In Form Builder, you can use the :item('item_name').ocx.server_name.property bind variable syntax to assign or retrieve ActiveX property values.
For example:
:item('ActXitem').OCX.Spindial.spindialctrl.1.Needleposition:= :item('ActXitem').OCX.Spindial.spindialctrl.1.Needleposition + 1;
ActXitem is the name of the item, Spindial.spindialctrl.1 is the name of the ActiveX control server, and Needleposition is the name of the property.
The following code also works if your system.cursor_item is an ActiveX control:
:form.cursor_item.OCX.spindial.spindialctrl.1.Needlposition := :form.cursor_item.OCX.spindial.spindialctrl.1.Needlposition + 1;
In Form Builder, you can use the property accessor functions and procedures to get and set ActiveX properties.
For example:
tblname varchar2; tblname := table_pkg.TableName(:item('Oblk.Oitm').interface);
Table_pkg is the name of the program unit created from the OLE Importer. TableName is the name of the property accessor. Oblk is the name of the block and Oitm is the name of the item.
This example gets a cell value from a Spread Table ActiveX control by using the GetCellByColRow method, which is provided in the SpreadTable package.
DECLARE Cur_Row number; Cur_Col number; The_OLE_Obj OleObj; BEGIN Cur_Row:=SpreadTable.CurrentRow(:ITEM('BLK.ITM').interface); Cur_Col:=SpreadTable.CurrentCol(:ITEM('BLK.ITM').interface); The_OLE_Obj:=SpreadTable.GetCellByColRow(:ITEM('BLK.ITM').interface, Cur_Col, Cur_Row); END;
You can customize and supplement your applications with foreign functions.
This section addresses:
Foreign functions are subprograms written in a 3GL programming language that allow you to customize your applications to meet the unique requirements of your users.
Foreign functions can interact with Oracle databases, and both Forms Developer and Reports Developer variables, items, columns, and parameters. You can also call any external function, such as Windows DLLs or APIs.
Foreign functions are often used to perform the following tasks:
You can develop three types of foreign functions:
An Oracle Precompiler foreign function is the most common foreign function. Using the Oracle Precompiler, you can create foreign functions that access Oracle databases as well as Forms Developer or Reports Developer variables, items, columns, and parameters.
An Oracle Precompiler foreign function incorporates the Oracle Precompiler interface. This interface enables you to write a subprogram in one of the following supported host languages with embedded SQL commands: Ada, C, COBOL, FORTRAN, Pascal, and PL/I.
An Oracle Precompiler foreign function source file includes host programming language statements and Oracle Precompiler statements with embedded SQL statements. Precompiling an Oracle Precompiler foreign function replaces the embedded SQL statements with equivalent host programming language statements. After precompiling, you have a source file that you can compile with a host language compiler.
An OCI foreign function incorporates the Oracle Call Interface. This interface enables you to write a subprogram that contains calls to Oracle databases. A foreign function that incorporates only the OCI (and not the Oracle Precompiler interface) cannot access Forms Developer or Reports Developer variables, items, columns, and parameters.
Note: You can also develop foreign functions that combine both the ORACLE Precompiler interface and the OCI.
A non-Oracle foreign function does not incorporate either the Oracle Precompiler interface or the OCI. For example, a non-Oracle foreign function might be written entirely in the C language. A non-Oracle foreign function cannot access Oracle databases, or Forms Developer or Reports Developer variables, items, columns, and parameters.
Both Forms Developer and Reports Developer use PL/SQL as their programming language. In order to call a foreign function, such as a C function in a Windows DLL, PL/SQL must have an interface to communicate with the foreign function.
You can communicate with your foreign function through two distinct interfaces, either the Oracle Foreign Function Interface (ORA_FFI) or the user exit interface.
ORA_FFI is a portable and generic mechanism for enabling Forms Developer or Reports Developer to call 3GL routines from PL/SQL subprograms.
Foreign functions that are invoked from a PL/SQL interface must be contained in a dynamic library. Examples of dynamic libraries include dynamic link libraries on Microsoft Windows and shared libraries on UNIX systems.
The user exit interface is a platform-specific mechanism for enabling Forms Developer or Reports Developer to call 3GL routines from PL/SQL subprograms.
The foreign functions that you invoke from a user exit interface must be contained in a dynamic link library (.DLL) or linked with an application executable.
This section describes the advantages and disadvantages of using ORA_FFI and user exits.
This section provides guidelines for working with foreign functions.
For more information about foreign functions, refer to the following publications:
This section provides detailed steps that describe how to create a foreign function interface:
The following example creates a PL/SQL package called WinSample. The WinSample package includes interfaces to the foreign function GetPrivateProfileString in the dynamic library KRNL386.EXE.
Note: When you create an ORA_FFI interface to a foreign function, you perform two basic steps. First, you create and associate a subprogram with a foreign function (the dispatcher function). By associating a PL/SQL subprogram with a foreign function, you can invoke the foreign function each time you call the associated PL/SQL subprogram. Associating a foreign function with a PL/SQL subprogram is necessary because both Forms Developer and Reports Developer use PL/SQL constructs. Second, you create a PL/SQL function which passes the arguments to the dispatcher function. The dispatcher function invokes the foreign function.
Your package spec must represent the library. It must also define the PL/SQL function that you want to invoke.
For example:
PACKAGE WinSample IS FUNCTION GetPrivateProfileString (Section IN VARCHAR2, Entry IN VARCHAR2, DefaultStr IN VARCHAR2, ReturnBuf IN OUT VARCHAR2, BufLen IN PLS_INTEGER, Filename IN VARCHAR2) RETURN PLS_INTEGER; END;
In this example, you call the WinSample.GetPrivateProfileString PL/SQL function to invoke the GetPrivateProfileString foreign function in the dynamic library KRNL386.EXE.
Note: You should check the parameters for the C function GetPrivateProfileString, and specify the matching PL/SQL parameter types and the PL/SQL return types. The C datatype int is equivalent to the PL/SQL parameter IN PLS_INTEGER and the PL/SQL return type PLS_INTEGER. The C datatype char is equivalent to the PL/SQL parameter IN VARCHAR2.
For example:
PACKAGE BODY WinSample IS lh_KRNL386 ORA_FFI.LIBHANDLETYPE; fh_GetPrivateProfileString ORA_FFI.FUNCHANDLETYPE;
In this step, you declare the handle types for the library and the function. Later you will load the library and register the function using ORA_FFI.LOAD_LIBRARY and ORA_FFI.REGISTER_FUNCTION. Each of these functions returns a handle (a pointer) to the specified library and the function. ORA_FFI.LIBHANDLETYPE and ORA_FFI.FUNCHANDLETYPE are the PL/SQL datatypes for these handles.
For example:
FUNCTION i_GetPrivateProfileString (funcHandle IN ORA_FFI.FUNCHANDLETYPE, Section IN OUT VARCHAR2, Entry IN OUT VARCHAR2, DefaultStr IN OUT VARCHAR2, ReturnBuf IN OUT VARCHAR2, BufLen IN PLS_INTEGER, Filename IN OUT VARCHAR2) RETURN PLS_INTEGER; PRAGMA INTERFACE(C,i_GetPrivateProfileString,11265);
The first argument of the dispatcher function that calls a foreign function must have at least one parameter, and the first parameter must be a handle to the registered foreign function that the subprogram invokes.
When you call the dispatcher function from the PL/SQL function, you pass the function handle as defined in step 2 (fh_GetPrivateProfileString).
When the dispatcher function gets called, the PRAGMA statement passes control to a memory location (11265 as specified in the above code) that communicates with the dynamic library.
For example:
FUNCTION GetPrivateProfileString (Section IN VARCHAR2, Entry IN VARCHAR2, DefaultStr IN VARCHAR2, ReturnBuf IN OUT VARCHAR2, BufLen IN PLS_INTEGER, Filename IN VARCHAR2) RETURN PLS_INTEGER IS Section_l VARCHAR2(512) := Section; Entry_l VARCHAR2(512) := Entry; DefaultStr_l VARCHAR2(512) := DefaultStr; ReturnBuf_l VARCHAR2(512) := RPAD(SUBSTR(NVL (ReturnBuf,' '),1,512),512,CHR(0)); BufLen_l PLS_INTEGER := BufLen; Filename_l VARCHAR2(512) := Filename; rc PLS_INTEGER; BEGIN rc := i_GetPrivateProfileString (fh_GetPrivateProfileString, Section_l, Entry_l, DefaultStr_l, ReturnBuf_l, BufLen_l, Filename_l); ReturnBuf := ReturnBuf_l; RETURN (rc); END;
This is the PL/SQL function you call from your application. This function passes the arguments to the dispatcher function i_GetPrivateProfileString, then i_GetPrivateProfileString invokes the C function GetPrivateProfileString in KRNL386.EXE. Recall that the first argument of a dispatcher function must be a function handle. Here fh_GetPrivateProfileString is used to pass the function handle declared in Step 2.
The package body must perform four steps to initialize a foreign function:
For example:
BEGIN /* Load the library .*/ lh_KRNL386 := ORA_FFI.LOAD_LIBRARY ('location of the DLL here','KRNL386.EXE'); /* Register the foreign function. */ fh_GetPrivateProfileString := ORA_FFI.REGISTER_FUNCTION (lh_ KRNL386,'GetPrivateProfileString',ORA_FFI.PASCAL_STD); /* Register the parameters. */ ORA_FFI.REGISTER_PARAMETER (fh_GetPrivateProfileString,ORA_FFI.C_CHAR_PTR); ORA_FFI.REGISTER_ PARAMETER (fh_GetPrivateProfileString,ORA_FFI.C_CHAR_PTR); ORA_FFI.REGISTER_ PARAMETER (fh_GetPrivateProfileString,ORA_FFI.C_CHAR_PTR); ORA_FFI.REGISTER_ PARAMETER (fh_GetPrivateProfileString,ORA_FFI.C_CHAR_PTR); ORA_FFI.REGISTER_PARAMETER (fh_GetPrivateProfileString,ORA_FFI.C_INT); ORA_FFI.REGISTER_PARAMETER (fh_GetPrivateProfileString,ORA_FFI.C_CHAR_PTR); /* Register the return type. */ ORA_FFI.REGISTER_RETURN(fh_GetPrivateProfileString,ORA_FFI.C_INT); END WinSample;
Recall that you declared two handles for the library and the function in Step 2. In this step, you assign values to the handles by using the ORA_FFI.LOAD_LIBRARY and ORA_FFI.REGISTER_FUNCTION functions.
ORA_FFI.LOAD_LIBRARY takes two arguments: the location and the name of the dynamic library. ORA_FFI.REGISTER_FUNCTION takes three arguments: the library handle for the library where the function resides, the function name, and the calling standard. The calling standard can be either C_STD (for the C calling standard) or PASCAL_STD (for the Pascal calling standard).
After you load the library and register the function, you must register the parameters and return types (if there are any).
ORA_FFI.REGISTER_PARAMETER and ORA_FFI.REGISTER_RETURN take two arguments each: the function handle and the argument type.
For example:
x := Winsample.GetPrivateProfileString ('Oracle', 'ORACLE_HOME', '<Not Set>', 'Value', 100, 'oracle.ini');
User exits are not generic; they are platform-specific. Some details of implementing user exits are specific to each operating system. The following example describes how to create a user exit on Windows 95.
On Microsoft Windows, a foreign function that can be invoked from a user exit is contained in a dynamic link library (.DLL). A DLL is a library that loads into memory only when the contained code is invoked.
The following example creates a foreign function that adds an ID column to the EMP table.
This example uses several sample files, including:
The user exit sample files are located in your ORACLE_HOME directory (for example, C:\ORAWIN95\FORMS60\USEREXIT).
For example, create a text file called UEXIT.PC, then add the following:
/* UEXIT.PC file */ /* This foreign function adds an ID column to the EMP table. */ #ifndef UE #include "ue.h" #endif #ifndef _WINDLL #define SQLCA_STORAGE_CLASS extern #endif EXEC SQL INCLUDE sqlca.h ; void AddColumn() { EXEC SQL alter table EMP add ID varchar(9); }
For example, use Pro*C to precompile the UEXIT.PC file. When you precompile UEXIT.PC, Pro*C creates a C file called UEXIT.C.
Note: When precompiling, be sure to specify the following MSVC compiler flags:
Large, Segment Setup: SS != DS, DSloads on function entry
Assume `extern' and Uninitialized Data `far' is checked Yes
In Windows Prolog/Epilogue, Generate prolog/Epilogue for None
Your header file must define your foreign function.
For example, modify the sample header file, UE.H, by adding the following:
extern void AddColumn();
For example, modify the sample file, UE_XTB.C, by adding an include statement for UE.H (# include "ue.h"), the name of the user exit (Add_ID_Column), the name of the foreign function (AddColumn), and the language type(XITCC).
#ifndef UE #include "ue.h" #endif /* UE */ #include "ue_samp.h" /* Define the user exit table */ exitr iapxtb[] = { /* Holds exit routine pointers */ "Add_ID_Column", AddColumn, XITCC, (char *) 0, 0, 0 /* zero entry marks the end */ }; /* end iapxtb */
For example, using your compiler, create a project that contains: UE_SAMP.MAK, IFXTB60.DEF, UEZ.OBJ, UE_XTB.C, and UEXIT.C.
Before building your DLL, you must link the following files:
LIBC.LIB OLDNAMES C:\ORAWIN95\FORMS60\USEREXIT\IFR60.LIB C:\ORAWIN95\PRO20\USEREXIT\SQLLIB18.LIB C:\ORAWIN95\PRO20\USEREXIT\SQXLIB18.LIB
After building the UE_SAMP.MAK project, the result is a DLL named UE_SAMP.DLL. Add the UE_SAMP.DLL entry to the list of DLLs defined by the FORMS60_USEREXITS parameter in the registry.
Alternatively, you can rename UE_SAMP.DLL to IFXTB60.DLL, backup the IFXTB60.DLL in the C:\ORAWIN95\BIN directory, and copy the new IFXTB60.DLL to the C:\ORAWIN95\BIN directory.
For example, create a When-Button-Pressed Trigger that calls the foreign function from a user exit.
The following statement demonstrates how to invoke the AddColumn foreign function by specifying the user exit name Add_ID_Column in the USER_EXIT built-in:
/* Trigger: When-Button-Pressed */ USER_EXIT('Add_ID_Column');
This section includes several examples that describe how to use foreign functions.
/* WinHelp ORA_FFI. */ /* */ /* */ /* Usage: WinHelp.WinHelp(helpfile VARCHAR2, */ /* command VARCHAR2, */ /* data {VARCHAR2/PLS_INTEGER See Below}) */ /* */ /* command can be one of the following: */ /* */ /* 'HELP_INDEX' Help Contents */ /* 'HELP_CONTENTS' " */ /* 'HELP_CONTEXT' Context Key (See below) */ /* 'HELP_KEY' Key Search */ /* 'HELP_PARTIALKEY' Partial Key Search */ /* 'HELP_QUIT' Quit */ /* */ /* data contains a string for the key search or a numeric context */ /* value if using topics. */ /* */ /* Winhelp.Winhelp('C:\ORAWIN95\TOOLS\DOC60\US\IF60.HLP', */ /* 'HELP_PARTIALKEY', */ /* 'ORA_FFI'); */ /* */ /* The commented sections replace the line below if using HELP_CONTEXT keys */ PACKAGE WinHelp IS FUNCTION WinHelp(helpfile IN VARCHAR2, command IN VARCHAR2, data IN VARCHAR2) RETURN PLS_INTEGER; END; PACKAGE BODY WinHelp IS lh_USER ora_ffi.libHandleType; fh_WinHelp ora_ffi.funcHandleType; FUNCTION i_WinHelp(funcHandle IN ora_ffi.funcHandleType, hwnd IN PLS_INTEGER, helpfile IN OUT VARCHAR2, command IN PLS_INTEGER, data IN OUT VARCHAR2) RETURN PLS_INTEGER; PRAGMA INTERFACE(C,i_WinHelp,11265); FUNCTION WinHelp(helpfile IN VARCHAR2, command IN VARCHAR2, data IN VARCHAR2) RETURN PLS_INTEGER IS hwnd_l PLS_INTEGER; helpfile_l VARCHAR2(512) := helpfile; command_l PLS_INTEGER; data_l VARCHAR2(512) := data; rc PLS_INTEGER; FUNCTION Help_Convert(command IN VARCHAR2) RETURN PLS_INTEGER IS BEGIN /* The windows.h definitions for command */ /* HELP_CONTEXT 0x0001 */ /* HELP_QUIT 0x0002 */ /* HELP_INDEX 0x0003 */ /* HELP_CONTENTS 0x0003 */ /* HELP_HELPONHELP 0x0004 */ /* HELP_SETINDEX 0x0005 */ /* HELP_SETCONTENTS 0x0005 */ /* HELP_CONTEXTPOPUP 0x0008 */ /* HELP_FORCEFILE 0x0009 */ /* HELP_KEY 0x0101 */ /* HELP_COMMAND 0x0102 */ /* HELP_PARTIALKEY 0x0105 */ /* HELP_MULTIKEY 0x0201 */ /* HELP_SETWINPOS 0x0203 */ if command = 'HELP_CONTEXT' then return(1); end if; if command = 'HELP_KEY' then return(257); end if; if command = 'HELP_PARTIALKEY' then return(261); end if; if command = 'HELP_QUIT' then return(2); end if; /* If nothing else go to the contents page */ return(3); END; BEGIN hwnd_l := TO_PLS_INTEGER(Get_Item_Property(name_in('SYSTEM.CURSOR_ITEM'),WINDOW_ HANDLE)); command_l := Help_Convert(command); rc := i_WinHelp(fh_WinHelp, hwnd_l, helpfile_l, command_l, data_l); RETURN (rc); END ; BEGIN BEGIN lh_USER := ora_ffi.find_library('USER.EXE'); EXCEPTION WHEN ora_ffi.FFI_ERROR THEN lh_USER := ora_ffi.load_library(NULL,'USER.EXE'); END ; fh_WinHelp := ora_ffi.register_function(lh_USER,'WinHelp',ora_ffi.PASCAL_STD); ora_ffi.register_parameter(fh_WinHelp,ORA_FFI.C_INT); /* HWND */ ora_ffi.register_parameter(fh_WinHelp,ORA_FFI.C_CHAR_PTR); /* LPCSTR */ ora_ffi.register_parameter(fh_WinHelp,ORA_FFI.C_INT); /* UINT */ ora_ffi.register_parameter(fh_WinHelp,ORA_FFI.C_CHAR_PTR); /* DWORD */ ora_ffi.register_return(fh_WinHelp,ORA_FFI.C_INT); /* BOOL */ END WinHelp;
PACKAGE OraDlg IS FUNCTION OraMultiFileDlg (Title IN VARCHAR2, Filter IN VARCHAR2, Dir IN VARCHAR2, FileString IN OUT VARCHAR2) RETURN PLS_INTEGER; FUNCTION OraSingleFileDlg (Title IN VARCHAR2, Filter IN VARCHAR2, Dir IN VARCHAR2, FileString IN OUT VARCHAR2) RETURN PLS_INTEGER; END OraDlg; PACKAGE BODY OraDlg IS lh_ORADLG ora_ffi.libHandleType; fh_OraMultiFileDlg ora_ffi.funcHandleType; fh_OraSingleFileDlg ora_ffi.funcHandleType; FUNCTION i_OraMultiFileDlg (funcHandle IN ora_ffi.funcHandleType, Title IN OUT VARCHAR2, Filter IN OUT VARCHAR2, Dir IN OUT VARCHAR2, FileString IN OUT VARCHAR2) RETURN PLS_INTEGER; PRAGMA INTERFACE(C,i_OraMultiFileDlg,11265); FUNCTION OraMultiFileDlg (Title IN VARCHAR2, Filter IN VARCHAR2, Dir IN VARCHAR2, FileString IN OUT VARCHAR2) RETURN PLS_INTEGER IS Title_l VARCHAR2(128) := RPAD(SUBSTR(NVL(Title,'Open'),1,128),128,CHR(0)); Filter_l VARCHAR2(128) := RPAD(SUBSTR(NVL (Filter,'All Files (*.*)|*.*|'),1,128),128,CHR(0)); Dir_l VARCHAR2(256) := RPAD(SUBSTR(NVL(Dir,' '),1,256),256,CHR(0)); FileString_l VARCHAR2(2000) := RPAD(SUBSTR(NVL(FileString,' '),1,2000),2000,CHR(0)); rc PLS_INTEGER; BEGIN rc := i_OraMultiFileDlg(fh_OraMultiFileDlg, Title_l, Filter_l, Dir_l, FileString_l); FileString := FileString_l; RETURN (rc); END ; FUNCTION i_OraSingleFileDlg (funcHandle IN ora_ffi.funcHandleType, Title IN OUT VARCHAR2, Filter IN OUT VARCHAR2, Dir IN OUT VARCHAR2, FileString IN OUT VARCHAR2) RETURN PLS_INTEGER; PRAGMA INTERFACE(C,i_OraSingleFileDlg,11265); FUNCTION OraSingleFileDlg (Title IN VARCHAR2, Filter IN VARCHAR2, Dir IN VARCHAR2, FileString IN OUT VARCHAR2) RETURN PLS_INTEGER IS Title_l VARCHAR2(128) := RPAD(SUBSTR(NVL(Title,'Open'),1,128),128,CHR(0)); Filter_l VARCHAR2(128) := RPAD(SUBSTR(NVL (Filter,'All Files (*.*)|*.*|'),1,128),128,CHR(0)); Dir_l VARCHAR2(256) := RPAD(SUBSTR(NVL(Dir,' '),1,256),256,CHR(0)); FileString_l VARCHAR2(2000) := RPAD(SUBSTR(NVL(FileString,' '),1,2000),2000,CHR(0)); rc PLS_INTEGER; BEGIN rc := i_OraSingleFileDlg(fh_OraSingleFileDlg, Title_l, Filter_l, Dir_l, FileString_l); FileString := FileString_l; RETURN (rc); END ; BEGIN BEGIN lh_ORADLG := ora_ffi.find_library('ORADLG.DLL'); EXCEPTION WHEN ora_ffi.FFI_ERROR THEN lh_ORADLG := ora_ffi.load_library(NULL,'ORADLG.DLL'); END ; fh_OraMultiFileDlg := ora_ffi.register_function (lh_ORADLG,'OraMultiFileDlg',ora_ffi.PASCAL_STD); ora_ffi.register_parameter(fh_OraMultiFileDlg,ORA_FFI.C_CHAR_PTR); ora_ffi.register_parameter(fh_OraMultiFileDlg,ORA_FFI.C_CHAR_PTR); ora_ffi.register_parameter(fh_OraMultiFileDlg,ORA_FFI.C_CHAR_PTR); ora_ffi.register_parameter(fh_OraMultiFileDlg,ORA_FFI.C_CHAR_PTR); ora_ffi.register_return(fh_OraMultiFileDlg,ORA_FFI.C_LONG); fh_OraSingleFileDlg := ora_ffi.register_function (lh_ORADLG,'OraSingleFileDlg',ora_ffi.PASCAL_STD); ora_ffi.register_parameter(fh_OraSingleFileDlg,ORA_FFI.C_CHAR_PTR); ora_ffi.register_parameter(fh_OraSingleFileDlg,ORA_FFI.C_CHAR_PTR); ora_ffi.register_parameter(fh_OraSingleFileDlg,ORA_FFI.C_CHAR_PTR); ora_ffi.register_parameter(fh_OraSingleFileDlg,ORA_FFI.C_CHAR_PTR); ora_ffi.register_return(fh_OraSingleFileDlg,ORA_FFI.C_LONG); END OraDlg;
/* Copyright (c) 1997 by Oracle Corporation */ /* NAME ora_pipe_io_spec.sql - Specification for access to Unix Pipe mechanism DESCRIPTION Demonstration of how to use the ORA_FFI Package to provide access to the Unix Pipe C functions. PUBLIC FUNCTION(S) popen - Open the Pipe command get_line - Get a line of Text from a Pipe put_line - Put a line of Text into a Pipe pclose - Close the Pipe is_open - Determine whether the Pipe descriptor is open. NOTES In Order to use these routines you could write the following PL/SQL Code: -- Example of Calls to ora_pipe_io functions DECLARE stream ora_pipe_io.PIPE; buffer VARCHAR2(240); BEGIN stream := ora_pipe_io.popen('ls -l', ora_pipe_io.READ_MODE); loop exit when not ora_pipe_io.get_line(stream, buffer, 240); :directory.file := buffer; down; end loop; ora_pipe_io.pclose(stream); END; MODIFIED (MM/DD/YY) smclark 08/05/94 - Creation */ PACKAGE ora_pipe_io is /* ** Arguments to popen. */ READ_MODE constant VARCHAR2(1) := 'r'; WRITE_MODE constant VARCHAR2(1) := 'w'; /* ------------- TYPE PIPE ----------- */ /* ** Public Type PIPE - Handle to a Un*x pipe ** ** Do not modify the private members of this type */ TYPE PIPE is RECORD (file_handle ORA_FFI.POINTERTYPE, is_open boolean, read_write_mode VARCHAR2(1)); /* ------------ FUNCTION POPEN ----------- */ /* ** Function POPEN -- Open a Un*x pipe command ** ** Given a Unix command to execute and a Pipe read/write mode in which ** to execute the instruction this Function will execute the Command ** and return a handle, of type PIPE, to the resulting Input/Output ** stream. ** ** The command to be executed is limited to 1024 characters. */ FUNCTION popen(command in VARCHAR2, ctype in VARCHAR2) RETURN PIPE; /* ------------ PROCEDURE PCLOSE ----------- */ /* ** Procedure PCLOSE -- Close a pipe ** ** Close a previously opened pipe. ** ** Raises a VALUE_ERROR exception if incorrect arguments are passed. */ PROCEDURE pclose(stream in out PIPE); /* ------------ FUNCTION GET_LINE ----------- */ /* ** Function GET_LINE ** -- Get a line of text into a buffer from the read mode pipe. ** ** Get a line of text from a previously opened pipe. ** ** Raises a VALUE_ERROR exception if incorrect arguments are passed. ** For example ** if you pass a pipe which has never been opened (using popen) */ FUNCTION get_line(stream in out PIPE, s in out VARCHAR2, n in PLS_INTEGER) RETURN BOOLEAN; /* ------------ PROCEDURE PUT_LINE ----------- */ /* ** Procedure PUT_LINE -- Put a line of text into a a write mode pipe. ** ** Put a line of text into a previously opened pipe. ** ** Raises a VALUE_ERROR exception if incorrect arguments are passed. ** For example ** if you pass a pipe which has never been opened (using popen) ** ** The Internal buffer for the string to write is limited to 2048 bytes */ PROCEDURE put_line(stream in out PIPE, s in VARCHAR2); /* ------------ FUNCTION IS_OPEN ----------- */ /* ** Function IS_OPEN -- Determines whether a pipe is open. ** ** Returns TRUE if the pipe is open, FALSE if the pipe is closed. */ FUNCTION is_open(stream in PIPE) RETURN BOOLEAN; END; /* ora_pipe_io_body.sql - Body of Package for access to Unix Pipe mechanism DESCRIPTION Demonstration of how to use the ORA_FFI Package to provide access to the Unix Pipe C functions. PUBLIC FUNCTION(S) popen - Open the Pipe command get_line - Get a line of Text from a Pipe put_line - Put a line of Text into a Pipe pclose - Close the Pipe is_open - Determine whether the Pipe descriptor is open. PRIVATE FUNCTION(S) icd_popen, icd_fgets, icd_fputs, icd_pclose NOTES MODIFIED (MM/DD/YY) smclark 11/02/94 - Modified for production release changes to ORA_FFI. smclark 08/05/94 - Creation */ PACKAGE BODY ora_pipe_io is lh_libc ora_ffi.libHandleType; fh_popen ora_ffi.funcHandleType; fh_pclose ora_ffi.funcHandleType; fh_fgets ora_ffi.funcHandleType; fh_fputs ora_ffi.funcHandleType; /* ------------ FUNCTION ICD_POPEN ----------- */ /* ** Function ICD_POPEN -- Interface routine to C function popen ** ** This function acts as the interface to the popen function in ** libc. */ FUNCTION icd_popen(funcHandle in ora_ffi.funcHandleType, command in out VARCHAR2, ctype in out VARCHAR2) return ORA_FFI.POINTERTYPE; pragma interface(c, icd_popen, 11265); /* ------------ PROCEDURE ICD_PCLOSE ----------- */ /* ** Function ICD_PCLOSE -- Interface routine to C function pclose ** ** This function acts as the interface to the pclose function in ** libc. */ PROCEDURE icd_pclose(funcHandle in ora_ffi.funcHandleType, stream in out ORA_FFI.POINTERTYPE); pragma interface(c, icd_pclose, 11265); /* ------------ FUNCTION ICD_FGETS ----------- */ /* ** Function ICD_FGETS -- Interface routine to C function fgets ** ** This function acts as the interface to the fgets function in ** libc. */ FUNCTION icd_fgets(funcHandle in ora_ffi.funcHandleType, s in out VARCHAR2, n in PLS_INTEGER, stream in out ORA_FFI.POINTERTYPE) RETURN ORA_FFI.POINTERTYPE; pragma interface(c, icd_fgets, 11265); /* ------------ FUNCTION ICD_FPUTS ----------- */ /* ** Function ICD_FPUTS -- Interface routine to C function fputs ** ** This function acts as the interface to the fputs function in ** libc. */ PROCEDURE icd_fputs(funcHandle in ora_ffi.funcHandleType, s in out VARCHAR2, stream in out ORA_FFI.POINTERTYPE); pragma interface(c, icd_fputs, 11265); /* ------------ FUNCTION POPEN ----------- */ /* ** Function POPEN -- Open a Un*x pipe command */ FUNCTION popen(command in VARCHAR2, ctype in VARCHAR2) RETURN PIPE is /* ** Take a copy of the arguments because we need to pass them ** IN OUT to icd_popen, but we really don't want people to have ** to call our routines in the same way. */ cmd varchar2(1024) := command; cmode varchar2(1) := ctype; stream PIPE; BEGIN if (cmode not in (READ_MODE, WRITE_MODE)) or (cmode is NULL) or (cmd is NULL) then raise VALUE_ERROR; end if; stream.file_handle := icd_popen(fh_popen, cmd, cmode); stream.is_open := TRUE; stream.read_write_mode := ctype; return(stream); END popen; /* ------------ PROCEDURE PCLOSE ----------- */ /* ** Procedure PCLOSE -- Close a pipe */ PROCEDURE pclose(stream in out PIPE) is BEGIN icd_pclose(fh_pclose, stream.file_handle); stream.is_open := FALSE; END pclose; /* ------------ FUNCTION GET_LINE ----------- */ /* ** Function GET_LINE -- Get a line of text into a buffer ** from the read mode pipe. */ FUNCTION get_line(stream in out PIPE, s in out VARCHAR2, n in PLS_INTEGER) RETURN BOOLEAN is buffer ORA_FFI.POINTERTYPE; BEGIN if (n <= 0) or (stream.is_open = FALSE) or (stream.is_open is NULL) or (stream.read_write_mode <> READ_MODE) then raise VALUE_ERROR; end if; /* ** Initialise the Buffer area to reserve the correct amount of space. */ s := rpad(' ', n); buffer := icd_fgets(fh_fgets, s, n, stream.file_handle); /* ** Determine whether a NULL pointer was returned. */ return (ora_ffi.is_null_ptr(buffer) = FALSE); END get_line; /* ------------ PROCEDURE PUT_LINE ----------- */ /* ** Procedure PUT_LINE -- Put a line of text into a a write mode pipe. */ PROCEDURE put_line(stream in out PIPE, s in VARCHAR2) is buffer varchar2(2048) := s; BEGIN if (stream.is_open = FALSE) or (stream.is_open is NULL) or (stream.read_write_mode <> WRITE_MODE) then raise VALUE_ERROR; end if; icd_fputs(fh_fputs, buffer, stream.file_handle); buffer := chr(10); icd_fputs(fh_fputs, buffer, stream.file_handle); END put_line; /* ------------ FUNCTION IS_OPEN ----------- */ /* ** Function IS_OPEN -- Determines whether a pipe is open. */ FUNCTION is_open(stream in PIPE) RETURN BOOLEAN is BEGIN return(stream.is_open); END is_open; BEGIN /* ** Declare a library handle as libc. (Internal so NULL,NULL) */ lh_libc := ora_ffi.load_library(NULL, NULL); if ora_ffi.is_null_ptr(lh_libc) then raise VALUE_ERROR; end if; /* ** Register the popen function, it's return type and arguments. */ fh_popen := ora_ffi.register_function(lh_libc, 'popen'); if ora_ffi.is_null_ptr(fh_popen) then raise VALUE_ERROR; end if; ora_ffi.register_return(fh_popen, ORA_FFI.C_DVOID_PTR); ora_ffi.register_parameter(fh_popen, ORA_FFI.C_CHAR_PTR); ora_ffi.register_parameter(fh_popen, ORA_FFI.C_CHAR_PTR); /* ** Register the pclose function, it's return type and arguments. */ fh_pclose := ora_ffi.register_function(lh_libc, 'pclose'); if ora_ffi.is_null_ptr(fh_pclose) then raise VALUE_ERROR; end if; ora_ffi.register_return(fh_pclose, ORA_FFI.C_VOID); ora_ffi.register_parameter(fh_pclose, ORA_FFI.C_DVOID_PTR); /* ** Register the fgets function, it's return type and arguments. */ fh_fgets := ora_ffi.register_function(lh_libc, 'fgets'); if ora_ffi.is_null_ptr(fh_fgets) then raise VALUE_ERROR; end if; ora_ffi.register_return(fh_fgets, ORA_FFI.C_DVOID_PTR); ora_ffi.register_parameter(fh_fgets, ORA_FFI.C_CHAR_PTR); ora_ffi.register_parameter(fh_fgets, ORA_FFI.C_INT); ora_ffi.register_parameter(fh_fgets, ORA_FFI.C_DVOID_PTR); /* ** Register the fputs function, it's return type and arguments. */ fh_fputs := ora_ffi.register_function(lh_libc, 'fputs'); if ora_ffi.is_null_ptr(fh_fputs) then raise VALUE_ERROR; end if; ora_ffi.register_return(fh_fputs, ORA_FFI.C_VOID); ora_ffi.register_parameter(fh_fputs, ORA_FFI.C_CHAR_PTR); ora_ffi.register_parameter(fh_fputs, ORA_FFI.C_DVOID_PTR); END ora_pipe_io;
This section describes the non-interactive, programmatic method for building and modifying Form Builder applications. It includes these topics:
The Open API is an advanced Form Builder feature for C/C++ developers that want the power and flexibility to create or modify form modules in a non-interactive environment.
Note: Before using the Open API, you should have a thorough understanding of Form Builder objects and their properties and relations.
Use the Open API when you want to quickly propagate development changes to a large number of form modules. You might, for example, use the Open API to update your applications to the current corporate standards for look and feel. This could involve updating hundreds for form modules.
You can also use the Open API to:
The Open API consists of one C header file for each Form Builder object. There are 34 Form Builder objects (see the figure). These objects correspond to the Form Builder objects that you are familiar with at design-time. Each header file contains several functions and macros that you use to create and manipulate Form Builder objects.
Within the Open API, you manipulate Form Builder objects by setting object properties.
Open API properties have their own unique names, such as D2FP_FONT_NAM. These properties correspond to the Form Builder properties that you are familiar with at design-time.
A property can be one of the following: Boolean, Text, Number, Object, or Blob.
The table below lists some common item properties with their corresponding Open API equivalents.
You use Open API functions and macros to create, destroy, duplicate, subclass, get, and set object properties.
For example, to determine an item's font size, use the D2FITMG_FONT_SIZ macro:
d2fitmg_font_siz(ctx, obj, val);
This macro returns the value of the Font Size property of the item object as type number.
To set a text item property, use the D2FITMST_SETTEXTPROP function:
d2fitmst_SetTextProp(d2fctx *pd2fctx, d2fitm *pd2fitm, ub2 pnum,text *prp );
This function sets the value of the specified item text property. You specify a pointer to the context in pd2fctx, the item in pd2fitm, the property number in pnum, and a handle to the text value in prp.
This section provides detailed steps that describe how to create and modify Form Builder modules using the Open API.
To create or modify a Form Builder module:
This section includes several examples that describe how to use the Open API.
/* This example determines if the Form Builder object is a subclassed object and returns the file path of the parent to NULL if the object is subclassed. This sample only processes the following object types: form level triggers, alerts, blocks, items, item level triggers, radio buttons, and block level triggers. Use a similar method to process other object types. */ #include <stdio.h> #include <string.h> #include <windows.h> #include <d2ferr.h> #include <d2fctx.h> #include <d2ffmd.h> #include <d2fblk.h> #include <d2fitm.h> #include <d2falt.h> #include <d2ftrg.h> #include <d2frdb.h> #define BUFSIZE 128 int WINAPI WinMain(HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpszCommandLine, int cmdShow) { d2fctx* pd2fctx; d2ffmd* pd2ffmd; d2fblk* pd2fblk; d2fitm* pd2fitm; d2fctxa d2fctx_attr; d2fstatus status; d2falt* pd2falt; d2ftrg* pd2ftrg; d2frdb* pd2frdb; int counter; char buf[BUFSIZE]; char* form_name=(char*)0; /* Get the form name from the command line */ strncpy(buf, lpszCommandLine, BUFSIZE); form_name = strtok(buf, "."); /* Initialize the attribute mask */ d2fctx_attr.mask_d2fctxa = 0; /* for MS Windows-only attributes */ d2fctx_attr.d2fihnd_d2fctxa = hInstance; d2fctx_attr.d2fphnd_d2fctxa = hPrevInstance; d2fctx_attr.d2fcmsh_d2fctxa = cmdShow; /* Create the API context */ status = d2fctxcr_Create(&pd2fctx, &d2fctx_attr); /* Load the form */ status = d2ffmdld_Load(pd2fctx, &pd2ffmd, form_name, FALSE) ; if (status == D2FS_D2FS_SUCCESS) { /*** Process Form Level Trigger Objects ***/ for(status = d2ffmdg_trigger(pd2fctx,pd2ffmd,&pd2ftrg); pd2ftrg != NULL; status = d2ftrgg_next(pd2fctx,pd2ftrg,&pd2ftrg)) { if (d2ftrgis_IsSubclassed(pd2fctx,pd2ftrg) == D2FS_YES) d2ftrgs_par_flpath(pd2fctx,pd2ftrg,NULL); } /*** Process Alert Objects ***/ for(status = d2ffmdg_alert(pd2fctx,pd2ffmd,&pd2falt); pd2falt != NULL; status = d2faltg_next(pd2fctx,pd2falt,&pd2falt)) { if (d2faltis_IsSubclassed(pd2fctx,pd2falt) == D2FS_YES) d2falts_par_flpath(pd2fctx,pd2falt,NULL); } /*** Process Block Objects ***/ for(status = d2ffmdg_block(pd2fctx,pd2ffmd,&pd2fblk); pd2fblk != NULL; status = d2fblkg_next(pd2fctx,pd2fblk,&pd2fblk)) { if (d2fblkis_IsSubclassed(pd2fctx,pd2fblk) == D2FS_YES) d2fblks_par_flpath(pd2fctx,pd2fblk,NULL); } /* Process Item Objects */ for(status = d2fblkg_item(pd2fctx,pd2fblk,&pd2fitm); pd2fitm != NULL; status = d2fitmg_next(pd2fctx,pd2fitm,&pd2fitm)) { if (d2fitmis_IsSubclassed(pd2fctx,pd2fitm) == D2FS_YES) d2fitms_par_flpath(pd2fctx,pd2fitm,NULL); /* Process Item Level Trigger Objects */ for(status = d2fitmg_trigger(pd2fctx,pd2fitm,&pd2ftrg); pd2ftrg != NULL; status = d2ftrgg_next(pd2fctx,pd2ftrg,&pd2ftrg)) { if (d2ftrgis_IsSubclassed(pd2fctx,pd2ftrg)==D2FS_YES) { d2ftrgs_par_flpath(pd2fctx,pd2ftrg,NULL); printf("item trigger is Subclassed\n"); } else if (d2ftrgis_IsSubclassed(pd2fctx, pd2ftrg)==D2FS_NO) printf("item trigger is NOT Subclassed\n"); } /* Process Radio Button Objects * for(status = d2fitmg_rad_but(pd2fctx,pd2fitm,&pd2frdb); pd2frdb != NULL; status = d2frdbs_next(pd2fctx,pd2frdb,&pd2frdb)) { if (d2frdbis_IsSubclassed(pd2fctx,pd2frdb)==D2FS_YES { d2frdbs_par_flpath(pd2fctx,pd2frdb,NULL); printf("radio button is Subclassed\n"); } else if (d2frdbis_IsSubclassed(pd2fctx, pd2frdb)==D2FS_NO) printf("radio button is NOT Subclassed\n"); } } /* Process Block Level Trigger Objects */ for(status = d2fblkg_trigger(pd2fctx,pd2fblk,&pd2ftrg); pd2ftrg != NULL; status = d2ftrgg_next(pd2fctx,pd2ftrg,&pd2ftrg)) { if (d2ftrgis_IsSubclassed(pd2fctx,pd2ftrg) == D2FS_YES) { d2ftrgs_par_flpath(pd2fctx,pd2ftrg,NULL); printf("block trigger is Subclassed\n"); } else if (d2ftrgis_IsSubclassed(pd2fctx, pd2ftrg)==D2FS_NO) printf("block trigger is NOT Subclassed\n"); } /* Save out the form */ d2ffmdsv_Save(pd2fctx, pd2ffmd, (text *)0, FALSE) ; /* Generate the forms executable (fmx) */ d2ffmdcf_CompileFile(pd2fctx, pd2ffmd ) ; /* Destroy the API Context */ d2fctxde_Destroy(pd2fctx) ; } }
/* This example creates a master-detail form based on the dept and emp database tables owned by the user scott. The master contains the following fields: empno, ename, job, sal, and deptno. The detail contains the following fields deptno, dname, and loc. The join condition is deptno. */ #include<stdio.h> #include<string.h> #include<windows.h> #include<d2fctx.h> #include<d2ffmd.h> #include<d2ffpr.h> #include<d2fob.h> #include<d2fcnv.h> #include<d2ftrg.h> #include<d2blk.h> #include<d2fitm.h> #include<d2fwin.h> #include<d2frel.h> #define D2FS_SUCCESS 0 #define FAIL 1 #define BUFSIZE 128 #define WBP_TXT "null;\n" int WINAPI WinMain(HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpszCommandLine, int cmdShow) { d2fctx *pd2fctx; d2ffmd *pd2ffmd; d2fcnv *pd2fcnv; d2fwin *pd2fwin; d2fblk *pempblk; d2fblk *pdeptblk; d2frel *pd2frel; d2fitm *pEempnoitm; d2fitm *pEenameitm; d2fitm *pEjobitm; d2fitm *pEsalitm; d2fitm *pEdeptnoitm; d2fitm *pDdeptnoitm; d2fitm *pDdnameitm; d2fitm *pDlocitm; text *name = (text *)0; text *form_name = (text *)0; d2fctxa d2fctx_attr; d2fstatus retval; char buf[BUFSIZE]; /* Get form name */ strncpy(buf, "empdept", BUFSIZE); form_name = (text*)strtok(buf, "."); /* Initialize the attribute mask */ d2fctx_attr.mask_d2fctxa = 0; /* for MS Windows-only attributes */ d2fctx_attr.d2fihnd_d2fctxa = hInstance; d2fctx_attr.d2fphnd_d2fctxa = hPrevInstance; d2fctx_attr.d2fcmsh_d2fctxa = cmdShow; /* Create the API context */ status = d2fctxcr_Create(&pd2fctx, &d2fctx_attr); /* Create the context */ d2fctxcn_Connect(pd2fctx, (text*)"scott/tiger@test"); /* Create the form */ d2ffmdcr_Create(pd2fctx, &pd2ffmd, form_name); /* Create a window */ d2fwincr_Create(pd2fctx,pd2ffmd,&pd2fwin,(text*)"MYWIN"); /*** Create Canvas and set canvas-related properties ***/ /* Create a canvas */ d2fcnvcr_Create(pd2fctx, pd2ffmd, &pd2fcnv, (text*)"MYCANVAS"); /* Set viewport width */ d2fcnvs_vprt_wid(pd2fctx, pd2fcnv, 512); /* Set viewport height */ d2fcnvs_vprt_hgt(pd2fctx, pd2fcnv, 403); /* Set window */ dwfcnvs_wnd_obj(pd2fctx, pd2fcnv, pd2fwin); /* Set viewport X-position */ d2fcnvs_vprt_x_pos(pd2fctx, pd2fcnv, 0); /* Set viewport Y-position */ d2fcnvs_vprt_y_pos(pd2fctx, pd2fcnv, 0); /* Set width */ d2fcnvs_width(pd2fctx, pd2fcnv, 538) /* Set height */ d2fcnvs_height(pd2fctx, pd2fcnv, 403) /*** Create Emp block and set block-related properties ***/ /* Create block */ d2fblkcr_Create(pd2fctx, pd2ffmd, &pempblk, (text*)"EMP"); /* Set to database block */ d2fblks_db_blk(pd2fctx, pempblk, TRUE); /* Set query data source to Table */ d2fblks_qry_dat_src_typ(pd2fctx, pempblk, D2FC_QRDA_TABLE); /* Set query data source name to EMP table */ d2fblks_qry_dat_src_nam(pd2fctx, pempblk, "EMP"); /* Set DML data source type to Table */ d2fblks_dml_dat_typ(Pd2fctx, pempblk, D2FC_DMDA_TABLE); /* Set DML data source name to EMP table */ d2fblks_dml_dat_nam(pd2fctx, pempblk, (text*)"EMP"); /*** Create Dept block and set block-related properties ***/ /* Create block */ d2fblkcr_Create(pd2fctx, pd2ffmd, &pdeptblk, (text*)"DEPT"); /* Set to database block */ d2fblks_db_blk(pd2fctx, pdeptblk, TRUE); /* Set query data source to Table */ d2fblks_qry_dat_src_typ(pd2fctx, pdeptblk, D2FC_QRDA_TABLE); /* Set query data source name to EMP table */ d2fblks_qry_dat_src_nam(pd2fctx, pdeptblk, "DEPT"); /* Set DML data source type to Table */ d2fblks_dml_dat_typ(Pd2fctx, pdeptblk, D2FC_DMDA_TABLE); /* Set DML data source name to EMP table */ d2fblks_dml_dat_nam(pd2fctx, pdeptblk, (text*)"DEPT"); /*** Create empno item and item-related properties ***/ /* Create item */ d2fitmcr_Create(pd2fctx, pempblk, &pEempnoitm, (text*)"EMPNO"); /* Set item type */ d2fitms_itm_type(pd2fctx, pEempnoitm, D2FC_ITTY_TI); /* Set Enable property */ d2fitms_enabled(pd2fctx, pEempnoitm, TRUE); /* Set item (keyboard) navigable property */ d2fitms_kbrd_navigable(pd2fctx, pEempnoitm, TRUE); /* Set item Data Type property */ d2fitms_dat_typ(pd2fctx, pEempnoitm, D2FC_DATY_NUMBER); /* Set item Max Length property */ d2fitms_max_len(pd2fctx, pEempnoitm, 6); /* Set item Required property */ d2fitms_required(pd2fctx, pEempnoitm, TRUE); /* Set Distance Between Records property */ d2fitms_dist_btwn_recs(pd2fctx, pEempnoitm, 0); /* Set Database block(Database Item) property */ d2fitms_db_itm(pd2fctx, pEempnoitm, TRUE); /* Set Query Allowed */ d2fitms_qry_allowed(pd2fctx, pEempnoitm, TRUE); /* Set Query Length */ d2fitms_qry_len(pd2fctx, pEempnoitm, 6); /* Set Update Allowed */ d2fitms_updt_allowed(pd2fctx, pEempnoitm, TRUE); /* Set Item Displayed (Visible) */ d2fitms_visible(pd2fctx, pEempnoitm, TRUE); /* Set Item Canvas property */ d2fitms_cnv_obj(pd2fctx, pEempnoitm, pd2fcnv); /* Set Item X-position */ d2fitms_x_pos(pd2fctx, pEempnoitm, 32); /* Set Item Y-position */ d2fitms_y_pos(pd2fctx, pEempnoitm, 50); /* Set Item Width */ d2fitms_width(pd2fctx, pEempnoitm, 51); /* Set Item Height */ d2fitms_height(pd2fctx, pEempnoitm, 17); /* Set Item Bevel */ d2fitms_bevel(pd2fctx, pEempnoitm, D2FC_BEST_LOWERED); /* Set item Hint */ d2fitms_hint(pd2fctx, PEempnoitm, (text*)"Enter value for :EMPNO"); /*** Create Ename item and item-related properties ***/ /* Create item */ d2fitmcr_Create(pd2fctx, pempblk, &pEenameitm, (text*)"ENAME"); /* Set item type */ d2fitms_itm_type(pd2fctx, pEenameitm, D2FC_ITTY_TI); /* Set Enable property */ d2fitms_enabled(pd2fctx, pEenameitm, TRUE); /* Set item (keyboard) navigable property */ d2fitms_kbrd_navigable(pd2fctx, pEenameitm, TRUE); /* Set item Data Type property */ d2fitms_dat_typ(pd2fctx, pEenameitm, D2FC_DATY_CHAR); /* Set item Max Length property */ d2fitms_max_len(pd2fctx, pEenameitm, 10); /* Set Distance Between Records property */ d2fitms_dist_btwn_recs(pd2fctx, pEenameitm, 0); /* Set Database block(Database Item) property */ d2fitms_db_itm(pd2fctx, pEenameitm, TRUE); /* Set Query Allowed */ d2fitms_qry_allowed(pd2fctx, pEenameitm, TRUE); /* Set Query Length */ d2fitms_qry_len(pd2fctx, pEenameitm, 10); /* Set Update Allowed */ d2fitms_updt_allowed(pd2fctx, pEenameitm, TRUE); /* Set Item Displayed (Visible) */ d2fitms_visible(pd2fctx, pEenameitm, TRUE); /* Set Item Canvas property */ d2fitms_cnv_obj(pd2fctx, pEenameitm, pd2fcnv); /* Set Item X-position */ d2fitms_x_pos(pd2fctx, pEenameitm, 83); /* Set Item Y-position */ d2fitms_y_pos(pd2fctx, pEenameitm, 50); /* Set Item Width */ d2fitms_width(pd2fctx, pEenameitm, 77); /* Set Item Height */ d2fitms_height(pd2fctx, pEenameitm, 17); /* Set Item Bevel */ d2fitms_bevel(pd2fctx, pEenameitm, D2FC_BEST_LOWERED); /* Set item Hint */ d2fitms_hint(pd2fctx, PEenameitm, (text*)"Enter value for :ENAME"); /*** Create JOB item and item-related properties ***/ /* Create item */ d2fitmcr_Create(pd2fctx, pempblk, &pEjobitm, (text*)"JOB"); /* Set item type */ d2fitms_itm_type(pd2fctx, pEjobitm, D2FC_ITTY_TI); /* Set Enable property */ d2fitms_enabled(pd2fctx, pEjobitm, TRUE); /* Set item (keyboard) navigable property */ d2fitms_kbrd_navigable(pd2fctx, pEjobitm, TRUE); /* Set item Data Type property */ d2fitms_dat_typ(pd2fctx, pEjobitm, D2FC_DATY_CHAR); /* Set item Max Length property */ d2fitms_max_len(pd2fctx, pEjobitm, 9); /* Set Distance Between Records property */ d2fitms_dist_btwn_recs(pd2fctx, pEjobitm, 0); /* Set Database block(Database Item) property */ d2fitms_db_itm(pd2fctx, pEjobitm, TRUE); /* Set Query Allowed */ d2fitms_qry_allowed(pd2fctx, pEjobitm, TRUE); /* Set Query Length */ d2fitms_qry_len(pd2fctx, pEjobitm, 9); /* Set Update Allowed */ d2fitms_updt_allowed(pd2fctx, pEjobitm, TRUE); /* Set Item Displayed (Visible) */ d2fitms_visible(pd2fctx, pEjobitm, TRUE); /* Set Item Canvas property */ d2fitms_cnv_obj(pd2fctx, pEjobitm, pd2fcnv); /* Set Item X-position */ d2fitms_x_pos(pd2fctx, pEjobitm, 160); /* Set Item Y-position */ d2fitms_y_pos(pd2fctx, pEjobitm, 50); /* Set Item Width */ d2fitms_width(pd2fctx, pEjobitm, 70); /* Set Item Height */ d2fitms_height(pd2fctx, pEjobitm, 17); /* Set Item Bevel */ d2fitms_bevel(pd2fctx, pEjobitm, D2FC_BEST_LOWERED); /* Set item Hint */ d2fitms_hint(pd2fctx, PEjobitm, (text*)"Enter value for :JOB"); /*** Create SALARY item and item-related properties ***/ /* Create item */ d2fitmcr_Create(pd2fctx, pempblk, &pEsalitm, (text*)"SAL"); /* Set item type */ d2fitms_itm_type(pd2fctx, pEsalitm, D2FC_ITTY_TI); /* Set Enable property */ d2fitms_enabled(pd2fctx, pEsalitm, TRUE); /* Set item (keyboard) navigable property */ d2fitms_kbrd_navigable(pd2fctx, pEsalitm, TRUE); /* Set item Data Type property */ d2fitms_dat_typ(pd2fctx, pEsalitm, D2FC_DATY_NUMBER); /* Set item Max Length property */ d2fitms_max_len(pd2fctx, pEsalitm, 9); /* Set Distance Between Records property */ d2fitms_dist_btwn_recs(pd2fctx, pEsalitm, 0); /* Set Database block(Database Item) property */ d2fitms_db_itm(pd2fctx, pEsalitm, TRUE); /* Set Query Allowed */ d2fitms_qry_allowed(pd2fctx, pEsalitm, TRUE); /* Set Query Length */ d2fitms_qry_len(pd2fctx, pEsalitm, 9); /* Set Update Allowed */ d2fitms_updt_allowed(pd2fctx, pEsalitm, TRUE); /* Set Item Displayed (Visible) */ d2fitms_visible(pd2fctx, pEsalitm, TRUE); /* Set Item Canvas property */ d2fitms_cnv_obj(pd2fctx, pEsalitm, pd2fcnv); /* Set Item X-position */ d2fitms_x_pos(pd2fctx, pEsalitm, 352); /* Set Item Y-position */ d2fitms_y_pos(pd2fctx, pEsalitm, 50); /* Set Item Width */ d2fitms_width(pd2fctx, pEsalitm, 70); /* Set Item Height */ d2fitms_height(pd2fctx, pEsalitm, 17); /* Set Item Bevel */ d2fitms_bevel(pd2fctx, pEsalitm, D2FC_BEST_LOWERED); /* Set item Hint */ d2fitms_hint(pd2fctx, PEsalitm, (text*)"Enter value for :SAL"); /*** Create DEPTNO item and item-related properties ***/ /* Create item */ d2fitmcr_Create(pd2fctx, pempblk, &pEdeptnoitm, (text*)"DEPTNO"); /* Set item type */ d2fitms_itm_type(pd2fctx, pEdeptnoitm, D2FC_ITTY_TI); /* Set Enable property */ d2fitms_enabled(pd2fctx, pEdeptnoitm, TRUE); /* Set item (keyboard) navigable property */ d2fitms_kbrd_navigable(pd2fctx, pEdeptnoitm, TRUE); /* Set item Data Type property */ d2fitms_dat_typ(pd2fctx, pEdeptnoitm, D2FC_DATY_NUMBER); /* Set item Max Length property */ d2fitms_max_len(pd2fctx, pEdeptnoitm, 4); /*Set item Required property */ d2fitms_required(pd2fctx, pEdeptnoitm, TRUE); /* Set Distance Between Records property */ d2fitms_dist_btwn_recs(pd2fctx, pEdeptnoitm, 0); /* Set Database block(Database Item) property */ d2fitms_db_itm(pd2fctx, pEdeptnoitm, TRUE); /* Set Query Allowed */ d2fitms_qry_allowed(pd2fctx, pEdeptnoitm, TRUE); /* Set Query Length */ d2fitms_qry_len(pd2fctx, pEdeptnoitm, 4); /* Set Update Allowed */ d2fitms_updt_allowed(pd2fctx, pEdeptnoitm, TRUE); /* Set Item Displayed (Visible) */ d2fitms_visible(pd2fctx, pEdeptnoitm, TRUE); /* Set Item Canvas property */ d2fitms_cnv_obj(pd2fctx, pEdeptnoitm, pd2fcnv); /* Set Item X-position */ d2fitms_x_pos(pd2fctx, pEdeptnoitm, 493); /* Set Item Y-position */ d2fitms_y_pos(pd2fctx, pEdeptnoitm, 50); /* Set Item Width */ d2fitms_width(pd2fctx, pEdeptnoitm, 30); /* Set Item Height */ d2fitms_height(pd2fctx, pEdeptnoitm, 17); /* Set Item Bevel */ d2fitms_bevel(pd2fctx, pEdeptnoitm, D2FC_BEST_LOWERED); /* Set item Hint */ d2fitms_hint(pd2fctx, PEdeptnoitm, (text*)"Enter value for :DEPTNO"); /*** Create DEPTNO item and item-related properties ***/ /* Create item */ d2fitmcr_Create(pd2fctx, pdeptblk, &pDdeptnoitm, (text*)"DEPTNO"); /* Set item type */ d2fitms_itm_type(pd2fctx, pDdeptnoitm, D2FC_ITTY_TI); /* Set Enable property */ d2fitms_enabled(pd2fctx, pDdeptnoitm, TRUE); /* Set item (keyboard) navigable property */ d2fitms_kbrd_navigable(pd2fctx, pDdeptnoitm, TRUE); /* Set item Data Type property */ d2fitms_dat_typ(pd2fctx, pDdeptnoitm, D2FC_DATY_NUMBER); /* Set item Max Length property */ d2fitms_max_len(pd2fctx, pDdeptnoitm, 4); /*Set item Required property */ d2fitms_required(pd2fctx, pDdeptnoitm, TRUE); /* Set Distance Between Records property */ d2fitms_dist_btwn_recs(pd2fctx, pDdeptnoitm, 0); /* Set Database block(Database Item) property */ d2fitms_db_itm(pd2fctx, pDdeptnoitm, TRUE); /* Set Query Allowed */ d2fitms_qry_allowed(pd2fctx, pDdeptnoitm, TRUE); /* Set Query Length */ d2fitms_qry_len(pd2fctx, pDdeptnoitm, 4); /* Set Update Allowed */ d2fitms_updt_allowed(pd2fctx, pDdeptnoitm, TRUE); /* Set Item Displayed (Visible) */ d2fitms_visible(pd2fctx, pDdeptnoitm, TRUE); /* Set Item Canvas property */ d2fitms_cnv_obj(pd2fctx, pDdeptnoitm, pd2fcnv); /* Set Item X-position */ d2fitms_x_pos(pd2fctx, pDdeptnoitm, 32); /* Set Item Y-position */ d2fitms_y_pos(pd2fctx, pDdeptnoitm, 151); /* Set Item Width */ d2fitms_width(pd2fctx, pDdeptnoitm, 38); /* Set Item Height */ d2fitms_height(pd2fctx, pDdeptnoitm, 17); /* Set Item Bevel */ d2fitms_bevel(pd2fctx, pDdeptnoitm, D2FC_BEST_LOWERED); /* Set item Hint */ d2fitms_hint(pd2fctx, PDdeptnoitm, (text*)"Enter value for :DEPTNO"); /*** Create DNAME item and item-related properties ***/ /* Create item */ d2fitmcr_Create(pd2fctx, pdeptblk, &pDdnameitm, (text*)"DNAME"); /* Set item type */ d2fitms_itm_type(pd2fctx, pDdnameitm, D2FC_ITTY_TI); /* Set Enable property */ d2fitms_enabled(pd2fctx, pDdnameitm, TRUE); /* Set item (keyboard) navigable property */ d2fitms_kbrd_navigable(pd2fctx, pDdnameitm, TRUE); /* Set item Data Type property */ d2fitms_dat_typ(pd2fctx, pDdnameitm, D2FC_DATY_CHAR); /* Set item Max Length property */ d2fitms_max_len(pd2fctx, pDdnameitm, 14); /* Set Distance Between Records property */ d2fitms_dist_btwn_recs(pd2fctx, pDdnameitm, 0); /* Set Database block(Database Item) property */ d2fitms_db_itm(pd2fctx, pDdnameitm, TRUE); /* Set Query Allowed */ d2fitms_qry_allowed(pd2fctx, pDdnameitm, TRUE); /* Set Query Length */ d2fitms_qry_len(pd2fctx, pDdnameitm, 14); /* Set Update Allowed */ d2fitms_updt_allowed(pd2fctx, pDdnameitm, TRUE); /* Set Item Displayed (Visible) */ d2fitms_visible(pd2fctx, pDdnameitm, TRUE); /* Set Item Canvas property */ d2fitms_cnv_obj(pd2fctx, pDdnameitm, pd2fcnv); /* Set Item X-position */ d2fitms_x_pos(pd2fctx, pDdnameitm, 70); /* Set Item Y-position */ d2fitms_y_pos(pd2fctx, pDdnameitm, 151); /* Set Item Width */ d2fitms_width(pd2fctx, pDdnameitm, 102); /* Set Item Height */ d2fitms_height(pd2fctx, pDdnameitm, 17); /* Set Item Bevel */ d2fitms_bevel(pd2fctx, pDdnameitm, D2FC_BEST_LOWERED); /* Set item Hint */ d2fitms_hint(pd2fctx, PDdnameitm, (text*)"Enter value for :DNAME"); /*** Create LOC item and item-related properties ***/ /* Create item */ d2fitmcr_Create(pd2fctx, pdeptblk, &pDlocitm, (text*)"LOC"); /* Set item type */ d2fitms_itm_type(pd2fctx, pDlocitm, D2FC_ITTY_TI); /* Set Enable property */ d2fitms_enabled(pd2fctx, pDlocitm, TRUE); /* Set item (keyboard) navigable property */ d2fitms_kbrd_navigable(pd2fctx, pDlocitm, TRUE); /* Set item Data Type property */ d2fitms_dat_typ(pd2fctx, pDlocitm, D2FC_DATY_CHAR); /* Set item Max Length property */ d2fitms_max_len(pd2fctx, pDlocitm, 13); /* Set Distance Between Records property */ d2fitms_dist_btwn_recs(pd2fctx, pDlocitm, 0); /* Set Database block(Database Item) property */ d2fitms_db_itm(pd2fctx, pDlocitm, TRUE); /* Set Query Allowed */ d2fitms_qry_allowed(pd2fctx, pDlocitm, TRUE); /* Set Query Length */ d2fitms_qry_len(pd2fctx, pDlocitm, 13); /* Set Update Allowed */ d2fitms_updt_allowed(pd2fctx, pDlocitm, TRUE); /* Set Item Displayed (Visible) */ d2fitms_visible(pd2fctx, pDlocitm, TRUE); /* Set Item Canvas property */ d2fitms_cnv_obj(pd2fctx, pDlocitm, pd2fcnv); /* Set Item X-position */ d2fitms_x_pos(pd2fctx, pDlocitm, 173); /* Set Item Y-position */ d2fitms_y_pos(pd2fctx, pDlocitm, 151); /* Set Item Width */ d2fitms_width(pd2fctx, pDlocitm, 96); /* Set Item Height */ d2fitms_height(pd2fctx, pDlocitm, 17); /* Set Item Bevel */ d2fitms_bevel(pd2fctx, pDlocitm, D2FC_BEST_LOWERED); /* Set item Hint */ d2fitms_hint(pd2fctx, PDlocitm, (text*)"Enter value for :LOC"); /*** Create Relations and relations-related properties ***/ /* Create Relation */ d2frelcr_Create(pd2fctx, (d2fob *)pdeptblk, &pd2frel, (text*)"DEPT_EMP"); /* Set Relation Detail block */ d2frels_detail_blk(pd2fctx, pd2frel, (text *)"EMP"); /* Set Master Deletes property */ d2frels_del_rec([pd2fctx, pd2frel, D2FC_DERE_NON_ISOLATED); /* Set Deferred property */ d2frels_deferred(pd2ctx, pd2frel, FALSE); /* Set Auto Query property */ d2frels_auto_qry(pd2ctx, pd2frel, FALSE); /* Set Prevent Masterless property */ d2frels_prvnt_mstrless_ops(pd2ctx, pd2frel, FALSE); /* Set Join Condition property */ d2frels_join_cond(pd2ctx, pd2frel, (text*)"DEPTNO"); /* Instantiate Relation: creates master-detail triggers */ d2frelup_Update(pd2fctx, pd2frel); /* Save Form */ d2ffmdsv_Save(pd2fctx, pd2ffmd, (text*)0, FALSE, TRUE); /* Compile Form */ d2ffmdcf_CompileFile(pd2fctx, pd2ffmd); /* Destroy Context */ d2fctxde_Destroy(pd2fctx); }
The data within your enterprise often resides within several heterogeneous datasources. Some portion of your data, for example, might be stored within an Oracle database, while another portion is stored within an Informix database. Building a single application that can access each datasource can be a difficult task.
However, by taking advantage of Forms Developer's and Reports Developer's open datasource support, you can build generic applications that run transparently against any ODBC-compliant datasource.
This section describes open datasource support. It includes these topics:
When you connect to an ODBC datasource, you use the Oracle Open Client Adapter (OCA). OCA is an ODBC level 2-compliant utility that allows Forms Developer or Reports Developer on Microsoft Windows 95, Windows NT, and Windows 3.1 to access ODBC -compliant datasources through ODBC drivers.
OCA is included with both Forms Developer and Reports Developer. You use the Oracle Installer to install OCA.
You should use OCA whenever your application must access non-Oracle datasources. Your Form and Report applications can automatically access any ODBC-compliant datasources. Refer to the online help for specific information about connecting to ODBC datasources.
The Oracle Open Client Adapter consists of the following:
To connect to an ODBC datasource, type the following connect string in the Connect dialog box:
[user[/password]]@ODBC:datasource[:dbname]
For example, to connect to Sybase System 10, type:
scott/tiger@ODBC:sybase_ds
When you connect to an ODBC datasource, you use an ODBC driver to communicate with the datasource. Both Forms Developer and Reports Developer include prebundled ODBC drivers for each supported datasource. These drivers are ODBC level 1-compliant and, to some extent, provide some level 2 functionality to achieve greater performance.
OPENDB.PLL is a PL/SQL library of functions that is included with OCA. You use OPENDB.PLL within applications to:
For more information about OPENDB.PLL, refer to OCA_INFO.PDF in the ORACLE_HOME\TOOLS\DOC20 directory.
To configure your application to run against an ODBC-compliant datasource, refer to the "Accessing non-Oracle datasources" topic in the online help.
|
Copyright © 2000 Oracle Corporation. All Rights Reserved. |
|