Today I found an application where I was stunned for a moment.
It took some seconds and investigation before I found out how this icon could be set at this position of the SAPGUI.
Containers All Around
If you want to place a control somewhere on the SAPGUI, you need a container. The most common containers are:
- CL_GUI_DOCKING_CONTAINER for docking a container to one side of the dynpro
- CL_GUI_CUSTOM_CONTAINER for implementing custom controls inside a dynpro
- CL_GUI_DIALOGBOX_CONTAINER for displaying a resizeable amodal popup
- CL_GUI_SPLITTER_CONTAINER which provides several containers divided by a splitter
- CL_GUI_EASY_SPLITTER_CONTAINER which provides two containers divided by a splitter
They all ere inherited by super class CL_GUI_CONTAINER.If you take a look at the sub classes of CL_GUI_CONTAINER then you will find another container class: CL_GUI_GOS_CONTAINER.
This is the container where I placed the attention image of the screen shot.
Coding Is Believing
Here is the minimum of code for hacking the SAPGUI
REPORT. PARAMETERS p_test. INITIALIZATION. DATA(picture) = NEW cl_gui_picture( parent = NEW cl_gui_gos_container( width = 38 ) ). DATA url TYPE cndp_url. CALL FUNCTION 'DP_PUBLISH_WWW_URL' EXPORTING objid = 'ACHTUNG' lifetime = cndp_lifetime_transaction IMPORTING url = url EXCEPTIONS dp_invalid_parameters = 1 no_object = 2 dp_error_publish = 3. IF sy-subrc = 0. picture->load_picture_from_url_async( url = url ). picture->set_display_mode( picture->display_mode_fit ). ENDIF.
I simply love things that are unusual or “impossible”. Therefore I started some experimenting with the “new” container.
I found out that it can be used multiple times, which gives a lot more options…
The following code displays the icons as shown above. Clicking on checkbox P_SHOW shows or hides the attention image.
Clicking on an icon brings up an information message.
REPORT. PARAMETERS p_test. PARAMETERS p_show AS CHECKBOX DEFAULT 'X' USER-COMMAND dummy. CLASS info DEFINITION. PUBLIC SECTION. METHODS icon IMPORTING name TYPE clike RETURNING VALUE(info) TYPE REF TO info. METHODS pic IMPORTING name TYPE clike RETURNING VALUE(info) TYPE REF TO info. METHODS constructor IMPORTING width TYPE i. METHODS with_text IMPORTING text TYPE clike RETURNING VALUE(info) TYPE REF TO info.. METHODS hide. METHODS show. PROTECTED SECTION. DATA picture TYPE REF TO cl_gui_picture. METHODS handle_click FOR EVENT picture_click OF cl_gui_picture. DATA text TYPE string. ENDCLASS. CLASS info IMPLEMENTATION. METHOD constructor. picture = NEW cl_gui_picture( parent = NEW cl_gui_gos_container( width = width ) ). picture->set_registered_events( VALUE #( ( eventid = cl_gui_picture=>eventid_picture_click ) ) ). SET HANDLER handle_click FOR picture. ENDMETHOD. METHOD icon. picture->load_picture_from_sap_icons( name ). picture->set_display_mode( picture->display_mode_fit ). info = me. ENDMETHOD. METHOD pic. DATA url TYPE cndp_url. CALL FUNCTION 'DP_PUBLISH_WWW_URL' EXPORTING objid = CONV w3objid( name ) lifetime = cndp_lifetime_transaction IMPORTING url = url EXCEPTIONS dp_invalid_parameters = 1 no_object = 2 dp_error_publish = 3. IF sy-subrc = 0. picture->load_picture_from_url_async( url = url ). picture->set_display_mode( picture->display_mode_fit ). ENDIF. info = me. ENDMETHOD. METHOD with_text. me->text = text. info = me. ENDMETHOD. METHOD handle_click. CHECK text IS NOT INITIAL. MESSAGE text TYPE 'I'. ENDMETHOD. METHOD hide. picture->set_visible( space ). ENDMETHOD. METHOD show. picture->set_visible( 'X' ). ENDMETHOD. ENDCLASS. INITIALIZATION. DATA(info) = NEW info( 38 )->pic( 'ACHTUNG' ). DATA(green) = NEW info( 39 )->icon( icon_led_green )->with_text( 'Everything ok' ). DATA(yellow) = NEW info( 39 )->icon( icon_led_yellow )->with_text( 'aargh...' ). DATA(red) = NEW info( 39 )->icon( icon_led_red )->with_text( 'error. error. error.' ). AT SELECTION-SCREEN OUTPUT. CASE p_show. WHEN abap_true. info->show( ). WHEN abap_false. info->hide( ). ENDCASE.
btw: Method Chaining
Because I like the idea of Paul Hardy to write the code in a way that the code itself says what will happen, I tried to do so in this little report via method chainging:
DATA(red) = NEW info( 39 )->icon( icon_led_red )->with_text( 'error. error. error.' ).
It’s not suitable for all methods, but within those little helper classes, I like the way it can be used.
If a container is a container, then I can place any control in it I like. Not too many make sense due to the size of the container, but…
Displaying an editable Text inside this container looks quite weird, but it works:
After this I got some kind of arrogant and wanted to display an HTML document inside the CL_GUI_GOS_CONTAINER. What can I say, it also works:
Even CL_SALV_TABLE is possible:
What is the purpose of this nerdy stuff, that absolutely destroys the standard behaviour of the SAPGUI?
Because I can… 😀
Seriously: I recommend NOT to use it in any of your custom transactions unless you have a really really good reason for it. It will confuse your users strongly…
…Keep on hacking!
Benny Hill! That bastion of PC…
Chaining has its place, but it can indicate a flaky encapsulation - exposing too much of the inner workings. Like, instead of dog->bark( ), dog->mouth_open( )->air_in( )->sound_out( ).
Anyway, must dash – and try some of these things!
In your constructor, this line gives syntax error "No type can be derived from the context for the operator "VALUE"."
I had to use a helper variable.
The implicit usage should work. oh: You missed one bracket:
As a workaround you could have specified the type w/o a helper table:
Sorry, typo in my post. The actual code was copy pasted, and identical to your implicit usage. The workaround you suggest (which I had tried already) says:
A value of the generic type "CNTL_SIMPLE_EVENTS" cannot be constructed.
Perhaps our versions of the type groups differ?
But the above is how it is in my 740 and 750 systems.
Yes, you are right - CNTL_SIMPLE_EVENTS is a "generic" type because of the missing option "WITH ... KEY".
So much surprising that the implicit type inhertiance works in my 750 system...
Enno Wulff crazy stuff. #HackingABAPContainers:). I actually liked method chaining when we do it particularly in Laravel framework of #PHP it is super powerful!
Keep sharing the crazy stuff.
I will... 😉