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:
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, muß 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 UnterprogrammON_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 muß in der Verarbeitungslogik programmiert werden. Falls kein passendes Unterprogramm vorhanden ist, wird kein Kontextmenü angezeigt.
Mehrere Bildschirmelementen könne mit dem gleichen Kontextmenü <context> verknü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 muß 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, daß 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 muß 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:
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 ;-)
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:
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 muß 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.