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:

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:

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

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:

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:

    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 
      

    1. 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:

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:


Previous Next Contents Index