|
|
|
この章では、Forms DeveloperおよびReports Developerで利用できる、オープンで拡張可能な環境開発を利用する上で役立つガイドラインを提供します。
この項ではOLEおよびActiveXの内容を説明し、さらにこのテクノロジの利用方法を説明します。この項では、次の項目について説明します。
注意: OLEおよびActiveXのサポートは、Windowsプラットフォームのみに制限されています。
Object Linking and Embedding (OLE)はMicrosoft の標準機能で、様々なソフトウェア・コンポーネントを1つのアプリケーションに統合して再使用できます。
たとえば、アプリケーションをMicrosoft Excel文書と統合すると、Forms Developer(またはReports Developer)およびMicrosoft Excelの機能を提供できるようになります。ユーザーは、Forms DeveloperまたはReports Developerの機能を使用してデータベースのデータの表示や操作を行う一方で、Microsoft Excelで提供されるテキスト処理機能を使用して文書の書式を整えることができます。
OLEオブジェクトをアプリケーションに取り込めば、専用のコンポーネントの様々なグループをシームレスに統合して完全なアプリケーションを作成できます。最初から新規にアプリケーション全体を作成する必要はありません。アプリケーションを短時間に、低コストで配布できます。
OLEは次のような場合に使用します。
たとえば、アプリケーションの機能をワープロ文書、スプレッドシート文書、ノブ・コントロール、ビデオ・クリップ、サウンドで拡張できます。
Microsoft Windowsでは、ほとんどのユーザーがMicrosoft WordやMicrosoft Excelに慣れています。ワープロやスプレッドシートの機能をアプリケーションに作成するのではなく、WordやExcelの文書をアプリケーションに埋め込むことができます。
OLEの基本概念は、クライアントとサーバーです。クライアントとは、別のアプリケーションのサービスを要求し利用するアプリケーションです。サーバーとは、このようなサービスを提供するアプリケーションです。
OLEサーバー・アプリケーションでは、OLEコンテナに埋め込まれたり、またはリンクされたOLEオブジェクトが作成されます。サーバー・アプリケーションでは、OLEオブジェクトの作成、保存および操作が行われます。たとえば、サーバーでは、オブジェクトの一部がはげてしまった場合に、そのオブジェクトをどう再ペイントするかが決定されます。
Graphics BuilderとMicrosoft Wordは、OLEサーバーの例です。
OLEサーバー・アプリケーションとは異なり、OLEコンテナ・アプリケーションでは埋込みまたはリンク用の文書は作成されません。かわりに、OLEコンテナ・アプリケーションでは、OLEサーバー・アプリケーションによって作成されたオブジェクトを格納および表示するための場所が提供されます。
Form BuilderとReport Builderは、OLEコンテナ・アプリケーションの一例です。
OLEオブジェクトをアプリケーションにリンクまたは埋め込むことができます。
リンクと埋込みの間には機能的違いはありません。OLEコンテナは、リンク・オブジェクトの場合であっても、埋込みオブジェクトの場合であっても、同じコードを実行していずれも同様に処理します。唯一の違いは、OLEオブジェクトを埋め込むとアプリケーションのサイズが増えることです。この結果として考慮するべき点はパフォーマンス(特にファイル・サーバー)への影響です。アプリケーションのサイズが大きくなるほど、オープンやメモリーへのロードに時間がかかります。
各クライアント・マシンにはOLEレジストレーション・データベースが含まれています。レジストレーション・データベースには、OLEオブジェクトを分類する一連のクラスが保存されています。レジストレーション・データベースに含まれている情報により、OLEコンテナにおける埋込みやリンクに使用可能なオブジェクト・クラスが決定されます。
OLEサーバー・アプリケーションでは、レジストレーション・データベースのメンバーとなる一連のクラスがエクスポートされます。各コンピュータには、レジストレーション・データベースが1つあります。OLEサーバー・アプリケーションのインストール時にレジストレーション・データベースが存在しない場合は、レジストレーション・データベースが1つ作成されます。
1つのOLEサーバー・アプリケーションによって、レジストレーション・データベースに多くのOLEクラスを追加できます。レジストレーション・データベースにクラスを追加するプロセスは、OLEサーバー・アプリケーションのインストールの間に透過的に行われます。たとえば、Microsoft Excelをインストールする場合、複数のクラスがレジストレーション・データベースに追加されます。レジストレーション・データベースにインストールされるクラスには、Excel Application、Excel Application5、Excel Chart、Excel Sheet、ExcelMacrosheet、ExcelWorkSheet などがあります。
OLEオブジェクトをアクティブ化することにより、OLEサーバー・アプリケーションの機能にアクセスできます。OLEオブジェクトをアクティブ化する方法には、内部アクティブ化と外部アクティブ化の2つがあります。
内部アクティブ化時には、境界線が引かれ、アクティブ化されたオブジェクトはその中に表示されます。アクティブ化されたオブジェクトのツールバー、メニュー、およびその他のコントロールは一時的に標準のメニュー・オプションと入れ替わります。入れ替わったメニュー・オプションやツールバーを使用して、OLEサーバー・アプリケーションで使用可能な機能にアクセスできます。標準のメニュー・オプションやツールバーは、内部アクティブ化を解除すると再表示されます。内部アクティブ化を解除するには、境界線の外側の任意の場所をクリックします。
注意: 内部アクティブ化は埋込みオブジェクトに使用できますが、リンク・オブジェクトには利用できません。
外部アクティブ化は、埋込みオブジェクトおよびリンク・オブジェクトに利用できます。
リンクされたソース・ファイルの内容が外部アクティブ化により変更された場合、リンクされたオブジェクトは手動で、または自動的に更新できます。手動で更新する場合には、リンクされたソース・ファイルの変更がオブジェクトに反映されるように明示的に指示する必要があります。自動更新は、リンクされたソース・ファイルの変更後にただちに行われます。
注意: 内部アクティブ化も外部アクティブ化も共に、OLEコンテナのOLEアクティブ化プロパティの設定に基づいて行われます。OLEサーバー・アプリケーションにアクセスできる場合、埋込みOLEオブジェクトがアクティブ化されたときに内部アクティブ化と外部アクティブ化のどちらが行われるかは、OLEコンテナのアクティブ化プロパティの設定値により決まります。リンク・オブジェクトの場合は、外部アクティブ化によりアクティブ化されます。 内部アクティブ化プロパティが「はい」に設定されていたとしても、内部アクティブ化はリンク・オブジェクトには適用されません。
OLEオブジェクト内のデータと対話したり、OLEオブジェクト内のデータを操作したいと考えることがあります。その場合に、PL/SQLおよびOLEオートメーションを使います。
OLEオートメーションにより、サーバー・アプリケーションで、OLEコンテナ・アプリケーションから起動できる一連のコマンドやファンクションを提供できます。これらのコマンドやファンクションを使用すれば、OLEコンテナ環境からOLEオブジェクトを操作できます。
Forms DeveloperおよびReports Developerでは、OLEサーバー・アプリケーションにより提供されるコマンドやファンクションには、PL/SQLを使用してアクセスします。OLEコマンドやファンクションの作成、操作、およびアクセスを行うためのPL/SQLアプリケーション・プログラミング・インタフェースは、ビルトインで提供されます。
注意: OLEコンテナ・アプリケーションのOLEオブジェクトの操作に利用できるオプションの多くは、OLEサーバー・アプリケーションによって決まります。たとえば、OLEポップアップ・メニューのオプション(別名OLE動詞)は、OLEサーバー・アプリケーションにより提供されます。オブジェクト・クラスなどの、レジストレーション・データベースに含まれている情報も、OLEサーバー・アプリケーションによって決まります。
Forms DeveloperおよびReports Developerは、OLEオートメーションに加え、OLEサーバー・サポートおよびOLEコンテナ・サポートも提供します。
OLEコンテナ・アプリケーションとして、Form BuilderおよびReport Builderでは次のことをサポートしています。
Form Builderでは、内部アクティブ化により、OLEサーバー・アプリケーションからメニューやツールバーにアクセスして埋め込まれたOLEオブジェクトを編集できます。
PL/SQLを使って、OLEサーバーにより提供されるコマンドやファンクションを呼び出すことができます。
OLEオブジェクトをデータベースに保存したり、OLEオブジェクトをデータベースから問い合せたりできます。リンク・オブジェクトを保存した場合には、イメージとリンク情報のみがデータベースに残ります。リンク・オブジェクトの内容は、リンクされたソース・ファイルに残ります。埋込みオブジェクトを保存した場合は、埋込みオブジェクトのすべての内容がデータベースに残ります。
Graphics BuilderはOLEサーバー・アプリケーションです。Graphics Builderの図表をForms DeveloperアプリケーションやReports Developerアプリケーションに埋め込んだり、リンクしたりできます。
推奨事項: Graphics Builder図表をアプリケーションに追加する場合は、OLEオブジェクトとしての埋込みやリンクは行わないでください。図表は、チャート・ウィザードを使用してアプリケーションに追加してください。
OLEコンテナ・プロパティにより、OLE表示属性、OLEコンテナとサーバーとの対話、コンテナの保存などが決まります。
注意: コンテナ・プロパティの他に、OLEオブジェクト・プロパティも設定できます。各OLEオブジェクトには複数のプロパティがあります。OLEオブジェクトのプロパティにアクセスするには、マウスの右ボタンをクリックしてポップアップ・メニューを表示します。
この項では、Forms DeveloperおよびReports DeveloperでサポートしているOLEコンテナ・プロパティを示します。
この項では、各コンポーネントでサポートされているOLEおよびActiveXビルトインをリストします。
OLEオブジェクトをアプリケーションに追加するための詳細な手順は、オンライン・ヘルプを参照してください。
OLEサーバー・アプリケーションは、OLEオブジェクトのプログラム上の操作を可能にする一連のコマンドを提供します。
OLEオブジェクトの操作方法は次のとおりです。
注意: OLEメソッドをコールする前に、まず、OLEオブジェクトのメソッドとプロパティをForms DeveloperまたはReports Developerにインポートする必要があります。OLEメソッドおよびプロパティをインポートすると、ネイティブ環境においてOLEオブジェクトと対話できるようになります。
アプリケーションからOLEメソッドにアクセスするには、STANDARD
(Form Builderのみ)およびOLE2
ビルトイン・パッケージから行います。
この項では、OLEのスタート・ガイドとしていくつかの例を紹介します。
フォーム・アプリケーションにおいて、:item('item_name').ocx.server_name.propertyバインド変数構文を使用して、プロパティ値を割り当てるか、または取り出すことができます。
例:
:item('OLEitem').OCX.SpreadSheet.CellForeGroundColor:= :item('OLEitem').OCX.SpreadSheet.CellForeGroundColor + 1;
OLEitemは項目名、SpreadSheetはOLEコントロール・サーバー名、CellForeGroundColorはプロパティ名です。
フォーム・アプリケーションにおいて、プロパティ・アセサー・ファンクションおよびプロシージャを使用して、プロパティ値を取得、設定できます。
例:
Variant OleVar; Variant := EXCEL_WORKSHEET.ole_Range(:CTRL.interface, To_variant('A1'));
EXCEL_WORKSHEET
は、OLEインポータから作成されたプログラム単位の名前です。OLE_RANGE
は、プロパティ・アセサー名です。
この例では、Excelスプレッドシートにおいてセル値を取得、設定します。
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;
セルにアクセスするには、次のコードを使用します。
spreadsheet.setcell(3, 5, 91.73); :block1.item1 := spreadsheet.getcell(2, 4);
ActiveXコントロール(OLEまたはOCXコントロールと呼ばれていたもの)は、スタンドアロン・ソフトウェア・コンポーネントで、アプリケーションに埋め込むことにより軽快なユーザー・インタフェース・コントロールを提供します。
ActiveXコントロールとOLEオブジェクトとの違いは次のとおりです。
ActiveXコントロールは通常、自己完結型機能性を追加することによりアプリケーションを拡張するために使用されます。
たとえば、タブ付プロパティ・パレット、スピン・コントロール、カレンダ・コントロール、ヘルプ・コントロールなどでアプリケーションを拡張できます。
独自のActiveXコントロールまたはOLEサーバーを開発するには、かなりの努力が必要です。サードパーティ・ベンダーにより開発および配布されているActiveXコントロールおよびOLEサーバーを使用することをお薦めします。
各ActiveXコントロールは、一連のプロパティ、メソッドおよびイベントを提供します。プロパティによってActiveXコントロールの物理属性および論理属性が定義され、メソッドによってActiveXコントロールが実行するアクションが定義されます。イベントはActiveXコントロールの状態の変更を示します。
ActiveXコントロールの操作方法は次のとおりです。
ActiveXコントロールを操作するには、(Forms Developerの)STANDARD
とOLE2
ビルトイン・パッケージを使用します。
ActiveXイベントへの応答は、ActiveXイベント・パッケージまたはOn-Dispatch-Eventトリガーに独自のコードを書き込んで行います。
各ActiveXイベントは、イベント・パッケージに定義されているPL/SQLプロシージャに対応付けられています。コントロールがイベントを起動すると、プロシージャのコードは自動的に実行されます。
プロシージャ名は、対応するイベントを表す内部番号により決まります。イベントにより生成される制限付きプロシージャには、次に示すものに似たアプリケーション・プログラミング・インタフェースがあります。
PROCEDURE /*Click*/ event4294966696(interface OleObj);
注意: ActiveXプロシージャは制限モードで実行されます。On-Dispatch-Eventトリガー内でイベント・プロシージャをコールする際に、そのプロシージャが制限モードで実行されるのか、または非制限モードで実行されるのかを、FORMS4W.DISPATCH_EVENT
コールを使用して明示的に定義できます。制限プロシージャの定義時に、OUT
パラメータは監視されません。
ActiveXコントロールを含むアプリケーションを利用するには、そのActiveXコントロールを利用する必要があります。
ActiveXコントロールを利用するには、次のことを行う必要があります。
ActiveXコントロールに付属しているインストール・プログラムを使用してActiveXコントロールをインストールする場合、登録は自動的に行われます。
手動による登録の場合は、regActiveX32.exe
またはregsvr32.exe
を使用します。これらは共にMicrosoftの開発ツールに付属し、またActiveXコントロール・ベンダーからも入手できます。
C:\WINDOWS\SYSTEM
)にコピーします。
ほとんどのActiveXコントロールでは、Microsoft Foundation Classランタイム・ライブラリ(MFC40.DLL
)などのサポートDLLを必要とします。DLLは、\WINDOWS\SYSTEM
ディレクトリまたは検索パスに存在する必要があります。DLLが古かったり、またはない場合、ActiveXコントロールは正しく登録されません。
注意: ActiveXコントロールは、サード・パーティのActiveXコントロール・ベンダーにより配布されたものなのか、アプリケーション開発ツールにバンドルされたものなのかにかかわらず、ActiveXコントロールを配布する前に、追加料金の支払いまたは追加ライセンスの取得が必要になる場合があります。
サポートとは、ActiveXコントロールを作成、操作し、ActiveXコントロールとの通信を行う機能を備えていることです。
コンポーネント | コンテナ |
---|---|
Form Builder |
あり |
Graphics Builder |
なし |
Procedure Builder |
なし |
Project Builder |
なし |
Query Builder |
なし |
Report Builder |
なし |
Schema Builder |
なし |
この項では、Forms DeveloperでサポートされているActiveXプロパティをリストします。
各コンポーネントでサポートされているActiveXおよびOLEビルトインのリストは、6.1.1.7.4項を参照してください。
ActiveXコントロールをアプリケーションに追加する方法の詳細は、オンライン・ヘルプを参照してください。
この項では、ActiveXコントロールのスタート・ガイドとしていくつかの例を紹介します。
Form Builderにおいて、:item('item_name').ocx.server_name.property
バインド変数構文を使用して、AactiveXのプロパティ値を割り当てるか、または取り出すことができます。
例:
:item('ActXitem').OCX.Spindial.spindialctrl.1.Needleposition:= :item('ActXitem').OCX.Spindial.spindialctrl.1.Needleposition + 1;
ActXitem
は項目名、Spindial.spindialctrl.1
はActiveXコントロール・サーバー名、Needleposition
はプロパティ名です。
system.cursor_item
がActiveXコントロールである場合は、次のコードも使用できます。
:form.cursor_item.OCX.spindial.spindialctrl.1.Needlposition := :form.cursor_item.OCX.spindial.spindialctrl.1.Needlposition + 1;
Form Builderにおいて、プロパティ・アセサー・ファンクションおよびプロシージャを使用して、ActiveXプロパティを取得、設定できます。
例:
tblname varchar2; tblname := table_pkg.TableName(:item('Oblk.Oitm').interface);
Table_pkg
は、OLEインポータから作成されたプログラム単位の名前です。TableName
は、プロパティ・アセサー名です。Oblk
は、ブロック名、Oitm
は項目名です。
この例では、SpreadTableパッケージ内のGetCellByColRow
メソッドを使用してSpread Table ActiveXコントロールからセル値を取得します。
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;
外部ファンクションを使用すると、アプリケーションをカスタマイズして機能を強化できます。
この項では、次のことを説明します。
外部ファンクションは3GLプログラミング言語で書かれたサブプログラムで、ユーザー固有の要件に合せてアプリケーションをカスタマイズできます。
外部ファンクションは、Oracleデータベース、Forms DeveloperおよびReports Developerの変数、項目、列およびパラメータとの対話に使用します。また、Windows DLLまたはAPIなどの外部定義ファンクションをコールすることもできます。
外部ファンクションは次の作業を行うためによく使用されます。
3種類の外部ファンクションを開発できます。
Oracleプリコンパイラ外部ファンクションは最も一般的な外部ファンクションです。Oracleプリコンパイラを使用すると、Oracleデータベース、Forms DeveloperまたはReports Developerの変数、項目、列およびパラメータなどにアクセスする外部ファンクションを作成できます。
Oracleプリコンパイラ外部ファンクションには、Oracleプリコンパイラ・インタフェースが取り込まれます。このインタフェースにより、埋込みSQLコマンドを使用して、次のサポートされたホスト言語のいずれかでプログラムを作成できます。Ada、C、COBOL、FORTRAN、PascalおよびPL/I。
Oracleプリコンパイラ外部ファンクションのソース・ファイルには、埋込みSQL文を使用したホスト・プログラミング言語文およびOracleプリコンパイラ文が含まれています。Oracleプリコンパイラ外部ファンクションをプリコンパイルすると、埋込みSQL文は等価のホスト・プログラミング言語文に置換されます。プリコンパイルにより、ホスト言語コンパイラでコンパイルできるソース・ファイルができます。
OCI外部ファンクションには、Oracleコール・インタフェースが取り込まれます。このインタフェースにより、Oracleデータベースのコールを含むサブプログラムを作成できます。OCIのみが取り込まれた(Oracleプリコンパイラ・インタフェースは取り込まれない)外部ファンクションでは、Forms DeveloperまたはReports Developerの変数、項目、列、パラメータにアクセスできません。
注意: Oracleプリコンパイラ・インタフェースとOCIの両方を組み合せた外部ファンクションを開発することもできます。
Oracle以外の外部ファンクションには、Oracleプリコンパイラ・インタフェースも、OCIも取り込まれません。たとえば、Oracle以外の外部ファンクションは、すべてC言語のみで作成されることもあります。オラクル以外の外部ファンクションでは、Oracleデータベースをはじめ、Forms DeveloperまたはReports Developerの変数、項目、列、パラメータのいずれにもアクセスできません。
Forms DeveloperおよびReports Developerでは、プログラミング言語としてPL/SQLを使用します。Windows DLLのCファンクションなどの外部ファンクションをコールするには、PL/SQLに外部ファンクションとの通信インタフェースが必要です。
外部ファンクションとの通信には、Oracle外部ファンクション・インタフェース(ORA_FFI
)またはユーザー・イグジット・インタフェースという2つの固有のインタフェースが使用できます。
ORA_FFI
は、Forms DeveloperおよびReports DeveloperでPL/SQLプログラムから3GLルーチンをコールするための移植性のある汎用メカニズムです。
PL/SQLインタフェースから起動する外部ファンクションは、ダイナミック・ライブラリに含まれている必要があります。ダイナミック・ライブラリの例としては、Microsoft Windowsのダイナミック・リンク・ライブラリやUNIXシステムの共有ライブラリがあります。
ユーザー・イグジット・インタフェースは、Forms DeveloperおよびReports DeveloperでPL/SQLサブプログラムから3GLルーチンをコールするためのプラットフォーム固有のメカニズムです。
ユーザー・イグジット・インタフェースから起動する外部ファンクションは、ダイナミック・リンク・ライブラリ(.DLL
)に含まれているか、または実行可能なアプリケーションにリンクされている必要があります。
この項では、ORA_FFI
およびユーザー・イグジットを使用する場合の長所と短所を説明します。
この項では、外部ファンクションを処理するためのガイドラインを提供します。
外部ファンクションの詳細は、次の出版物を参照してください。
この項では、外部ファンクションのインタフェースを作成するための詳細な手順を説明します。
次の例では、WinSample
という名前のPL/SQLパッケージを作成します。WinSample
パッケージには、ダイナミック・ライブラリKRNL386.EXE
にある外部ファンクションGetPrivateProfileString
へのインタフェースが含まれています。
注意: 外部ファンクションへのORA_FFI
インタフェースを作成する場合は、2つの基本的な手順を実行します。第一に、サブプログラムを作成し、外部ファンクション(ディスパッチャ・ファンクション)に関連付けます。PL/SQLサブプログラムを外部ファンクションに対応付けることにより、対応付けられたPL/SQLサブプログラムをコールするたびに、外部ファンクションを起動することができます。外部ファンクションとPL/SQLサブプログラムとの対応付けが必要な理由は、Forms DeveloperおよびReports DeveloperでPL/SQL構成体が使用されるためです。第二に、引数をディスパッチャ・ファンクションに渡すPL/SQLファンクションを作成します。ディスパッチャ・ファンクションは外部ファンクションを起動します。
パッケージ仕様部はライブラリを表している必要があります。また、起動しようとするPL/SQLファンクションを定義する必要があります。
例:
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;
この例では、WinSample.GetPrivateProfileString PL/SQL
ファンクションを呼び出して、ダイナミック・ライブラリKRNL386.EXE
にあるGetPrivateProfileString
外部ファンクションを起動します。
注意: CファンクションGetPrivateProfileString
のパラメータをチェックして、一致するPL/SQLパラメータ型とPL/SQL戻り型を指定します。Cデータ型intは、PL/SQLパラメータIN PLS_INTEGER
およびPL/SQL戻り型PLS_INTEGER
と等価です。Cデータ型charは、PL/SQLパラメータIN VARCHAR2
と等価です。
例:
PACKAGE BODY WinSample IS lh_KRNL386 ORA_FFI.LIBHANDLETYPE; fh_GetPrivateProfileString ORA_FFI.FUNCHANDLETYPE;
この手順において、ライブラリおよびファンクションのハンドル型を宣言します。後で、ORA_FFI.LOAD_LIBRARY
およびORA_FFI.REGISTER_FUNCTION
を使用してライブラリをロードして、ファンクションを登録します。これらのファンクションはそれぞれ、指定したライブラリおよびファンクションにハンドル(ポインタ)を戻します。ORA_FFI.LIBHANDLETYPE
およびORA_FFI.FUNCHANDLETYPE
は、これらのハンドルのPL/SQLデータ型です。
例:
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);
外部ファンクションをコールするディスパッチャ・ファンクションの最初の引数には、少なくとも1つのパラメータが必要です。また、最初のパラメータは、サブプログラムが起動する登録された外部ファンクションのハンドルである必要があります。
ディスパッチャ・ファンクションをPL/SQLファンクションからコールする場合は、手順2(fh_GetPrivateProfileString
)での定義に従ってファンクション・ハンドルを渡します。
ディスパッチャ・ファンクションのコール時に、PRAGMA
文は、ダイナミック・ライブラリと通信するメモリー位置(前述のコードで指定した11265
)に制御を渡します。
例:
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;
これは、アプリケーションからコールするPL/SQLファンクションです。このファンクションが引数をディスパッチャ・ファンクションi_GetPrivateProfileString
に渡すと、i_GetPrivateProfileString
がKRNL386.EXE
にあるCファンクションGetPrivateProfileString
を起動します。ディスパッチャ・ファンクションの最初の引数はファンクション・ハンドルでなければならないことを思い出してください。ここで、fh_GetPrivateProfileString
は、手順2で宣言されているファンクション・ハンドルを渡すために使用されます。
パッケージ本体では、外部ファンクションを初期化するために、次の4つの手順が実行される必要があります。
例:
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;
手順2において、ライブラリおよびファンクションに対して2つのハンドルを宣言したことを思い出してください。この手順において、ORA_FFI.LOAD_LIBRARY
およびORA_FFI.REGISTER_FUNCTION
ファンクションを使用して、ハンドルに値を割り当てます。
ORA_FFI.LOAD_LIBRARY
は、2つの引数を取ります。ダイナミック・ライブラリの位置と名前です。ORA_FFI.REGISTER_FUNCTION
は、3つの引数を取り出します。ファンクションが含まれるライブラリのライブラリ・ハンドル、ファンクション名、コール標準です。コール標準は、C_STD
(Cコール標準の場合)またはPASCAL_STD
(Pascalコール標準の場合)のいずれかです。
ライブラリのロードおよびファンクションの登録後に、パラメータおよび戻り値の型(ある場合)を登録する必要があります。
ORA_FFI.REGISTER_PARAMETER
とORA_FFI.REGISTER_RETURN
はそれぞれ2つの引数を取ります。ファンクション・ハンドルおよび引数型です。
例:
x := Winsample.GetPrivateProfileString ('Oracle', 'ORACLE_HOME', '<Not Set>', 'Value', 100, 'oracle.ini');
ユーザー・イグジットは汎用ではありません。プラットフォーム固有です。ユーザー・イグジットのインプリメントの詳細の中には、各オペレーティング・システムに固有のものがあります。次の例では、Windows 95におけるユーザー・イグジットの作成方法について説明します。
Microsoft Windowsでは、ユーザー・イグジットから起動する外部ファンクションは、ダイナミック・リンク・ライブラリ(.DLL
)に含まれています。DLLは、含まれているコードが起動されたときにのみメモリーにロードされるライブラリです。
次の例では、ID列をEMP表に追加する外部ファンクションを作成します。
この例では、次に示す複数のサンプル・ファイルを使用します。
IAPXTB
コントロール構造体を含むプロジェクト・ファイルです。このプロジェクトを作成すると、UE_SAMP.DLL
が生成されます。
ORACLE_HOME\BIN
ディレクトリに配置されます。新規の外部ファンクションの作成時には、既存のIFXTB60.DLL
ファイルを新規のIFXTB60.DLL
と置き換えてください。
IAPXTB
コントロール構造体を作成するためのテンプレート・ソース・ファイルです。UE_XTB.C
には、IAPXTB
コントロール構造体のエントリの例が含まれています。このファイルを変更し、外部ファンクション・エントリを追加します。
IAPXTB
構造体の定義に使用されるサンプル・ヘッダー・ファイルです。
.DEF
を使用して、外部ファンクションをエクスポートします。IFXTB60.DEF
には複数のエクスポート文が含まれています。これらのエクスポート文は、ユーザー・イグジット・インタフェースにアクセスするためにForm Builderで使用されますので、変更しないでください。
.OBJ
ファイルにリンクする.OBJ
ファイルです。
ユーザー・イグジットのサンプル・ファイルは、ORACLE_HOME
ディレクトリ(たとえば、 C:\ORAWIN95\FORMS60\USEREXIT
)にあります。
たとえば、テキスト・ファイルUEXIT.PC
を作成してから、次を追加します。
/* 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); }
たとえば、Pro*Cを使用してUEXIT.PC
ファイルをプリコンパイルします。UEXIT.PC
をプリコンパイルすると、Pro*Cでは、UEXIT.C
という名前のCファイルが作成されます。
注意: プリコンパイル時に、次のMSVCコンパイラ・フラグを必ず指定します。
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
ヘッダー・ファイルは、外部ファンクションを定義する必要があります。
たとえば、次の行を追加して、サンプル・ヘッダー・ファイルUE.H
を変更します。
extern void AddColumn();
IAPXTB
コントロール構造体を作成します。
たとえば、UE.H
のインクルード文UE.H (# include "ue.h")
、ユーザー・イグジット名(Add_ID_Column)
、外部ファンクション名(AddColumn)
、および言語タイプ(XITCC
)を追加して、サンプル・ファイルUE_XTB.C
を変更します。
#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 */
例えば、コンパイラを使用して、次のものを含むプロジェクトを作成します。UE_SAMP.MAK、IFXTB60.DEF
、UEZ.OBJ
、UE_XTB.C
およびUEXIT.C
DLLを作成する前に、次のファイルをリンクする必要があります。
LIBC.LIB OLDNAMES C:\ORAWIN95\FORMS60\USEREXIT\IFR60.LIB C:\ORAWIN95\PRO20\USEREXIT\SQLLIB18.LIB C:\ORAWIN95\PRO20\USEREXIT\SQXLIB18.LIB
/* Trigger: When-Button-Pressed */ USER_EXIT('Add_ID_Column');
この項では、複数の例を示しながら外部ファンクションの使用方法を説明します。
/* 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;
この項では、Form Builderアプリケーションを作成および変更するための非インタラクティブなプログラミング方法を説明します。この項では次の項目について説明します。
オープンAPIは、非インタラクティブな環境においてフォーム・モジュールの作成または変更を行うための機能と柔軟性を求めるC/C++開発者のためのForm Builder拡張機能です。
注意: オープンAPIを使用する前に、Form Builderオブジェクトおよびそのプロパティとリレーションについて完全に理解してください。
開発の変更内容を多数のフォーム・モジュールにすばやく反映させたい場合は、オープンAPIを使用します。たとえば、オープンAPIを使用して、アプリケーションのルック&フィールを現行の企業規格に更新します。この場合、フォーム・モジュールの更新は数百にのぼることもあります。
オープンAPIには他にも次のような使用方法があります。
オープンAPIは、1つのForm Builderオブジェクトに対して1つのCヘッダー・ファイルから構成されています。Form Builderオブジェクトは34個あります(図を参照)。これらのオブジェクトは、設計時に使い慣れているForm Builderオブジェクトと対応しています。各ヘッダー・ファイルには、Form Builderオブジェクトの作成および操作に使用する関数やマクロが複数含まれています。
オープンAPIでは、オブジェクト・プロパティを設定してForm Builderオブジェクトを操作します。
オープンAPIプロパティには、D2FP_FONT_NAM
をはじめとする一意の名前があります。これらのプロパティは、設計時に使い慣れているForm Builderプロパティと対応しています。
プロパティには次のものがあります。Boolean、Text、Number、Object、またはBlobです。
次の表では、共通項目プロパティおよびそれらと対応するオープンAPI等価プロパティをリストします。
オープンAPIプロパティ | Form Builder(設計時)プロパティ |
---|---|
D2FP_ACCESS_KEY |
アクセス・キー |
D2FP_BEVEL_STY |
凹凸 |
D2FP_CNV_NAM |
キャンバス |
D2FP_ENABLED |
変更可 |
D2FP_FONT_NAM |
フォント名 |
D2FP_HEIGHT |
幅/高さ |
D2FP_X_POS |
X位置 |
D2FP_Y_POS |
Y位置 |
オープンAPIファンクションおよびマクロを使用して、オブジェクト・プロパティの作成、破棄、複製、サブクラス化、取得、設定を行うことができます。
たとえば、項目のフォント・サイズを決めるには、D2FITMG_FONT_SIZ
マクロを使用します。
d2fitmg_font_siz(ctx, obj, val);
このマクロは、項目オブジェクトのフォント・サイズ・プロパティの値をタイプ番号として戻します。
テキスト項目プロパティを設定するには、D2FITMST_SETTEXTPROP
ファンクションを使用します。
d2fitmst_SetTextProp(d2fctx *pd2fctx, d2fitm *pd2fitm, ub2 pnum,text *prp );
このファンクションは、指定の項目テキスト・プロパティの値を設定します。ポインタをpd2fctx
の内容に、項目をpd2fitm
に、プロパティ番号をpnum
に、ハンドルをprp
のテキスト値に指定します。
項目 | 推奨事項 |
---|---|
ファイル・バックアップ |
オープンAPIは非インタラクティブです。妥当性チェックおよびエラー・チェックはサポートされていません。オープンAPIを使用する前に、フォーム・モジュール( |
リレーション・オブジェクトの作成 |
リレーション・オブジェクトの作成時に、次のことを行う必要があります。 |
この項では、オープンAPIを使用してForm Builderモジュールを作成および変更するための詳細な手順を説明します。
Form Builderモジュールを作成または変更するには、次のようにします。
CompileFile()
ファンクションを使用して、.FMX
または.MMX
コンパイル・フォームを生成します。
d2ffmdsv_Save()
、メニュー・モジュールのd2fmmdsv_Save()
、またはオブジェクト・ライブラリのd2folbsv_Save()
など)を保存します。
d2fctxde_Destroy()
をコールして、オープン・フォームAPIコンテキストを破棄します。このファンクションのコールは最後に行う必要があることに注意してください。
ifd2f60.lib
)にリンクします。
.EXE
ファイル)を作成します。
.FMB
)の作成または変更を行います。
この項では、複数の例を示しながらオープン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); }
企業内のデータは、複数の異種データソースに常駐することがよくあります。たとえば、データの一部がOracleデータベースに保存され、別の一部がInformixデータベースに保存されている場合があります。単一でそのすべてのデータソースにアクセスできるアプリケーションの作成は、難しい作業になりかねません。
しかし、Forms DeveloperおよびReports Developerのオープン・データソース・サポートを利用すれば、すべてのODBC準拠データソースに対して透過的に実行される汎用アプリケーションを構築することができます。
この項では、オープン・データソース・サポートについて説明します。この項では次の項目について説明します。
ODBCデータソースに接続する場合、Oracle Open Client Adapter (OCA)を使用します。OCAはODBCレベル2に準拠したユーティリティで、Microsoft Windows 95、Windows NT環境のForms DeveloperおよびReports Developerでは、これを使用することによりODBCドライバを介してODBC準拠データソースにアクセスできます。
OCAは、Forms DeveloperおよびReports Developerに含まれています。OCAをインストールするには、Oracle Installerを使用します。
アプリケーションで非Oracleデータソースにアクセスする必要がある場合は、必ずOCAを使ってください。Forms DeveloperおよびReports Developerアプリケーションでは、すべてのODBC準拠データソースに自動的にアクセスできます。ODBCデータソースへの接続の詳細は、オンライン・ヘルプを参照してください。
Oracle Open Client Adapterの構成は次のとおりです。
ODBCデータソースに接続するには、接続ダイアログ・ボックスに次の接続文字列を入力します。
[user[/password]]@ODBC:datasource[:dbname]
たとえば、Sybase System 10に接続する場合は、次のように入力します。
scott/tiger@ODBC:sybase_ds
ODBCデータソースに接続する場合、ODBCドライバを使用してデータソースと通信します。Forms DeveloperおよびReports Developerには、サポートしている各データソースに対応したODBCドライバがすでにバンドルされています。これらのドライバはODBCレベル1準拠ですが、パフォーマンスを向上させるためにレベル2の機能性を一部提供しています。
OPENDB.PLL
は、OCA付属のPL/SQLファンクション・ライブラリです。アプリケーションでOPENDB.PLL
を使用すると、次のことができます。
OPENDB.PLL
の詳細は、ORACLE_ HOME\TOOLS\DOC20
ディレクトリのOCA_INFO.PDF
を参照してください。
ODBC準拠データソースに対して実行するためにアプリケーションを設定するには、オンライン・ヘルプのトピック「非Oracleデータソースへのアクセス」を参照してください。
|
Copyright © 2000 Oracle Corporation. All Rights Reserved. |
|