[ABAP] Klasse zur Darstellung von Nachrichtentexten in einem SALV-Grid in einem Popup-Dialog

CLASS lcl_popup_msg_box DEFINITION.

  PUBLIC SECTION.
* Typ Textzeile
    TYPES: BEGIN OF ty_textline,
             idx  TYPE rspos,
             text TYPE bapi_msg,
           END OF ty_textline.

    TYPES: ty_it_messagetab TYPE STANDARD TABLE OF ty_textline WITH DEFAULT KEY.

* Typ Button-Event
    TYPES: ty_it_events TYPE STANDARD TABLE OF cntl_simple_event WITH DEFAULT KEY.

* Anzeige des Popups
    CLASS-METHODS show
      IMPORTING
                i_window_title   TYPE string
                i_window_top     TYPE i
                i_window_left    TYPE i
                i_window_width   TYPE i
                i_window_height  TYPE i
                i_show_functions TYPE boolean
                i_it_messages    TYPE ty_it_messagetab
      RETURNING VALUE(rv_ok)     TYPE boolean.

  PRIVATE SECTION.

* Button Funktionskonstanten
    CONSTANTS: co_btn_ok TYPE ui_func VALUE 'BTN_OK'.
    CONSTANTS: co_btn_cancel TYPE ui_func VALUE 'BTN_CANCEL'.

* Message-Tabelle
    CLASS-DATA: it_messages TYPE ty_it_messagetab.

* GUI-Objekte
    CLASS-DATA: o_cnt TYPE REF TO cl_gui_dialogbox_container.
    CLASS-DATA: o_salv TYPE REF TO cl_salv_table.
    CLASS-DATA: o_split TYPE REF TO cl_gui_splitter_container.
    CLASS-DATA: o_tool TYPE REF TO cl_gui_toolbar.
    CLASS-DATA: gv_retval TYPE boolean VALUE abap_false.

* on_close-Handler
    CLASS-METHODS:
      on_close FOR EVENT close OF cl_gui_dialogbox_container
        IMPORTING
            sender.
* on_function_selected Handler
    CLASS-METHODS:
      on_function_selected FOR EVENT function_selected OF cl_gui_toolbar
        IMPORTING
            fcode
            sender.

ENDCLASS.

CLASS lcl_popup_msg_box IMPLEMENTATION.

  METHOD show.

    it_messages = i_it_messages.

* Container für GUI-Elemente
    o_cnt = NEW #( parent = cl_gui_container=>default_screen
                   caption = |{ i_window_title }|
                   top = i_window_top
                   left = i_window_left
                   width = i_window_width
                   height = i_window_height
                   no_autodef_progid_dynnr = abap_true
                 ).

* on_close-Handler setzen
    SET HANDLER on_close FOR o_cnt.

* Splitter für Grid und Toolbar
    o_split = NEW #( parent = o_cnt
                     no_autodef_progid_dynnr = abap_true
                     rows = 2
                     columns = 1 ).

* Unteren Splitterbereich setzen
    o_split->set_row_sash( id    = 2
                           type  = cl_gui_splitter_container=>type_movable
                           value = cl_gui_splitter_container=>false ).

    o_split->set_row_sash( id    = 2
                           type  = cl_gui_splitter_container=>type_sashvisible
                           value = cl_gui_splitter_container=>false ).

    o_split->set_row_height( id = 2 height = 8 ).

* Oberen und unteren Splittercontainer holen
    DATA(o_container_top)    = o_split->get_container( row = 1 column = 1 ).
    DATA(o_container_bottom) = o_split->get_container( row = 2 column = 1 ).
* Toolbar für Buttons erzeugen
    DATA(o_tool) = NEW cl_gui_toolbar( parent       = o_container_bottom
                                       display_mode = cl_gui_toolbar=>m_mode_horizontal
                                       align_right  = 1 ).

* Toolbarevents
    DATA(it_events) = VALUE ty_it_events( ( eventid    = cl_gui_toolbar=>m_id_function_selected
                                            appl_event = abap_true ) ).

    o_tool->set_registered_events( events = it_events ).

* Buttons + Separator einfügen
    o_tool->add_button( fcode       = co_btn_ok
                        icon        = icon_okay
                        butn_type   = cntb_btype_button
                        text        = 'Ok'
                        quickinfo   = 'Ok'
                        is_checked  = abap_false
                        is_disabled = abap_false ).

    o_tool->add_button( fcode       = ''
                        icon        = ''
                        butn_type   = cntb_btype_sep
                        text        = ''
                        quickinfo   = ''
                        is_checked  = abap_false
                        is_disabled = abap_false ).

    o_tool->add_button( fcode       = co_btn_cancel
                        icon        = icon_cancel
                        butn_type   = cntb_btype_button
                        text        = 'Abbruch'
                        quickinfo   = 'Abbruch'
                        is_checked  = abap_false
                        is_disabled = abap_false ).

* on_function_selected-Handler
    SET HANDLER on_function_selected FOR o_tool.

* SALV-Grid im oberen Splitter einfügen
    cl_salv_table=>factory( EXPORTING
                              r_container  = o_container_top
                            IMPORTING
                              r_salv_table = o_salv
                            CHANGING
                              t_table      = it_messages ).

* Eigenschaften SALV-Grid
    o_salv->get_columns( )->set_optimize( abap_true ).
    o_salv->get_display_settings( )->set_striped_pattern( abap_true ).
    IF i_show_functions = abap_true.
      o_salv->get_functions( )->set_all( ).
    ENDIF.
    o_salv->get_selections( )->set_selection_mode( if_salv_c_selection_mode=>row_column ).
    o_salv->display( ).

* Dummy-Screen aufrufen und somit cl_gui_container=>default_screen erzeugen -> Trägerdynpro für cl_gui_dialogbox_container
    CALL SCREEN 100.

* nach Buttonclick noch die Ergebnisrückgabe
    rv_ok = gv_retval.
  ENDMETHOD.

  METHOD on_close.

* cl_gui_dialogbox_container bei Klick auf Schließen-Kreuz schließen
    IF sender IS NOT INITIAL.
      sender->free( ).
    ENDIF.

* Zum aufrufenden Dynpro zurück
    LEAVE TO SCREEN 0.

  ENDMETHOD.

* Button ermitteln -> Reaktion -> Setzen des Rückgabewertes beim Schließen des Popups
  METHOD on_function_selected.
    CASE fcode.
      WHEN co_btn_ok.
        gv_retval = abap_true.
      WHEN co_btn_cancel.
        gv_retval = abap_false.
    ENDCASE.

* Popup-Fenster schließen
    on_close( o_cnt ).
  ENDMETHOD.
ENDCLASS.

* Dummy-Screen für cl_gui_container=>default_screen deklarieren
SELECTION-SCREEN BEGIN OF SCREEN 100.
SELECTION-SCREEN END OF SCREEN 100.

START-OF-SELECTION.

* Nachrichtentabelle erzeugen
  DATA(it_msg) = VALUE lcl_popup_msg_box=>ty_it_messagetab( ( idx = 1 text = 'Nachricht 1' )
                                                            ( idx = 2 text = 'Nachricht 2' )
                                                          ).

* Popup mit Nachrichten anzeigen
  IF abap_true = lcl_popup_msg_box=>show( EXPORTING
                                            i_window_title   = 'Meldungen'
                                            i_window_top     = 100
                                            i_window_left    = 100
                                            i_window_width   = 240
                                            i_window_height  = 240
                                            i_show_functions = abap_false
                                            i_it_messages    = it_msg ).
    WRITE: / 'OK.'.
  ELSE.
    WRITE: / 'Abbruch.'.
  ENDIF.

[ABAP] Popup-Fenster mit Eingabefeldern anzeigen

Variante 1 (Einfaches Popup-Fenster mit Eingabefeld)

* Button Pos 2 Länge 20, sendet Kommando 'CMD_SHOW'
SELECTION-SCREEN: PUSHBUTTON 2(20) btn1 USER-COMMAND cmd_show.

* Popup-Fenster (Selektionsbild 100) deklarieren
SELECTION-SCREEN BEGIN OF SCREEN 100 TITLE title.
PARAMETERS: p_text TYPE string.
SELECTION-SCREEN END OF SCREEN 100.

INITIALIZATION.
* Fenstertitel
  title = 'Popup'.
* Button-Text setzen
  btn1 = |{ icon_activity }Popup anzeigen|.

AT SELECTION-SCREEN.
* wenn Button-Kommando 'CMD_SHOW'
  IF sy-ucomm = 'CMD_SHOW'.
* Popup-Fenster (Selektionsbild 100) anzeigen
    CALL SELECTION-SCREEN 100 STARTING AT 10 5.
  ENDIF.

START-OF-SELECTION.
* Datenausgabe
  WRITE: / p_text.

Variante 2 (Passwortdialog mit eigenem PF-Status)

* Inspiriert (Quelle) von: http://www.abapgit.org
DATA: gv_user TYPE string.
DATA: gv_pass TYPE string.

**********************************************************************
*
* Dynproelemente für Standard-Selektionbild
*
**********************************************************************
SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN PUSHBUTTON 2(30) b_pop USER-COMMAND pop.
SELECTION-SCREEN END OF LINE.
**********************************************************************
*
* Dynproelemente für Popup
*
**********************************************************************
SELECTION-SCREEN BEGIN OF SCREEN 3000 TITLE s_title.

SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN COMMENT 1(10) s_user FOR FIELD p_user.
PARAMETERS: p_user TYPE string LOWER CASE.
SELECTION-SCREEN END OF LINE.

SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN COMMENT 1(10) s_pass FOR FIELD p_pass.
PARAMETERS: p_pass TYPE string LOWER CASE.
SELECTION-SCREEN END OF LINE.

SELECTION-SCREEN END OF SCREEN 3000.
**********************************************************************
*
* Klasse zur Anzeige des Popup-Fensters
*
**********************************************************************
CLASS lcl_pwdlg DEFINITION FINAL.

  PUBLIC SECTION.
    CONSTANTS: co_dynnr TYPE char4 VALUE '3000'.

    CLASS-METHODS on_initialization.
    CLASS-METHODS on_output.
    CLASS-METHODS on_event
      IMPORTING
        i_ucomm TYPE sy-ucomm.

    CLASS-METHODS show
      IMPORTING
        i_user TYPE string
      EXPORTING
        e_user TYPE string
        e_pass TYPE string.

  PRIVATE SECTION.
    CLASS-DATA: gv_ok TYPE abap_bool.

ENDCLASS.

CLASS lcl_pwdlg IMPLEMENTATION.

  METHOD on_initialization.
    s_title = 'Loginfenster'.
    s_user  = 'Benutzer'.
    s_pass  = 'Passwort'.
  ENDMETHOD.

  METHOD on_output.
    IF sy-dynnr = lcl_pwdlg=>co_dynnr.
* Wenn Popup angezeigt werden soll

* GUI Status aus Program RSDBRUNT setzen (Ausführen- und Schließen-Button)
      PERFORM set_pf_status IN PROGRAM rsdbrunt IF FOUND.

      DATA: it_ucomm TYPE STANDARD TABLE OF sy-ucomm WITH DEFAULT KEY.

* Prüfen-Button entfernen
      APPEND 'NONE' TO it_ucomm.
* Variante-Speichern-Button entfernen
      APPEND 'SPOS' TO it_ucomm.

      CALL FUNCTION 'RS_SET_SELSCREEN_STATUS'
        EXPORTING
          p_status  = sy-pfkey
        TABLES
          p_exclude = it_ucomm.

      IF NOT p_user IS INITIAL.
* Cursor in Passwort-Feld setzen
        SET CURSOR FIELD 'P_PASS'.
      ENDIF.
    ENDIF.
  ENDMETHOD.

  METHOD show.

* User + Passwort setzen
    p_user = i_user.
    CLEAR: p_pass.

    gv_ok = abap_false.

* Selektionsbild CO_DYNNR (das Popup) anzeigen
    CALL SELECTION-SCREEN co_dynnr STARTING AT 15 10 ENDING AT 75 12.

    IF gv_ok = abap_true.
* wenn Popup per Ausführen (F8) oder ENTER geschlossen wird, dann Werte übernehmen
      e_user = p_user.
      e_pass = p_pass.
    ENDIF.

    CLEAR: p_user.
    CLEAR: p_pass.

  ENDMETHOD.

  METHOD on_event.
* Tastendrücke vom Popup abfangen
    IF sy-dynnr = co_dynnr.
      CASE i_ucomm.
        WHEN 'CRET'.
* für Ausführen (F8)
          gv_ok = abap_true.
        WHEN OTHERS.
* für ENTER
          gv_ok = abap_true.
          LEAVE TO SCREEN 0.
      ENDCASE.
    ENDIF.
  ENDMETHOD.

ENDCLASS.

INITIALIZATION.
  b_pop   = 'Popup öffnen'.
* Popup initialisieren
  lcl_pwdlg=>on_initialization( ).

AT SELECTION-SCREEN OUTPUT.
  CASE sy-dynnr.
    WHEN 1000.
* wenn Ereignis aus dem Standart-Selektionsbild (Dynpro 1000) getriggert wird

    WHEN lcl_pwdlg=>co_dynnr.
* wenn Ereignis aus dem Popup (Dynpro CO_DYNNR) getriggert wird
      lcl_pwdlg=>on_output( ).
    WHEN OTHERS.
  ENDCASE.

AT SELECTION-SCREEN.
  CASE sy-dynnr.
    WHEN 1000.
* wenn Ereignis aus dem Standart-Selektionsbild (Dynpro 1000) getriggert wird
      CASE sy-ucomm.
* Button "Popup öffnen" geklickt
        WHEN 'POP'.
* Popup anzeigen
          lcl_pwdlg=>show( EXPORTING i_user = CONV #( sy-uname )
                           IMPORTING e_user = gv_user
                                     e_pass = gv_pass ).
      ENDCASE.
    WHEN lcl_pwdlg=>co_dynnr.
* wenn Ereignis aus dem Popup (Dynpro CO_DYNNR) getriggert wird
      lcl_pwdlg=>on_event( sy-ucomm ).
  ENDCASE.

START-OF-SELECTION.
  WRITE: / gv_user.
  WRITE: / gv_pass.

[ABAP] Einfaches Popupfenster mit Texteditor anzeigen

Variante 1 (cl_gui_dialogbox_container)

DATA: o_cnt TYPE REF TO cl_gui_dialogbox_container.
DATA: o_edit TYPE REF TO cl_gui_textedit.
DATA: it_editor TYPE STANDARD TABLE OF char1024.

CLASS lcl_events DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS on_close FOR EVENT close OF cl_gui_dialogbox_container
      IMPORTING sender.
ENDCLASS.

CLASS lcl_events IMPLEMENTATION.
* Event, wenn auf das Schließen-Kreuz geklickt wird
  METHOD on_close.
    IF NOT o_edit IS INITIAL.
* vor dem Schließen Text aus dem Editor holen
      o_edit->get_text_as_stream( IMPORTING text = it_editor ).

      sender->free( ).
    ENDIF.
  ENDMETHOD.
ENDCLASS.

* Button Pos 2 Länge 20, sendet Kommando 'CMD_SHOW'
SELECTION-SCREEN: PUSHBUTTON 2(20) btn1 USER-COMMAND cmd_show.

INITIALIZATION.
* Button-Text setzen
  btn1 = |{ icon_activity }Popup anzeigen|.

AT SELECTION-SCREEN.
* wenn Button-Kommando 'CMD_SHOW'
  IF sy-ucomm = 'CMD_SHOW'.

    o_cnt = NEW #( no_autodef_progid_dynnr = abap_true
                   caption = 'Texteditor'
                   top = 100
                   left = 200
                   width = 640
                   height = 240 ).

* on_close Handler setzen
    SET HANDLER lcl_events=>on_close FOR o_cnt.

* neues Editorobjekt erzeugen (überschreibt vorherige Referenz!)
    o_edit = NEW #( wordwrap_mode = cl_gui_textedit=>wordwrap_at_windowborder
                    wordwrap_to_linebreak_mode = cl_gui_textedit=>true
                    parent = o_cnt ).

* feste Zeichenbreite
    o_edit->set_font_fixed( mode = cl_gui_textedit=>true ).
  ENDIF.

START-OF-SELECTION.
  LOOP AT it_editor ASSIGNING FIELD-SYMBOL(<l>).
    WRITE: / <l>.
  ENDLOOP.

Variante 2 (SELECTION-SCREEN)

DATA: it_editor TYPE STANDARD TABLE OF char1024.

* Button Pos 2 Länge 20, sendet Kommando 'CMD_SHOW'
SELECTION-SCREEN: PUSHBUTTON 2(20) btn1 USER-COMMAND cmd_show.

* Popup-Fenster (Selektionsbild 100) deklarieren
SELECTION-SCREEN BEGIN OF SCREEN 100 TITLE title.
SELECTION-SCREEN END OF SCREEN 100.

INITIALIZATION.
* Fenstertitel
  title = 'Texteditor'.
* Button-Text setzen
  btn1 = |{ icon_activity }Popup anzeigen|.

AT SELECTION-SCREEN.
* wenn Button-Kommando 'CMD_SHOW'
  IF sy-ucomm = 'CMD_SHOW'.
* cl_gui_container=>screen1 == SELECTION-SCREEN 100
    DATA(o_edit) = NEW cl_gui_textedit( wordwrap_mode = cl_gui_textedit=>wordwrap_at_windowborder
                                        wordwrap_to_linebreak_mode = cl_gui_textedit=>true
                                        parent = cl_gui_container=>screen1 ).

* feste Zeichenbreite
    o_edit->set_font_fixed( mode = cl_gui_textedit=>true ).

* Popup-Fenster (Selektionsbild 100) anzeigen -> cl_gui_container=>screen1 wird erzeugt
    CALL SELECTION-SCREEN 100 STARTING AT 10 5 ENDING AT 100 20.

* Text aus dem Editor holen
    o_edit->get_text_as_stream( IMPORTING text = it_editor ).

* Editorobjekt freigeben
    FREE: o_edit.
  ENDIF.

START-OF-SELECTION.
  LOOP AT it_editor ASSIGNING FIELD-SYMBOL(<l>).
    WRITE: / <l>.
  ENDLOOP.