Code listing for ZSAPTALKF01(include)

The below code is part of the SAPTAlk Instant messaging program for SAP.


*INCLUDE ZSAPTALKF01
*&-------------------------------------------------------------*
*&  Include           ZSAPTALKF01                              *
*&-------------------------------------------------------------*
*&-------------------------------------------------------------*
*&      Form  CREATE_ALVTREE_CONTAINER
*&-------------------------------------------------------------*
*       Create container for alv-tree
*----------------------------------------------------------------------*
FORM create_alvtree_container.
  gd_tree_container_name = 'CC_USERLIST'.
  create object gd_custom_container
      exporting
            container_name = gd_tree_container_name
      exceptions
            cntl_error                  = 1
            cntl_system_error           = 2
            create_error                = 3
            lifetime_error              = 4
            lifetime_dynpro_dynpro_link = 5.
  if sy-subrc <> 0.
    message x208(00) with 'ERROR'.
  endif.
ENDFORM.                    "create_alvtree_container
*&---------------------------------------------------------------------*
*&      Form  CREATE_OBJECT_IN_CONTAINER
*&---------------------------------------------------------------------*
*       Create ALVtree control
*----------------------------------------------------------------------*
FORM create_object_in_container.
  create object gd_userlist
    exporting
        parent              = gd_custom_container
        node_selection_mode = cl_gui_column_tree=>node_sel_mode_single
        item_selection      = 'X'
        no_html_header      = ''
        no_toolbar          = ''
    exceptions
        cntl_error                   = 1
        cntl_system_error            = 2
        create_error                 = 3
        lifetime_error               = 4
        illegal_node_selection_mode  = 5
        failed                       = 6
        illegal_column_name          = 7.
  if sy-subrc <> 0.
    message x208(00) with 'ERROR'.
  endif.
ENDFORM.                    "create_object_in_container
*&---------------------------------------------------------------------*
*&      Form  CREATE_EMPTY_ALVTREE_CONTROL
*&---------------------------------------------------------------------*
*       Create empty tree control
*----------------------------------------------------------------------*
FORM create_empty_alvtree_control.
* Create emty tree-control
  CLEAR: it_emptytab.
  REFRESH: it_emptytab.
  CALL METHOD gd_userlist->set_table_for_first_display
     EXPORTING
               is_hierarchy_header  = gd_hierarchy_header
               it_list_commentary   = gd_report_title
               i_logo               = gd_logo
*               i_background_id      = 'ALV_BACKGROUND'
               i_save               = 'A'
               is_variant            = gd_variant
     CHANGING
               it_outtab            =  it_emptytab      "Must be empty
               it_fieldcatalog      =  gd_fieldcat.
ENDFORM.                    " CREATE_EMPTY_ALVTREE_CONTROL
*&---------------------------------------------------------------------*
*&      Form  BUILD_FIELDCATALOG
*&---------------------------------------------------------------------*
*       Build Fieldcatalog for ALV Report
*----------------------------------------------------------------------*
FORM build_fieldcatalog.
* Please not there are a number of differences between the structure of
* ALVtree fieldcatalogs and ALVgrid fieldcatalogs.
* For example the field seltext_m is replace by scrtext_m in ALVtree.
  fieldcatalog-fieldname   = 'BNAME'.           "Field name in itab
  fieldcatalog-scrtext_m   = 'User ID'.  "Column text
  fieldcatalog-COLTEXT     = 'User ID'.  "Column Text
  fieldcatalog-col_pos     = 0.                 "Column position
  fieldcatalog-outputlen   = 30.                "Column width
  fieldcatalog-emphasize   = 'X'.               "Emphasize  (X or SPACE)
  fieldcatalog-key         = 'X'.               "Key Field? (X or SPACE)
*  fieldcatalog-do_sum      = 'X'.              "Sum Column?
*  fieldcatalog-no_zero     = 'X'.              "Don't display if zero
  APPEND fieldcatalog TO gd_fieldcat.
  CLEAR  fieldcatalog.
*  fieldcatalog-fieldname   = 'DISNAME'.           "Field name in itab
*  fieldcatalog-scrtext_m   = 'Name'.            "Column text
*  fieldcatalog-COLTEXT     = 'Name'.            "Column Text
*  fieldcatalog-col_pos     = 0.                 "Column position
*  fieldcatalog-outputlen   = 12.                "Column width
*  fieldcatalog-emphasize   = 'X'.             "Emphasize  (X or SPACE)
*  fieldcatalog-key         = 'X'.             "Key Field? (X or SPACE)
**  fieldcatalog-do_sum      = 'X'.              "Sum Column?
**  fieldcatalog-no_zero     = 'X'.              "Don't display if zero
*  APPEND fieldcatalog TO gd_fieldcat.
*  CLEAR  fieldcatalog.
ENDFORM.                    " BUILD_FIELDCATALOG
*&---------------------------------------------------------------------*
*&      Form  BUILD_LAYOUT
*&---------------------------------------------------------------------*
*       Build layout for ALV grid report
*----------------------------------------------------------------------*
FORM build_layout.
  gd_layout-no_input          = 'X'.
  gd_layout-colwidth_optimize = 'X'.
  gd_layout-totals_text       = 'Totals'(201).
*  gd_layout-totals_only        = 'X'.
*  gd_layout-f2code            = 'DISP'.  "Sets fcode for when double
*                                         "click(press f2)
*  gd_layout-zebra             = 'X'.
*  gd_layout-group_change_edit = 'X'.
*  gd_layout-header_text       = 'helllllo'.
ENDFORM.                    " BUILD_LAYOUT
*&---------------------------------------------------------------------*
*&      Form  build_hierarchy_header
*&---------------------------------------------------------------------*
*       build hierarchy-header-information
*----------------------------------------------------------------------*
*      -->P_L_HIERARCHY_HEADER  structure for hierarchy-header
*----------------------------------------------------------------------*
FORM build_hierarchy_header CHANGING
                               p_hierarchy_header TYPE treev_hhdr.
  p_hierarchy_header-heading = 'User List'(013).
  p_hierarchy_header-tooltip = 'User list'(014).
  p_hierarchy_header-width = 30.
  p_hierarchy_header-width_pix = ''.
ENDFORM.                               " build_hierarchy_header
*&---------------------------------------------------------------------*
*&      Form  BUILD_REPORT_TITLE
*&---------------------------------------------------------------------*
*       Build table for ALVtree header
*----------------------------------------------------------------------*
*  <->  p1        Header details
*  <->  p2        Logo value
*----------------------------------------------------------------------*
FORM build_report_title CHANGING
      pt_report_title  TYPE slis_t_listheader
      pa_logo             TYPE sdydo_value.
  DATA: ls_line TYPE slis_listheader,
        ld_date(10) TYPE c.
* List Heading Line(TYPE H)
  CLEAR ls_line.
  ls_line-typ  = 'H'.
* ls_line-key     "Not Used For This Type(H)
  ls_line-info = 'User Message Service'.
  APPEND ls_line TO pt_report_title.
* Users name (Status Line- TYPE S)
  ls_line-typ  = 'S'.
  ls_line-key  = 'Name '.
  ls_line-info = gd_myname.
  APPEND ls_line TO pt_report_title.
* Status Line(TYPE S)
  ld_date(2) = sy-datum+6(2).
  ld_date+2(1) = '/'.
  ld_date+3(2) = sy-datum+4(2).
  ld_date+5(1) = '/'.
  ld_date+6(4) = sy-datum(4).
  ls_line-typ  = 'S'.
  ls_line-key  = 'Date'.
  ls_line-info = ld_date.
  APPEND ls_line TO pt_report_title.
** Action Line(TYPE A)
*  CLEAR ls_line.
*  ls_line-typ  = 'A'.
*  CONCATENATE 'Report: ' sy-repid INTO ls_line-info  SEPARATED BY space
  .
*  APPEND ls_line TO pt_report_title.
ENDFORM.                    "build_report_title
*&---------------------------------------------------------------------*
*&      Form  BUILD_VARIANT
*&---------------------------------------------------------------------*
*       Build variant
*----------------------------------------------------------------------*
form build_variant.
* Set repid for storing variants
  gd_variant-report = sy-repid.
endform.                    " BUILD_VARIANT
*&---------------------------------------------------------------------*
*&      Form  CREATE_ALVTREE_HIERARCHY
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*       Builds ALV tree display, (inserts nodes, subnodes etc)
*----------------------------------------------------------------------*
form create_alvtree_hierarchy.
  data: ls_sflight type sflight,
        lt_sflight type sflight occurs 0.
  data: ld_ebeln_key type lvc_nkey,
        ld_ebelp_key type lvc_nkey.
*  clear: wa_usrtab.
*  wa_usrtab-disname = 'Contacts'.
*  perform add_user_node using      wa_usrtab
*                                   ''
*                          changing ld_ebeln_key.
  If p_friend EQ ' '.
    loop at it_messfriends into wa_messfriends
                        where friend ne sy-uname.
      perform add_user_line using      wa_messfriends
                                       ld_ebeln_key
                              changing ld_ebelp_key.
    endloop.
  ELSE.
    loop at it_usrtab into wa_usrtab
                      where bname ne sy-uname.
      perform add_user_line using      wa_usrtab
                                       ld_ebeln_key
                              changing ld_ebelp_key.
    endloop.
  endif.
* calculate totals
  call method gd_userlist->update_calculations.
* this method must be called to send the data to the frontend
  call method gd_userlist->frontend_update.
endform.                    " CREATE_ALVTREE_HIERARCHY
*&---------------------------------------------------------------------*
*&      Form  ADD_EKKO_NODE
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_WA_EKPO  text
*      -->P_0553   text
*      <--P_EBELN_KEY  text
*----------------------------------------------------------------------*
form add_user_node using    ps_usrtab like wa_usrtab
                            value(p_relate_key)
                   changing p_node_key.
  data: ld_node_text type lvc_value,
        ls_sflight type sflight.
* Set item-layout
  data: lt_item_layout type lvc_t_layi,
        ls_item_layout type lvc_s_layi.
  if not ps_usrtab-disname is initial.
    ld_node_text             = ps_usrtab-disname.
  else.
    ld_node_text             = ps_usrtab-bname.
  endif.
  ls_item_layout-t_image   = '@3P@'.                        "'@3Y@'.
*  ls_item_layout-fieldname = gd_userlist->c_hierarchy_column_name.
*  if ld_node_text EQ gd_talkingto.
*    ls_item_layout-style =
*                    cl_gui_column_tree=>STYLE_EMPHASIZED_POSITIVE.
*  else.
  ls_item_layout-style = cl_gui_column_tree=>STYLE_DEFAULT.
*  endif.
  append ls_item_layout to lt_item_layout.
* Add node
  call method gd_userlist->add_node
    EXPORTING
      i_relat_node_key = p_relate_key
      i_relationship   = cl_gui_column_tree=>relat_last_child
      i_node_text      = ld_node_text
      is_outtab_line   = ps_usrtab
      it_item_layout   = lt_item_layout
    IMPORTING
      e_new_node_key   = p_node_key.
endform.                    " ADD_USER_NODE
*---------------------------------------------------------------------*
*       FORM WHEN_FINISHED                                            *
*---------------------------------------------------------------------*
*       ........                                                      *
*---------------------------------------------------------------------*
*  -->  TASKNAME                                                      *
*---------------------------------------------------------------------*
form when_finished using taskname.
  receive results from function 'Z_ENQUE_SLEEP'.
  g_ref_from_timer = 'X'.
* Trigger an event to run the at user-command
  set user-command 'FCT_R'.
  ok_code = 'FCT_R'.
  save_ok =  'FCT_R'.
  sy-ucomm = 'FCT_R'.
  GET PARAMETER ID 'ZMESSAGE' field gd_stoprfc.
  check gd_stoprfc is initial.
  leave to screen 0.
* perform update_conversation using gd_talkingto.
endform.                    " WHEN_FINISHED
**&---------------------------------------------------------------------
*
**&      Form  ADD_EKPO_LINE
**&---------------------------------------------------------------------
*
**       text
**----------------------------------------------------------------------
*
**      -->P_WA_EKPO  text
**      -->P_LD_EBELN_KEY  text
**      <--P_LD_EBELP_KEY  text
**----------------------------------------------------------------------
*
form add_user_line using    ps_usrtab like wa_usrtab
                            value(p_relate_key)
                   changing p_node_key.
  data: ld_node_text type lvc_value,
        ls_sflight type sflight.
* Set item-layout
  data: lt_item_layout type lvc_t_layi,
        ls_item_layout type lvc_s_layi.
* Check if user has unread messages for contact
  read table it_messtab into wa_messtab
                          with key fromuser = ps_usrtab-bname.
* If so display envolope icon next to contacts name
  if sy-subrc eq 0.
    ls_item_layout-t_image   = '@E2@'.
  endif.
  ls_item_layout-fieldname = gd_userlist->c_hierarchy_column_name.
  ls_item_layout-style     = cl_gui_column_tree=>style_default.
* Define display text for node
  if not ps_usrtab-disname is initial.
    ld_node_text             = ps_usrtab-disname.
  else.
    ld_node_text             = ps_usrtab-bname.
  endif.
* Displaying friends list
  if p_friend EQ ' '.
*   Check if friend is online
    read table it_usrtab into wa_usrtab
                            with key bname = ps_usrtab-bname.
    if sy-subrc NE 0.
      ls_item_layout-style     = cl_gui_column_tree=>STYLE_INACTIVE.
      concatenate ld_node_text '(offline)' into ld_node_text.
    endif.
  endif.
* Append node/item layout settings the layout table
  append ls_item_layout to lt_item_layout.
* Add node to ALV tree
  call method gd_userlist->add_node
    EXPORTING
      i_relat_node_key = p_relate_key
      i_relationship   = cl_gui_column_tree=>relat_last_child
      i_node_text      = ld_node_text
      is_outtab_line   = ps_usrtab
      it_item_layout   = lt_item_layout
    IMPORTING
      e_new_node_key   = p_node_key.
endform.                    " ADD_EKPO_LINE
*&---------------------------------------------------------------------*
*&      Form  register_events
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM register_events .
*&---------------------------------------------------------------------*
*&      REGISTER_EVENTS
*&---------------------------------------------------------------------*
* define the events which will be passed to the backend
  data: lt_events type cntl_simple_events,
        l_event type cntl_simple_event.
* define the events which will be passed to the backend
  l_event-eventid = cl_gui_column_tree=>eventid_expand_no_children.
  append l_event to lt_events.
  l_event-eventid = cl_gui_column_tree=>eventid_checkbox_change.
  append l_event to lt_events.
  l_event-eventid = cl_gui_column_tree=>eventid_header_context_men_req.
  append l_event to lt_events.
  l_event-eventid = cl_gui_column_tree=>eventid_node_context_menu_req.
  append l_event to lt_events.
  l_event-eventid = cl_gui_column_tree=>eventid_item_context_menu_req.
  append l_event to lt_events.
  l_event-eventid = cl_gui_column_tree=>EVENTID_LINK_CLICK.
  append l_event to lt_events.
  l_event-eventid = cl_gui_column_tree=>eventid_item_double_click.
  append l_event to lt_events.
  l_event-eventid = cl_gui_column_tree=>eventid_header_click.
  append l_event to lt_events.
  l_event-eventid = cl_gui_column_tree=>eventid_item_keypress.
  append l_event to lt_events.
  call method gd_userlist->set_registered_events
    EXPORTING
      events                    = lt_events
    EXCEPTIONS
      cntl_error                = 1
      cntl_system_error         = 2
      illegal_event_combination = 3.
  if sy-subrc <> 0.
    message x208(00) with 'ERROR'.                          "#EC NOTEXT
  endif.
* set Handler
  data: l_event_receiver type ref to lcl_tree_event_receiver.
  create object l_event_receiver.
  set handler l_event_receiver->handle_node_ctmenu_request
                                                        for gd_userlist.
  set handler l_event_receiver->handle_node_ctmenu_selected
                                                        for gd_userlist.
  set handler l_event_receiver->handle_item_ctmenu_request
                                                        for gd_userlist.
  set handler l_event_receiver->handle_item_ctmenu_selected
                                                        for gd_userlist.
  set handler l_event_receiver->handle_item_double_click
                                                        for gd_userlist.
  set handler l_event_receiver->handle_link_click
                                                        for gd_userlist.
  set handler l_event_receiver->handle_header_click
                                                        for gd_userlist.
  set handler l_event_receiver->handle_item_keypress
                                                        for gd_userlist.
ENDFORM.                    " register_events
*&---------------------------------------------------------------------*
*&      Form  get_all_users_online
*&---------------------------------------------------------------------*
*       Get all user currently online
*----------------------------------------------------------------------*
FORM get_all_users_online  TABLES   P_USR_TAB STRUCTURE it_USRTAB.
  refresh: it_usrtab, it_allusers.
  clear: it_usrtab, it_allusers.
  call 'ThUsrInfo' id 'OPCODE' field OPCODE_LIST
    id 'TAB' field it_allusers-*sys*.
  wa_allusers-bname = sy-uname.
  append wa_allusers to it_allusers.
  sort it_allusers by bname.
  delete adjacent duplicates from it_allusers comparing bname.
  loop at it_allusers into wa_allusers.
    move-corresponding wa_allusers to wa_usrtab.
    select single disname
      from zmessoptions
      into wa_usrtab-disname
     where uname eq wa_allusers-bname.
    append wa_usrtab to it_usrtab.
    clear: wa_usrtab.
  endloop.
ENDFORM.                    " get_all_users_online
*&---------------------------------------------------------------------*
*&      Form  update_conversation
*&---------------------------------------------------------------------*
*       Update conversation for selected contact
*----------------------------------------------------------------------*
FORM update_conversation  USING    P_TALKINGTO like sy-uname
                                   p_task type c.
  data: ld_node type LVC_NKEY.
  data: ld_disname type ZMESSOPTIONS-disname.
  data: ld_talkdisname type ZMESSOPTIONS-disname,
        ld_subrc type sy-subrc,
        ld_disurl(200) type c.
*  if sy-xcode eq 'FCT_R'.
*    break-point.
*  endif.
  if p_task EQ 'S'.  "Stop
    gd_stoprfc = 1.
    SET PARAMETER ID 'ZMESSAGE' field gd_stoprfc.
  endif.
  if p_task EQ 'X' or p_task EQ 'U'.
*   refresh User List
    CALL METHOD gd_userlist->delete_all_nodes.
*   get active messages
    perform retrieve_unread_messages.
*   create ALVtree Hierarchy
    PERFORM create_alvtree_hierarchy.
*****    CALL METHOD cl_gui_cfw=>flush.
*    CALL METHOD gd_userlist->get_top_node
*      IMPORTING
*        e_node_key = ld_node.
*    CALL METHOD gd_userlist->EXPAND_NODE
*      EXPORTING
*        I_NODE_KEY = ld_node.
  endif.
  GET PARAMETER ID 'ZMESSAGE' field gd_stoprfc.
  if p_task EQ 'X' and gd_stoprfc is initial .
    gd_task = gd_task + 1.
***    free memory.
***    SET UPDATE TASK LOCAL.
**********************
*Version 2, change
**   Execute program asyncronously while still continuing following code
*    call function 'Z_ENQUE_SLEEP'
*       starting new task gd_task  " 'WAIT'
*       performing when_finished on end of task
*       EXCEPTIONS
*         COMMUNICATION_FAILURE = 1
*         SYSTEM_FAILURE        = 2
*         RESOURCE_FAILURE      = 3.
IF ti_container IS INITIAL.
CREATE OBJECT ti_container
EXPORTING container_name = 'TI_CONTAINER'.
CREATE OBJECT timer EXPORTING parent = ti_container.
SET HANDLER event_handler->on_finished FOR timer.
* 4) and start your timer
timer->interval = timeout.
CALL METHOD timer->run.
ENDIF.
    if sy-subrc ne 0.
      break-point.
    endif.
  endif.
  IF gv_html_help_container IS INITIAL.
    CREATE OBJECT gv_html_help_container
        EXPORTING
            container_name = 'CC_CONVERSATION'
        EXCEPTIONS
            others = 1.
    CASE sy-subrc.
      WHEN '0'.
*       everything is fine here.
      WHEN OTHERS.
        RAISE cntl_error.
    ENDCASE.
  ENDIF.
  IF gv_html_help IS INITIAL.
    CREATE OBJECT gv_html_help
         EXPORTING
              parent    = gv_html_help_container.
    IF sy-subrc NE 0.
      RAISE cntl_error.
    ENDIF.
  ENDIF.
*    Registering for the events.
  wa_events-eventid = gv_html_help->m_id_sapevent.
  wa_events-appl_event = 'X'.
  APPEND wa_events TO events.
*    CALL METHOD gv_html_help->set_registered_events
*      EXPORTING
*        events = events.
*    doc_url = 'C:/TEMP/TEST.TXT'.
  if not gd_talkingto is initial.
* Retrieve users display name if one is setup
    perform get_name_for_display changing ld_disname ld_talkdisname.
* Build html document for conversation window
    perform populate_message_file using ld_disname ld_talkdisname
                               changing ld_subrc.
* Check new file has been created.
    ld_disurl = gd_openurl.
    CALL METHOD gv_html_help->show_data
      EXPORTING
        url        = ld_disurl "doc_url
      EXCEPTIONS
        cntl_error = 1.
    IF sy-subrc = 1.
      RAISE cntl_error.
    ENDIF.
  endif.
* updates display box which shows user who they are talking too
  perform update_whos_in_conversation using ld_talkdisname.
*  call method cl_gui_cfw=>flush.
ENDFORM.                    " update_conversation
*&---------------------------------------------------------------------*
*&      Form  populate_message_file
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM populate_message_file using p_disname p_talkdisname
                        changing p_subrc.
  data: ld_newmess type c.
  DATA: e_file TYPE  STRING.
  clear: p_subrc, it_datatab, ld_newmess.
  refresh it_datatab.
* Retrieve messages from current user
  perform get_messages_from_user tables it_messtab.
* Generate HTML document
  it_datatab-row = '<html>'.
  append it_datatab.
  it_datatab-row = '<head></head>'.
  append it_datatab.
  it_datatab-row = '<body bgcolor="#FFFFFF">'.
  append it_datatab.
  loop at it_messtab into wa_messtab.
    if sy-uname eq wa_messtab-touser.
      wa_messtab-torecieved = 'X'.
    elseif sy-uname eq wa_messtab-fromuser.
      wa_messtab-fromrecieved = 'X'.
    endif.
    if wa_messtab-fromuser EQ sy-uname.
      concatenate
        '<font color="#999999" size ="1" face="Times New Roman">'
        p_disname
        ':</font> <font size ="2" face="Times New Roman">'
        wa_messtab-message
        '</font><br>'
             into it_datatab-row.
    else.
      concatenate
       '<font color="#999999" size ="1" face="Times New Roman">'
       p_talkdisname
       ':</font> <font size ="2" face="Times New Roman">'
       wa_messtab-message
       '</font><br>'
             into it_datatab-row.
    endif.
*    it_datatab-row = wa_messtab-message.
    append it_datatab.
    modify zmesstab from wa_messtab.
  endloop.
  if sy-subrc eq 0.
    ld_newmess = 'X'.
    it_datatab-row = '</body>'.
    append it_datatab.
    it_datatab-row = '</html>'.
    append it_datatab.
  endif.
  read table it_messtalk into wa_messtalk
                               with key uname = gd_talkingto.
  if sy-subrc ne 0 or ld_newmess eq 'X'.
    perform download_conversation_file  using gd_openurl 'X'
                                   changing p_subrc.
  endif.
ENDFORM.                    " populate_message_file
*&---------------------------------------------------------------------*
*&      Form  populate_table
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_GD_TALKINGTO  text
*      -->P_SY_UNAME  text
*      -->P_SC_MESSAGE1  text
*----------------------------------------------------------------------*
FORM populate_table  USING    P_touser
                              P_fromuser
                              P_MESSAGE.
*  select messnum
*   up to 1 rows
*    from zmesstab
*    into wa_messtab-messnum
*   where touser eq p_touser and
*         fromuser eq p_fromuser
*   order by messnum DESCENDING.
*  endselect.
  select messnum
   up to 1 rows
    from zmesstab
    into wa_messtab-messnum
   where ( touser eq p_touser and
           fromuser eq p_fromuser ) or
         ( touser eq p_fromuser and
           fromuser eq p_touser )
   order by messnum DESCENDING.
  endselect.
  if sy-subrc eq 0.
    wa_messtab-messnum  = wa_messtab-messnum + 1.
  else.
    wa_messtab-messnum  = 1.
  endif.
  clear: wa_messtab-torecieved, wa_messtab-fromrecieved.
  wa_messtab-touser   =   P_touser.
  wa_messtab-fromuser =   p_fromuser.
  wa_messtab-message  =   p_message.
  insert zmesstab from wa_messtab.
*  commit work.
ENDFORM.                    " populate_table
*&---------------------------------------------------------------------*
*&      Form  get_who_user_is_talking_too
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM get_who_user_is_talking_too .
  data: ld_filepath like gd_filepath.
  clear: ld_filepath, gd_ucomm.
  select single talkingto filepath DISNAME ucomm
    from zmessoptions
    into (gd_talkingto,ld_filepath,gd_myname,gd_ucomm)
   where uname eq sy-uname.
  if not ld_filepath is initial.
    gd_filepath = ld_filepath.
  endif.
  if gd_myname is initial.
    gd_myname = sy-uname.
  endif.
  if not gd_ucomm is initial.
    update zmessoptions set ucomm = ' '
                  where uname eq sy-uname.
  endif.
* Setup file path/name to store conversation files
  perform setup_global_filenames.
  concatenate doc_url gd_talkingto '.HTM' into gd_openurl.
ENDFORM.                    " get_who_user_is_talking_too
*&---------------------------------------------------------------------*
*&      Form  initialise_conversation
*&---------------------------------------------------------------------*
*       Sets up conversation with new contact
*----------------------------------------------------------------------*
FORM initialise_conversation .
* Processing for when user double clicks on ALVtree
  DATA: ls_sflight           TYPE sflight.
  DATA: lt_selected_node     TYPE lvc_nkey,
        lt_fieldname         TYPE lvc_fname.
  DATA: l_selected_node      TYPE lvc_nkey,
        lt_outtab_line(100)  TYPE c,
        lt_node_text         TYPE lvc_value,
        ld_file type string,
        ld_subrc type sy-subrc.
*        DATA: lt_selected_node TYPE lvc_t_nkey.
*    call method gd_userlist->select_nodes
*      exporting
*          node_key_table = lt_selected_node. "lt_sel_nodes.
  clear: ld_subrc.
*   Retrieve selected Node ID
  CALL METHOD gd_userlist->get_selected_item
    IMPORTING
      e_selected_node = lt_selected_node
      e_fieldname     = lt_fieldname.
*   Retrieve Selected Node + Row contents
  CALL METHOD gd_userlist->get_outtab_line
    EXPORTING
      i_node_key     = lt_selected_node
    IMPORTING
      e_outtab_line  = lt_outtab_line
      e_node_text    = lt_node_text
    EXCEPTIONS
      NODE_NOT_FOUND = 1.
  check sy-subrc eq 0.
  gd_talkingto = lt_outtab_line+0(8).
  SC_TALKINGTO = gd_talkingto.
* create blank file
  concatenate doc_url gd_talkingto '.HTM' into gd_openurl.
  refresh it_datatab.
**  read table it_messtalk into wa_messtalk
**                               with key uname = gd_talkingto.
**  if sy-subrc ne 0.
**    perform download_conversation_file using gd_openurl ' '
**                                    changing ld_subrc.
**  endif.
  if ld_subrc EQ 0.
    update zmessoptions set talkingto = gd_talkingto
                  where uname eq sy-uname.
    if sy-subrc ne 0.
      wa_messopt-uname = sy-uname.
      wa_messopt-talkingto = gd_talkingto.
      modify zmessoptions from wa_messopt.
    endif.
  else.
    clear: gd_talkingto.
  endif.
ENDFORM.                    " initialise_conversation
*&---------------------------------------------------------------------*
*&      Form  update_whos_in_conversation
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM update_whos_in_conversation using p_disname .
  IF gv_html_who_container IS INITIAL.
    CREATE OBJECT gv_html_who_container
        EXPORTING
            container_name = 'CC_TALKINGTO'
        EXCEPTIONS
            others = 1.
    CASE sy-subrc.
      WHEN '0'.
*       everything is fine here.
      WHEN OTHERS.
        RAISE cntl_error.
    ENDCASE.
  ENDIF.
  IF gv_html_who IS INITIAL.
    CREATE OBJECT gv_html_who
         EXPORTING
              parent    = gv_html_who_container.
    IF sy-subrc NE 0.
      RAISE cntl_error.
    ENDIF.
  ENDIF.
*    Registering for the events.
*  wa_events-eventid = gv_html_who->m_id_sapevent.
*  wa_events-appl_event = 'X'.
*  APPEND wa_events TO events.
*    CALL METHOD gv_html_help->set_registered_events
*      EXPORTING
*        events = events.
*    doc_url = 'C:/TEMP/TEST.TXT'.
* create file to display whos in conversation
  perform populate_talkingto_file using p_disname.
  CALL METHOD gv_html_who->show_data
    EXPORTING
      url        = who_url
    EXCEPTIONS
      cntl_error = 1.
  IF sy-subrc = 1.
    RAISE cntl_error.
  ENDIF.
ENDFORM.                    " update_whos_in_conversation
*&---------------------------------------------------------------------*
*&      Form  populate_talkingto_file
*&---------------------------------------------------------------------*
*       Create file with list of users in conversation
*----------------------------------------------------------------------*
FORM populate_talkingto_file using p_disname.
  DATA: begin of it_datatab occurs 0,
     row(500) type c,
    end of it_datatab.
  DATA: e_file TYPE  STRING.
  concatenate 'Conversation:' p_disname into it_datatab-row
                                               separated by space.
  append it_datatab.
  e_file = who_url.
  call function 'GUI_DOWNLOAD'
    EXPORTING
      filename         = e_file
      filetype         = 'ASC'
    TABLES
      data_tab         = it_datatab[]
    EXCEPTIONS
      file_open_error  = 1
      file_write_error = 2
      others           = 3.
ENDFORM.                    " populate_talkingto_file
*&---------------------------------------------------------------------*
*&      Form  retrieve_unread_messages
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM retrieve_unread_messages .
  refresh: it_messtab.
  select *
    from zmesstab
    into table it_messtab
   where touser   eq sy-uname and
        torecieved  eq ' '.
ENDFORM.                    " retrieve_unread_messages
*&---------------------------------------------------------------------*
*&      Form  add_buttons
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM add_buttons .
*&---------------------------------------------------------------------*
*&      CHANGE_TOOLBAR
*&---------------------------------------------------------------------*
  data: toolbar_event_receiver type ref to lcl_toolbar_event_receiver.
* get toolbar control
  call method gd_userlist->get_toolbar_object
    IMPORTING
      er_toolbar = mr_toolbar.
  check not mr_toolbar is initial.
  call method mr_toolbar->delete_button
    EXPORTING
      fcode = '&CALC'.
  call method mr_toolbar->delete_button
    EXPORTING
      fcode = '&LOAD'.
  call method mr_toolbar->delete_button
    EXPORTING
      fcode = '&EXPAND'.
  call method mr_toolbar->delete_button
    EXPORTING
      fcode = '&COLLAPSE'.
  call method mr_toolbar->delete_button
    EXPORTING
      fcode = '&FIND'.
  call method mr_toolbar->delete_button
    EXPORTING
      fcode = '&PRINT_BACK'.
* add seperator to toolbar
*  CALL METHOD mr_toolbar->add_button
*    EXPORTING
*      fcode     = ''
*      icon      = ''
*      butn_type = cntb_btype_sep
*      text      = ''
*      quickinfo = 'This is a Seperator'.                    "#EC NOTEXT
* add Standard Button to toolbar (for Delete Subtree)
  call method mr_toolbar->add_button
    EXPORTING
      fcode     = 'CONT'
      icon      = '@A0@'
      butn_type = CNTB_BTYPE_DROPDOWN  "cntb_btype_button
      text      = ''
      quickinfo = 'Friends List'.                           "#EC NOTEXT
** add seperator to toolbar
*  call method mr_toolbar->add_button
*          exporting
*              fcode     = ''
*              icon      = ''
*              butn_type = cntb_btype_sep
*              text      = ''
*              quickinfo = 'This is a Seperator'.         "#EC NOTEXT
*
** add Standard Button to toolbar (for Delete Subtree)
*  call method mr_toolbar->add_button
*          exporting
*              fcode     = 'DELETE'           "Function code of button
*              icon      = '@18@'             "Icon ID (see )
*              butn_type = cntb_btype_button  "Button type
*              text      = ''                 "Button text
*              quickinfo = 'Delete subtree'.  "Quick info text
*
** add Dropdown Button to toolbar (for Insert Line)
*  call method mr_toolbar->add_button
*          exporting
*              fcode     = 'INSERT_LC'         "Function code of button
*              icon      = '@17@'              "Icon ID (see )
*              butn_type = cntb_btype_dropdown "Button type
*              text      = ''                  "Button text
*              quickinfo = 'Insert Line'.      "Quick info text
* set event-handler for toolbar-control
*  data: toolbar_event_receiver type ref to lcl_toolbar_event_receiver.
  create object toolbar_event_receiver.
  set handler toolbar_event_receiver->on_function_selected
                                                      for mr_toolbar.
  set handler toolbar_event_receiver->on_toolbar_dropdown
                                                      for mr_toolbar.
ENDFORM.                    " add_buttons
*&---------------------------------------------------------------------*
*&      Form  get_friends_list
*&---------------------------------------------------------------------*
FORM get_friends_list .
  refresh: it_messfriends.
  select friend
    from zmessfriends
    into corresponding fields of table it_messfriends
   where uname eq sy-uname.
  wa_messfriends-friend = sy-uname.
  append wa_messfriends to it_messfriends.
  loop at it_messfriends into wa_messfriends.
    select single disname
      from zmessoptions
      into wa_messfriends-disname
     where uname eq wa_messfriends-friend.
    modify it_messfriends from wa_messfriends.
  endloop.
ENDFORM.                    " get_friends_list
*&---------------------------------------------------------------------*
*&      Form  get_name_for_display
*&---------------------------------------------------------------------*
*       Retrieve users display name if one is setup
*----------------------------------------------------------------------*
*      <--P_DISNAME  Name text for display purposes
*----------------------------------------------------------------------*
FORM get_name_for_display  CHANGING P_DISNAME p_talkdisname.
  If p_friend EQ ' '.
    read table it_messfriends
                into wa_messfriends with key FRIEND = gd_talkingto.
    if sy-subrc eq 0 and not wa_messfriends-disname is initial.
      p_talkdisname = wa_messfriends-disname.
    else.
      p_talkdisname = gd_talkingto.
    endif.
    read table it_messfriends
                into wa_messfriends with key FRIEND = sy-uname.
    if sy-subrc eq 0 and not wa_messfriends-disname is initial.
      p_disname = wa_messfriends-disname.
    else.
      p_disname = sy-uname.
    endif.
  ELSE.
    read table it_usrtab
                into wa_usrtab with key BNAME = gd_talkingto.
    if sy-subrc eq 0 and not wa_usrtab-disname is initial.
      p_talkdisname = wa_usrtab-disname.
    else.
      p_talkdisname = gd_talkingto.
    endif.
    read table it_usrtab
                into wa_usrtab with key BNAME = sy-uname.
    if sy-subrc eq 0 and not wa_usrtab-disname is initial.
      p_disname = wa_usrtab-disname.
    else.
      p_disname = sy-uname.
    endif.
  endif.
ENDFORM.                    " get_name_for_display
*&---------------------------------------------------------------------*
*&      Form  get_messages_from_user
*&---------------------------------------------------------------------*
*       * Retrieve messages from current user
*----------------------------------------------------------------------*
*      -->P_IT_MESSTAB  text
*----------------------------------------------------------------------*
FORM get_messages_from_user  TABLES   P_MESSTAB STRUCTURE ZMESSTAB.
  refresh p_messtab.
  select *
    from zmesstab
    into table p_messtab
   where ( touser eq sy-uname and
         fromuser eq gd_talkingto ) or
         ( touser eq gd_talkingto and
         fromuser eq sy-uname ).
  loop at p_messtab into wa_messtab.  " where recieved ne 'X'.
    if wa_messtab-touser eq sy-uname and wa_messtab-torecieved EQ 'X'.
      delete p_messtab.
      if wa_messtab-fromrecieved eq 'X'.
        DELETE zmesstab from wa_messtab.
      endif.
    endif.
    if wa_messtab-fromuser eq sy-uname and
                            wa_messtab-fromrecieved EQ 'X'.
      delete p_messtab.
* removed otherwise two users could try and delete same database entry
*      if wa_messtab-torecieved eq 'X'.
*        DELETE zmesstab from wa_messtab.
*      endif.
    endif.
  endloop.
  if sy-subrc ne 0.
    refresh p_messtab.
  endif.
  sort p_messtab by messnum.
ENDFORM.                    " get_messages_from_user
*&---------------------------------------------------------------------*
*&      Form  display_feedback_html_text
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM display_feedback_html_text .
  data: ld_disurl(200) type c.
  IF gv_html_feedback_container IS INITIAL.
    CREATE OBJECT gv_html_feedback_container
        EXPORTING
            container_name = 'CC_FEEDBACK'
        EXCEPTIONS
            others = 1.
    CASE sy-subrc.
      WHEN '0'.
*       everything is fine here.
      WHEN OTHERS.
        RAISE cntl_error.
    ENDCASE.
  ENDIF.
  IF gv_html_feedback IS INITIAL.
    CREATE OBJECT gv_html_feedback
         EXPORTING
              parent    = gv_html_feedback_container.
    IF sy-subrc NE 0.
      RAISE cntl_error.
    ENDIF.
  ENDIF.
* Build html document for conversation window
  perform populate_feedback_file changing ld_disurl.
  CALL METHOD gv_html_feedback->show_data
    EXPORTING
* use if internet connection is available
       url = 'www.sapdevelopment.co.uk/saptalk/feedback/feedback.htm'
* Use this if no internet connection is available
*      url        =   ld_disurl
    EXCEPTIONS
      cntl_error = 1.
ENDFORM.                    " display_feedback_html_text
*&---------------------------------------------------------------------*
*&      Form  populate_feedback_file
*&---------------------------------------------------------------------*
FORM populate_feedback_file changing p_disurl .
  DATA: begin of it_datatab occurs 0,
    row(500) type c,
   end of it_datatab.
  DATA: e_file TYPE  STRING.
* Generate HTML document
  it_datatab-row = '<html>'.
  append it_datatab.
  it_datatab-row = '<head></head>'.
  append it_datatab.
  it_datatab-row = '<body bgcolor="#FFFFFF">'.
  append it_datatab.
  concatenate '<font size ="2" face="Times New Roman">'
  'Any feedback regarding issues or development suggestions would<br>'
  'be gratefully received.<br><br>'
  'Please send  to'
  ':</font> <font size ="2" face="Times New Roman">'
  '<a HREF="mailto:webmaster@SAP Development">webmaster@SAP Development </a>'
  '<br> Or visit website: '
  '<a Target="MAIN" href="../../?topic=index">www.SAP Development</a>'
  '</font><br>'
        into it_datatab-row separated by space.
  append it_datatab.
  modify zmesstab from wa_messtab.
  it_datatab-row = '</body>'.
  append it_datatab.
  it_datatab-row = '</html>'.
  append it_datatab.
  concatenate gd_filepath 'FEEDBACK.HTM' into p_disurl.
  e_file = p_disurl .
  call function 'GUI_DOWNLOAD'
    EXPORTING
      filename         = e_file
      filetype         = 'ASC'
    TABLES
      data_tab         = it_datatab[]
    EXCEPTIONS
      file_open_error  = 1
      file_write_error = 2
      others           = 3.
ENDFORM.                    " populate_feedback_file
*&---------------------------------------------------------------------*
*&      Form  set_parameter_id
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_0027   text
*      -->P_GD_STOPRFC  text
*----------------------------------------------------------------------*
FORM set_parameter_id  USING    VALUE(P_PID)
                                P_value.
  SET PARAMETER ID p_pid field p_value.
ENDFORM.                    " set_parameter_id
*&---------------------------------------------------------------------*
*&      Form  setup_global_filenames
*&---------------------------------------------------------------------*
FORM setup_global_filenames .
  concatenate  gd_filepath sy-uname into doc_url.
ENDFORM.                    " setup_global_filenames
*&---------------------------------------------------------------------*
*&      Form  download_conversation_file
*&---------------------------------------------------------------------*
FORM download_conversation_file USING P_FILE TYPE  STRING
                                      VALUE(P_APPEND)
                             CHANGING p_subrc.
  DATA: rc TYPE sy-ucomm,
        ld_file type rlgrap-filename.
  if p_append eq 'X' or p_append eq ' ' .
    call function 'GUI_DOWNLOAD'
      EXPORTING
        filename                = p_file
        filetype                = 'ASC'
        append                  = 'X'
      TABLES
        data_tab                = it_datatab[]
      EXCEPTIONS
        FILE_WRITE_ERROR        = 1
        NO_BATCH                = 2
        GUI_REFUSE_FILETRANSFER = 3
        INVALID_TYPE            = 4
        NO_AUTHORITY            = 5
        UNKNOWN_ERROR           = 6
        HEADER_NOT_ALLOWED      = 7
        SEPARATOR_NOT_ALLOWED   = 8
        FILESIZE_NOT_ALLOWED    = 9
        HEADER_TOO_LONG         = 10
        DP_ERROR_CREATE         = 11
        DP_ERROR_SEND           = 12
        DP_ERROR_WRITE          = 13
        UNKNOWN_DP_ERROR        = 14
        ACCESS_DENIED           = 15
        DP_OUT_OF_MEMORY        = 16
        DISK_FULL               = 17
        DP_TIMEOUT              = 18
        FILE_NOT_FOUND          = 19
        DATAPROVIDER_EXCEPTION  = 20
        CONTROL_FLUSH_ERROR     = 21
        OTHERS                  = 22.
    if sy-subrc ne 0.
      ld_file = p_file.
*    CALL FUNCTION 'WS_DOWNLOAD'
*      EXPORTING
**       BIN_FILESIZE                  = ' '
**       CODEPAGE                      = ' '
*        FILENAME                      = ld_file
**       FILETYPE                      = 'ASC'
**       MODE                          = ' '
**       WK1_N_FORMAT                  = ' '
**       WK1_N_SIZE                    = ' '
**       WK1_T_FORMAT                  = ' '
**       WK1_T_SIZE                    = ' '
**       COL_SELECT                    = ' '
**       COL_SELECTMASK                = ' '
**       NO_AUTH_CHECK                 = ' '
**     IMPORTING
**       FILELENGTH                    =
*      TABLES
*        DATA_TAB                      = it_datatab[]
**       FIELDNAMES                    =
*     EXCEPTIONS
*       FILE_OPEN_ERROR               = 1
*       FILE_WRITE_ERROR              = 2
*       INVALID_FILESIZE              = 3
*       INVALID_TYPE                  = 4
*       NO_BATCH                      = 5
*       UNKNOWN_ERROR                 = 6
*       INVALID_TABLE_WIDTH           = 7
*       GUI_REFUSE_FILETRANSFER       = 8
*       CUSTOMER_ERROR                = 9
*       NO_AUTHORITY                  = 10
*       OTHERS                        = 11.
      CALL FUNCTION 'GUI_DOWNLOAD'
        EXPORTING
*       BIN_FILESIZE                  =
          FILENAME                      = p_file
          FILETYPE                      = 'ASC'
          APPEND                        = ' '
*       WRITE_FIELD_SEPARATOR         = ' '
*       HEADER                        = '00'
*       TRUNC_TRAILING_BLANKS         = ' '
*       WRITE_LF                      = 'X'
*       COL_SELECT                    = ' '
*       COL_SELECT_MASK               = ' '
*       DAT_MODE                      = ' '
*       CONFIRM_OVERWRITE             = ' '
*       NO_AUTH_CHECK                 = ' '
*       CODEPAGE                      = ' '
*       IGNORE_CERR                   = ABAP_TRUE
*       REPLACEMENT                   = '#'
*       WRITE_BOM                     = ' '
*     IMPORTING
*       FILELENGTH                    =
        TABLES
          DATA_TAB                      = it_datatab[]
       EXCEPTIONS
         FILE_WRITE_ERROR              = 1
         NO_BATCH                      = 2
         GUI_REFUSE_FILETRANSFER       = 3
         INVALID_TYPE                  = 4
         NO_AUTHORITY                  = 5
         UNKNOWN_ERROR                 = 6
         HEADER_NOT_ALLOWED            = 7
         SEPARATOR_NOT_ALLOWED         = 8
         FILESIZE_NOT_ALLOWED          = 9
         HEADER_TOO_LONG               = 10
         DP_ERROR_CREATE               = 11
         DP_ERROR_SEND                 = 12
         DP_ERROR_WRITE                = 13
         UNKNOWN_DP_ERROR              = 14
         ACCESS_DENIED                 = 15
         DP_OUT_OF_MEMORY              = 16
         DISK_FULL                     = 17
         DP_TIMEOUT                    = 18
         FILE_NOT_FOUND                = 19
         DATAPROVIDER_EXCEPTION        = 20
         CONTROL_FLUSH_ERROR           = 21
         OTHERS                        = 22.
      IF SY-SUBRC <> 0.
       message i000(zumess) with 'Error downloading file, Please check'
                                 'file path in' 'user settings!'.
        p_subrc = 4.
      endif.
    endif.
* Build list of active conversations
    wa_messtalk-uname = gd_talkingto.
    append wa_messtalk to it_messtalk.
*  else.
**    ld_file = p_file.
**    CALL FUNCTION 'WS_QUERY'
**      EXPORTING
**        query    = 'FE'  "File Exist?
**        filename = ld_file
**      IMPORTING
**        return   = rc.
*
*    IF rc NE 0.                       "If File alread exists
**      perform download_conversation_file using p_file 'X' p_subrc.
*    else.
*      call function 'GUI_DOWNLOAD'
*        EXPORTING
*          filename         = p_file
*          filetype         = 'ASC'
*          append           = 'X'
*        TABLES
*          data_tab         = it_datatab[]
*        EXCEPTIONS
*          file_open_error  = 1
*          file_write_error = 2
*          others           = 3.
*      if sy-subrc ne 0.
*       message i000(zumess) with 'Error downloading file, Please check'
*                                 'file path in' 'user settings!'.
*        p_subrc = 4.
*      endif.
*    endif.
  endif.
ENDFORM.                    " download_conversation_file
*&---------------------------------------------------------------------*
*&      Form  get_users_filepath
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM get_users_filepath .
  data: ld_filepath like gd_filepath.
  clear: ld_filepath.
  select single filepath DISNAME
   from zmessoptions
   into (ld_filepath,gd_myname)
  where uname eq sy-uname.
  if not ld_filepath is initial.
    gd_filepath = ld_filepath.
  endif.
  if gd_myname is initial.
    gd_myname = sy-uname.
  endif.
ENDFORM.                    " get_users_filepath
*&---------------------------------------------------------------------*
*&      Form  set_status_online
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_ONLINE   Set whether user is online
*----------------------------------------------------------------------*
FORM set_status_online  USING    VALUE(P_ONLINE).
  update zmessoptions set isonline = p_online
                where uname eq sy-uname.
  if sy-subrc ne 0.
    wa_messopt-uname = sy-uname.
    wa_messopt-isonline = p_online.
    modify zmessoptions from wa_messopt.
  endif.
ENDFORM.                    " set_status_online
*&---------------------------------------------------------------------*
*&      Form  send_popup_message_if_required
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM send_popup_message_if_required .
  data: ld_isonline type c,
        ld_message type SM04DIC-POPUPMSG.
* build popup message to send to user direct
  ld_message = sc_message.
  concatenate gd_talkingto 'says:' ld_message(57) into ld_message
                                              separated by space.
  concatenate ld_message '...' into ld_message.
  if sy-tcode is initial.
    concatenate ld_message
         '(Please use transaction ZTALK to reply to this message)'
                             into ld_message separated by space.
  else.
    concatenate ld_message
         '(Please use transaction' sy-tcode 'to reply to this message)'
                             into ld_message separated by space.
  endif.
* check if user is online (logged into SAP)
  read table it_usrtab with key bname = gd_talkingto.
  if sy-subrc eq 0.
*   check if user is logged into saptalk(executing program)
    select single isonline
      into ld_isonline
      from zmessoptions
     where uname eq gd_talkingto.
    if ld_isonline ne 'X'.
*   Send preview message
*   call function 'WS_MSG'
*         exporting msg_type = 'I'  " 'I'-Info, 'A'-Alert, 'E'-Emergency
*                   text     =  ld_message
*                   titl     = 'Message preview'(242).
*  Send popup message to user.
      CALL FUNCTION 'TH_POPUP'
        EXPORTING
          CLIENT               = sy-mandt
          USER                 = gd_talkingto
          MESSAGE              = ld_message
*          MESSAGE_LEN          = 0
*          CUT_BLANKS           = ' '
       EXCEPTIONS
         USER_NOT_FOUND       = 1
         OTHERS               = 2.
      IF SY-SUBRC <> 0.
      ENDIF.
    endif.
  endif.
ENDFORM.                    " send_popup_message_if_required
*&---------------------------------------------------------------------*
*&      Form  recall_transaction
*&---------------------------------------------------------------------*
*       reset all process by recalling transaction
*----------------------------------------------------------------------*
FORM recall_transaction USING    VALUE(P_option).
  case p_option.
    when 'X'.
      update zmessoptions set ucomm = sy-ucomm
                where uname eq sy-uname.
      leave to transaction 'ZTALK'.
    when 'C'.
      leave to transaction 'ZMESSCLEARUP'.
  endcase.
ENDFORM.                    " recall_transaction
*&---------------------------------------------------------------------*
*&      Form  add_user_to_friends_list
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM add_user_to_friends_list .
  DATA: lt_selected_node     TYPE lvc_nkey,
        lt_fieldname         TYPE lvc_fname.
  DATA: l_selected_node      TYPE lvc_nkey,
        lt_outtab_line(100)  TYPE c,
        lt_node_text         TYPE lvc_value.
*        ld_file type string,
*        ld_subrc type sy-subrc.
*   Retrieve selected Node ID
  CALL METHOD gd_userlist->get_selected_item
    IMPORTING
      e_selected_node = lt_selected_node
      e_fieldname     = lt_fieldname.
*   Retrieve Selected Node + Row contents
  CALL METHOD gd_userlist->get_outtab_line
    EXPORTING
      i_node_key     = lt_selected_node
    IMPORTING
      e_outtab_line  = lt_outtab_line
      e_node_text    = lt_node_text
    EXCEPTIONS
      NODE_NOT_FOUND = 1.
  check sy-subrc eq 0.
  zmessfriends-uname  = sy-uname.
  zmessfriends-friend = lt_outtab_line+0(8).
  modify zmessfriends.
ENDFORM.                    " add_user_to_friends_list
*&---------------------------------------------------------------------*
*&      Form  del_user_from_friends_list
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM del_user_from_friends_list .
  DATA: lt_selected_node     TYPE lvc_nkey,
        lt_fieldname         TYPE lvc_fname.
  DATA: l_selected_node      TYPE lvc_nkey,
        lt_outtab_line(100)  TYPE c,
        lt_node_text         TYPE lvc_value.
*        ld_file type string,
*        ld_subrc type sy-subrc.
*   Retrieve selected Node ID
  CALL METHOD gd_userlist->get_selected_item
    IMPORTING
      e_selected_node = lt_selected_node
      e_fieldname     = lt_fieldname.
*   Retrieve Selected Node + Row contents
  CALL METHOD gd_userlist->get_outtab_line
    EXPORTING
      i_node_key     = lt_selected_node
    IMPORTING
      e_outtab_line  = lt_outtab_line
      e_node_text    = lt_node_text
    EXCEPTIONS
      NODE_NOT_FOUND = 1.
  check sy-subrc eq 0.
  zmessfriends-uname  = sy-uname.
  zmessfriends-friend = lt_outtab_line+0(8).
  delete zmessfriends.
  delete it_messfriends where friend eq lt_outtab_line+0(8).
  perform update_conversation using gd_talkingto 'U'.
ENDFORM.                    " del_user_from_friends_list
*&---------------------------------------------------------------------*
*&      Form  execute_user_command
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM execute_user_command .
if not gd_ucomm is initial.
  CALL FUNCTION 'SAPGUI_SET_FUNCTIONCODE'
   EXPORTING
     FUNCTIONCODE                 = gd_ucomm
   EXCEPTIONS
     FUNCTION_NOT_SUPPORTED       = 1
     OTHERS                       = 2.
  IF SY-SUBRC <> 0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*         WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
  ENDIF.
  clear: gd_ucomm.
endif.
ENDFORM.                    " execute_user_command

Related Articles

Background to the SAPTalk application
SapTALK User Messaging service
Example SAPTalk Screens
SAPTalk create screen 0100 with the following elements (see below screen shots for layout):
Create function module Z_SEND_MESSAGE
Create function module Z_ENQUE_SLEEP
Creation of GUI Status FEEDBACK
Creation of GUI Status 'MESS'
Creation of GUI Status 'OPTIONS'
Creation GUI Status 'ULIST'
SAPTalk - MSM messenger application for SAP
Code listings for SAPTALK includes
Code listing for ZSAPTALKI01(include)
Code listing for ZSAPTALKO01(include)
SAPTalk selection screen parameters
Code listing for ZSAPTALKTOP(include)



SAPTALK - table creation
Code listing for ZMESSCLEARUP
ZMESS: Function group creation details
Code listings for SAPLZMESS(fgroup)
Code listings for SAPLZMESS includes
SAPLZMESS(fgroup ZMESS) - Screen creation
SapTALK: Report creation details
Code listing for SAPTALK
SAPTALK - Include creation
SAPTALK - Screen creation
SAPTALK - GUI Status creation
SAPTALK - GUI Title creation
SapTALK - Transaction creation
Create SAPTalk SAP tables
Create table ZMESSFRIENDS
Create table ZMESSOPTIONS
Create table ZMESSTAB
SAPLZMESS(fgroup)- Function module creation
Message Class and messages
SAPTalk Parameter ID's
SAPTAlk clearup tranasction code