       Last Minute News on Async Professional 2.0 for Delphi
       =====================================================

This file describes changes, additions, and clarifications to Async
Professional for Delphi that do not appear in the printed
documentation. Please print and read this file prior to using Async
Professional for Delphi, and save it for future reference. It includes
the following sections, which are organized according to the
topic/module to which they apply:

 1. Changes from Async Professional 1.0 for Delphi
 2. Changes from Early Experience Program (EEP) versions
 3. Problems with COMM.DRV and 16-bit applications
 4. Problems with VCOMM/SERIAL.VXD and 32-bit applications
 5. Communications driver replacement sources
 6. Supported TAPI environments
 7. Supported APF printer driver environments
 8. New example programs
 9. Exception/ErrorCode changes and additions
10. ShortString vs. String vs. TPassString
11. Processor utilization during protocol receives
12  Delphi 2.0 capacity limits
13. AWDEFINE.INC - conditional defines
14. ADPORT - TApdComPort
15. ADTAPI - TApdTapiDevice
16. ADTERM - TApdTerminal
17. ADFAX - TApdAbstractFax, TApdSendFax, TApdReceiveFax,
            TApdFaxStatus, TApdFaxLog
18. ADPROTCL - TApdProtocol, TApdProtocolStatus, TApdProtocolLog
19. ADFVIEW - TApdFaxViewer
20. OOMISC - TEmuCommand
21. Printer driver issues
22. SendFax/RcvFax Demonstration programs
23. Corrections to the Manual

1. Changes from Async Professional 1.0 for Delphi
=====================================================================
The ForceGets property, published in Async Professional 1.0 for Delphi,
is still available in Async Professional 2.0 for Delphi, but was
changed to an unpublished, public property.

ForceGets is provided *only* for compatibility with trigger handlers
moved from Async Professional for Windows programs to Async
Professional for Delphi programs. Changing ForceGets significantly
alters the behavior of the internal dispatcher and OnTriggerAvail
events and it should not be changed unless absolutely necessary.

The change from published to public was made to reduce the likelyhood
that the property could be changed accidently.

This change may cause Delphi to generate a warning message when loading
Async Professional 1.0 for Delphi applications; the warning states the
the property ForceGets cannot be found. Simply ignore the warning.
Once the project is saved the warning won't be repeated.

If the application really needs to enable ForceGets, then it must now
set ForceGets at run-time instead of design-time.

The declarations of the protocol event handlers OnProtocolAccept and
OnProtocolNextFile were changed slightly: the string parameters were
changed to TPassString, which is identical to the Delphi 1.0 string
parameter.

When applications containing event handlers for these events are loaded
into Delphi 2.0 using Async Professional 2.0 for Delphi, Delphi
generates the following warning:

  The Xxx method referenced by OnXxx has an incompatible parameter
  list. Remove the reference?

Answer "No" to this question, then find the Xxx method in your source
code and change "String" to "TPassString". Change both the declaration
of the Xxx method and its implementation. Save the project.

See the sections "ShortString vs. String vs. TPassString" and
"AWDEFINE.INC - conditional defines" for more information about this
issue.


2. Changes from Early Experience Program (EEP) versions
=====================================================================
Some applications created with some EEP versions of Async Professional
for Delphi (EEP releases 1 through 4) require a minor change before
they can be used with the production release of Async Professional for
Delphi.

The declarations of the fax event handlers OnFaxNext and OnFaxName were
changed slightly: the string parameters were changed to TPassString.
When EEP applications containing event handlers for these events are
loaded into Delphi 2.0 using the final release of Async Professional
2.0 for Delphi, Delphi generates the following warning:

  The Xxx method referenced by OnXxx has an incompatible parameter list.
  Remove the reference?

Answer "No" to this question, then find the Xxx method in your source
code and change "String" to "TPassString". Change both the declaration
of the Xxx method and its implementation. Save the project.

See the section "ShortString vs. String vs. TPassString" for more
information about this issue.


3. Problems with COMM.DRV and 16-bit applications
=====================================================================
COMM.DRV, the Windows 3.1 communications driver, has two major roles:
1) to program the serial port hardware (the UART) and service all UART
interrupts; and 2) to provide an API that USER.EXE and application
programs use to control the serial port and receive and transmit data.

COMM.DRV has many documented bugs and behavioral quirks. The list below
describes these problems, from most-severe to least-severe. Each item
indicates whether Async Professional for Delphi works around the issue
or describes a workaround for application programs.

 1. The posting of communication notification messages may stop
    unexpectedly. Async Professional for Delphi avoids this problem by
    using a timer in conjunction with notification messages.

 2. Random reboots occur when using communication notification events.
    The exact cause of this problem isn't clear and seems to affect only
    a small percentage of Windows users. Microsoft's suggested
    workaround is to turn off communication notification events if you
    are affected by the problem. In Async Professional for Delphi, this
    is accomplished by setting the TApdComPort.DispatchMode property to
    dTimer (the default).

 3. Machines with a PCI bus and a 16550 UART may hang or stop processing
    communications events under Windows for Workgroups 3.11. The
    solution is to replace the SERIAL.386 driver that came with Windows
    for Workgroups. The complete problem description and the replacement
    driver are available in the Microsoft Knowledge Base under entry
    WG1001.

 4. Random hangs or reboots occur when a program uses COM1 with an IRQ
    shared with another open port. Microsoft's suggested solution is not
    to share an IRQ with COM1.

 5. Programs appear to hang when closing a communications port. This
    occurs because COMM.DRV attempts to send all data in the output
    buffer before closing a port, which results in an apparent hang if
    output is blocked by flow control. Async Professional for Delphi
    avoids this problem by flushing the output buffer before closing a
    port.

 6. Random program behavior and random crashes occur when input/output
    buffers sizes greater than 32K are used. Async Professional for
    Delphi avoids this problem by limiting buffer sizes to 32K.

 7. The CBR_14400 baud rate constant isn't treated correctly, resulting
    in an actual baud rate other than 14400. Async Professional for
    Delphi avoids this problem by passing the baud directly instead of
    using CBR_14400.

 8. The Windows function UngetCommChar may cause data loss or a general
    protection fault. Async Professional for Delphi never calls this
    function.

 9. The Windows API does not provide information about the absolute
    value of modem status lines. Microsoft's suggested workaround is to
    peek at a location within COMM.DRV to obtain these signal values.
    Async Professional for Delphi implements this workaround by default
    but it can be turned off for COMM.DRV replacements that don't
    support the workaround. See the TApdComPort property UseMSRShadow
    for more information.

 10. The Windows documented method of detecting changes in the data
     carrier detect (DCD) signal do not work. The solution is the same
     as in item 9.

 11. SetCommState, when used to set or reset the DTR/RTS signals, leaves
     interrupts off too long and may cause data loss. Async Professional
     for Delphi avoids this problem by using EscapeCommFunction to
     control the DTR/RTS signals.

 12. Under Windows for Workgroups 3.11 a random byte may be
     transmitted as a port is closed. This is a bug in the SERIAL.386
     driver and can be fixed by downloading WG1001 from the Microsoft
     Knowledge Base, which contains a fixed version of SERIAL.386.


4. Problems with VCOMM/SERIAL.VXD and 32-bit applications
=====================================================================
SERIAL.VXD, the Windows 95 and Windows NT serial port driver has two
major roles: 1) to program the serial port hardware (the UART) and
service all UART interrupts; and 2) to work with VCOMM, the general
purpose serial communications controller, and application programs to
provide serial port control and input/output functions.

VCOMM and SERIAL.VXD have one known bug:

 1. At least some releases of Windows NT 3.51 workstation do not provide
    access to the RI (ring indicator) modem signal. The Microsoft
    support forum recommends looking for incoming 'RING' strings from
    the modem when waiting for incoming calls instead of using the RI
    signal.


5. Communications driver replacement sources
=====================================================================
Although it is possible for Async Professional for Delphi or an
application program to work around all known communications
driver problems, replacement drivers are available which also work
around these problems. Some replacements also offer higher performance
or additional features.

Below is a list of replacement communications drivers that we have
tested with Async Professional for Delphi. All of these drivers are for
16-bit Windows only; we don't know of any replacement drivers for
32-bit Windows.

CYBERCOM.DRV from CyberSoft Corporation Pty Ltd., also available as
CYBERCOM.LZH on the TurboPower BBS. It's also in several forums on
CompuServe; one is CYBERC.ZIP in IBMCOM/Comm Utilities.

TURBOCOM.DRV from Pacific Comware, voice: 503-482-2744, fax:
503-482-2627, BBS: 503-482-2633.

For highest performance and reliability, intelligent communications
boards with replacement drivers are the best solution. Intelligent
communications boards use a dedicated processor to handle the physical
serial I/O. This relieves the main CPU of that burden and assures that
received data is retrieved in a timely fashion. The intelligent board
then holds the received data until the Windows application asks for it.

Below is a list of intelligent communications boards that we have tested
with Async Professional for Delphi. DigiBoard offers drivers for all
16-bit and 32-bit Windows environments.

T/PORT board from Telcor Systems Corporation, voice: 508-653-3995, fax:
508-651-0065.

DigiBoard family of boards, DigiBoard Incorporated, voice:
612-912-3444 (800-344-4273), BBS: 612-912-4800, fax: 612-912-4952,
email: sales@dgii.com


6. Supported TAPI environments
=======================================================================
Async Professional for Delphi supports the following TAPI environments:

  TAPI 1.4 in Windows 95, 32-bit applications only

Async Professional for Delphi also supports TAPI 1.3 functions in
16-bit applications for Windows 3.1 and Windows for Workgroups, but
those environments lack a general purpose modem service provider, which
render most of the TAPI functions useless for serial communications
programs.


7. Supported APF printer driver environments
=======================================================================
Async Professional for Delphi's APF printer driver is a 16-bit
UNIDRV-based printer driver that works in the following Windows
environments:

  Windows 3.1
  Windows for Workgroups
  Windows 95

It does not yet work in Windows NT; that support is planned for a
future release of Async Professional for Delphi.


8. New example programs
=======================================================================
The following new example programs were added since the manual was
printed:

EXFAXB - Demonstrates how a TApdSendFax and a TApdReceiveFax component
         on the same form can share a single TApdFaxStatus component.

EXADAPT - Demonstrates how to perform adaptive answering (distinguishing
          an incoming data call from an incoming fax call).


9. Exception/ErrorCode changes and additions
=======================================================================
The error messages attached to the EHardware and EBadID were changed.
Previously they contained the same text as found in the Windows SDK
documentation. That text proved to be somewhat confusing, so the error
messages in Async Professional for Delphi were changed to:

Exception     ErrorCode        Error message
EHardware     ecHardware       Specified comport is already in
                               use (ie_Hardware)
EBadId        ecBadId          Specified comport does not
                               exist (ie_BadId)

EHardware is raised when a program attempts to open a serial port that
is in use by another program (e.g, a program attempts to open COM1 when
COM1 is used by a serial mouse). EBadId is raised when a program
attempts to open a serial port that does not exist (e.g., a program
attempts to open COM5 on a machine that has only COM1 through COM4).


10. ShortString vs. String vs. TPassString
=======================================================================
Async Professional for Delphi uses a custom string type, TPassString,
in event handlers that return var strings. TPassString is defined as

  TPassString = string[255];

This special string type is required due to several possibly unexpected
side effects of using strings or long strings in event handlers.

Because Async Professional for Delphi provides the option of compiling
the bulk its code into several DLLs, it *could* require that
applications include the Delphi unit ShareMem as the first unit in
their uses lists. (The Delphi 2.0 manual points out that ShareMem is
necessary whenever a DLL and application use the same long string.) To
avoid imposing this easily overlooked step on applications, Async
Professional for Delphi simply avoids using long strings in any
situation where a string is passed between an application and one of
the APW?.DLLs.

Unfortunately, using the ShortString type instead of string is not an
option because Delphi uses the string type when generating source code
for event handlers at design-time. If a unit containing such an event
handler is compiled with the $H+ compiler option (string = AnsiString),
the compiler generates the wrong code for that event handler. It
generates code to handle long strings, but the routine calling the
event handler passes in short strings.

TPassString is the solution to this problem. All Async Professional for
Delphi event handlers that return var string parameters use TPassString
for the string type. TPassString is short string, which avoids the
DLL/application memory allocation problem. And when Delphi generates
the source code for those events it uses TPassString instead of string,
removing the string/long string ambiguity.

Only four Async Professional for Delphi event handlers require
TPassString:

  TApdProtocol.OnProtocolNextFile
  TApdProtocol.OnProtocolAccept
  TApdSendFax.OnFaxNext
  TApdRecieveFax.OnFaxName

TPassString was added to Async Professional for Delphi after the manual
was printed and the declarations of the above routines in the manual
show "string" instead of "TPassString". The corrected declarations are
shown later in this file, in their appropriate sections.


11. Processor utilization during protocol receives
=======================================================================
Some processor utilization monitors may indicate that 32-bit Async
Professional for Delphi programs use 100% of processor capacity during
streaming protocol receive sessions such as Zmodem. Although this
indication is accurate, it is also misleading.

Async Professional for Delphi takes advantage of threads, overlapped
I/O and other Win32 features to optimize performance and response time
and, in most cases, minimize processor utilization. The communications
thread sleeps, releasing all processor time, until a communications
event occurs. When a large block of data arrives, the thread wakes
immediately and processes all available data. When processing is
complete the thread sleeps again, only to be reawakened immediately if
new data followed the last block of data without pause, which is
typical in a streaming protocol like Zmodem.

In this mode a Zmodem program seems to consume all processor time. In
fact, it is consuming all *available* time. That is, if other threads
are started, the communication thread naturally shares processor time
with those threads. The result is that the communication thread wakes
less often, but processes more data each time it wakes.

That Zmodem and other streaming input sessions seem to consume 100% of
the processor does *not* indicate that they are operating at the
throughput ceiling of the machine/environment. The true throughput
ceiling of any environment is reached only when actual measured
throughput begins degrading.


12. Delphi 2.0 capacity limits
=======================================================================
Delphi 2.0 exhibits two capacity limitations that may become apparent
when installing and using Async Professional for Delphi. These
limitations have nothing to do with Async Professional for Delphi and
affect all third party libraries.

The first capacity limit is in the Delphi 2.0 help system. When too
many keyword files are added to Delphi's integrated help system, Delphi
"loses" information about some keywords. That is, you may find that
Delphi can't find a keyword in the help file even though you are
certain the keyword is there. The only workaround is to remove some KWF
files from Delphi's help system.

The second capacity limitation is even more severe than the first.
Adding too many third party libraries to the Delphi 2.0 component
library causes Delphi to stop with a "stack overflow" while rebuilding
CMPLIB32. There are two solutions to this problem: one, remove unused
libraries, or two, use the command line compiler (DCC32.EXE) to rebuild
CMPLIB32.DPR.

To compile CMPLIB32 using the command line compiler requires that you
manually add Async Professional for Delphi information (assuming that
adding Async Professional for Delphi components is what put you over
the limit) to CMPLIB32.DPR. To add all three registration units modify
CMPLIB32.DPR as shown below:

CMPLIB32.DPR:
uses
  ...
  SampReg,
  apdreg,                                                 <----
  apdfreg,                                                <----
  apdtreg,                                                <----
  LibMain;
...
{$R 'e:\Delphi2\Lib\SampReg.dcr'}
{$R 'd:\apd\apdreg.d32'}                                  <----
{$R 'd:\apd\apdfreg.d32'}                                 <----
{$R 'd:\apd\apdtreg.d32'}                                 <----
...
  RegisterModule('SampReg', SampReg.Register);
  RegisterModule('apdreg', apdreg.Register);              <----
  RegisterModule('apdfreg', apdfreg.Register);            <----
  RegisterModule('apdtreg', apdtreg.Register);            <----

Compile with "DCC32 CMPLIB32", then rename CMPLIB32.DLL to
CMPLIB32.DCL.

Borland has been notified of both problems and is working on solutions.


13. AWDEFINE.INC - Conditional defines
=======================================================================
Two new conditional defines were added to AWDEFINE.INC:

{.$DEFINE EnableTapi16}

This define enables TAPI components in 16-bit applications. TAPI
typically isn't usable in 16-bit environments due to a lack of service
providers (notably, the lack of UNIMDM.TSP) in Windows 3.XX, and due to
a bug in Windows 95 that prevents obtaining a 16-bit comm handle to a
TAPI port. This define is off by default; enable it to use TAPI in
16-bit environments, but *only* if you are certain that environment
properly supports TAPI.

{.$DEFINE Prot16OpenStrings}

This define activates an Async Professional 1.0 for Delphi behavior for
Async Professional 2.0 for Delphi programs, concerning the TApdProtocol
component's OnProtocolNextFile and OnProtocolAccept events. When this
define is active Async Professional 2.0 for Delphi uses "OpenString"
for string parameters passed in these events, which is the same type
used by Async Professional 1.0 for Delphi. When this define is not
active Async Professional 2.0 for Delphi uses TPassString for those
events.

This define is off by default and is intended *only* to provide
seamless backward compatibility with existing Async Professional 1.0
for Delphi programs.


14. ADPORT - TApdComPort
=======================================================================
The type of the following properties was changed from string to
ShortString:

  property TraceFile : ShortString;
  property LogFile   : ShortString;


15. ADTAPI - TApdTapiDevice
========================================================================
The following new property was added to TApdTapiDevice:

property ShowTapiDevices : Boolean
Default: DefShowTapiDevices (False in 16-bit mode, True in 32-bit mode)

=> ShowTapiDevices controls whether TAPI devices are displayed by
SelectDevice method.

When ShowTapiDevices is True, SelectDevice shows both TAPI devices and
available comports. When ShowTapiDevices is False, SelectDevice shows
only comports.

ShowTapiDevices defaults to True in 32-bit applications because the
most widespread 32-bit environment, Windows 95, provides TAPI services
and a general purpose service provider for modems.

ShowTapiDevices defaults to False in 16-bit applications because 16-bit
Windows environments don't include a general purpose service provider
for modems, making TAPI unusable by serial communications programs in
those environments. This applies to 16-bit programs running under
Windows 95 as well. Although TAPI devices seem to be available, Windows
95 does *not* provide a way for 16-bit applications to use comports
opened by TAPI.

Set this property to True in 16-bit programs *only* if you are certain
that TAPI and a suitable service provider are available for use by
general purpose communication programs.

The following new exception was added to the
TApdTapiDevice.SelectDevice method and the
TApdTapiDevice.SelectedDevice property.

 ETapi16Disabled,   ecTapi16Disabled, "TAPI disabled for 16-bit
                                       environments"

This exception is raised when a 16-bit application attempts to select a
TAPI device but EnableTapi16 is not defined in AWDEFINE.INC. It is
intended to alert the programmer that a 16-bit application is
attempting to use TAPI, which won't work except unless a TAPI service
provider for modems is installed (16-bit Windows environments do not
have a built-in modem service provider).


The TApdAbstractTapiStatus.TapiDevice property is designated in the
printed manual as "read-only run-time". It is in fact a published
property.


The following new property was added to TApdTapiLog:

property TapiDevice : TApdCustomTapiDevice

=> TapiDevice is the TAPI component that is using the log component.

TapiDevice is automatically initialized when the TapiLog property of
the owning TAPI component is set. Programs can change TapiDevice to
assign the log component to a different TAPI component.


16. ADFAX - TApdAbstractFax, TApdSendFax, TApdReceiveFax,
            TApdFaxStatus, TApdFaxLog
=======================================================================
The declaration of OnFaxName was changed. The new declaration is:

  TFaxNameEvent = procedure(CP : TObject;
                            var Name : TPassString) of object;

The declaration of OnFaxNext was changed. The new declaration is:

  TFaxNextEvent   = procedure(CP : TObject;
                              var APhoneNumber : TPassString;
                              var AFaxFile : TPassString;
                              var ACoverFile : TPassString) of object;

A new class was added the fax send/receive class hierarchy. The
complete new hierarchy is:

  TComponent
   - TApdCustomAbstractFax           <---- new class
     - TApdAbstractFax
       - TApdCustomSendFax
         - TApdSendFax
       - TApdCustomReceiveFax
         - TApdRecieveFax


The TApdCustomAbstractFax is identical to the documented
TApdAbstractFax, except that it doesn't publish any properties. The
TApdCustomAbstractFax is provided to facilitate your creation of
descendent fax components.

The TApdAbstractFaxStatus.Fax property is designated in the printed
manual as "read-only run-time". It is in fact a published property.

The following new property was added to TApdFaxLog:

property Fax : TApdCustomAbstractFax

=> Fax is the fax component that is using the log component.

Fax is automatically initialized when the FaxLog property of the owning
fax component is set. Programs can change Fax to assign the log
component to a different fax component.


17. ADTERM - TApdTerminal
=======================================================================
The manual neglects to mention that the VT100 margin control feature is
available only when the client height of the terminal window (the
DisplayRows property) is equal to the page size expected by the VT100
host (the PageHeight property). Most VT100 hosts expect a page height
of 25 rows, thus DisplayRows and PageHeight must both be set to 25.

This requirement is not enforced by the TApdTerminal component.
Applications to be used with VT100 applications using margins must
assure DisplayRows and PageHeight are set to the size expected by the
VT100 host.


18. ADPROTCL - TApdProtocol
=======================================================================
The declaration of OnProtocolAccept was changed, the new declaration
is:

  TProtocolAcceptEvent   = procedure(CP : TObject;
                                     var Accept : Boolean;
                                     var FName : TPassString) of object;

The declaration of OnProtocolNextFile was changed, the new declaration
is:

  TProtocolNextFileEvent = procedure(CP : TObject;
                                     var FName : TPassString) of object;

The following new property was added to the TApdProtocol component:

property UpcaseFileNames : Boolean
Default: DefUpcaseFileNames (True)

=> UpcaseFileNames determines whether the protocol "upcases" file
names.

Applications provide file names to protocols in the OnProtocolNextFile
event or by setting the FileName property; file names can also be
received as part of the protocol transfer. Because the DOS/Windows16
file system stores all file names in upper case, the protocol component
converts file and path names to uppercase so that when those names are
referenced in status and log routines they are in uppercase.

Windows 95 and Windows NT preserve the specified case of file names,
although they don't normally use case to distinguish between file
names. For example, the file name "MixCase.Txt" is stored by the file
system with the upper and lower case characters preserved. In these
environments applications may wish to display the preserved case in
status and log routines. Set UpcaseFileNames to False to do so.


The TApdAbstractStatus.Protocol property is designated in the printed
manual as "read-only run-time". It is in fact a published property.


The following new property was added to TApdProtocolLog:

property Protocol : TApdCustomProtocol

=> Protocol is the protocol component that is using the log component.

Protocol is automatically initialized when the ProtocolLog property of
the owning protocol component is set. Programs can change Protocol to
assign the log component to a different protocol component.

19. ADFVIEW - TApdFaxViewer
=======================================================================

property BusyCursor : TCursor;

=> Specifies the cursor that the TApdFaxViewer component displays during
   lengthy operations.

At times, the TApdFaxViewer component must load portions of the displayed
fax into memory. This can be time-consuming, especially if the fax is
large. To let the user know that a lengthy operation is taking place, the
TApdFaxViewer will change the mouse cursor to the cursor specified by the
BusyCursor property until the lengthy operation is completed. After the
operation has completed, the cursor changes back to the cursor specified
by the Cursor property.

The following example demonstrates the user of the BusyCursor property. It
tells the fax viewer to display the hourglass cursor during lengthy
operations:

  ApdFaxViewer1.BusyCursor := crHourglass;

property OnPageChange : TNotifyEvent;

=> OnPageChange defines an event handler that is called when the active
   page changes.

The user of the TApdFaxViewer component can change pages by pressing the
PgUp and PgDn keys. When the user does this, the TApdFaxViewer component
notifies you that the active page is changing by calling the OnPageChange
event.

The following example demonstrates the use of the OnPageChange event. The
example updates a label on a form to display information about the current
page:

  procedure TMainForm.ApdFaxViewer1PageChange(Sender: TObject);
  begin
    if (ApdFaxViewer1.FileName <> '') then
      StatusPanel.Caption :=
        Format('  Viewing page %d of %d in %s',
        [ApdFaxViewer1.ActivePage, AFaxViewer1.NumPages,
        ApdFaxViewer1.FileName])
    else
      StatusPanel.Caption := '  No file loaded';
  end;

property OnViewerError : TViewerErrorEvent

TViewerErrorEvent = procedure(Sender : TObject; ErrorCode : Integer) of object;

=> Defines and event handler that reports fax viewer errors.

When the LoadWholeFax property is False, the TApdFaxViewer is
sometimes forced to load faxes in the background. When this happens,
the component cannot raise exceptions. In situations like this, then
OnViewerError event is called to notify the user of an error.

ErrorCode contains the number of the error that occurred. It can be
any one of the ecXxx error codes (see the manual for details).


20. OOMISC - TEmuCommand
=======================================================================
The field EmuType was added to the TEmuCommand record structure.  This
field can be used to determine what type of emulator created the TEmuCommand
record.

The complete record structure is as follows:

  {record type used to describe a command and its parameters}
  TEmuCommand = record
    Ch      : Char;                 {Character}
    Cmd     : Byte;                 {Command}
    X, Y    : Byte;                 {Coordinates}
    FColor  : Byte;                 {Foreground color}
    BColor  : Byte;                 {Background color}
    ExtAttr : Byte;                 {Extended attributes}
    EmuType : Byte;                 {Emulator Type}
    case Byte of
      1 : (Other  : array[1..MaxOther] of Byte);  {Other data}
      2 : (OtherStr : String[10]);
  end;


21. Printer driver issues
=======================================================================
The printer driver installation process was changed. The printer driver
installation units no longer use the global file PDRVINST.INC to
specify the name and properties of all printer drivers. Now each
printer driver has its own resource file that includes the string table
listing the printer name, port name, and other fields. The files
APFFILE.RC and APFSENDF.RC show examples of these string tables.

The InstallDriver function in PDRVINST.PAS now requires the filename of
the printer driver to be installed. This filename can include a path to
the driver along with the filename or just the filename alone.

A version resource was added to the printer driver engine. This
version resource is located in APFPDENG.RC. It includes the version
number of Async Professional for Delphi, the version number of the
printer driver engine, and the default copyright message displayed in
the printer driver "About" box. The installation routines currently do
not use the version information, but a future release will use the
version information to prevent installation of an older printer driver
over a newer driver.

The printer driver name entry, which was located in the APFPDENG.RC
resource file, was moved to the resource file for each printer driver.
Moving this string table entry out of the printer driver engine's file
provides the ability to customize print drivers without changing the
printer driver engine. However, as stated in the manual, this string
table entry needs to be added back into the APFPDENG.RC file if you
want to edit any printer driver parameters with the DDK utility
UniTool.Exe.

When the supporting files (i.e., UNIDRV.DLL and related files) required
by the printer driver are not already installed on the user's machine,
extracting these files during the printer driver installation under
Windows 95 can take several seconds. During this time it may appear as
though the program has stopped running, although the files do continue
to be unpacked and installed in the background.


22. SendFax/RcvFax Demonstration programs
=======================================================================
TAPI support was added to the SendFax and RcvFax demonstration
programs. Even when TAPI support is not enabled in the operating
system, the TAPI component is still present and can be used to select
direct comports as well as (or instead of) TAPI devices.

The main screen of each program has a new button labelled "Select
port". Press this button to pop up the "Device Selection" form. This is
a small form with a dropdown combo box and Ok/Cancel buttons. The
dropdown combo box shows all available TAPI devices, followed by all
available comports. If TAPI is not available or the program was
compiled in 16-bit mode, then only comports are shown. Highlight the
desired TAPI device or comport and press the OK button. Press the
Cancel button to return the main screen without selecting a new device.


23. Corrections to the Manual
=======================================================================

p. 516      In the documentation for the TApdFaxPrinter, the property
            named FaxPrintLog should be FaxPrinterLog.

