Show TOC Anfang des Inhaltsbereichs

Kontextmenüs  Dokument im Navigationsbaum lokalisieren

Die Benutzungsoberfläche eines Dynpros wird in der Regel durch einen im Menu Painter definierten GUI-Status vom Typ Dialogstatus festgelegt. Zu jedem Dialogstatus erzeugt das System automatisch ein Standardkontextmenü, das der Benutzer durch einen Klick der rechten Maustaste (oder Auswahl von SHIFT F10) auf dem Bildschirmbild des Dynpros aufrufen kann. Dieses Standardkontextmenü listet alle mit Funktionen verknüpften Funktionstasten auf. Es erleichtert also den Zugang zu allen über die Tastatur erreichbaren Funktionscodes, von denen normalerweise nur die wichtigsten in der Drucktastenleiste liegen.

Zusätzlich zum Standardkontextmenü können auf Dynpros kontextspezifische Menüs für folgende Bildschirmelemente vorgesehen werden:

·        Ein-/Ausgabefelder

·        Textfelder

·        Table Controls

·        Rahmen

·        Subscreens

Bei Auswahl eines dieser Elemente mit der rechten Maustaste kann dann im ABAP Programm ein dynamisches Kontextmenü erzeugt werden. Dieses Kontextmenü kann beliebige Funktionen auflisten und ist nicht auf Funktionstasten beschränkt. Drucktasten, Ankreuzfelder und Auswahlknöpfe können keine eigenen Kontextmenüs haben. Sie können statt dessen mit eindeutigen Funktionscodes versehen werden.

Die Klasse CL_CTMENU

Kontextmenüs sind Objekte der globalen ABAP Objects Klasse CL_CTMENU. Diese Klasse gehört in der Klassenbibliothek organisatorisch zu den Frontend Services, in denen auch die Klassen des Control Framework (siehe Custom Controls) aufgehoben sind. Sie enthält Methoden, um programmlokale Kontextmenüs dynamisch zu definieren. Als Vorlage können hierbei im Menu Painter statisch (vor)definierte Kontextmenüs verwendet werden.

Die wichtigsten Methoden der Klasse CL_CTMENU sind:

Methode

Funktion

LOAD_GUI_STATUS

Hängt ein im Menu Painter statisch (vor)definiertes Kontextmenü an ein programmlokales Kontextmenü an.

ADD_FUNCTION

Hängt eine einzelne Funktion an ein programmlokales Kontextmenü an.

ADD_MENU

Hängt ein anderes programmlokales Kontextmenü an ein programmlokales Kontextmenü an.

ADD_SUBMENU

Hängt ein anderes programmlokales Kontextmenü als Untermenü an ein programmlokales Kontextmenü an.

ADD_SEPARATOR

Hinzufügen einer Trennlinie.

HIDE_FUNCTIONS

Funktionen ausblenden

SHOW_FUNCTIONS

Funktionen einblenden

DISABLE_FUNCTIONS

Funktionen deaktivieren.

ENABLE_FUNCTIONS

Funktionen aktivieren.

SET_DEFAULT_FUNCTION

Standardfunktion festlegen. D.h. die Funktion wird in der Anzeige hervorgehoben.

Mit programmlokalen Kontextmenü ist in obiger Tabelle ein Objekt der Klasse CL_CTMENU gemeint. Je nach Kontext wird mit CL_CTMENU unterschiedlich gearbeitet:

Falls auf einem Control mit Kontextmenüs gearbeitet werden soll, richtet es sich nach der Klasse des Controls, ob Objekte der Klasse CL_CTMENU erzeugt werden müssen, oder ob ihre Funktionalität in der Klasse des Controls gekapselt ist und ihre Methoden durch die Methoden der Control-Klasse nach außen gereicht werden. In der Regel sollte ein Control-Benutzer nicht selber für die Erzeugung von Kontextmenüs sorgen müssen, damit keine Konflikte mit der Ereignisbehandlung des Controls entstehen. Mehr dazu findet sich in der Dokumentation der einzelnen Control-Klassen.

Bei der Definition von Kontextmenüs auf Dynpros (und auch auf Listen) werden die zugehörigen Objekte der Klasse CL_CTMENU nicht explizit im Programm sondern automatisch von der Laufzeitumgebung erzeugt. Referenzen auf die Objekte werden als Parameter an spezielle Callback-Routinen im ABAP Programm übergeben.

Kontextmenüs für Bildschirmelemente auf Dynpros

Um ein Kontextmenü mit einem der oben angegebenen Bildschirmelemente zu verknüpfen, muss in den Attributen des Elements im Screen Painter lediglich eine Kennung context im Feld Contextmenu angegeben werden. Wird für ein Bildschirmelement kein eigenes Kontextmenü angegeben, erbt dieses Element das Kontextmenü des hierarchisch nächsthöheren Elements. Alle Bildschirmelemente ohne eigenes Kontextmenü in einem Rahmen erben beispielsweise das Kontextmenü des Rahmens. Die höchste Hierarchiestufe ist das Standardkontextmenü mit sämtlichen Tastenbelegungen des aktuellen Dialogstatus.

Wenn ein Bildschirmelement mit einem eigenen oder geerbten Kontextmenü verknüpft ist, wird bei Auswahl dieses Elements mit der rechten Maustaste (oder SHIFT F10) ein Unterprogramm

ON_CTMENU_context

im zugehörigen ABAP-Programm aufgerufen (es wird dabei aber nicht PAI ausgelöst!). Dieses Unterprogramm (Callback-Routine) dient der dynamischen Definition des Kontextmenüs und muss in der Verarbeitungslogik programmiert werden. Falls kein passendes Unterprogramm vorhanden ist, wird kein Kontextmenü angezeigt.

Mehrere Bildschirmelemente können mit dem gleichen Kontextmenü contextverknüpft werden. Sie arbeiten dann gemeinsam mit dem gleichen Unterprogramm.

Definition der Kontextmenüs in der Verarbeitungslogik

Für jedes in den Bildschirmelementen der zu einem ABAP-Programm gehörigen Dynpros angegebene Kontextmenü context sollte im ABAP-Programm eine entsprechende Callback-Routine programmiert werden:

FORM ON_CTMENU_context USING l_menu TYPE REF TO cl_ctmenu.
  ...
ENDFORM.

Jede dieser Routinen muss genau einen USING-Parameter vom Typ einer Referenzvariablen für die Klasse CL_CTMENU haben. Die Laufzeitumgebung erzeugt für jedes bei den Bildschirmelementen angegebene Kontextmenü automatisch ein Objekt dieser Klasse. Bei Auswahl des Bildschirmelements mit der rechten Maustaste (oder SHIFT F10) wird das entsprechende Unterprogramm aufgerufen und eine Referenz auf das zugehörige Objekt an den Formalparameter übergeben.

Das Objekt ist bei seiner Übergabe initial in dem Sinn, dass das Kontextmenü keine Einträge enthält. Im Unterprogramm kann nun mit den oben aufgeführten Methoden des Objekts das Kontextmenü dynamisch und kontextabhängig aufgebaut werden.

Verwendung vordefinierter Kontextmenüs

Ein im Menu Painter vordefiniertes Kontextmenü ist neben Dialogstatus und Status für Dialogfenster ein weiterer Typ eines GUI-Status. Das Anlegen von Kontextmenüs im Menu Painter der ABAP Workbench ist unter Kontextmenü anlegen beschrieben.

Ein vordefiniertes Kontextmenü bietet die Möglichkeit, Teilmengen der statisch bekannten Funktionscodes eines ABAP Programms kontextabhängig zur Verfügung zu stellen. Mit der Methode LOAD_GUI_STATUS können Kontextmenüs beliebiger ABAP Programme an programmlokale Kontextmenüs angehängt werden. In der Regel verwendet man vordefinierte Kontextmenüs, um die Funktionscodes des Dialogstatus mit der gleichen Semantik aber kontextspezifisch wiederzuverwenden. Nach dem Laden eines vordefinierten Kontextmenüs in ein programmlokales Kontextmenü, kann dieses beliebig modifiziert werden (andere vordefinierte Kontextmenüs anhängen, Funktionen hinzufügen oder entfernen, andere Kontextmenüs einbinden).

Definition neuer Kontextmenüs

Durch die Modifikation vordefinierter Kontextmenüs, oder durch den Aufbau von Kontextmenüs aus neuen Funktionen können kontextabhängig völlig neue Kontextmenüs erstellt werden.

Zum einen können einem Kontextmenü beliebige neue Funktion hinzugefügt werden. Beim Hinzufügen einer neuen Funktion, müssen Funktionstext, Funktionscode und Funktionstyp (wie z.B. E für unbedingten Modulaufruf) angegeben werden.

Zum anderen können beliebige andere programmlokale Kontextmenü-Objekte eingebunden werden. Hierfür muss dem Kontextmenü nur eine Referenz auf ein anderes Kontextmenü übergeben werden (siehe Beispiel unten). Man kann sich in einem Programm also eine Sammlung von Kontextmenü-Objekten erzeugen, und diese nach Bedarf verwenden. Dabei ist auch die Bildung von Untermenüs möglich. Wenn eingebundene Untermenüs wieder Untermenüs enthalten entstehen tief geschachtelte Menüs.

Stilrichtlinien

Bei der Gestaltung von Kontextmenüs empfiehlt es sich folgenden Regeln zu folgen:

·        Die Funktionen auf Kontextmenüs sollten Teilmengen der Funktionsliste des Programms sein. Dies wird durch die Benutzung vordefinierter Kontextmenüs unterstützt.

·        Ein Kontextmenü sollte auf einer Ebene nicht mehr als zehn Einträge enthalten.

·        Wenn ein Kontextmenü zu einem Bildschirmelement verwendet wird, dann sollte es auch alle für dieses Element möglichen Funktionen enthalten, zumindest aber die Standardbefehle, wie z.B. Auswählen, Kopieren, Ausschneiden, Einsetzen für kopierbare Felder.

·        Die Reihenfolge der Funktionen sollte sein: objektspezifische Befehle, Kopierbefehle, weitere Befehle.

·        Bis auf Ausnahmen sollten keine über direkte Auswahl (linke Maustaste) möglichen Befehle in Kontextmenüs dupliziert werden.

Anzeige des Kontextmenüs

Nach der dynamischen Definition des Kontextmenüs in der Callback-Routine, wird es sofort auf dem Bildschirmbild dargestellt. Wählt der Benutzer einen Menüpunkt aus, wird das Ereignis PAI ausgelöst und der entsprechende Funktionscode in sy-ucomm und dem OK-Feld an das ABAP-Programm übergeben.

Beispiel

Das folgende Beispiel zeigt einige der technischen Möglichkeiten bei der Definition von Kontextmenüs, ohne besondere Berücksichtigung der Stilrichtlinien ;-)

Beispiel

REPORT demo_dynpro_context_menu.

DATA: field1 TYPE i VALUE 10,
      field2 TYPE p DECIMALS 4.

DATA: prog TYPE sy-repid,
      flag(1) TYPE c VALUE 'X'.

DATA: ok_code TYPE sy-ucomm,
      save_ok TYPE sy-ucomm.

prog = sy-repid.

CALL SCREEN 100.

MODULE status_0100 OUTPUT.
  SET TITLEBAR 'TIT100'.
  IF flag = 'X'.
    SET PF-STATUS 'SCREEN_100' EXCLUDING 'REVEAL'.
  ELSEIF flag = ' '.
    SET PF-STATUS 'SCREEN_100' EXCLUDING 'HIDE'.
  ENDIF.
  
LOOP AT SCREEN.
    IF screen-group1 = 'MOD'.
      IF flag = 'X'.
        screen-active = '1'.
      ELSEIF flag = ' '.
        screen-active = '0'.
      ENDIF.
      MODIFY SCREEN.
    ELSEIF screen-name = 'TEXT_IN_FRAME'.
      IF flag = 'X'.
        screen-active = '0'.
      ELSEIF flag = ' '.
        screen-active = '1'.
      ENDIF.
      MODIFY SCREEN.
    ENDIF.
  ENDLOOP.
ENDMODULE.

MODULE cancel INPUT.
  LEAVE PROGRAM.
ENDMODULE.

MODULE user_command_0100.
  save_ok = ok_code.
  CLEAR ok_code.
  CASE save_ok.
    WHEN 'HIDE'.
      flag = ' '.
    WHEN 'REVEAL'.
      flag = 'X'.
    WHEN 'SQUARE'.
      field2 = field1 ** 2.
    WHEN 'CUBE'.
      field2 = field1 ** 3.
    WHEN 'SQUAREROOT'.
      field2 = field1 ** ( 1 / 2 ).
    WHEN 'CUBICROOT'.
      field2 = field1 ** ( 1 / 3 ).
  ENDCASE.
ENDMODULE.

*******************************************************
* Callback-Routines
*******************************************************

FORM on_ctmenu_text USING l_menu TYPE REF TO cl_ctmenu.
  CALL METHOD:l_menu->load_gui_status
                       EXPORTING program = prog
                                 status  = 'CONTEXT_MENU_1'
                                 menu    = l_menu.
ENDFORM.

FORM on_ctmenu_frame USING l_menu TYPE REF TO cl_ctmenu.
  CALL METHOD:l_menu->load_gui_status
                      EXPORTING program = prog
                                status  = 'CONTEXT_MENU_2'
                                menu    = l_menu,
              l_menu->load_gui_status
                      EXPORTING program = prog
                                status  = 'CONTEXT_MENU_1'
                                menu    = l_menu,
              l_menu->set_default_function
                      EXPORTING fcode = 'HIDE'.
ENDFORM.

FORM on_ctmenu_reveal USING l_menu TYPE REF TO cl_ctmenu.
  CALL METHOD:l_menu->load_gui_status
                      EXPORTING program = prog
                                status  = 'CONTEXT_MENU_3'
                                menu    = l_menu,
              l_menu->load_gui_status
                      EXPORTING program = prog
                                status  = 'CONTEXT_MENU_1'
                                menu    = l_menu,
              l_menu->set_default_function
                      EXPORTING fcode = 'REVEAL'.
ENDFORM.

FORM on_ctmenu_input USING l_menu TYPE REF TO cl_ctmenu.
  DATA calculate_menu TYPE REF TO cl_ctmenu.
  CREATE OBJECT calculate_menu.
  CALL METHOD: calculate_menu->add_function
                      EXPORTING fcode = 'SQUARE'
                                text  = text-001,
               calculate_menu->add_function
                       EXPORTING fcode = 'CUBE'
                                 text  = text-002,
               calculate_menu->add_function
                       EXPORTING fcode = 'SQUAREROOT'
                                 text  = text-003,
               calculate_menu->add_function
                       EXPORTING fcode = 'CUBICROOT'
                                 text  = text-004,
               l_menu->add_submenu
                       EXPORTING menu = calculate_menu
                                 text = text-005.
ENDFORM.

Die statische Folgedynpronummer von Dynpro 100 ist 100 und sein Layout ist:

Diese Grafik wird im zugehörigen Text erklärt

Der für Kontextmenüs relevante Teil der Elementliste ist wie folgt:

Name

Typ

Inhalt

Contextmenu

TEXT

Text

Probieren Sie ...

TEXT

FRAME

Frame

 

FRAME

TEXT1

Text

Eingabe

INPUT

FIELD1

I/O

 

INPUT

TEXT2

Text

Ergebnis

 

FIELD2

I/O

 

 

TEXT_IN_FRAME

Text

Ergebnis einblenden

REVEAL

Die Elemente TEXT2 und FIELD2 haben keine eigenen Kontextmenüs. Sie erben das Kontextmenü FRAME des Rahmens. Ihnen ist die Modifikationsgruppe MOD zugeteilt.

Die Dynproablauflogik ist:

PROCESS BEFORE OUTPUT.
  
MODULE status_0100.

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

Zu diesem ABAP-Programm sind folgende Funktionscodes und GUI-Status statisch definiert:

Funktionscodes

BACK

CANCEL

EXIT

HIDE

REVEAL

Dialogstatus

 

 

 

 

 

SCREEN_100

X

X

X

X

X

Kontextmenüs

 

 

 

 

 

CONTEXT_MENU_1

X

 

 

 

 

CONTEXT_MENU_2

 

 

 

X

 

CONTEXT_MENU_3

 

 

 

 

X

Die Tabelle zeigt, welche GUI-Status welche Funktionscodes enthalten.

Der Dialogstatus SCREEN_100 wird zu PBO statisch gesetzt, wobei abhängig vom Feld FLAG die Funktionscodes HIDE oder REVEAL ausgeblendet werden.

Die Kontextmenüs zu den Bildschirmelementen werden in den Callback-Routinen wie folgt aufgebaut:

TEXT:
Laden des statischen Kontextmenüs CONTEXT_MENU_1 ohne Modifikation. Dieses Kontextmenü hat eine Zeile Abbrechen.

FRAME:
Aufbau des Kontextmenüs aus den statischen Kontextmenüs CONTEXT_MENU_2 und CONTEXT_MENU_1. Dieses Kontextmenü hat zwei Zeilen Ergebnis ausblenden und Abbrechen. Die Zeile zum Funktionscode HIDE wird hervorgehoben dargestellt.

REVEAL:
Aufbau des Kontextmenüs aus den statischen Kontextmenüs CONTEXT_MENU_3 und CONTEXT_MENU_1. Dieses Kontextmenü hat zwei Zeilen Ergebnis einblenden und Abbrechen. Die Zeile zum Funktionscode REVEAL wird hervorgehoben dargestellt.

INPUT:
Aufbau des Kontextmenüs durch Einbinden des vierzeiligen lokalen Kontextmenüs CALCULATE_MENU als Untermenü. Für letzteres wird im Unterprogramm eine lokale Referenzvariable mit Bezug auf CL_CTMENU angelegt, ein Objekt erzeugt und neue Funktionscodes SQUARE, CUBE, SQUAREROOT und CUBICROOT hinzugefügt. Beim Einbinden in das Kontextmenü für INPUT muss ein Text für den Eintrag angegeben werden, hinter dem das Untermenü hängt.

Bei der Ausführung des Programms, erhält der Benutzer bei Auswahl der rechten Maustaste bzw. SHIFT F10 auf der ersten Zeile das Kontextmenü TEXT, auf der zweiten Zeile das Kontextmenü INPUT und auf der dritten Zeile das Kontextmenü FRAME. Die vierte Zeile ist nach Programmstart ausgeblendet. Auf allen übrigen Bildschirmbereichen erscheint das Standardkontextmenü mit allen statischen Funktionscodes und zusätzlich F1 und F4.

Bei Auswahl einer der neuen dynamischen Funktionen, werden Berechnungen mit der Zahl im Eingabefeld FIELD1 ausgeführt und nach FIELD2 gestellt.

Bei Auswahl der Funktion Ergebnis ausblenden (HIDE) wird das Bildschirmbild dynamisch modifiziert. Dadurch wird die vierte Zeile sichtbar und damit wird das Kontextmenü REVEAL zugänglich.

 

Ende des Inhaltsbereichs