Handling Events

An event is a way to notify an application that a specified action has occurred in the host session so that the application can respond accordingly. In the Attachmate Verastream SDK for Unisys and Airlines, the Screen object receives an event from the host session, and then passes the event to the application.

The SDK provides support for the following events that can occur during a host session or that are generated by the transport:

This event
Is generated when
onConnectionLost The connection to the host is broken.
onError An error occurs.
onLostRemoteWindow Reserved for internal use.
onScreenChanged Any part of the host screen changes.
onScreenShapeChanged The host screen shape (number of rows and/or columns) changes.
onStatusReceived Any status message is received from the host transport.

To use events in your application, your Screen object must implement the appropriate event interfaces. For host session events, use IScreenListener (for Java), IScreenListenerEx (for COM), or ScreenUPG delegates (for .NET). For transport events, use IStatusListener (for Java and COM) or ScreenUPG delegates (for .NET).

Once you have implemented the proper interface, you can use the Screen object's screen listener methods to add event listening capabilities to your application. The Screen object provides six methods for event handling, two that are specific to Java-based applications and four that are specific to COM/.NET-based applications:

Details on coding events for each of these environments are provided in the following sections:

Note It is very important that the code in your event handlers does as little processing as possible so that the callback can return quickly to the SDK objects. Never call a Screen object method from inside an event handler method.

Handling Events in Java

To add event support to your Java application:
  1. Import the following package for event support, as follows:

    com.attachmate.UPG.screen.*;

  2. Specify that your class extends IScreenListener (or IStatusListener), as follows:

    public class MyClass extends Thread implements IScreenListener

  3. Implement the IScreenListener interface by providing methods for handling the events within your class.

  4. Call the Screen object's implementation of addIScreenListener, passing in the class that implements IScreenListener, as outlined in steps 2 and 3, above:

    screenObj.addIScreenListener(this);

  5. After your application is finished receiving events—but before destroying the Screen object—always remove the screen listener, again passing in the class that implements IScreenListener, as follows:

    screenObj.removeIScreenListener(this);

Handling Events in Visual C++

Adding event support in Visual C++ is a bit more complex than in Java, so each of the major tasks is broken down into individual steps. If you are using Microsoft Foundation Classes (MFC) and your class derives from CCmdTarget, you can use ClassWizard to do much of the work. If your class derives from CWinThread, however, it must be added manually; the code for doing so is provided in the following procedure.

Complete the following major tasks to add event support to your Visual C++ application:

  1. Set up the class to receive events.

  2. Register and de-register the class with the screen object.

  3. Initialize OLE.


To set up the class to receive events:
  1. Declare an event class that extends a class that supports message maps; for example, CCmdTarget or CWinThread:
    //CSessn thread
    class CSessn : public CWinThread
    {
       DECLARE_DYNCREATE(CSessn)
    
    Note The event class calls DECLARE_DYNCREATE(ClassName). You must also call IMPLEMENT_DYNCREATE(ClassName, CWinThread) in the implementation file (*.CPP) before the event class declaration:

    IMPLEMENT_DYNCREATE(CSessn, CWinThread)
    
    CSessn::CSessn()
    {
    
  2. Add the following statement to the header file for this event class:

    #include "vsdkdefs.h"

    This includes the IID for IID_IScreenListenerEx that you will need in step 4, below.

  3. In the header file for the event class, declare a message map and an interface map as part of the class; this will be handed back to the SDK during run-time using addIScreenListenerEx:
    DECLARE_MESSAGE_MAP()
    //Generated OLE dispatch map functions
    //{{AFX_DISPATCH(CSessn)
    afx_msg void onConnectionLost();
    afx_msg void onError();
    afx_msg void onScreenChanged();
    afx_msg void onScreenShapeChanged();
    afx_msg void onLostRemoteWindow();
    //}}AFX_DISPATCH
    DECLARE_DISPATCH_MAP()
    DECLARE_INTERFACE_MAP()
    
  4. Include a dispatch map in your implementation file (*.CPP), declaring which of your Member methods handle the corresponding events, as well as the IID that is included in the header file for the interface map:
    BEGIN_INTERFACE_MAP(CSessn, CWinThread)
       INTERFACE_PART(CSessn, IID_IScreenListenerEx, Dispatch)
    END_INTERFACE_MAP()
    
    BEGIN_DISPATCH_MAP(CSessn, CWinThread)
       //{{AFX_DISPATCH_MAP(CSessn)
       DISP_FUNCTION_ID(CSessn, "onScreenChanged",     0x1, onScreenChanged, VT_EMPTY, VTS_NONE)
       DISP_FUNCTION_ID(CSessn, "onConnectionLost",    0x2, onConnectionLost, VT_EMPTY, VTS_NONE)
       DISP_FUNCTION_ID(CSessn, "onError",             0x3, onError, VT_EMPTY, VTS_NONE)
       DISP_FUNCTION_ID(CSessn, "onScreenShapeChanged",0x4, onScreenShapeChanged, VT_EMPTY, VTS_NONE)
       DISP_FUNCTION_ID(CSessn, "onLostRemoteWindow",  0x5, onLostRemoteWindow, VT_EMPTY, VTS_NONE)
       //}}AFX_DISPATCH_MAP
    END_DISPATCH_MAP()
    
  5. Enable OLE automation in the application class; for example, using the CCmdTarget::EnableAutomation (or similar) method.

To register and de-register the class with the screen object:
  1. Call addIScreenListenerEx, passing in the Dispatch pointer of the class that implemented the event interface. In the example below, the class that implements the event is the current class (CSessn):
    if (pScreen)
    {
       // Get the dispatch pointer
       LPUNKNOWN pUnkSink = GetIDispatch(FALSE);
    
       // Create the connection point (registers our event handlers)
       AfxConnectionAdvise(lpScreenDisp, IID_ IID_IScreenListenerEx, pUnkSink, FALSE, &m_dwCookie);
    
       // enable event notification
       pScreen->addIScreenListenerEx(GetIDispatch(TRUE));
    
       //open the host connection
       pScreen->Open();
       return;
    }
    
  2. Remove the screen listener from the Screen object when event processing is finished:
    if (pScreen)
    {
       pScreen->removeIScreenListenerEx(GetIDispatch(FALSE));
       AfxConnectionUnadvise(lpScreenDisp, IID_ IID_IScreenListenerEx, pUnkSink, FALSE, m_dwCookie);
       delete m_pScreenOb;
       pScreen = NULL;
    }
    
    Caution Be sure to always remove the screen listener before destroying the Screen object; failure to do so may cause a fault to occur.
To initialize OLE Automation:
  • Initialize OLE automation for each process or thread that uses automation by calling CoInitializeEx with the ApartmentThreaded model option:

    CoInitializeEx(NULL,COINIT_APARTMENTTHREADED);

    Note Be sure to also call CoUninitialize before destroying the thread.

Handling Events under .NET in C#

class Program
{
public ScreenUPG.ScreenUPG screen;
      public Program instance = new Program();

      // Delegate handlers
      public ScreenUPG.ScreenUPG.onConnectionLostHandler myConnectionLostHandler;
      public ScreenUPG.ScreenUPG.onScreenChangedHandler myScreenChangedHandler;
      public ScreenUPG.ScreenUPG.onScreenChangedHandler myScreenShapeChangedHandler;
      public ScreenUPG.ScreenUPG.onLostRemoteWindowHandler myLostRemoteWindowHandler;
      public ScreenUPG.ScreenUPG.onErrorHandler myErrorHandler;
      public void onScreenChanged()
      {
            ....// TODO: Place your code here
      }

      public void onConnectionLost()
      {
            ....// TODO: Place your code here
      }

      public void onError()
      {
            ....// TODO: Place your code here
      }

      public void onScreenShapeChanged()
      {
            ....// TODO: Place your code here
      }

      public void onLostRemoteWindow()
      {
            ....// TODO: Place your code here
      }

      static void Main(string[] args)
      {
            SessionLoader.SessionLoader sl = new SessionLoader.SessionLoader();
            string xmlConfig = "your host XML configuration";
            screen = sl.requestScreenEx("", "", xmlConfig, 0);
            if (screen != null)
            {
                  // Setup the delegates
                  instance = new Program();
                  myConnectionLostHandler = new ScreenUPG.ScreenUPG.onConnectionLostHandler(instance.onConnectionLost);
                  screen.onConnectionLost += myConnectionLostHandler;
                  myScreenChangedHandler = new ScreenUPG.ScreenUPG.onScreenChangedHandler(instance.onScreenChanged);
                  screen.onScreenChanged += myScreenChangedHandler;
                  myScreenShapeChangedHandler = new ScreenUPG.ScreenUPG.onScreenShapeChangedHandler(instance.onScreenShapeChanged);
                  screen.onScreenShapeChanged += myScreenShapeChangedHandler;
                  myLostRemoteWindowHandler = new ScreenUPG.ScreenUPG.onLostRemoteWindowHandler(instance.onLostRemoteWindow);
                  screen.onLostRemoteWindow += myLostRemoteWindowHandler;
                  myOnErrorHandler = new ScreenUPG.ScreenUPG.onErrorHandler(instance.onError);
                  screen.onError += onErrorHandler;

                  // Register a listener and it's delegates
                  screen.addIScreenListenerEx(null);

                  // Open host connection
                  if (screen.Open())
                  {
                        ....// TODO: Place your code here
                  }
            }
      }
}

Handling Events under Visual Basic

Dim WithEvents screen As ScreenUPG.ScreenUPG

Private Sub screen_onConnectionLost()
'TODO: Place your code here
End Sub

Private Sub screen_onError()
'TODO: Place your code here
End Sub

Private Sub screen_onScreenChanged()
'TODO: Place your code here
End Sub

Private Sub screen_onScreenShapeChanged()
'TODO: Place your code here
End Sub

Private Sub screen_onLostRemoteWindow()
'TODO: Place your code here
End Sub

Private Sub addScreenListener()
screen.addIScreenListenerEx screen
End Sub
Related Topics
Common Tasks
The Screen Object Model
Handling Exceptions
  Footer