With no fanfare whatsoever, IBM introduced a major new API set for the Windows client of Client Access/400. This set, collectively known as the Distributed Program APIs, is available with the System Object Access function. Simply stated, the APIs let you develop programs on the PC that can directly call programs on the AS/400, passing and receiving parameter values.
This is a radical innovation, and potentially will help you develop client/ server programs much more quickly than using other APIs. Because you can directly call an AS/400 program, you dont need to code special communications code, as with the APPC APIs, or include data queue handling when using the data queue APIs. In fact, if you have AS/400 functions already split out into subprogramsfor example, a tax calculation routine that is in a separate programyou should be able to call those programs directly from your PC program. The Distributed Program APIs can help you create client/server programs more quickly than other methods because you can use the AS/400 programs that you already have.
How to Get the APIs
You get the Windows DLL that provides the API functions when you install System Object Access (SOA). You can order SOA as a PTF package (SF21273 for licensed program 5763-XC1), or install SOA from the Client Access/400 refresh that is scheduled for release soon. If you order the PTF, you need to specify DELIVERY(*ANY). The PTF package will be sent to you on tape because the package is too large to be sent over ECS. (See the May/June 1995 issue of PCSE for a review of other functions in SOA, System Object Access - Application or API?)
When you install SOA, a subdirectory called SOASPGMS is created in your CAWIN directory. The SOASPGMS directory contains sample programs and source
code for running the SOA programs. The file that you want to look at is EHNDPW.H, the C header file for the Distributed Program-Windows APIs. The header file contains some documentation for the APIs, constants used with the APIs, and function declarations for each of the APIs.
In addition to the header file, file EHNDPW.DLL is installed in the CAWIN directory. The DLL file contains the executable code for each of the APIs. The DLL can be used with any PC language that supports the C calling convention. The APIs in EHNDPW.DLL can only be used by Windows programs.
API Functions Provided
There are 25 user-accessible functions within EHNDPW.DLL. These functions are divided into three groups.
System Functions are used to create a connection between the PC program and the AS/400. When you use the system functions, you start a server job on the AS/400 that processes your program call requests. You also end the server job using a system function API.
The Program Functions group contains APIs to define the program that will be called, work with parameters for the program, call the program, and get information about the program and parameters.
Finally, the Message Functions group helps you get messages and information about messages that are sent as a result of errors when calling the program.
As with any API set, it makes sense to learn about the APIs by looking at how theyre used, rather than by proceeding through the APIs alphabetically. There is a specific sequence that youll need to use when calling a program with the APIs. Youll also find that you only need to use a subset of the APIs to get started.
Getting Started with the APIs
To get started with the APIs, youll first want to print file EHNDPW.H, the C header file. Even if you plan to use a PC language other than C, youll need to examine this file to learn about the APIs, the parameters used on the functions, and the return code values that you might encounter. Later in this article, Ill tell you how to get an equivalent file of function declarations that you can use with Visual Basic.
EHNDPW.H starts with notes about how the APIs are used. If you are accustomed to working with PC languages, the concepts and program flow will probably be easy to grasp. However, if most of your experience is as an RPG programmer, you might find it difficult, at first, to understand how the APIs are used. With an RPG program, you customarily include a CALL statement, followed by PARM statements. The Distributed Program APIs define the parameters first, then call the program. Ill explain this in more detail later.
After the initial documentation, EHNDPW.H continues with definitions for constants. The first set of constants is used to define the maximum number of parameters, and the parameter types. You can call an AS/400 with up to 25 parameters.
Parameter types can be defined as input, output, or input/output. These types provide options that are different from the way an AS/400 programmer customarily uses parameters. In an RPG, COBOL, or CL program, all parameters are input/output, as values can be passed and returned through any parameter (i.e., if you call an AS/400 program from another AS/400 program, the called program can change a parameter, and the change is reflected back to the caller).
The input and output parameter types are used extensively with the APIs themselves. An input parameter is passed from the calling program to the called program. Any changes to the parameter are not returned to the caller. An output parameter is in the parameter list of the calling program; however, any value that you set in the calling program is not passed to the called program. The called program can change the value of the output parameter. The changed value is available to the calling program upon return from the called program.
To call existing AS/400 programs, you might want to consider defining the parameters as input/output, as that provides the same type of parameter usage available with AS/400 languages. Youll need to examine existing code carefully to see if you can define parameters as simple input or output parameters.
The next set of constants in EHNDPW.H is used to define message types. These constants are used with the Message Functions API group. For example, you can test a message to determine if it is a completion, diagnostic, notify, or escape message.
The final set of constants define return codes from the API functions. These are in four general groups: the OK return code, meaning that the API functioned correctly; communications return codes (e.g., no connection to system); program errors (e.g., program not found, too many/ too few parameters); and environment errors (e.g., invalid window, system, or program handle). As with any API, you should, at a minimum, check for the OK return code. If the return code is not OK, you can then go to a generic error handling routine, or you can branch to specific error handling depending on the type of return code.
The Function Declarations
After the constants, EHNDPW.H begins the function declarations. The declarations are listed by function group (i.e., system, program, message), and roughly in order by usage within the groups.
Each API function declaration starts with a synopsis that includes the name of the API, a brief description of it, then a list of the parameters used with the API. Although the synopsis includes a reference for return codes, none of the APIs currently have any documented return codes. You should be able to examine the return code constants and determine which ones will apply to an API. You can also test each API individually to discover the return codes that you might encounter (e.g., call a nonexistent program to discover the return code that you get in that situation).
The function declarations are standard C syntax and formatting. Windows conventions are used for the data type and variable names.
All of the Distributed Program functions start with the character string EHNDP_. The second part of the function name is descriptive of the function. For example, the EHNDP_StartSys API is used to start the conversation with the AS/400.
If you work with C, you should find the function declarations to be straightforward. But even if youre unfamiliar with C, or dont use C as your primary programming language, you should spend some time reading through the declarations. Youll want to know the functions that are available, their names, and the parameters used with each function.
The Distributed Program API Tester Program
I created a test program in Visual Basic to learn about the Distributed Program APIs. Figure 1 shows the dialog that is presented when the program is run. The program uses six command buttons to run Distributed Program functions. The Visual Basic
program calls an AS/400 CL program, passing parameters to it. The CL program sends a message to the QSYSOPR message queue, displaying the parameters. The CL program finishes by moving a value into a parameter. The return value is obtained with a Distributed Program API and placed into the message list box shown in the figure. The code for these programs is too long to include with this article, but you can get it with the Visual Basic function declaration file. Even without the code, we can examine the flow of the Tester program, which I feel is representative of the flow that you would use for production programs. The Tester demonstrates the initialization and cleanup work youll need to do, and also how to define parameters, put values into them, call the AS/400 program, and extract the value for returned parameters.
Before stepping through the details of the program, we need to get an overview of processing flow, as it relates to using the Distributed Program APIs.
Sequence and Flow of the APIs
I mentioned earlier that using the Distributed Program APIs is not quite the same as the AS/400 CALL/PARM construct. There are several additional steps that you need to take before issuing the program call. You need those additional steps because you must create the proper environment for the program call. You then need to provide details about each of the parameters youre going to use. After actually calling the program, you retrieve the parameters that contain return values. When youre finished, you close the environment that you created for the APIs.
Before you can use the Distributed Program APIs, you need a router connection to the AS/400 where the program that you want to call is located. Your first step with the Distributed Program APIs is to start a connection to the system. You then create a program, which means that you identify the program youre going to call. After creating the program, you can add up to 25 parameters to it. As with any AS/400 program, the parameters must match those on the called program.
At that point, you can call the AS/400 program. Assuming that youve correctly defined the parameters and have a working connection, the AS/400 program will run. The called program must be batch oriented; you cannot call an AS/400 program that uses display file I/O.
When the AS/400 program returns or ends, you then call Distributed Program APIs to retrieve the parameter values. Unlike standard AS/400 programs, where values for all of the parameters are available to the calling program when the called program returns, you specifically have to retrieve the value from each parameter in which youre interested.
At this point, you can call the same or another program. You already have the connection environment, so you dont need to start the system again. If youre calling a different program, you need to create the program and add parameters to it. If youre recalling a program that youve already created and added parameters to, you can use an API to set the value of the parameters for a subsequent call.
When youre done working with the AS/400 programs, you delete the program, which removes it from your PC environment. Finally, you stop the system, which means that your connection with the AS/400 is dropped (not the router, just the Distributed Program connection to the server program).
At any point during your calling sequence, you may need to use the APIs that obtain information about the environment. After calling an API, you will need to check the return code. If the call was unsuccessful, you may need to call the message handling
APIs to retrieve the AS/400 error messages. The message handling APIs provide functions equivalent to the program message queue handling operations on the AS/400.
Ill explain what happens when you click each of the command buttons on the Tester. When you obtain the source code and run the program, youll find it useful to step through the program and set breakpoints.
The Start System Function
Before you can call an AS/400 program with the Distributed Program API, you have to start a connection to the AS/400. This connection is between your PC program and an AS/400 server job. This connection presumes that you have an active router connection to the AS/400.
If you attempt to start the program connection without having an active router session, the start attempt fails.
You start the program connection with the EHNDP_StartSys (StartSys) API. Figure 2 shows the details of this API. StartSys uses four parameters. The first, hWnd, is the handle to the window that the program is associated with. This is standard Windows programming practice. hWnd is the first parameter of all of the Distributed Programming APIs, so I wont describe it again from this point on.
The second parameter is the name of the system with which you want to start the connection. This is one of the systems to which you have a router connection. As with other Client Access APIs, you can pass a null value for this parameter, in which case the default system is used.
The third parameter is the application name. This is supposed to be a unique identifier for the application youre starting. A null value is allowed for this parameter. The application name is not used in any of the other Distributed Program APIs, so its purpose is unclear.
The last parameter is a return value, the handle to the system. This is a very important value, as it is used with other Distributed Program APIs to point the APIs to the correct system. For example, if you start connections to two systems within the same PC program, you need to use StartSys for each system. Youll get a unique handle for each system, which then identifies that system. As with any handle, you must never alter its value. You just use the value that is passed back from the API. The value has no meaning as far as your application is concerned; it is used internally by the APIs.
When you use StartSys, two jobs are started in the QCMN subsystem. The first job starts program QLZPSERV. I couldnt determine the functions performed by this job, in relation to the Distributed Program APIs. The second QCMN job starts program QIWS/QZRCSRVR. This program is the actual server processor, which handles Distributed Program requests from your PC program. This job uses ICF file QIWS/QCZRCICF to communicate with the PC. Examining this job shows that APPC is being used to communicate from the PC program to the AS/400 program. However, were insulated from the low-level APPC programming required for communications between the two machines. This is one of the main advantages of the Distributed Program APIs.
If you used a null value for the system name on StartSys, you can find out the name of the system used with the EHNDP_GetSysName (GetSysName) API. The API is described in Figure 3. If you explicitly passed a system name, there would be no point to call this API because youd already know the name of the system. But if youre creating general-purpose programs that might run with different AS/400s, you might need to use the null system name value on StartSys, then use GetSysName to get the default
name. You could also use EHNAPPC_GetDefaultSystem from the APPC API, but GetSysName ensures that you get the system name that applies to the StartSys API usage.
GetSysName uses three parameters. The second is the handle to the system that was returned from StartSys. The third is the name of the system that the connection was started to.
Figure 1 shows the result of clicking the Start System command button. The message list box at the top of the figure contains messages that I formatted after calling the APIs. After calling each API, I check for a return code of EHNDP_OK, meaning that the API completed successfully. If the return code is not OK, I go to an error message formatting routine. For some APIs, such as the StartSys API, I include additional information on normal completion. In this example, Im displaying the hex value of the system handle returned by StartSys. I include a separator line between each API, as shown in the figure. After clicking each command button, you can review the additional messages by scrolling through the message list box. I cant show you the entire sequence of messages in the list box, so I wont describe them any more in this article. Just be aware of the function when you run the sample program.
The Create Program Function
Contrary to what you make think from its name, the EHNDP_CreatePgm (CreatePgm) API does not create a program on the AS/400 in the way that a CRTxxxPGM command does. Instead, the CreatePgm API creates a program object in your PC memory. That object is used to identify the actual program that you want to call on the AS/400, and serves as a connection between your PC and the actual AS/400 program. Figure 4 shows the parameters used with CreatePgm.
If most of your programming experience is in the AS/400 environment, youll want to take the time to be clear on how the terminology used with this API differs from the AS/400 terminology. The API uses the verb create and the noun object, which AS/400 programmers instinctively associate with a program object being created from source.
As you can see from Figure 4, what youre really creating with this API is a handle to a named program. This is all done in the PC memory. When you run this API, there is no communication flow to the AS/400. The API does not verify that you supplied a valid library and program name. If you used incorrect values (e.g., you specified a program name that doesnt exist), you wont find out about it until you actually call the program.
You need to run this API to get the handle assignment. After getting the handle to the program, youll need to add parameters to the program using the handle. Finally, you can call the program.
I havent yet experimented with special or NULL values for the library name parameter. The QCMN communications entry that handles the program evoke request when the program is called specifies a default user value of *SYS. The user profile used to start the router is associated with the server job that processes the request, so the library list for the user is available to the job. I presume that special values like *LIBL are supported for the library name parameter on this API.
After calling the CreatePgm API, you have a handle to the system where the program is located, and a handle to the program object that youre going to call. That takes care of establishing the environment for the program. You now need to add parameters to the program before calling it.
The Add Parameter Function
Unlike the AS/400 CALL/PARM construct, you define your parameters before issuing the call. You define parameters with the EHNDP_AddParm (AddParm) API, shown in Figure 5.
When you use AddParm, what youre really doing is reserving space in your PC memory. This space is simply a sequence of 1 to n bytes. You specify how many bytes to reserve for the parameter. When you use AddParm, a pointer to that space is set, and the parameter count is incremented. The pointers and parameter count are associated with the program that youre going to call, by the program handle value that was returned in CreatePgm.
AddParm uses a parameter to specify the type of parameter, which has nothing to do with the field characteristics (string or numeric and length). The type of parameter is input, output, or input/output. If youre an AS/400 programmer, youll probably be most comfortable defining all of the parameters as input/output, as that provides an equivalent to how AS/400 programs call each other. As you become more familiar with the Distributed Program APIs and processes, you might want to refine your parameter type usage.
This is actually a pretty interesting process, under the covers. The way this process works, it appears that there is a mechanism within the AS/400 server to add parameters dynamically to a program call. This differs from the usual AS/400 programming practice, where you hard-code the number of parameters into your AS/400 source programs. Now, for sure, the AS/400 has always had such a built-in parameter handling mechanism because it has to resolve the number of parameters when one AS/400 program calls another. Here, we have access to this parameter list building process.
Unlike AS/400 programs, you dont specify the type of parameter, but only the length of the parameter. For character string fields, you can simply use the length of the string. For numeric fields, youll have to be careful to match the expected parameter in the AS/400 program. For packed fields, which are the default in CL programs and RPG programs unless defined differently, you need to calculate the number of bytes required to hold the field and the sign half-byte. For example, if a CL program parameter variable is DEC(5,0), youll need a parameter length of 3 on the AddParm API (two and a half bytes used for the five digits, one-half byte for the sign). If the parameter is DEC(6,0), you need a parameter length of 4.
If youve defined the numeric field explicitly as zoned or binary, then you need to specify the number of bytes required to hold the field.
In my testing, I found numeric parameters to be particularly troublesome. This is because of the parameter length consideration, and also because the values need to be converted from ASCII to packed, zoned, or binary, then back, when returning to the PC program. The conversion functions are in the Data Transform API (EHNDT). They are not particularly easy to use in Visual Basic, as you need to work with pointers to the values. The sample program includes an example of ASCII-to-Packed conversion.
As with any call to an AS/400 program, you must supply the right number of parameters, and values for numeric parameters must be valid. For example, if your AS/400 has three parameters, you cant just concatenate all of the values in your PC program and pass one parameter thats as long as all three. You need to pass three corresponding parameters. If you dont pass valid numeric values, youll get MCH-type error messages when your called program on the AS/400 references the parameter. Based on the experience I had with the Distributed Program APIs, youll want a program like Tester to experiment with parameter passing.
The Call Program Function
After defining your parameters, you use the EHNDP_CallPgm (CallPgm) API to actually call the AS/400 program from your PC program. Looking at the function definition in Figure 6, you can see that this API is almost anticlimactic. Thats because youve done all of the set-up work before issuing the call. The API simply references the handles of the system and the program that were created earlier. The parameter list is from the AddParm API calls that you did before using this API.
As with AS/400 program-to-program calls, this is where the action and the problems start. Youll run into the usual problems, such as the program not being found, authority problems, incorrect parameters, and so on. Upon return to your PC program, you absolutely must check the return code from the CallPgm API before you even think of using any other Distributed Program APIs. If the return code is anything other than EHNDP_OK, you had a problem. You can use the message function APIs to retrieve the messages sent from the AS/400, and possibly determine what the cause of the failure was (chances are that the system operator will also get messages on the AS/400, and youll have a job log from the failed job to work with).
The Distributed Program APIs include two APIs that relate to the call mode of the program. The default call mode is synchronous, meaning that while the called AS/400 program is processing, your PC program is locked. The EHNDP_SetCallMode API lets you set the call mode to asynchronous, meaning that you can call the AS/400 program, then resume your PC program while waiting for the called program to return. The EHNDP_GetCallMode API retrieves a value that lets you determine the current mode being used.
I didnt see any documentation about how this feature works, but I suspect that Windows call-back processing is used. If so, Visual Basic programs are limited to synchronous mode, unless third-party VBXs or custom controls that provide call-back support are obtained. I did not test the SetCallMode API; all of my tests were done with the default, synchronous call mode.
My feeling is that this should not present too much of a problem. If youre going to use existing AS/400 modules, chances are that those modules are already working with interactive programs. In that case, when you call the module from an AS/400 program, you are, in effect, working in synchronous mode anyway. Your response time should be comparable to an AS/400-to-AS/400 program call, meaning that it should be tolerable, especially after the first call. If you find response time of synchronous calls to be an issue, and youre working with Visual Basic (no call-back support), you might need to consider alternative methods of submitting work and then checking for a response, such as data queues.
The Get Parm API
At this point, you have all of the APIs you need to call an AS/400 program and pass parameters to it. Although useful, you probably also want to receive parameters back. To do that, youll need to use the EHNDP_GetParm (GetParm) API, shown in Figure 7.
You need to call GetParm for every parameter for which you want to retrieve a value. Thats because you dont have a parameter list, as in an RPG program; you cant just refer to values. Even though you added the parameter earlier with the AddParm API, you need to use GetParm. Think about whats happening: the AS/400 program has returned, and written the parameter values out. You didnt directly call the AS/400 program; you used the server program on the AS/400 as your intermediary.
Because the server program doesnt have hard-coded knowledge of how many parameters youre working with, you have to request those parameters from the server with the GetParm API. When you use GetParm, the parameter values are retrieved from the server program and written to your PC memory, where you can then reference them.
GetParm is tricky to use, especially in Visual Basic, because the returned parameter is a pointer to a pointer. Youll need to use either the EHNDT_MemCopy API or the Windows lstrcpy function to copy the returned parameter from the memory location indicated by the pointer to a buffer (string) that you can use in Visual Basic.
Another consideration with GetParm is that you reference the parameter you want by relative order in the parameter list. You need to refer to the parameter by number because there are no field names associated with the returned parameter list, as in an RPG program. The list is zero-based, meaning that the first parameter is identified as parameter zero, the second parameter in the list is identified as parameter one, and so on.
Another API that you might need to use is EHNDP_GetParmCount (GetParmCount), shown in Figure 8. This API returns a value that indicates the number of parameters in the list. Using GetParmCount, you might be able to create a generic parameter retrieval routine in your PC program, looping through GetParm for the number of parameters from GetParmCount. The alternative is simply hard-coding GetParm code for each parameter.
After you retrieve the parameters that you can work with (in Visual Basic you have to move them to a buffer), youll need to do some additional work before you can use the value. For character string values, youll need to do an EBCDIC to ASCII translation. For numeric parameters, youll need to use the appropriate Data Transform API to convert from packed, zoned, or binary to an ASCII numeric value. This can be tedious and error-prone coding. Youll probably want to run some test cases, then create wrapper functions that you can simply include in your production programs.
The Delete Program API
When youre done calling the AS/400 program, you should call the EHNDP_DeletePgm (DeletePgm) API to remove the program object from your PC memory. Doing so will free up the memory for other purposes. The DeletePgm API does not delete the program object on the AS/400.
Figure 9 shows the DeletePgm API parameters. After you call this API, you can no longer use the CallPgm API for the same program handle. You would have to use CreatePgm again to create a new handle and program object.
You can call DeletePgm at any point after creating the program handle. For example, if your application only needs to call an AS/400 program once for initialization purposes, theres no point to keeping the program object constructs in PC memory after the initialization.
The Stop System API
When youre done calling AS/400 programs from your PC program, youll want to call the EHNDP_StopSys (StopSys) API, shown in Figure 10. Calling this API terminates the conversation with the server program on the AS/400. If you neglect to call this API, the server program remains active.
After calling this API, the handle to the system that was created in the StartSys API is no longer usable. If you want to call AS/400 programs again, you need to go through the entire process, starting with StartSys.
If you started conversations to multiple systems, you need to run StopSys for each system. Conversely, you can use StopSys for one system, but continue to use active conversations to other systems.
Other APIs
In this article, I have not shown or described many other APIs. Figure 11 shows the names of those APIs and briefly describes them.
In the Tester program, I use several of the Message Function APIs to retrieve error messages from the AS/400.
Distributed Program Versus Other Techniques
As exciting as the Distributed Program API suite is, you need to consider where it fits in with other Client Access/400 APIs and techniques. It is true that this suite provides the equivalent function that AS/400 programmers have used for years: the capability of calling one program from another, and passing parameters between the programs. However, that technique has always had built-in limitations.
For example, say that you want to create a server program that youll call to read records from a file. You dont know how many records each call will return; it could be from zero to many. Its tricky to write such a server, and fill up an arbitrary buffer with records. I know; Ive created a system that uses such servers. In this case, it might be better to use an APPC or a CPI-C program, or a data queues program, to receive the file processing request, then fill a buffer that is external to the program. For example, APPC and CPI-C send operations will fill a communications buffer that the system manages. With data queues, you simply write a data queue entry for each record. The system manages the buffer. Your receiving program has a far easier job because it can simply retrieve one entry at a time from the buffer or queue.
On the other hand, you probably have a number of routines already coded that youve been using for years in your production systems. If youve been careful to create stand-alone modules, you can probably call those modules from your Windows programs. This will help you quickly develop a Windows equivalent to the AS/400 program because you dont have to recreate the logic that is available in the existing modules.
There is no limitation on using any of these techniques exclusively in a program. You might find that you use both the Data Queues and the Distributed Program APIs in the same program. The Distributed Program API is certainly a welcome addition, but it does not render the existing techniques obsolete.
The Tester Program
The Tester program, as illustrated in Figure 1 and described in this article, includes the Visual Basic code for the form and a Visual Basic equivalent of the EHNDPW.H file, in which I provide function declares for the Distributed Program APIs.
This code is available on the Midrange Computing BBS in the AS/400 file download area, or directly from me. The BBS number is listed on page 2 of this issue of PCSE.
If you prefer, you can send your request for the code to me at the address shown below. Youll need to include a self-addressed, stamped envelope with 55 cents postage for U.S. addresses (foreign subscribers, please determine the correct postage and prestamp your envelope with U.S. postage). Youll also need to include one 3.5-inch
blank, IBM-formatted diskette. Requests without postage or the diskette will not be processed.
Acknowledgments
I especially want to thank Mike Young and his developers at the IBM Rochester lab. Mike called me about some other issues, and during our conversation, I mentioned that I was working with the Distributed Program APIs. At the time, I encountered what I thought might be a bug in the DLL. The problem was with the EHNDP_GetParm API. Mike confirmed the problem and sent an updated version of the DLL to me. He also indicated that this correction will be made available as a PTF at some point. The version of EHNDPW.DLL that I have is dated 6/27/95. The version distributed with SOA is 3/30/95. If you install the SOA code and have that version of the file, you will encounter the bug. I cannot provide the updated version of the DLL, so you will have to monitor either the IBM PTF list (SF97310), or check future issues of PCSE for notification of the public availability of the fix.
Finally, I want to thank Daniel Appleman of Desaware in San Jose, California. Daniel helped me with the code required to reference a parameter on the EHNDP_GetParm API. Daniel specializes in Visual Basic API programming. In addition to creating tools for Visual Basic, he wrote the definitive book on accessing Windows DLLs from Visual Basic. Ive listed the book title below. If youre going to work with Visual Basic and the Client Access/400 or PC Support APIs, you will find this book to be an outstanding resource.
References
Visual Basic Programmers Guide to the Windows API, Daniel Appleman, Ziff- Davis Press, 1993 (ISBN 1-56276-073-4).
Tester Diskette Address Craig Pelkie PO Box 1473 Valley Center, CA 92082-1473
Figure 1: The Distributed Program API Tester Dialog
Purpose Start a conversation with an AS/400. If successful, a handle for the conversation is returned.
Parameters
hWnd Handle to the window. lpszSystemName ASCIIZ string containing the system name, or NULL for default system. lpszAppName ASCIIZ string of unique application identifier. Can by NULL. lphSystem Handle to the conversation for the system.
Figure 2: The EHNDP_StartSys API
Purpose Get the name of the system used when starting the connection with
EHNDP_StartSys.
Parameters
hWnd Handle to the window. hSystem Handle to the system. This is from the lphSystem parameter on EHNDP_StartSys. lpszSystemName 9-character buffer where the name of the system
will be written (8-character system name, 1 space for terminating NULL character).
Figure 3: The EHNDP_GetSysName API
Purpose Create a program object (handle to the program) for a given library and program name.
Parameters
hWnd Handle to the window. lpszProgramName ASCIIZ string containing the name of the AS/400
program to be called. lpszLibraryName ASCIIZ string containing the name of the AS/400 library where the program is located.
lphProgram Handle to the program object.
Figure 4: The EHNDP_CreatePgm API
Purpose Add a parameter to the program identified by the program handle. Use this
API for each parameter to be passed. Parameters are added to the program in the order that this API is called.
Parameters
hWnd Handle to the window. hProgram Handle to the program object (from EHNDP_CreatePgm). uiType The type of parameter. This can be EHNDP_INPUT, EHNDP_OUTPUT, or
EHNDP_INOUT (see EHNDPW.H for definitions of those constants). ulLength The length of the parameter.
lpParameter Pointer to the buffer where the parameter value is located for INPUT or
INOUT parameter types; or pointer to buffer where parameter value will be returned for OUTPUT or INOUT parameter types.
Figure 5: The EHNDP_AddParm API
Purpose Calls the program identified by the program handle. The return code indicates the success or failure of the call.
Parameters
hWnd Handle to the window. hSystem Handle to the system from EHNDP_StartSys. hProgram Handle to the program object (from EHNDP_CreatePgm).
Figure 6: The EHNDP_CallPgm API
Purpose Retrieve the parameter identified by the index. You have to call this API for every parameter for which you want to retrieve a value.
Parameters
hWnd Handle to the window. hProgram Handle to the program object (from EHNDP_CreatePgm). uiIndex Number of the parameter to retrieve. Parameter count starts at 0. lpuiType Pointer to the type of parameter (EHNDP_INPUT, EHNDP_OUTPUT,
EHNDP_INOUT). length The length of the parameter in bytes. lplpParameter Pointer to a pointer that indicates where the parameter value is written.
Figure 7: The EHNDP_GetParm API
Purpose Get the number of parameters for the program identified by the program handle.
Parameters
hWnd Handle to the window.
hProgram Handle to the program object (from EHNDP_CreatePgm). lpusCount Unsigned integer containing the number of parameters.
Figure 8: The EHNDP_GetParmCount API
Purpose Delete the program object (construct in PC memory) identified by the handle.
Parameters
hWnd Handle to the window. hProgram Handle to the program object (from EHNDP_CreatePgm).
Figure 9: The EHNDP_DeletePgm API
Purpose Stop a conversation with the system identified by the handle.
Parameters
hWnd Handle to the window. hSystem Handle to the system that was created by the EHNDP_StartSys API.
Figure 10: The EHNDP_StopSys API
API Description
EHNDP_GetPgmName Get the name of the program used on the EHNDP_CreatePgm API. EHNDP_GetLibName Get the name of the library used on the EHNDP_CreatePgm API. EHNDP_SetParm Set the parameter value identified by the index. Use this to change a parameter value, after using the EHNDP_AddParm API. EHNDP_SetPgmName Set the name of the program.
EHNDP_SetLibName Set the name of the library. EHNDP_GetMsgCount Get the number of messages returned by the AS/400. EHNDP_GetMsgId Get the message ID of the message returned from the AS/400. EHNDP_GetMsgType Get the type of message returned from the AS/400. EHNDP_GetMsgLen Get the length of the message returned from the AS/400. EHNDP_GetMsgSev Get the message severity of the message returned from the AS/400. EHNDP_GetMsgFile Get the message file name and library for the message returned from the
AS/400. EHNDP_GetMsgText Get the message text returned from the AS/400. EHNDP_GetSubstTextLen Get the length of the substitution text for the message returned from the
AS/400. EHNDP_GetSubstText Get the substitution text for the message returned from the AS/400.
Figure 11: Other Distributed Program APIs
LATEST COMMENTS
MC Press Online