Using custom buttons on the MessageForm

 The default MessageForm used by the MessageFormHelper API supports adding custom buttons so that developers can extend the functionality of the dialog. This enables the end user to receive additional information or to provide customized support utilities like linking to a web page or preparing an email with relevant support information.  

This document describes how to add custom buttons to the message dialog. This document describes how to add custom buttons to the error dialog. In our example we create three buttons with the functionality to copy the message from the message dialog to the clipboard, show the stacktrace or kill the session if the Debug Mode is activated in the application.  


How to add new buttons to the MessageForm 

In order to add custom buttons to the messageForm dialog you need to provide a class that implements the service interface Consultingwerk.Windows.Util.Forms.IMessageFormButtonProvider and register it in the default service container. The table below shows the two methods which are required for the correct display and functionality of the buttons. 

Method 

Description 

METHOD PUBLIC "System.Collections.Generic.List<System.Windows.Forms.Button>" GetButtonsForMessage (poMessage AS Message) 

Returns the list of buttons to be added to the dialog. 

The buttons should have a meaningful name. 

METHOD PUBLIC LOGICAL HandleButtonClick (poButton AS System.Windows.Forms.Button, poMessage AS Message).

Handles the click event of a custom button. 

The following code snippet displays the implementation of both methods in a sample MessageFormButtonProvider. 

The parameter poMessage (Consultingwerk.SmartFramework.Message) to the GetButtonsForMessage method provides the refrence to the Message structure that is currently being shown. Depending on the message context or the message type you can view different buttons on the message dialog.

USING Consultingwerk.Framework.*          FROM PROPATH . 
USING Consultingwerk.Framework.Enum.*     FROM PROPATH .  
USING Consultingwerk.Util.*               FROM PROPATH .  
USING Consultingwerk.Windows.Util.Forms.* FROM PROPATH .   
USING Progress.Lang.*                     FROM PROPATH . 

CLASS Consultingwerk.Windows.Util.Forms.SampleMessageFormButtonProvider 
	  IMPLEMENTS IMessageFormButtonProvider:

    /*------------------------------------------------------------------------------
    Purpose: Returns the List of Buttons to be added to the dialog
    Notes:   Buttons should have a meaningful name
    @param poMessage The Message that is currently being processed
    @return The List the System.Windows.Forms.Button objects to be added to the MessageForm    
    ------------------------------------------------------------------------------*/
    METHOD PUBLIC "System.Collections.Generic.List<System.Windows.Forms.Button>" GetButtonsForMessage (poMessage AS Message):

        DEFINE VARIABLE oList   AS "System.Collections.Generic.List<System.Windows.Forms.Button>" NO-UNDO . 
        DEFINE VARIABLE oButton AS System.Windows.Forms.Button                                    NO-UNDO .                                   

        oList = NEW "System.Collections.Generic.List<System.Windows.Forms.Button>" () .

	    IF FrameworkSettings:DebugMode THEN DO:
			oButton = NEW System.Windows.Forms.Button () .
			oButton:Name = "Kill":U .
			oButton:Text = "Kill session"{&TRAN} . 
			oList:Add (oButton) .
		END.

		oButton = NEW System.Windows.Forms.Button () .
		
		oButton:Name = "Copy":U .
		oButton:Text = "Copy"{&TRAN} . 

		oList:Add (oButton) .

		oButton = NEW System.Windows.Forms.Button () . 

		oButton:Name = "Stacktrace":U . 
		oButton:Text = "Stacktrace":U . 

		oList:Add (oButton) .

		RETURN oList . 

    END METHOD . 


The method HandleButtonClick has two parameters. The first parameter is poButton (System.Windows.Forms.Button) and provides a reference of the clicked button on the message dialog. In our case, we use this trigger to execute the desired functionality. The second parameter poMessage (Consultingwerk.SmartFramework.Message) provides the reference to the Message structure that is currently shown.

    /*------------------------------------------------------------------------------
        Purpose: Handles the click event of a custom button
        Notes:   
        @param poButton The reference to the Button that was clicked
        @param poMessage The reference to the Message that is currently shown
        @return Logical value indicating if the  Message Form should be closed (True = Close)   
    ------------------------------------------------------------------------------*/
    METHOD PUBLIC LOGICAL HandleButtonClick (poButton AS System.Windows.Forms.Button,
											 poMessage AS Message):
		CASE poButton:Name:
			WHEN "Kill":U THEN DO:
				IF MessageFormHelper:AskQuestion ("Are yousure?"{&TRAN}) = DialogResultEnum:DialogResultYes THEN 
					System.Diagnostics.Process:GetCurrentProcess():Kill () .
				END.     
			
			WHEN "Copy":U THEN
				CLIPBOARD:VALUE = SUBSTITUTE ("&1&3&2":U, poMessage:Text, poMessage:Detail, Consultingwerk.Environment:NewLine) .

			WHEN "Stacktrace":U THEN
				MESSAGE Consultingwerk.Util.ErrorHelper:CurrentStacktrace V
					IEW-AS ALERT-BOX INFO .

        END CASE.

    END METHOD .


In our example we use the Consultingwerk sample class. This class implements the functionality of the buttons “Kill session” “Copy” and „Stacktrace“.  

Note: The „Kill Session“ button is only returned when the client session Debug Mode is activated. 

The next step is to initialize and register the service. For this purpose we create a new service.xml file containing the service for the “IMessageFormButtonProvider” interface and the “SampleMessageFormButtonProvider” as the implementation. 

<?xml version="1.0"?> 
<ttServiceLoader xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
	<ttServiceLoaderRow> 
		<Order>1</Order> 
		<ServiceTypeName>Consultingwerk.Windows.Util.Forms.IMessageFormButtonProvider</ServiceTypeName> 
		<ServiceClassName>Consultingwerk.Windows.Util.Forms.SampleMessageFormButtonProvider</ServiceClassName> 
	</ttServiceLoaderRow> 
</ttServiceLoader> 

In order to use this service, we have to load them when the application starts. So add the following method and invoke it when the application is started. 


/*------------------------------------------------------------------------------ 
    Purpose: Load the services from the services.xml 
	Notes: 
------------------------------------------------------------------------------*/ 
METHOD PUBLIC VOID LoadServices (): 

	DEFINE VARIABLE oLoader AS Consultingwerk.Framework.ServiceLoader NO-UNDO. 

	oLoader = NEW Consultingwerk.Framework.ServiceLoader (). 
       
	oLoader:LOAD ("Sample/Message/services.xml":U).  

END METHOD. 

Note: You can also add the service reference for the IMessageFormButtonProvider also to an existing service.xml file.


Now we can create a message and visualize the message using the MessageFormHelper:ShowMessage  method: 

DEFINE VARIABLE oDialogResult AS Consultingwerk.Framework.Enum.DialogResultEnum NO-UNDO .

oDialogResult = Consultingwerk.Util.MessageFormHelper:ShowMessage ("This is a sample message?"{&TRAN}, "Sample Message"{&TRAN}) .

The message dialog displays only the “Copy” and „stacktrace“ button. If you want to show the “Kill session” button, you have to set the following code line: 

Consultingwerk.Framework.FrameworkSettings:DebugMode = TRUE. 

Note: This setting is usually made in the session startup procedure or based on a setting during startup. The following screenshot displays the output with activated Debug Mode: