Reflection provides a number of functions you can use to navigate through IBM 3270 or 5250 host screens. After sending a command (Enter, PF3, etc.) to a host, macros must wait until the host screen has fully arrived before attempting to send any data or commands to the host.
When developing macros for IBM 3270 or 5250 host sessions over TCP/IP connections, it is important to be aware of the limitations of the underlying TN3270 and TN5250 protocols. In some cases, the data stream from a Host system is broken across multiple TCP/IP packets, so these packets arrive at different times. This can lead to errors in a macro if it tries to enter data before the complete Host screen is displayed and ready for input.
Typically, this is not a problem when a user is sitting in front of the terminal session, because the few seconds it takes for the user to realize the Host screen has updated and then type in the next input data is greater than the interval between the packets arriving. But a macro typically takes just milliseconds to process the arriving data and sends the next outbound data immediately if it isn't designed to wait for the screen to update.
Reflection provides several "Wait-type" functions that can be called after the inbound keystrokes are sent to the Host. These functions pause execution until the new Host screen has fully arrived, and the next inbound data can be sent.
While using a Reflection Wait function is a requirement for creating reliable Host screen navigation, getting stellar performance out of screen navigation in a macro is one of the goals of a developer. And the type of Wait function you use can significantly impact performance.
There are a variety of Wait functions available in the Reflection Desktop API. Some are simple to use, but take longer to execute, whereas others complete quickly but require additional coding to verify the results. The WaitForHostSettle or WaitForKeyboardEnabled functions wait a set interval (settletime) after any Host session has updated, and are simple to use in your code. Unfortunately, these functions use a hard-coded timer that is not responsive to fast host connections or screen updates and can lead to very slow performance.
Other functions, such as WaitForText or WaitForCursor, can be used to verify that a specific host screen has arrived without waiting a set time, but because the TCP/IP stack breaks large frames apart, these functions can sometimes falsely indicate that a screen is ready, when it has only partially arrived.
To provide the best solution for reliable screen navigation and performance, consider creating your own "SmartWait" function. This is what we call a function that calls two or more Wait-type functions that do not rely on timers and waits until both of them indicate the screen has arrived before it indicates the screen is ready. Using just a single Wait-type function that doesn't rely on a hard-coded timer can work in many cases, but to be absolutely certain that screen-navigation is as reliable as possible, creating a function within your own code that uses a combination of these types of functions is the best means for navigation.
For example, combining the WaitForText with the WaitForCursor functions with unique values and making sure both have identified the appropriate text and cursor locations before proceeding in the code is a great place to start. There are many ways to structure your own SmartWait function, but this is one example that is fairly quick and efficient.
SmartWait Example |
Copy Code
|
---|---|
' SmartWait is a local function used to determine if a Host screen has appeared using the WaitForText ' and WaitForCursor functions. Parameters passed include: ' sText String of Host data to be searched for. ' sTextRow Integer of Host screen row with starting location for Host data to be searched for. ' sTextColumn Integer of Host screen column with starting location for Host data to be searched for. ' cRow Integer of Host screen row with location of cursor. ' cColumn Integer of Host screen column with location of cursor. ' screen IIbmScreen variable for the host screen object. Public Function SmartWait(sText As String, sTextRow As Integer, sTextColumn As Integer, cRow As Integer, cColumn As Integer, screen As IbmScreen) As Boolean Dim timeout As Integer Dim textPresent, cursorPresent As Boolean Dim returnvalue As ReturnCode Dim startTotalTime Dim TimeNow Dim retVal As Boolean retVal = True timeout = 50 'milliseconds to wait until a retry of the Reflection Wait function. textPresent = False 'set value that searched for Text is not present yet. cursorPresent = False 'set value that cursor location is not found yet. startTotalTime = Timer 'keep track of total elapsed time while searching for Host data. 'Enter loop to wait for host screen to be fully updated Do While (cursorPresent = False) Or (textPresent = False) TimeNow = Timer 'Check to see if 20 seconds have passed, so an exit from this function can happen if the Host screen never arrives. If TimeNow - startTotalTime < 20 Then 'If the Host screen text is not present, then continue looking for it. If textPresent = False Then If screen.WaitForText1(timeout, sText, sTextRow, sTextColumn, TextComparisonOption_IgnoreCase) = ReturnCode_Success Then textPresent = True End If End If 'If the Host screen cursor is not present on the screen, then continue looking for it. If cursorPresent = False Then If screen.WaitForCursor1(timeout, cRow, cColumn) = ReturnCode_Success Then cursorPresent = True End If End If Else retVal = False Exit Do End If Loop SmartWait = retVal End Function |
There are several things to note about this SmartWait function example:
This example shows how you can use this example SmartWait function in an IBM session macro.
First, it shows how to place this function in the Common Project, so that it can be called by any of your IBM session macros. Then it shows how to use this function in a session macro that is connected to the Reflection demo.
Example Title |
Copy Code
|
---|---|
Public Sub TestSmartWaitNavigation() 'Declare application, terminal, and view object variables: Dim app As Attachmate_Reflection_Objects_Framework.ApplicationObject Dim terminal As Attachmate_Reflection_Objects_Emulation_IbmHosts.IbmTerminal Dim View As Attachmate_Reflection_Objects.View Dim screen As IbmScreen Dim HostScreenFound As Boolean 'Get an instance of Reflection, create a terminal, and connect to the Reflection demo Set app = GetObject("Reflection Workspace") Set terminal = app.CreateControl2("{09E5A1B4-0BA6-4546-A27D-FE4762B7ACE1}") terminal.HostAddress = "demo:ibm3270.sim" terminal.port = "623" 'Create a view to display the session Set View = ThisFrame.CreateView(terminal) Set screen = terminal.screen 'For each screen, identify a string on the screen to search for and the initial position of the cursor after the screen loads. 'For the first screen, wait until the string "ONLINE" is found at row 1 and column 13, and the cursor location is row 20 and column 16. HostScreenFound = Utilities.SmartWait("ONLINE", 1, 13, 20, 16, screen) 'If the SmartWait method returns success (true), the appropriate Host screen was found and you can enter commands on the screen. If HostScreenFound = True Then screen.SendControlKey (ControlKeyCode_Transmit) Else Exit Sub End If End Sub |