When you're used to create buttons in ALV Grid dynamically then you think why SAP doesn't allow create dynamically buttons on GUI STATUS. You can change icon or text if you defined that function has dynamic text but you cannot create buttons at runtime and you always have to create GUI STATUS and GUI TITLE in SE41, which personally I don't like, as in most small reports you have to create usually one to five buttons. 
So what I want to present to you today is a way to create buttons dynamically at program runtime without a need to create GUI STATUS and GUI TITLE for each program. In fact whole trick is to create firstly a GUI STATUS in empty program which will contain only functions with dynamic texts, and then to fill properly static class attribute.
So let's begin with creating our program to keep GUI STATUS and GUI TITLE. I will call it ZAB_DYNAMIC_GUI_STATUS. In the source code you do not need to put anything beside report keyword.

"! Dummy program for keeping GUI STATUS and TITLE
"! Do not delete it!!!
report zab_dynamic_gui_status.

Yes, that's all from the code point of view in this program. As said it's only to keep GUI STATUS and GUI TITLE
Lets create GUI STATUS firstly and call it DYNAMIC_STATUS. Items on application toolbar will have the same naming pattern Fxx, so F01, F02 etc. Each of this function code should have dynamic function text with pattern ZCA_AB_DYNAMIC_GUI=>BUTTONS-Fxx where Fxx you have to replace by current function code.
Additionally to application toolbar, fill also function keys for save, up, back, exit, print... etc so you can also use it in your programs.
Save & activate GUI STATUS.
Now create also GUI TITLE and call it DYNAMIC_TITLE. As a text put &1 &2 &3 &4 &5. Save & activate. 
That's all for ZAB_DYNAMIC_GUI_STATUS program. Now it's time to create class with static methods to be able to use created STATUS and TITLE everywhere we need.
Class is called ZCA_AB_DYNAMIC_GUI. Once created please make sure that constant program_name contains name of program which stores DYNAMIC_STATUS and DYNAMIC_TITLE

class zca_ab_dynamic_gui definition
  create public .

  public section.
    typesbegin of t_buttons,
             f01 type rsfunc_txt,
             f02 type rsfunc_txt,
             f03 type rsfunc_txt,
             f04 type rsfunc_txt,
             f05 type rsfunc_txt,
             f06 type rsfunc_txt,
             f07 type rsfunc_txt,
             f08 type rsfunc_txt,
             f09 type rsfunc_txt,
             f10 type rsfunc_txt,
             f11 type rsfunc_txt,
             f12 type rsfunc_txt,
             f13 type rsfunc_txt,
             f14 type rsfunc_txt,
             f15 type rsfunc_txt,
             f16 type rsfunc_txt,
             f17 type rsfunc_txt,
             f18 type rsfunc_txt,
             f19 type rsfunc_txt,
             f20 type rsfunc_txt,
             f21 type rsfunc_txt,
             f22 type rsfunc_txt,
             f23 type rsfunc_txt,
             f24 type rsfunc_txt,
             f25 type rsfunc_txt,
             f26 type rsfunc_txt,
             f27 type rsfunc_txt,
             f28 type rsfunc_txt,
             f29 type rsfunc_txt,
             f30 type rsfunc_txt,
             f31 type rsfunc_txt,
             f32 type rsfunc_txt,
             f33 type rsfunc_txt,
             f34 type rsfunc_txt,
             f35 type rsfunc_txt,
           end of t_buttons.
    typesbegin of t_allowed_but,
             function type sy-ucomm,
           end of t_allowed_but.
    typestt_excluded_but type standard table of sy-ucomm.
    typestt_allowed_but type standard table of t_allowed_but.

    constantsb_save          type sy-ucomm value 'SAVE',
               b_back           type sy-ucomm value 'BACK',
               b_up            type sy-ucomm value 'UP',
               b_exit          type sy-ucomm value 'EXIT',
               b_print         type sy-ucomm value 'PRINT',
               b_find          type sy-ucomm value 'FIND',
               b_find_next     type sy-ucomm value 'FINDNEXT',
               b_first_page    type sy-ucomm value 'PGHOME',
               b_last_page     type sy-ucomm value 'PGEND',
               b_previous_page type sy-ucomm value 'PGUP',
               b_next_page     type sy-ucomm value 'PGDOWN',
               b_01            type sy-ucomm value 'F01',
               b_02            type sy-ucomm value 'F02',
               b_03            type sy-ucomm value 'F03',
               b_04            type sy-ucomm value 'F04',
               b_05            type sy-ucomm value 'F05',
               b_06            type sy-ucomm value 'F06',
               b_07            type sy-ucomm value 'F07',
               b_08            type sy-ucomm value 'F08',
               b_09            type sy-ucomm value 'F09',
               b_10            type sy-ucomm value 'F10',
               b_11            type sy-ucomm value 'F11',
               b_12            type sy-ucomm value 'F12',
               b_13            type sy-ucomm value 'F13',
               b_14            type sy-ucomm value 'F14',
               b_15            type sy-ucomm value 'F15',
               b_16            type sy-ucomm value 'F16',
               b_17            type sy-ucomm value 'F17',
               b_18            type sy-ucomm value 'F18',
               b_19            type sy-ucomm value 'F19',
               b_20            type sy-ucomm value 'F20',
               b_21            type sy-ucomm value 'F21',
               b_22            type sy-ucomm value 'F22',
               b_23            type sy-ucomm value 'F23',
               b_24            type sy-ucomm value 'F24',
               b_25            type sy-ucomm value 'F25',
               b_26            type sy-ucomm value 'F26',
               b_27            type sy-ucomm value 'F27',
               b_28            type sy-ucomm value 'F28',
               b_29            type sy-ucomm value 'F29',
               b_30            type sy-ucomm value 'F30',
               b_31            type sy-ucomm value 'F31',
               b_32            type sy-ucomm value 'F32',
               b_33            type sy-ucomm value 'F33',
               b_34            type sy-ucomm value 'F34',
               b_35            type sy-ucomm value 'F35',
               program_name    type progname value 'ZAB_DYNAMIC_GUI_STATUS'.

    class-dataallowed_buttons type tt_allowed_but.
    class-databuttons type t_buttons.
    class-dataexcluded_buttons type tt_excluded_but.
    class-methodsadd_button importing  value(iv_button)  type sy-ucomm
                                         value(iv_text)    type smp_dyntxt-text optional
                                         value(iv_icon)    type smp_dyntxt-icon_id optional
                                         value(iv_qinfo)   type smp_dyntxt-quickinfo optional
                                         value(iv_allowedtype abap_bool default abap_true
    class-methodshide_button importing value(iv_buttontype sy-ucomm.
    class-methodsshow_button importing value(iv_buttontype sy-ucomm.
    class-methodsget_toolbar exporting e_toolbar type t_buttons.
    class-methodsadd_separator importing  value(iv_button)  type sy-ucomm.
    class-methodsshow_title  importing value(iv_text1type string
                                         value(iv_text2type string optional
                                         value(iv_text3type string optional
                                         value(iv_text4type string optional
                                         value(iv_text5type string optional.
  protected section.
  private section.


class zca_ab_dynamic_gui implementation.
  method add_button.
    data button type smp_dyntxt.
    check iv_button is not initial.

    if iv_text is initial and iv_icon is initial.
      raise icon_and_text_empty.

    button-icon_id iv_icon.
    button-icon_text iv_text.
    button-text      iv_text.
    button-quickinfo iv_qinfo.

    assign component iv_button of structure buttons to field-symbol(<bt>).
    if <bt> is assigned.
      if <bt> is initial.
        <bt> button.
        if iv_allowed eq abap_true.
          show_buttoniv_button iv_button ).
        raise button_already_filled.
      raise button_does_not_exists.

  method add_separator.
        iv_button              iv_button
        iv_text                |{ cl_abap_char_utilities=>minchar }|
*        iv_icon                = iv_icon
*        iv_qinfo               = iv_qinfo
         iv_allowed             abap_true
        button_already_filled  1
        button_does_not_exists 2
        icon_and_text_empty    3
        others                 4
    if sy-subrc <> 0.
*     message id sy-msgid type sy-msgty number sy-msgno
*                with sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.

  method class_constructor.
    excluded_buttons value #b_01 b_02 b_03 b_04 b_05 b_06 b_07 b_08 b_09 )
                                b_10 b_11 b_12 b_13 b_14 b_15 b_16 b_17 b_18 b_19 )
                                b_20 b_21 b_22 b_23 b_24 b_25 b_26 b_27 b_28 b_29 )
                                b_30 b_31 b_32 b_33 b_34 b_35 )
                                b_save b_find b_find_next b_first_page b_last_page b_next_page b_previous_page b_print ).

  method get_toolbar.
    e_toolbar buttons.

  method hide_button.
    check iv_button is not initial.
    if line_existsallowed_buttons[ function iv_button ] ).
      delete allowed_buttons where function iv_button.
      append iv_button to excluded_buttons.

  method show_button.
    check iv_button is not initial.
    if not line_existsallowed_buttons[ function iv_button ] ).
      data(allowedvalue t_allowed_butfunction iv_button ).
      append allowed to allowed_buttons.
      delete excluded_buttons where table_line eq iv_button.

  method show_gui_status.
    set pf-status 'DYNAMIC_STATUS' excluding excluded_buttons[] of program program_name.

  method show_title.
    set titlebar 'DYNAMIC_TITLE' of program program_name with iv_text1 iv_text2 iv_text3 iv_text4 iv_text5.

Once the class is created in dictionary, you can now easily use it in any program to create dynamic STATUS and TITLE. All you need to do is to call in PBO of the screen methods show_gui_status and show_title. To add new button you have to use methods add_button and pass text or icon or both. As I used every possible item to put function code in the GUI STATUS then if you need separator then you can use method add_separator and pass it's place. This method will add in fact a button without any text or description which will just looks like separator.  
If you want to allow disabled function keys you have to use method show_button and pass it's name to it.
Example of use ( create screen 0100 which calls PBO and PAI modules ):

report zab_dynamic_gui_demo.

dataok_code type sy-ucomm.


"! Add button at position 01
      iv_button              zca_ab_dynamic_gui=>b_01
      iv_text                |Test|
      iv_icon                icon_delete
      iv_qinfo               |Delete|
      iv_allowed             abap_true
      button_already_filled  1
      button_does_not_exists 2
      icon_and_text_empty    3
      others                 4
  if sy-subrc <> 0endif.

"! Add separator ( empty button )  position 02
  zca_ab_dynamic_gui=>add_separatoriv_button zca_ab_dynamic_gui=>b_02 ).

"! Add button at position 03
      iv_button              zca_ab_dynamic_gui=>b_03
      iv_text                |Test 2|
      iv_icon                icon_delete
*      iv_qinfo               = 'Delete'
      iv_allowed             abap_true
      button_already_filled  1
      button_does_not_exists 2
      icon_and_text_empty    3
      others                 4
  if sy-subrc <> 0endif.

"! Acitvate print button ( in default only BACK, UP , EXIT are active )
  zca_ab_dynamic_gui=>show_buttoniv_button zca_ab_dynamic_gui=>b_print ).

  call screen 0100.

module pbo_0100 output.
    zca_ab_dynamic_gui=>show_titleiv_text1 | Test Title | ).

module pai_0100 input.
  case ok_code.
    when zca_ab_dynamic_gui=>b_up or zca_ab_dynamic_gui=>b_back or zca_ab_dynamic_gui=>b_exit.
      leave program.
    when zca_ab_dynamic_gui=>b_01.
      "! Do some action here
    when zca_ab_dynamic_gui=>b_03.
      "! Do some action here

The output of this program is as follows.
Isn't this easy?