Anfang des InhaltsbereichsCustom Controls Dokument im Navigationsbaum lokalisieren

Custom Controls sind rechteckige Bereiche auf dem Bildschirmbild eines Dynpros. Sie werden mit dem Screen Painter angelegt und haben wie jedes Bildschirmelement einen eindeutigen Namen. In diesen Bereichen können sogenannte Controls eingebettet werden. Controls sind Softwarekomponenten des Präsentationsservers. Abhängig vom verwendeten SAP GUI sind dies entweder ActiveX Controls oder JavaBeans. Controls erlauben es, bestimmte Tätigkeiten, wie z.B. das Editieren eines Texts, auf dem Präsentationsserver auszuführen. Die Anwendungslogik steuert die Controls und läuft nach wie vor auf dem Applikationsserver.

Das SAP Control Framework

Die Kommunikation zwischen den Controls auf dem Präsentationsserver und den ABAP-Anwendungsprogrammen auf dem Applikationsserver erfolgt über das Strukturlink SAP Control Framework. Das SAP Control Framework ist in ABAP Objects programmiert. Es enthält globale Klassen, die in der Klassenbibliothek unter Basis ® Frontend Services zu finden sind. Diese Klassen kapseln die über Remote-Aufrufe realisierte Kommunikation zwischen Applikationsserver und Präsentationsserver.

Weiterhin ist auch jedes verfügbare Anwendungs-Control in einer globalen Klasse gekapselt. Die Klassen für die von der SAP Basis ausgelieferte Controls finden sich beispielsweise in der Klassenbibliothek unter Basis ® Frontend Services oder Basis ® Component Integration. Ein Programm, das Controls auf dem Bildschirmbild eines Dynpros verwendet, arbeitet ausschließlich mit den Methoden und Ereignissen dieser Klassen.

Container Controls

Um mit einem Custom Control auf einem Bildschirmbild arbeiten zu können, muß ihm zuerst ein sogenanntes Strukturlink Container Controls zugeordnet werden. Container Controls sind Instanzen spezieller globaler Klassen des Control Frameworks. Für Custom Controls ist die Klasse CL_GUI_CUSTOM_CONTAINER als Container vorgesehen. Die Verknüpfung eines Custom Controls mit dem Container Control geschieht durch die Übergabe des Custom Control-Namens an den Konstruktor des Container Controls während dessen Instanziierung mit CREATE OBJECT.

Um Controls mit Dynpros zu verknüpfen, können außer Custom Container auch sogenannte Docking Container der Klasse CL_GUI_DOCKING_CONTAINER verwendet werden. Mit Docking Container werden Controls nicht in das Bildschimbild des Dynpros eingebettet, sondern an den Seiten angeheftet. Weiterhin sind Container schachtelbar. Beispielsweise können Splitter Controls der Klassen CL_GUI_EASY_SPLITTER_CONTAINER oder CL_GUI_SPLITTER_CONTAINER mit anderen Containern verknüpft werden. Dies ermöglicht die Aufteilung von Custom Controls oder Docking Controls in mehrere Fenster und damit die Verwendung mehrerer unabhängiger Anwendungs-Controls in einem Container.

Diese Grafik wird im zugehörigen Text erklärt

Anwendungs-Control

Für das eigentliche Anwendungs-Control, z.B. ein TextEdit-Control der Klasse CL_GUI_TEXTEDIT oder ein Tree Control der Klasse CL_GUI_SIMPLE_TREE, das im Bereich des Custom Controls erscheinen soll, muß ebenfalls eine Instanz im ABAP-Programm erzeugt werden. Bei der Instanziierung wird dem Control das gewünschte Container Control an den Parameter PARENT des Konstruktors übergeben. Der Container kann direkt eine Instanz der Klasse CL_GUI_CUSTOM_CONTAINER sein, aber auch ein darin geschachtelter anderer Container.

Control-Methoden

Die Methoden eines Controls und deren Dokumentation können dem Class Builder oder der erweiterten Hilfe entnommen werden. Um die Netzlast zwischen Applikations- und Präsentationsserver gering zu halten, werden die Methodenaufrufe in der Strukturlink Automation Queue gepuffert und zu definierten Synchronisationspunkten, an den Präsentationsserver gesendet. Ein automatischer Synchronisationspunkt ist das Ende der PBO-Verarbeitung. Im Programm können Synchronisationspunkte durch nicht gepufferte Methodenaufrufe oder durch einen Aufruf der statischen Methode FLUSH der globalen Klasse CL_GUI_CFW des Control Frameworks definiert werden.

Control-Ereignisse

Während auf Dynpros bei einer Benutzeraktion normalerweise das Ereignis PAI ausgelöst, und die Kontrolle an den Applikationsserver übergeben wird, gelangen Benutzeraktionen auf Controls nicht ohne weiteres an den Applikationsserver. Ereignisse, die an den Applikationsserver gelangen sollen, müssen im Programm mit der speziellen Methode SET_REGISTERED_EVENTS der Klasse des Controls registriert werden. Die Liste der registrierbaren Ereignisse sind der Definition der jeweiligen Klasse im Class Builder zu entnehmen. Bei der Registrierung mit SET_REGISTERED_EVENTS können zwei Arten der Strukturlink Ereignisbehandlung definiert werden:

Behandlung als Systemereignis (Standard)

Das Ereignis wird an den Applikationsserver übergeben, löst aber kein PAI aus. Falls im zugehörigen ABAP-Programm eine Ereignisbehandlermethode mit SET HANDLER als Behandler für das Ereignis registriert ist, wird diese Methode auf dem Applikationsserver ausgeführt.

Innerhalb der Ereignisbehandlermethode kann mit der statische Methode SET_NEW_OK_CODE der globalen Klasse CL_GUI_CFW das Ereignis PAI programmgesteuert ausgelöst und ein beliebiger Funktionscode übergeben werden. Nach der PAI-Verarbeitung wird das Ereignis PBO des Folgebilds ausgelöst.

Von Vorteil ist dabei, daß die Ereignisbehandlermethode automatisch ausgeführt wird und es keine Konflikte mit der automatischen Eingabeüberprüfung des Dynpros für andere Felder geben kann. Von Nachteil ist, daß der Inhalt der übrigen Dynprofelder nicht automatisch transportiert wird, so daß auf dem Folgebild veraltete Werte erscheinen können. Als Abhilfe kann nach der Ereignisbehandlung der Feldtransport mit der Methode SET_NEW_OK_CODE veranlaßt werden.

Diese Grafik wird im zugehörigen Text erklärt

Behandlung als Applikationsereignis

Das Ereignis wird an den Applikationsserver übergeben und löst PAI aus. Der übergebene Funktionscode enthält eine interne Kennung, die im ABAP-Programm nicht ausgewertet werden muß. Statt dessen muß in einem PAI-Dialogmodul die statische Methode DISPATCH der globalen Klasse CL_GUI_CFW aufgerufen werden, falls das Ereignis speziell behandelt werden soll. Falls nämlich im gleichen Programm eine Ereignisbehandlermethode mit SET HANDLER als Behandler für das Ereignis registriert ist, ruft die Methode DISPATCH die Ausführung der Ereignisbehandlermethode auf. Nach der Ereignisbehandlung wird hinter den Aufruf der Methode DISPATCH zurückgekehrt und weiter die PAI-Verarbeitung ausgeführt.

Von Vorteil ist dabei, daß der Verarbeitungszeitpunkt im Programm festgelegt werden kann und die Inhalte der übrigen Dynprofelder vor der Ereignisbehandlung transportiert werden können. Von Nachteil ist, daß diese Art der Ereignisbehandlung zu Konflikten mit der automatischen Eingabeüberprüfung des Dynpros führen kann, wobei Ereignisse verloren gehen können.

Diese Grafik wird im zugehörigen Text erklärt

Weitere Informationen

Weiterführende Informationen zu Controls, insbesondere auch zur Flushoptimierung und zur Fehlerbehebung finden sich unter Strukturlink BC - Controls Tutorial und Strukturlink BC - SAP Control Framework.

Beispiel

Das folgende Beispiel demonstriert den Unterschied zwischen System- und Anwendungsereignissen.

Beispiel

REPORT demo_custom_control .

* Declarations *****************************************************

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) TYPE c,
      text_tab LIKE STANDARD TABLE OF line,
      field LIKE line.

DATA handle TYPE REF TO event_handler.

* Reporting Events ***************************************************

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.

* Dialog Modules *****************************************************

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 Implementations **********************************************

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.

Das Layout von Dynpro 100 ist:

Diese Grafik wird im zugehörigen Text erklärt

Das Dynpro enthält ein Ausgabefeld FIELD und ein Custom Control namens TEXTEDIT.

Die Ablauflogik von Dynpro 100 ist:

PROCESS BEFORE OUTPUT.
  MODULE status_0100.

PROCESS AFTER INPUT.
  MODULE cancel AT EXIT-COMMAND.
  MODULE user_command_0100.

Im GUI-Status SCREEN_100 sind die Funktionscodes BACK, EXIT und CANCEL mit dem Typ E und der Funktionscode INSERT ohne besonderen Typ angelegt.

Das Programm enthält eine lokale Klasse EVENT_HANDLER mit Ereignisbehandlermethoden für die Ereignisse F1 und F4 der globalen Klasse CL_GUI_TEXTEDIT. Bei der Programmausführung werden zu PBO von Dynpro 100 Objekte der Klassen CL_GUI_CUSTOM_CONTROL, CL_GUI_TEXTEDIT und EVENT_HANDLER instantiiert.

Das Container Control wird mit dem Custom Control auf dem Dynpro verknüpft und die Instanz des TEXTEDIT-Controls mit diesem Container. Die Ereignisse F1 und F4 des TEXTEDIT-Controls sollen an den Applikationsserver übergeben werden und werden deshalb mit der Methode SET_REGISTERED_EVENTS registriert. Dabei wird F1 als System- und F4 als Applikationsereignis festgelegt. Die Ereignisbehandlermethoden der Instanz HANDLE der Klasse EVENT_HANDLER werden als Behandler für die Ereignisse registriert.

Vorm Senden des Dynpros wird das TEXTEDIT-Control mit dem Inhalt der Tabelle TEXT_TAB gefüllt. Während der Dynproanzeige kann der Benutzer den Text editieren. Bei der Auswahl von INSERT wird PAI ausgelöst und der aktuelle Text aus dem TEXTEDIT-Control in die Tabelle TEXT_TAB übernommen.

Bei Auswahl der Taste F1 auf dem TEXTEDIT-Control wird sofort die Methode HANDLE_F1 ausgeführt. Dort wird der Zeileninhalt an das Feld FIELD zugewiesen. Durch Aufruf der Methode SET_NEW_OK_CODE wird PAI ausgelöst. Nur dadurch wird auch PBO durchlaufen und der Inhalt von FIELD an das Dynpro transportiert.

Bei Auswahl der Taste F4 auf dem TEXTEDIT-Control wird PAI ausgelöst. Aufruf der Methode DISPATCH bewirkt die Ausführung der Methode HANDLE_F4. Dort wird der Zeileninhalt an das Feld FIELD zugewiesen. Da danach automatisch in die PAI-Verarbeitung zurückgekehrt wird, wird auch PBO durchlaufen und der Feldinhalt transportiert.

Sowohl bei F1 als auch bei F4 wird der Inhalt des TEXTEDIT-Controls hier nicht an die interne Tabelle TEXT_TAB übergeben. Deshalb wird das TEXTEDIT-Control bei PBO wieder mit dem vorhergehenden Inhalt von TEXT_TAB überschrieben.

Ende des Inhaltsbereichs