# Compaq TP Desktop Connector
for ACMS
Client Application Programming Guide

Previous | Contents | Index

# 5.7 Building and Debugging Windows Desktop Client Programs

Example 5-9 shows a sample makefile to build the AVERTZ.EXE sample desktop client program.

Example 5-9 Sample Windows Makefile

    #  AVERTDEV
    #
    #  This makefile is used while Avertz is under development. It
    #  compiles and links debug AND creates a Browser database
    #  of the Avertz source (for use in Microsoft C's PWB).
    #
    all: avertz.exe

    # Update the resource file if necessary

    avertz.res: avertz.rc avertz.h  resvform.h
        rc -r avertz.rc

    # Update the object files if necessary

    avertz.obj: avertz.c avertz.h resvform.h session.h
        cl /FR -d -c -AM -Gsw -Od -Zpi avertz.c

    enablew.obj:  enablew.c  acmsdi.h  forms.h session.h
        cl /FR -d -c -AM -Gsw -Od -Zpi enablew.c

    disablew.obj: disablew.c acmsdi.h  forms.h
        cl /FR -d -c -AM -Gsw -Od -Zpi disablew.c

    transw.obj:   transw.c   acmsdi.h  forms.h avertzpp.h session.h
        cl /FR -d -c -AM -Gsw -Od -Zpi transw.c

    sendw.obj:    sendw.c    acmsdi.h  forms.h avertzpp.h session.h
        cl /FR -d -c -AM -Gsw -Od -Zpi sendw.c

    recvw.obj:    recvw.c    acmsdi.h  forms.h
        cl /FR -d -c -AM -Gsw -Od -Zpi recvw.c

    requestw.obj: requestw.c  acmsdi.h tdms.h
        cl /FR -d -c -AM -Gsw -Od -Zpi requestw.c

    versionw.obj: versionw.c  forms.h
        cl /FR -d -c -AM -Gsw -Od -Zpi versionw.c

    avertzpp.obj: avertzpp.c  avertzpp.h  avertz.h  resvform.h forms.h
        cl /FR -d -c -AM -Gsw -Od -Zpi avertzpp.c

    avertzmm.obj: avertzmm.c  avertzmm.h
        cl /FR -d -c -AM -Gsw -Od -Zpi avertzmm.c

    list_pkg.obj: list_pkg.c  list_pkg.h
        cl /FR -d -c -AM -Gsw -Od -Zpi list_pkg.c

    resvform.obj: resvform.c  resvform.h  avertz.h  session.h
        cl /FR -d -c -AM -Gsw -Od -Zpi resvform.c

    session.obj: session.c  avertz.h  session.h  resvform.h avertzmm.h acmsdi.h
        cl /FR -d -c -AM -Gsw -Od -Zpi session.c

    sitelist.obj: sitelist.c sitelist.h  avertz.h resvform.h
        cl /FR -d -c -AM -Gsw -Od -Zpi sitelist.c

    # Build an intermediate library  for the presentation procedure
    # dispatch modules. (This is done in order to get the length
    # of the 'link' command line under 132 characters, thereby avoiding
    # truncation of that command line.)

    dispatch.lib: enablew.obj disablew.obj transw.obj sendw.obj recvw.obj
    requestw.obj versionw.obj
        lib  dispatch.lib -+enablew.obj -+disablew.obj -+transw.obj -+sendw.obj
    -+recvw.obj  -+requestw.obj  -+versionw.obj,,;

    # Build the Avertz executable and source browser
    # - Link the executable
    # - Incorporate the resources defined in the .res file into the executable
    # - Build the browser database

    avertz.exe: dispatch.lib avertz.obj avertzpp.obj avertzmm.obj list_pkg.obj
    resvform.obj session.obj sitelist.obj avertz.def avertz.res avertz.h
        link /NOD/COD avertz avertzpp avertzmm list_pkg resvform session sitelist,,,

    mlibcew libw MWDNETV4 acmsdiM dispatch, avertz.def
        rc -K avertz.res
        PWBRMAKE -Iu avertz.sbr enablew.sbr transw.sbr sendw.sbr avertzpp.sbr
    avertzmm.sbr resvform.sbr session.sbr  sitelist.sbr

Remember to link in stub routines for modules that your desktop client program does not use (see Section 4.5.7).

The Windows SDK provides the tools listed in Table 5-1 to assist in debugging and testing your desktop client program.

Table 5-1 Debugging Tools for Windows Clients
Tool | Description
--- | ---
Codeview for Windows | Debugging in protected mode; requires a second (monochrome) monitor and adapter card
80386 Debugger | Advanced debugging in Protected Mode
Spy | For monitoring Windows messages
Heap Walker | For viewing the memory heap
Shaker | For moving memory
Profiler | For analyzing CPU time
Swap | For analyzing swaps

## 5.7.1 Building a Windows 95 or Windows NT Client Application

TP Desktop Connector client services are provided for Win32 through DLLs only. The ACMSDI.LIB is an import library, not a static-link library.

The ACMSDIWS.DLL is built to use the Winsock over TCP/IP DLL provided on the Windows 95 or Windows NT kit. The Winsock DLL is called WSOCK32.DLL and must be in a directory where Windows 95 or Windows NT can locate it at run time.

The ACMSDIDN.DLL uses the DECnet transport and the PATHWORKS DLLS provided on the PATHWORKS kit. Both the ACMSDIDN.DLL and the PATHWORKS DLLS must be located in the executable path in a directory available to the operating system at run time. Use the following DLLs:

- Windows 95 --- PWSOCK32.DLL
- Windows NT --- PWSOCK.DLL

Follow these steps to use the TCP/IP or DECnet transport:

1. Select either ACMSDIWS.DLL or ACMSDIDN.DLL.
2. Copy and rename it to ACMSDI.DLL.
3. Place ACMSDI.DLL in the executable path, where it can be located by the operating system when running the application.
4. Copy the reference library ACMSDI.LIB from the appropriate Windows 95 or Windows NT directory on the TP Desktop Connector Gateway for ACMS host.
5. Link the application code with the reference library ACMSDI.LIB.

See Compaq TP Desktop Connector for ACMS Installation Guide for directions on obtaining the files that match the Windows operating environment.

Like Windows Version 3.x applications that use DLLs, a Windows NT application must do the following:

- If the application includes exchange steps (presentation procedures), pass the addresses of the presentation procedures on the Call_Options parameter of acmsdi_call_task.
- List all TP Desktop Connector presentation procedures and completion routines as EXPORTED procedures in the application's module definition file.

Unlike Windows Version 3.x applications, a Win32 (or Windows NT) application does not need to do the following:

- The Windows NT application does not need to specify FAR pointers to TP Desktop Connector parameters.
- The Windows NT application does not need to use the MakeProcInstance function for function pointers passed to the TP Desktop Connector DLLs.

## 5.7.2 Maximum Lengths for Environmental Variables

The length of values for TP Desktop Connector environment logical names must not be greater than the maximum lengths indicated in Table 5-2. Using logical names that have values longer than the indicated maximum length can produce unpredictable results.

For example:

    > set ACMSDI_LOG=my_file_name

where my_file_name is 256 characters or less.

Table 5-2 Maximum Lengths for Environmental Variables
Logical Name | Maximum Length of Value
--- | ---
ACMSDI_LOG | 256
ACMSDI_MAXBUF | 4
ACMSDI_TCPIP_PORT_host | 7

# 5.8 Using TP Desktop Connector DLLs in Windows Version 3.1A Applications

Building a Windows application that can use the TP Desktop Connector dynamic-link library (DLL) has several advantages: the Desktop application image is smaller, and multiple TP Desktop Connector applications can share one instance of the TP Desktop Connector client services.

If your Windows application uses the TP Desktop Connector DLL, then the network transport must also use a DLL. Likewise, if the application uses a TP Desktop Connector static-link library, then the network transport must also use a static-link library.

Note Windows applications that run on Novell NetWare or TCP/IP transports must use the TP Desktop Connector (and network transport) DLLs.

You must take certain steps to build a Windows application that can use the TP Desktop Connector DLL. The following sections summarize the general requirements and guidelines for enabling a Windows application to use the TP Desktop Connector DLL and the network transport DLLs.

## 5.8.1 Guidelines for Using DLLs

The following guidelines apply to any procedure in a Windows application that is called by a DLL, such as presentation procedures and completion routines:

- Define the procedure as a FAR PASCAL routine.
- Pass only FAR parameters in the procedure.
- Export the procedure in the module definition file of the application.

Perform the following steps to allow your Windows application to use the TP Desktop Connector DLL correctly:

1. Define completion routines for nonblocking services.
   Define all completion routines for nonblocking services using the ACMSDI_PROC_PREFIX definition.
   Using ACMSDI_PROC_PREFIX and ACMSDI_PTR_PREFIX ensures that the TP Desktop Connector services are declared as FAR PASCAL routines, and pointers to TP Desktop Connector parameters are declared as FAR pointers.
   In Windows applications, pass all function pointers passed to DLL routines using handles created by the Windows function, MakeProcInstance(). Therefore, make sure that each time you specify a completion routine for a nonblocking service, you pass the function handle returned by the MakeProcInstance() function, as shown in Example 5-10.

   Example 5-10 Passing the Function Handle

        BOOL FAR PASCAL NewSession(
                         HWND hDlg,      /* window handle of the dialog box */
                         WORD message,   /* type of message                 */
                         WORD wParam,    /* message-specific information    */
                         LONG lParam)
        {
         FARPROC       lpProcComplete_sign_in;

        .
        .
        .

         lpProcComplete_sign_in = MakeProcInstance(NewSession_Complete);

         status = acmsdi_sign_in(
                          session_ptr->node,
                          session_ptr->username,
                          session_ptr->password,
                          (long) 0,
                          session_ptr->submitter_id,
                          &session_ptr->completion_status,
                          lpProcComplete_sign_in,
                          (void *) session_ptr);

          .
          .
          .

        }

2. Define presentation procedures.
   Define all presentation procedures, including acmsdi_check_version(), using the ACMSDI_PROC_PREFIX definition or FAR PASCAL.
   For example, define acmsdi_enable() in the following way:

       long int ACMSDI_PROC_PREFIX acmsdi_enable(
            ACMSDI_SUBMITTER_ID     ACMSDI_PTR_PREFIX *submitter_id,
            ACMSDI_FORMS_SESSION_ID ACMSDI_PTR_PREFIX *session_id,
            char                    ACMSDI_PTR_PREFIX *form_file_spec,
            char                    ACMSDI_PTR_PREFIX *form_name,
            char                    ACMSDI_PTR_PREFIX *print_file,
            char                    ACMSDI_PTR_PREFIX *form_language,
            ACMSDI_CALL_ID          ACMSDI_PTR_PREFIX *call_id,
            void                    ACMSDI_PTR_PREFIX *call_context)

   Register the function pointers for each presentation procedure as part of the call_options array when invoking the acmsdi_call_task service, as shown in Example 5-11.

   Example 5-11 Registering Function Pointers

       /****************************************************************************

           FUNCTION:   set_presentation_procedure_ptrs

           SUMMARY:    Identify presentation procedure ptrs for the
                       acmsdi_call_task options array

           COMMENTS:   Needed only for applications using the TP Desktop Connector DLL

       ****************************************************************************/

       void set_presentation_procedure_ptrs(ACMSDI_CALL_OPTION *opt)
       {
         opt[0].option = ACMSDI_CALL_OPT_ENABLE;
         opt[0].enable_routine.pacmsdi_enable =
              (ACMSDI_ENABLE_TYPE *)MakeProcInstance((FARPROC)acmsdi_enable, hInst);

         opt[1].option = ACMSDI_CALL_OPT_DISABLE;
         opt[1].disable_routine.pacmsdi_disable =
              (ACMSDI_DISABLE_TYPE *)MakeProcInstance((FARPROC)acmsdi_disable, hInst);

         opt[2].option = ACMSDI_CALL_OPT_SEND;
         opt[2].send_routine.pacmsdi_send=
              (ACMSDI_SEND_TYPE *)MakeProcInstance((FARPROC)acmsdi_send, hInst);

         opt[3].option = ACMSDI_CALL_OPT_RECEIVE;
         opt[3].receive_routine.pacmsdi_receive=
              (ACMSDI_RECEIVE_TYPE *)MakeProcInstance((FARPROC)acmsdi_receive, hInst);

         opt[4].option = ACMSDI_CALL_OPT_TRANSCEIVE;
         opt[4].transceive_routine.pacmsdi_transceive=
              (ACMSDI_TRANSCEIVE_TYPE *)MakeProcInstance((FARPROC)acmsdi_transceive, h

         opt[5].option = ACMSDI_CALL_OPT_REQUEST;
         opt[5].request_routine.pacmsdi_request=
              (ACMSDI_REQUEST_TYPE *)MakeProcInstance((FARPROC)acmsdi_request, hInst);

         opt[6].option = ACMSDI_CALL_OPT_CHECK_VERSION;
         opt[6].check_version_routine.pacmsdi_check_version=
              (ACMSDI_CHECK_VERSION_TYPE *) MakeProcInstance((FARPROC)acmsdi_check_ver

         opt[7].option = ACMSDI_CALL_OPT_END_LIST;

       }

3. Build the application.
   Because you must pass all FAR parameters on completion routines and presentation procedures, by far the simplest approach is to build the Windows application as a large-model application. The large model automatically casts all parameters as FAR parameters for you. However, large-model applications come with their own set of restrictions:
   - The data segments of a large-model Windows application must be FIXED.
   - Only one instance of a given large-model Windows application can run at one time.

   Note Explicitly forcing all parameters to be FAR parameters can be extremely cumbersome, because you may need to do a lot of conversion work. If you want to use these parameters with these functions, you may also run into some compatibility issues. For example, strcmp and strcpy do not work with FAR pointers. Under Microsoft C, you must use -fstrcmp and -fstrcpy. If you store any FAR pointers, you still must have FIXED data segments.

   1. Add constants to the compile line.
      Add the WINDOWS and ACMSDI_DLL constants to the compile commands using the -D compile option. This ensures that the TP Desktop Connector client services and presentation procedures are defined to use DLLs.
      If you decide to build the application for the large-memory model, specify the large-memory model compile option. In Microsoft C, this is the -AL option.
      For example:

          cl  -d -c -AL -Gsw -Od -Zpei -D WINDOWS -D ACMSDI_DLL  avertz.c

   2. Specify the link command line.
      Do not specify the TP Desktop Connector, DECnet, or NetWare libraries in the link command line.
      If you are building for the large-memory model, link with the large-model Windows C runtime library. For example:

          link /NOD/COD avertz other_objs ,,,llibcew libw pp, avertz.def

   3. Specify the module definition file.
      If you are building for the large-memory model, specify that data segments are FIXED in the module definition file of the application:

          DATA  PRELOAD  FIXED  MULTIPLE

      Note If data segments are not fixed, then Windows can move the data segment that your FAR pointer is pointing into, making your FAR pointer invalid. By specifying that data segments remain fixed, you are guaranteed that your FAR pointer continues to point to the same data.

      Add an imports list for all the TP Desktop Connector services in the TP Desktop Connector (ACMSDI) DLL:

          IMPORTS
            ACMSDI.acmsdi_sign_in
            ACMSDI.acmsdi_sign_out
            ACMSDI.acmsdi_call_task
            ACMSDI.acmsdi_dispatch_message
            ACMSDI.acmsdi_complete_pp

      Add an Exports list of all routines called from the TP Desktop Connector DLL. This includes all presentation procedures and all nonblocking services' completion routines:

          EXPORTS
            acmsdi_check_version
            acmsdi_enable
            acmsdi_disable
            acmsdi_transceive
            acmsdi_send
            acmsdi_receive
            acmsdi_request
            NewSession_Complete
            ExitSession_Complete
            SessionTask_Complete
            SessionShutdown_Complete

# 5.9 Debugging the Nonblocking Desktop Client Program with Tasks

First, debug the presentation code on the desktop system. Use the second monitor recommended for Windows environments. When the presentation code runs, debug the desktop client program with the ACMS software. Follow these guidelines:

- For debugging tasks, see Section 3.6.3.
- For using logging in troubleshooting, see Compaq TP Desktop Connector for ACMS Gateway Management Guide.

## 5.9.1 Using a Debugger to Step Through the Microsoft Windows Sample Application

To get a better feel for the flow of the nonblocking Desktop application, use a debugger to step through the Microsoft Windows sample provided on the kit.

Set a breakpoint at the following functions:

- avertz.c
  - Search for "IDM_NEW_SESSION", and set a breakpoint at the first C statement after it.
  - Search for "IDM_END_SESSION", and set a breakpoint at the first C statement after it.
  - Search for "IDM_CREATE_RESV", and set a breakpoint at the first C statement after it.
- session.c
  - NewSession
  - NewSession_Complete
  - SessionTask_Complete
  - ExitSession
  - ExitSession_Complete
- enablew.c
  - acmsdi_enable
- disablew.c
  - acmsdi_disable
- transw.c
  - acmsdi_transceive
- avertzpp.c
  - Trans_List3_List2
  - End_Trans_List3_List2
  Optionally, you can also set breakpoints to the other presentation procedures that can be invoked as part of the RESERVE task, for example:
  - Trans_List5_List6
  - End_Trans_List5_List6
  - Trans_List7_List6
  - End_Trans_List7_List6
  - Trans_List8_List9
  - End_Trans_List8_List9
- resvform.c
  - Search for "IDOK" in the dialog function, Reserve. Set a breakpoint at the first C statement after it.

Previous | Next | Contents | Index