!--a11y-->

カスタムコントロールは、Dynpro 上の領域です。このコントロールはスクリーンペインタで登録され、他のすべての Dynpro オブジェクトと同様に一意の名称を持ちます。カスタムコントロールは、コントロールを埋め込むために使用します。コントロールはプレゼンテーションサーバ上のソフトウェアコンポーネントで、使用している SAPgui によって ActiveX コントロールまたは JavaBean のいずれかが利用可能です。これを使用すると、テキスト編集などのタスクをプレゼンテーションサーバでローカルに実行することができます。このコントロールは、アプリケーションサーバで実行されるアプリケーションロジックによって制御されます。
プレゼンテーションサーバ上のコントロールとアプリケーションサーバ上の ABAP
アプリケーションプログラムは、
SAP
コントロールフレームワーク
を使用して通信します。これは ABAP
オブジェクト
にプログラムされており、クラスブラウザでベーシス
→
フロントエンドサービス
を選択して照会することができるグローバルクラスのセットを格納しています。これらのクラスによってアプリケーションサーバとプレゼンテーションサーバ間の通信がカプセル化され、リモートファンクションコールを使用して実装されます。
すべてのアプリケーションコントロールがグローバルクラスにカプセル化されています。SAP ベーシスコントロールを照会するには、クラスブラウザでベーシス → フロントエンドサービス またはベーシス → コンポーネント統合 を選択します。Dynpro でコントロールを使用するプログラムでは、これらをカプセル化するグローバルクラスのメソッドとイベントが使用されます。
Dynpro
でカスタムコントロールを使用するには、
SAP
コンテナコントロール
を割り当てておく必要があります。コンテナコントロールは、SAP
コントロールフレームワーク内の特殊なグローバルクラスのインスタンスです。カスタムコントロールのグローバルクラスは、CL_GUI_CUSTOM_CONTAINER
と呼ばれます。カスタムコントロールをコンテナコントロールにリンクするには、インスタンス化する際にコンテナコントロールコンストラクタのCONTAINER_NAME
パラメータにカスタムコントロール名を渡します。
カスタムコンテナを使用する他に、SAP ドッキングコンテナを使用して Dynpro にコントロールをリンクすることもできます。これは、グローバルクラス CL_GUI_DOCKING_CONTAINER にカプセル化されています。SAP ドッキングコンテナを使用して、Dynpro 内にコントロールを挿入することはできません。代わりに、4 つの辺のいずれかにコントロールを接続します。コンテナはネストすることができます。たとえば、他のコンテナ内で SAP スプリッタコンテナ ( クラス CL_GUI_EASY_SPLITTER_CONTAINER または CL_GUI_SPLITTER_CONTAINER) を使用することができます。これにより、カスタムコントロールやドッキングコントロールを複数の領域に分割し、複数のコントロールを埋め込むことができます。

SAP テキスト編集コントロール ( クラス CL_GUI_TEXTEDIT) や SAP ツリーコントロール (CL_GUI_SIMPLE_TREE などの複数のグローバルクラスがあります) などのコンテナ内に挿入するアプリケーションコントロールにも、インスタンスを作成する必要があります。コントロールをインスタンス化する際には、コントロールを挿入するコンテナへの参照をそのコンストラクタメソッドの PARENT パラメータに渡します。このコンテナはクラス CL_GUI_CUSTOM_CONTAINER のインスタンスですが、他の SAP コンテナコントロールのいずれかのインスタンスでもかまいません。
コントロールメソッドとそれらの文書については、クラスビルダまたは SAP
ライブラリ文書のクラス定義を参照してください。アプリケーションサーバとプレゼンテーションサーバ間のネットワーク負荷を最小化するために、定義されている同期ポイントで、プレゼンテーションサーバに送信される前にメソッドコールが
オートメーションキューにバッファされます。自動同期ポイントの 1
つは、PBO
処理の終了時です。プログラムで同期ポイントを強制するには、バッファされていないメソッドを呼び出すか、静的メソッド FLUSH
を呼び出します。
ユーザの操作によって PAI
イベントがトリガされて、制御がアプリケーションサーバに戻る Dynpro
とは異なり、コントロール上でのユーザの操作はアプリケーションサーバに自動的に渡されるわけではありません。イベントをアプリケーションサーバに渡すには、特殊なメソッドSET_REGISTERED_EVENTS
を使用してプログラムに登録する必要があります。各コントロールについて登録可能なイベントの一覧については、クラスビルダでそのラッパクラスを参照してください。SET_REGISTERED_EVENTS
を使用して、以下の 2
種類の
イベント処理を登録することができます。
このイベントはアプリケーションサーバに渡されますが、PAI をトリガしません。SET HANDLER 命令を使用して、ABAP プログラムにこのイベントのイベントハンドラメソッドを登録している場合、アプリケーションサーバでそのメソッドが実行されます。
イベントハンドラメソッド内では、グローバルクラス CL_GUI_CFW の静的メソッド SET_NEW_OK_CODE を使用して機能コードを設定し、PAI イベントを自分でトリガすることができます。PAI が処理されると、次画面の PBO イベントがトリガされます。
この方法を使用するメリットは、イベントハンドラメソッドが自動的に実行され、Dynpro に関連する自動入力チェックでコンフリクトが発生しない点です。デメリットは、Dynpro 項目の内容がプログラムに移送されないため、次画面に古い値が表示される可能性がある点です。これを回避するには、イベントハンドラが完了した 後、SET_NEW_OK_CODE メソッドを使用して項目移送と PAI イベントをトリガします。

このイベントはアプリケーションサーバに渡され、PAI をトリガします。渡す機能コードには、内部 ID が格納されます。ABAP プログラムでこれを評価する必要はありません。代わりに、イベントを処理する場合、グローバルクラス CL_GUI_CFW の静的メソッド DISPATCH の PAI ダイアログモジュールにメソッドコールを組み込む必要があります。SET HANDLER 命令を使用して、ABAP プログラムでこのイベントのイベントハンドラメソッドを定義している場合、DISPATCH メソッドによってそのメソッドが呼び出されます。イベントハンドラが処理されると、DISPATCH 命令の後でコントロールが PAI イベントに戻り、PAI 処理が続行されます。
この方法のメリットは、イベントが処理されるポイントを自分で指定することができる点と、Dynpro 項目の内容が事前にアプリケーションサーバに移送される点です。デメリットは、このようなイベント処理によって、Dynpro に関する自動入力チェックでコンフリクトが発生し、イベントが失われる可能性がある点です。

コントロールの詳細、特に、同期のトラブルシューティングと最適化に関するヘルプについては、
BC
コントロールチュートリアル
および
BC SAP
コントロールフレームワーク
を参照してください。
次の例では、システムイベントとアプリケーションイベントの違いを説明します。

REPORT demo_custom_control .
* 宣言 *****************************************************
CLASS event_handler
DEFINITION.
PUBLIC
SECTION.
METHODS: handle_f1 FOR EVENT f1 OF cl_gui_textedit
IMPORTING sender,
handle_f4 FOR EVENT f4 OF cl_gui_textedit
IMPORTING sender.
ENDCLASS.
DATA: ok_code LIKE
sy-ucomm,
save_ok LIKE sy-ucomm.
DATA: init,
container TYPE REF TO
cl_gui_custom_container,
editor TYPE REF TO
cl_gui_textedit.
DATA: event_tab TYPE
cntl_simple_events,
event TYPE
cntl_simple_event.
DATA: line(256),
text_tab LIKE STANDARD TABLE OF line,
field LIKE line.
DATA handle TYPE REF TO event_handler.
* レポートイベント ***************************************************
START-OF-SELECTION.
line = 'First line in TextEditControl'.
APPEND line TO text_tab.
line =
'--------------------------------------------------'.
APPEND line TO text_tab.
line = '...'.
APPEND line TO text_tab.
CALL SCREEN 100.
* ダイアログモジュール *****************************************************
MODULE status_0100
OUTPUT.
SET PF-STATUS 'SCREEN_100'.
IF init is initial.
init = 'X'.
CREATE OBJECT:
container
EXPORTING container_name = 'TEXTEDIT',
editor EXPORTING parent = container,
handle.
event-eventid = cl_gui_textedit=>event_f1.
event-appl_event = '
'.
"system event
APPEND event TO event_tab.
event-eventid =
cl_gui_textedit=>event_f4.
event-appl_event =
'X'.
"application event
APPEND event TO event_tab.
CALL METHOD: editor->set_registered_events
EXPORTING events = event_tab.
SET HANDLER handle->handle_f1
handle->handle_f4
FOR editor.
ENDIF.
CALL METHOD editor->set_text_as_stream
EXPORTING
text = text_tab.
ENDMODULE.
MODULE cancel
INPUT.
LEAVE PROGRAM.
ENDMODULE.
MODULE user_command_0100
INPUT.
save_ok = ok_code.
CLEAR ok_code.
CASE
save_ok.
WHEN 'INSERT'.
CALL METHOD editor->get_text_as_stream
IMPORTING
text = text_tab.
WHEN 'F1'.
MESSAGE i888(sabapdocu) WITH text-001.
WHEN OTHERS.
MESSAGE i888(sabapdocu) WITH text-002.
CALL METHOD
cl_gui_cfw=>dispatch.
ENDCASE.
SET SCREEN 100.
ENDMODULE.
* クラスの実装 **********************************************
CLASS event_handler
IMPLEMENTATION.
METHOD handle_f1.
DATA row TYPE i.
MESSAGE i888(sabapdocu) WITH text-003.
CALL METHOD sender->get_selection_pos
IMPORTING from_line =
row.
CALL METHOD sender->get_line_text
EXPORTING line_number =
row
IMPORTING text =
field.
CALL METHOD cl_gui_cfw=>set_new_ok_code
EXPORTING new_code =
'F1'.
CALL METHOD cl_gui_cfw=>flush.
ENDMETHOD.
METHOD handle_f4.
DATA row TYPE i.
MESSAGE i888(sabapdocu) WITH text-004.
CALL METHOD sender->get_selection_pos
IMPORTING from_line =
row.
CALL METHOD sender->get_line_text
EXPORTING line_number =
row
IMPORTING text =
field.
CALL METHOD cl_gui_cfw=>flush.
ENDMETHOD.
ENDCLASS.
Dynpro 100 のレイアウトは次のとおりです。

この Dynpro には、出力項目 FIELD とカスタムコントロール TEXTEDIT があります。
制御ロジックは次のとおりです。
PROCESS BEFORE
OUTPUT.
MODULE
STATUS_0100.
PROCESS AFTER
INPUT.
MODULE CANCEL AT EXIT-COMMAND.
MODULE
USER_COMMAND_0100.
GUI ステータス SCREEN_100 には、機能 BACK 、EXIT 、および CANCEL ( 機能タイプ E) と機能 INSERT ( 通常の機能) があります。
プログラムで定義されているローカルクラス EVENT_HANDLER があります。このクラスには、グローバルクラス CL_GUI_TEXTEDIT の F1 および F4 イベントのイベントハンドラメソッドが格納されています。プログラムを実行すると、Dynpro 100 の PBO でクラス CL_GUI_CUSTOM_CONTROL 、CL_GUI_TEXTEDIT 、および EVENT_HANDLER がインスタンス化されます。
コンテナコントロールは Dynpro のカスタムコントロールにリンクされ、SAP テキスト編集のインスタンスはコンテナにリンクされています。SAP テキスト編集の F1 および F4 イベントは、発生時にアプリケーションサーバに渡されるように SET_REGISTERED_EVENTS メソッドを使用して登録されています。F1 はシステムイベントとして、F4 はアプリケーションイベントとして定義されています。クラス EVENT_HANDLER の HANDLE インスタンスのイベントハンドラメソッドは、イベントのハンドラとして登録されています。
Dynpro 100 が表示される前に、プログラムによって SAP テキスト編集コントロールにテーブル TEXT_TAB の内容が書き込まれます。この Dynpro が表示されている間、ユーザはテキストを編集することができます。ユーザが INSERT を選択すると PAI イベントがトリガされ、SAP テキスト編集の現在のテキストがテーブル TEXT_TAB にコピーされます。
ユーザがコントロール上で F1 を選択すると、HANDLE_F1 メソッドが実行されます。その結果、項目 FIELD に行の内容が割り当てられます。メソッドSET_NEW_OK_CODE によって、PAI イベントがトリガされます。これにより、確実に PBO が処理され、FIELD の内容が Dynpro に送信されます。
ユーザがコントロール上で F4 を選択すると、PAI イベントがトリガされます。DISPATCH メソッドが呼び出され、これによってメソッド HANDLE_F4 がトリガされます。その結果、項目 FIELD に行の内容が割り当てられます。イベント後、PAI 処理が続行され、続いて PBO イベントがトリガされ、項目内容が Dynpro に転送されます。
F1 後も F4 後も、コントロールの内容は内部テーブル TEXT_TAB に渡されません。そのため、コントロールの内容は、PBO イベントで TEXT_TAB の前の内容で上書きされます。