/*DDK*************************************************************************/
/*                                                                           */
/* COPYRIGHT (C) Lexmark Corporation, 1989                                   */
/* COPYRIGHT    Copyright (C) 1995 IBM Corporation                           */
/*                                                                           */
/*    The following IBM OS/2 WARP source code is provided to you solely for  */
/*    the purpose of assisting you in your development of OS/2 WARP device   */
/*    drivers. You may use this code in accordance with the IBM License      */
/*    Agreement provided in the IBM Device Driver Source Kit for OS/2. This  */
/*    Copyright statement may not be removed.                                */
/*                                                                           */
/*****************************************************************************/
/**************************************************************************
 *
 * SOURCE FILE NAME = PRDMMAIN
 *
 * DESCRIPTIVE NAME =
 *
 *
 * VERSION
 *
 * DATE
 *
 * DESCRIPTION
 *
 * FUNCTIONS   prdm_MainDlgProc
 *             prdm_ControlProc
 *             prdm_InitFormsDlg
 *             prdm_InitFormListTemplate
 *             prdm_InitFormList
 *             prdm_PaintFormTemplate
 *             prdm_PaintForm
 *             prdm_DeleteForm
 *             prdm_DigitToASCII
 *             prdm_TextFromNumeric
 *             prdm_ReadWordFromDecText
 *
 * ENTRY POINTS:
 *
 * DEPENDENCIES:
 *
 * NOTES
 *
 *
 * STRUCTURES
 *
 * EXTERNAL REFERENCES
 *
 * EXTERNAL FUNCTIONS
 *
*/

#define INCL_32                           /* CON3201 */
#define INCL_DOSPROCESS                   /* CON3201 */
#define INCL_WINHELP
#define INCL_DOSSEMAPHORES
#define INCL_GPIERRORS
#define INCL_GPIPRIMITIVES
#define INCL_WINHEAP
#define INCL_GPIBITMAPS
#define INCL_DOSMODULEMGR
#define INCL_WINFRAMEMGR
#define INCL_WINLISTBOXES
#define INCL_WINBUTTONS
#define INCL_WINERRORS
#define INCL_WINDIALOGS
#define INCL_WINSHELLDATA
#define INCL_WINENTRYFIELDS
#define INCL_WINMESSAGEMGR
#define INCL_WININPUT
#define INCL_WINMENUS
#define INCL_WINWINDOWMGR
#define INCL_WINPOINTERS
#include <os2.h>
#undef INCL_DOSPROCESS                    /* CON3201 */
#undef INCL_DOSSEMAPHORES
#undef INCL_GPIERRORS
#undef INCL_GPIPRIMITIVES
#undef INCL_WINHEAP
#undef INCL_GPIBITMAPS
#undef INCL_DOSMODULEMGR
#undef INCL_WINFRAMEMGR
#undef INCL_WINLISTBOXES
#undef INCL_WINBUTTONS
#undef INCL_WINERRORS
#undef INCL_WINDIALOGS
#undef INCL_WINSHELLDATA
#undef INCL_WINENTRYFIELDS
#undef INCL_WINMESSAGEMGR
#undef INCL_WININPUT
#undef INCL_WINMENUS
#undef INCL_WINWINDOWMGR
#undef INCL_WINPOINTERS
#undef INCL_WINHELP

#define INCL_DDIBUNDLES
#define INCL_DDIFONTSTRUCS
#define INCL_DDIDEFS
#include <pmddi.h>
#undef INCL_DDIBUNDLES
#undef INCL_DDIFONTSTRUCS
#undef INCL_DDIDEFS

#define INCL_WINP_SELSERVER
#define INCL_WINP_SELECTIVE
#define INCL_WINP_SEI
#include <pmwinx.h>
#undef INCL_WINP_SELSERVER
#undef INCL_WINP_SELECTIVE
#undef INCL_WINP_SEI

#define INCL_WINSHELLDATA
/* #include <pmshlp.h>                                              DLM01 */
#define INCL_WINSHELLDATA

#define INCL_HELP
#define PRDMTYPE_INCL
#define NO_CONSTANT_INCL
#include <prdinclt.h>
#undef INCL_HELP
#undef PRDMTYPE_INCL
#undef NO_CONSTANT_INCL
#undef INCL_32                          /* CON3201 */

#include <prdconse.h>
#include <prddcone.h>
#include <prdmcone.h>

#include <prdmextf.h>
#include <prdmhelp.h>
#include <prdyextf.h>


/******************************************************************************/
/* Set up external accesses                                                   */
/******************************************************************************/
extern HMODULE             prdd_ModHandle;
extern DModeDataType       DMData;
extern lpDMSettings        pDMSettings;
extern DMIniEntryType      DMIniEntry[LARGEST_NO_OF_PRINTERS];

extern CHAR                szMessage[SLEN_BOX_MESSAGE];

extern lpDDTType           DDT [];
extern lpDVTCPSource       DVTCodePageCaps [];
extern HWND                PPhwnd;                       /* PD00364           */
extern BYTE                UStoNLS238X [];               /* PD00651, PD00657  */
extern BYTE                NLStoUS238X [];               /* PD00651, PD00657  */
extern BYTE                UStoNLS239X [];               /* PD00651, PD00657  */
extern BYTE                NLStoUS239X [];               /* PD00651, PD00657  */



/******************************************************************************/
/*                                                                            */
/*   FUNCTION: prdm_MainDlgProc                                               */
/*                                                                            */
/*   PARAMETERS:                                                              */
/*                                                                            */
/*   Standard dialog box control procedure parameter block                    */
/*                                                                            */
/*   HWND    hwnd;                                                            */
/*   USHORT  msg;                                                             */
/*   MPARAM  lparam1;                                                         */
/*   MPARAM  lparam2;                                                         */
/*                                                                            */
/*   DESCRIPTION:                                                             */
/*                                                                            */
/*   This function interprets the users responses to the dialog boxes.        */
/*   It works for either dialog box (it effectively calls itself for          */
/*   the define forms box). DMData.DialogId is a flag to allow the            */
/*   function to differentiate between different dialog modes.  The           */
/*   function switches according to which message it has received.            */
/*                                                                            */
/******************************************************************************/
/*CON3201
MRESULT pascal far _loadds prdm_MainDlgProc( hwnd,
                                             msg,
                                             lparam1,
                                             lparam2 )

HWND    hwnd;
USHORT  msg;
MPARAM  lparam1;
MPARAM  lparam2;
                   */
MRESULT  prdm_MainDlgProc(HWND    hwnd,
                          USHORT  msg,
                          MPARAM  lparam1,
                          MPARAM  lparam2)


{
#define TFUNC "prdm_MainDlgProc"

    /**************************************************************************/
    /* Local Variables                                                        */
    /**************************************************************************/
    MRESULT       DlgResult;   /* The result of calls to Win...               */
                               /* functions                                   */
    USHORT        Result;      /* Function call return values                 */
    lpDDTType     pDDT;        /* Pointer to DDT                              */
    lpDVTCPSource  CodePageCaps;       /* Code Page info for this             */
                                       /* printer type                        */
    ERRORID       Error;               /*                                     */

    /**************************************************************************/
    /* Set up pointer to the DDT.                                             */
    /**************************************************************************/
    pDDT = DDT[pDMSettings->PrinterType];

#ifdef OMIT
    /**************************************************************************/
    /* Trap help messages                                                     */
    /**************************************************************************/
    if ( (msg >= HM_MSG_BASE) && (msg <= HM_INFORM))
    {
        haltproc();
    }
#endif

    /**************************************************************************/
    /* Make sure this function will return false unless user has              */
    /* selected ENTER and prdm_EnterValues has worked.                        */
    /**************************************************************************/
    Result = FALSE;

    switch (msg)
    {
        case WM_HELP:
            /******************************************************************/
            /* PD00199 : The message is always going to go to the             */
            /* default handler, but give the driver a chance to do            */
            /* a little bit of processing first.                              */
            /******************************************************************/
            (VOID) prdm_HelpMessageProcessing ( hwnd, msg, lparam1, lparam2 );

            /******************************************************************/
            /* Now pass message to the default message handler.               */
            /******************************************************************/
            return(WinDefDlgProc( hwnd, msg, lparam1, lparam2 ));

        case WM_CLOSE:
            /******************************************************************/
            /* Trap Close from system menu                                    */
            /* Note: this will fall into WM_COMMAND with CANCEL set           */
            /******************************************************************/
/*          SHORT1FROMMP(lparam1) = DB_PSH_PPCANCEL;                  CON3201 */
            lparam1 = MPFROM2SHORT( DB_PSH_PPCANCEL,         /*CON3201*/
                                    SHORT2FROMMP(lparam1) ); /*CON3201*/

        case WM_COMMAND:
            /******************************************************************/
            /* If any of the push buttons are pressed (except ENTER           */
            /* or CANCEL) assume that the body data is going to be            */
            /* changed - therefore set the change flag to ensure the          */
            /* new data is written to the INI entry.                          */
            /******************************************************************/
            if ( SHORT1FROMMP(lparam1) == DB_PSH_CODEPAGES      ||
                 SHORT1FROMMP(lparam1) == DB_PSH_CARTRIDGES     ||
                 SHORT1FROMMP(lparam1) == DB_PSH_DEFAULT_FONT   ||
                 SHORT1FROMMP(lparam1) == DB_PSH_DOWNLOAD       ||
                 SHORT1FROMMP(lparam1) == DB_PSH_ADD_FORM       ||
                 SHORT1FROMMP(lparam1) == DB_PSH_CHANGE_FORM    ||
                 SHORT1FROMMP(lparam1) == DB_PSH_DELETE_FORM    ||
                 SHORT1FROMMP(lparam1) == DB_PSH_CONNECTIONS )
            {
                TRACE4(TFUNC, "Change flag set", FNULL, 0);
                DMData.BodyDataChanged = TRUE;
            }

            /******************************************************************/
            /* The message is a command (ie a button) so switch               */
            /* depending on which button it was.                              */
            /******************************************************************/
            switch (SHORT1FROMMP(lparam1))
            {
                case DB_PSH_PPENTER:
                    /**********************************************************/
                    /* For ENTER try to save the current values in            */
                    /* this dialog box.  Note that if this call is            */
                    /* succesful processing falls through to the              */
                    /* CANCEL label where the dialog box is dismissed         */
                    /**********************************************************/
                    if ( !(Result = prdm_EnterValues( hwnd )) )
                        break;

                case DID_CANCEL:
                case DB_PSH_PPCANCEL:
                    /**********************************************************/
                    /* HELP1 : Tidied this arm by moving font memory          */
                    /* release and disable into the DialogId test arm         */
                    /**********************************************************/
                    /**********************************************************/
                    /* Special case the exit from the main printer            */
                    /* properties dialog box so that we can tidy up           */
                    /* and prompt                                             */
                    /**********************************************************/
                    if (DMData.DialogId == pDDT->DDTPP_DialogId)
                    {
                        /******************************************************/
                        /* If cancel was pressed then check that they         */
                        /* really want to do that. if they don't then         */
                        /* qw just break out of the case statement.           */
                        /******************************************************/
                        if (SHORT1FROMMP(lparam1) != DB_PSH_PPENTER )
                        {
                            if ( MBID_NO == prdm_DispMessageBox(
                                          hwnd,
                                          IDS_CONFIRM_CANCEL,
                                          SLEN_BOX_MESSAGE,
                                          DB_PSH_CANCEL,
                                          MB_YESNO | MB_ICONQUESTION ) )
                                break;
                        }

                        /******************************************************/
                        /* They are really going so tidy up....               */
                        /******************************************************/
                        prdm_ReleaseFontTableMemory();
                        prdm_DisableHelp();
                    }

                    /**********************************************************/
                    /* ... and dismiss the dialog.                            */
                    /**********************************************************/
                    WinDismissDlg( hwnd, Result);
                    break;

                case DB_PSH_CODEPAGES:
                    /**********************************************************/
                    /* Cannot go into the code page dialog box if the         */
                    /* memory is not available                                */
                    /**********************************************************/
                    CodePageCaps =
                              DVTCodePageCaps[pDMSettings->PrinterType];

                    /**********************************************************/
                    /* DIAL/NILE : Can now go in when printer has             */
                    /* partial memory.                                        */
                    /**********************************************************/
                    if ( (pDMSettings->DownCPMemAvail
                                            == DOWN_CP_MEM_NOT_AVAIL) &&
                        !(pDDT->DDTFontFlags & DDT_DOWN_CP_MEM_SUBSET_AVAIL) )
                    {

                         prdm_DispMessageBox( hwnd,
                                              IDS_CP_NOT_SUPPORTED,
                                              SLEN_BOX_MESSAGE,
                                              pDDT->DDTPP_DialogId,
                                              MB_OK | MB_ICONEXCLAMATION );
                         break;
                    }

                    /**********************************************************/
                    /* To change code page font options we need the           */
                    /* DB_CODE_PAGE_LIST dialog window.                       */
                    /**********************************************************/
                    DMData.DialogId = DB_CODE_PAGE_LIST;

/* CON3201          DlgResult =  WinDlgBox( (HWND)HWND_DESKTOP,               */
                                 WinDlgBox( (HWND)HWND_DESKTOP,
                                            hwnd,
                                            (PFNWP)prdm_CodePageDlgProc,
                                            DMData.HModule,
                                            DMData.DialogId,
                                            (PVOID)NULL);

                    /**********************************************************/
                    /* After processing this dialog box set the               */
                    /* DialogId to pDDT->DDTPP_DialogId.                      */
                    /**********************************************************/
                    DMData.DialogId = pDDT->DDTPP_DialogId;

                    /**********************************************************/
                    /* Set the active window help table.                      */
                    /* PD00263 : Remove set active window. Now window         */
                    /* always appeasr in the same place.                      */
                    /**********************************************************/
//                  WinSendMsg( DMData.hwndHelp,
//                              HM_SET_ACTIVE_WINDOW,
//                              hwnd,
//                              hwnd );

                    break;


                case DB_PSH_DEFAULT_FONT:
                    /**********************************************************/
                    /* Put up the list of default fonts.                      */
                    /**********************************************************/
                    DMData.DialogId = pDDT->DDTDEFNT_DialogId;

/* CON3201          DlgResult =  WinDlgBox( (HWND)HWND_DESKTOP,               */
                                 WinDlgBox( (HWND)HWND_DESKTOP,
                                            hwnd,
                                            (PFNWP)prdm_DfltFontDlgProc,
                                            DMData.HModule,
                                            DMData.DialogId,
                                            (PVOID)NULL);

                    /**********************************************************/
                    /* After processing this dialog box set the               */
                    /* DialogId to pDDT->DDTPP_DialogId.                      */
                    /**********************************************************/
                    DMData.DialogId = pDDT->DDTPP_DialogId;

                    /**********************************************************/
                    /* Set the active window help table.                      */
                    /* PD00263 : Remove set active window, now window         */
                    /* always appears in the same place.                      */
                    /**********************************************************/
//                  WinSendMsg( DMData.hwndHelp,
//                              HM_SET_ACTIVE_WINDOW,
//                              hwnd,
//                              hwnd );

                    break;

                case DB_PSH_CHANGE_FORM:
                    /**********************************************************/
                    /* Go into the CHANGE_FORM dialog.                        */
                    /* Prevent the user from changing a pre-defined           */
                    /* form.                                                  */
                    /**********************************************************/
                    if ( pDMSettings->SelectedForm <
                                             pDDT->DDTNoOfDefinedForms )
                    {
                        prdm_DispMessageBox( hwnd,
                                             IDS_CHANGE_PREDEF,
                                             SLEN_BOX_MESSAGE,
                                             DB_PSH_DELETE_FORM,
                                             MB_OK | MB_ICONEXCLAMATION );
                        break;
                    }
                    /**********************************************************/
                    /*  INKJET : The 4072 has the non-printable margin flag   */
                    /*  but uses the dialog DB_ADD_MARGIN dialog.             */
                    /**********************************************************/
                    if ( ( pDDT->DDTFormFlags & DDT_NON_PRINTABLE_MARGIN ) &&
                         ( pDDT->DDTDriverType != DDT_IBM42XX_DRV ) )
                        DMData.DialogId = DB_CHANGE_FORM_MARGIN;
                    else
                        DMData.DialogId = DB_CHANGE_FORM;

/* CON3201          DlgResult =  WinDlgBox( (HWND)HWND_DESKTOP,               */
                                 WinDlgBox( (HWND)HWND_DESKTOP,
                                            hwnd,
                                            (PFNWP)prdm_MainDlgProc,
                                            DMData.HModule,
                                            DMData.DialogId,
                                            (PVOID)NULL );

                    /**********************************************************/
                    /* After processing form dialog box set the               */
                    /* DialogId to pDDT->DDTPP_DialogId.                      */
                    /**********************************************************/
                    DMData.DialogId = pDDT->DDTPP_DialogId;

                    /**********************************************************/
                    /* HELP2 : Set the active window                          */
                    /* PD00263 : Remove set active window. Now window         */
                    /* always appears in the same place.                      */
                    /**********************************************************/
//                  WinSendMsg( DMData.hwndHelp,
//                              HM_SET_ACTIVE_WINDOW,
//                              hwnd,
//                              hwnd );

                    break;

                case DB_PSH_ADD_FORM:
                    /**********************************************************/
                    /* Enter the ADD_FORM dialog window.                      */
                    /*  INKJET : The 4072 has the non-printable margin flag   */
                    /*  but uses the dialog DB_ADD_MARGIN dialog.             */
                    /**********************************************************/
                    if ( ( pDDT->DDTFormFlags & DDT_NON_PRINTABLE_MARGIN ) &&
                         ( pDDT->DDTDriverType != DDT_IBM42XX_DRV ) )
                        DMData.DialogId = DB_ADD_FORM_MARGIN;
                    else
                        DMData.DialogId = DB_ADD_FORM;

/* CON3201          DlgResult =  WinDlgBox( (HWND)HWND_DESKTOP,               */
                                 WinDlgBox( (HWND)HWND_DESKTOP,
                                            hwnd,
                                            (PFNWP)prdm_MainDlgProc,
                                            DMData.HModule,
                                            DMData.DialogId,
                                            (PVOID)NULL );

                    /**********************************************************/
                    /* After processing form dialog box set the               */
                    /* DialogId to pDDT->DDTPP_DialogId.                      */
                    /**********************************************************/
                    DMData.DialogId = pDDT->DDTPP_DialogId;

                    /**********************************************************/
                    /* HELP2 : Set the active window                          */
                    /* PD00263 : Remove set active window. Now window         */
                    /* always appears in the same place.                      */
                    /**********************************************************/
//                  WinSendMsg( DMData.hwndHelp,
//                              HM_SET_ACTIVE_WINDOW,
//                              hwnd,
//                              hwnd );

                    break;

                case DB_PSH_DELETE_FORM:
                    /**********************************************************/
                    /* Call delete form subroutine.                           */
                    /**********************************************************/
                    prdm_DeleteForm( hwnd );
                    break;

                case DB_PSH_CONNECTIONS:
                    /**********************************************************/
                    /* To change paper source information we need the         */
                    /* FORM_CONNECTIONS dialog window. There is               */
                    /* separate identifier for each set of printers.          */
                    /* Rather than using another DDT field, let's             */
                    /* just fiddle with the main dialogid.                    */
                    /**********************************************************/
                    DMData.DialogId = pDDT->DDTFORMC_DialogId;

/* CON3201          DlgResult =  WinDlgBox( (HWND)HWND_DESKTOP,               */
                                 WinDlgBox( (HWND)HWND_DESKTOP,
                                              hwnd,
                                              (PFNWP)prdm_ConnDlgProc,
                                              DMData.HModule,
                                              DMData.DialogId,
                                              (PVOID)NULL);

                    /**********************************************************/
                    /* After processing this dialog box set the               */
                    /* DialogId to pDDT->DDTPP_DialogId.                      */
                    /**********************************************************/
                    DMData.DialogId = pDDT->DDTPP_DialogId;

                    /**********************************************************/
                    /* Set the active window help table.                      */
                    /* PD00263 : Remove set active window, now window         */
                    /* always appears in the same place.                      */
                    /**********************************************************/
//                  WinSendMsg( DMData.hwndHelp,
//                              HM_SET_ACTIVE_WINDOW,
//                              hwnd,
//                              hwnd );

                    break;

                default:
                    break;
            }
            /*.. switch (SHORT1FROMMP(lparam1)) ..............................*/

            break;

        case WM_CONTROL:
            /******************************************************************/
            /* The message is a control (ie something in a listbox or         */
            /* a textbox for us to handle).                                   */
            /******************************************************************/
            if ( prdm_ControlProc( hwnd,
                                   SHORT1FROMMP(lparam1),
                                   SHORT2FROMMP(lparam1) ) != OK )
            {
                return(FNULL);
            }

            break;

        case WM_INITDLG:
            /******************************************************************/
            /* Initialise the dialog boxes.                                   */
            /* If we are initialising the current options dialog then         */
            /* store the value of hwnd for later use.                         */
            /******************************************************************/
            if ( DMData.DialogId == pDDT->DDTPP_DialogId )
            {
                /**************************************************************/
                /* PD00364 : Setting Global variable to the main              */
                /* printer properties dialog.                                 */
                /* PD00517 : Moved this bit of code so that it is only done   */
                /* when we are in the main printer dialog and not the add or  */
                /* change form dialog.                                        */
                /**************************************************************/
                PPhwnd = hwnd;

                DMData.hwndMain = hwnd;
                prdm_InitMainDlg( hwnd );
            }
            else
            {
                prdm_InitFormsDlg( hwnd );
            }

            break;
        case HM_QUERY_KEYS_HELP:
            /******************************************************************/
            /*  PD00637 : Return Keys Help panel ID if Keys Help is requested */
            /******************************************************************/
            return (MRESULT) IDH_KEYS;
            break;

        default:
            /******************************************************************/
            /* Pass any other messages to the default handler.                */
            /******************************************************************/
            return(WinDefDlgProc( hwnd, msg, lparam1, lparam2 ));
            break;
    }

    /*.. switch (msg) ........................................................*/

}
#undef TFUNC






/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prdm_ControlProc                                       */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   HWND   hwnd;          The handle for the dialog window we are in */
/*   USHORT WindowId;      The ID of the window (in the dialog box)   */
/*                         which the message refers to                */
/*   USHORT NotifyCode;    The message about WindowId                 */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   This function is called when prdm_MainDlgProc recieves a message */
/*   relating to a listbox or a textbox.  For some of these events    */
/*   we must do some processing or checking - the rest can be left    */
/*   to default case as we don't care what happens as the dialog      */
/*   box will control everything.                                     */
/*                                                                    */
/*   PD00183 : Tidied considerably for sources re-write. Could save   */
/*             all values here, then remove the code from QueryMain-  */
/*             Selections.                                            */
/**********************************************************************/
/*CON3201
USHORT pascal prdm_ControlProc( hwnd,
                                WindowId,
                                NotifyCode )

HWND       hwnd;
USHORT     WindowId;
USHORT     NotifyCode;
         */
USHORT prdm_ControlProc(HWND       hwnd,
                        USHORT     WindowId,
                        USHORT     NotifyCode)

{
#define TFUNC "prdm_ControlProc"

    /******************************************************************/
    /* Local Variables                                                */
    /******************************************************************/
    MRESULT     DlgResult;              /* Result of Win.. calls       */
    USHORT      FormIndex;              /* Index of selected form      */
    USHORT      i;                      /* Loop control variable       */
    lpDDTType   pDDT;                   /* Pointer to DDT              */
    RadCtrlType Source;                 /* For sources                 */


    TRACE4(TFUNC, "WindowId", &WindowId, 1);
    TRACE4(TFUNC, "NotifyCode", &NotifyCode, 1);

    /******************************************************************/
    /* Set up pointer to the DDT.                                     */
    /******************************************************************/
    pDDT = DDT[pDMSettings->PrinterType];

    /******************************************************************/
    /* PD00419 :       dialog ID for PP2300 series printer properties */
    /******************************************************************/
    switch (DMData.DialogId)
    {
      case DB_DLG_PPPROS:
      case DB_DLG_PP4224:
      case DB_DLG_PPQUES:
      case DB_DLG_PP3816:
      case DB_DLG_PP2300_2:


        /**************************************************************/
        /* Trap a list box selection. Careful about this test because */
        /* LN_SELECT and BN_CLICKED are the same value.               */
        /**************************************************************/
        if (( NotifyCode == LN_SELECT ) &&
            ( WindowId == DB_LST_DEFINED_FORMS ) )
        {
            /**********************************************************/
            /* We need to keep the selected form number up to date.   */
            /* Why?                                                   */
            /**********************************************************/
            pDMSettings->SelectedForm = (USHORT)WinSendDlgItemMsg(
                                           hwnd,
                                           DB_LST_DEFINED_FORMS,
                                           LM_QUERYSELECTION,
                                           (MPARAM)(ULONG)LIT_FIRST,
                                           (MPARAM)FNULL );
        }

        /**************************************************************/
        /* Trap a button click on a radio button.                     */
        /**************************************************************/
        else if ( NotifyCode == BN_CLICKED )
        {
            /**********************************************************/
            /* The following items all give values for the source     */
            /* index. First the 42XX items.                           */
            /**********************************************************/
            if ( WindowId == DB_RAD_42XX_F1 )
               pDMSettings->SourceIndex = 0;

            else if ( WindowId == DB_RAD_42XX_F2 )
               pDMSettings->SourceIndex = 1;

            else if ( WindowId == DB_RAD_42XX_F3 )
               pDMSettings->SourceIndex = 2;

            else if ( WindowId == DB_RAD_42XX_F4 )
               pDMSettings->SourceIndex = 3;

            /******************************************************************/
            /*  PD00651 : Add check for a change in NLS version for Nile/     */
            /*  Tiber.  This was moved here from prdmsubr.c                   */
            /******************************************************************/
            /******************************************************************/
            /* DIAL/NILE :                                                    */
            /* Nile/Tiber have two versions of the machine, U.S and NLS       */
            /* Must get the type of machine.                                  */
            /******************************************************************/
            else if (WindowId == DB_RAD_NLS_MACHINE)
            {
               if (pDMSettings->MachineType == US_MACHINE)
               {
                  if ( (pDDT->DDTDriverType == DDT_IBM42XX_DRV) &&
                       ((pDMSettings->PrinterType == IBM_NILE_24) ||
                        (pDMSettings->PrinterType == IBM_TIBER_24)) )
                     {
                        /******************************************************/
                        /*  If the default font has an index greater than 94  */
                        /*  (Gothic PS code page 865) then display a message  */
                        /*  that tells the user that the default font is      */
                        /*  reverting to the default resident font.           */
                        /******************************************************/
                        if (DMData.DfltFontInfo.Info.Index > 94)
                        {
                           (void) prdm_DispMessageBox(
                                            hwnd,
                                            IDS_CODE_PAGE_REMOVED,
                                            SLEN_BOX_MESSAGE,
                                            DB_DLG_PP2300_2,
                                            MB_OK | MB_ICONASTERISK );
                        }
                        DMData.DfltFontInfo.Info.Index = UStoNLS239X[DMData.DfltFontInfo.Info.Index];
                     }
                  else
                     DMData.DfltFontInfo.Info.Index = UStoNLS238X[DMData.DfltFontInfo.Info.Index];

                  prdm_ReleaseFontTableMemory();
                  pDMSettings->MachineType = NLS_MACHINE;
               }
            }
            else if (WindowId == DB_RAD_US_MACHINE)
            {
               if (pDMSettings->MachineType == NLS_MACHINE)
               {
                  if ( (pDDT->DDTDriverType == DDT_IBM42XX_DRV) &&
                       ((pDMSettings->PrinterType == IBM_NILE_24) ||
                        (pDMSettings->PrinterType == IBM_TIBER_24)) )
                     DMData.DfltFontInfo.Info.Index = NLStoUS239X[DMData.DfltFontInfo.Info.Index];
                  else
                     DMData.DfltFontInfo.Info.Index = NLStoUS238X[DMData.DfltFontInfo.Info.Index];

                  prdm_ReleaseFontTableMemory();
                  pDMSettings->MachineType = US_MACHINE;
               }
            }


            /**********************************************************/
            /* The following items all give values for the added      */
            /* feed.                                                  */
            /**********************************************************/
            else if ( WindowId == DB_RAD_NO_FEED )
                pDMSettings->AddedFeed = FD_NONE;

            else if ( WindowId == DB_RAD_ENVELOPE )
                pDMSettings->AddedFeed = FD_ENVELOPE;

            else if ( WindowId == DB_RAD_MM_NONE )
                pDMSettings->AddedFeed = FD_NONE;

            else if ( WindowId == DB_RAD_MM_ENVELOPE )
                pDMSettings->AddedFeed = FD_ENVELOPE;

            else if ( WindowId == DB_RAD_MM_ENVPLUS )
                pDMSettings->AddedFeed = FD_MULTIMEDIA;

            else if ( WindowId == DB_RAD_MM_100_SHEET )
                pDMSettings->AddedFeed = FD_100_SHEET;


            /**********************************************************/
            /* These affect the DownCPMemAvail field                  */
            /**********************************************************/
            else if ( WindowId == DB_RAD_CPMEM_NO )
                pDMSettings->DownCPMemAvail = DOWN_CP_MEM_NOT_AVAIL;

            else if ( WindowId == DB_RAD_CPMEM_YES )
                pDMSettings->DownCPMemAvail = DOWN_CP_MEM_AVAIL;

            /**********************************************************/
            /* These affect the DuplexEnabled setting                 */
            /**********************************************************/
            else if ( WindowId == DB_RAD_DUP_ENABLED ||
                      WindowId == DB_RAD_DUP_DISABLED )
            {
                /******************************************************/
                /* Grey or ungrey the duplex option.                  */
                /******************************************************/
                Source.RadNumber    = 3;
                Source.RadItem[0]   = DB_RAD_SIMPLEX;
                Source.RadItem[1]   = DB_RAD_NORMAL;
                Source.RadItem[2]   = DB_RAD_TUMBLE;

                if ( WindowId == DB_RAD_DUP_ENABLED )
                {
                    /**************************************************/
                    /* The duplex option has been enabled.            */
                    /**************************************************/
                    Source.RadGreyed    = FALSE;
                    Source.RadHighlight = pDMSettings->SimDup;
                    pDMSettings->DuplexEnabled = TRUE;
                }
                else
                {
                    /**************************************************/
                    /* The duplex option has been disabled.           */
                    /**************************************************/
                    Source.RadGreyed    = TRUE;
                    Source.RadHighlight = Source.RadNumber + 1;
                    pDMSettings->DuplexEnabled = FALSE;
                }

                /******************************************************/
                /* Now change the state                               */
                /******************************************************/
                (VOID) prdm_RadioButtonControl (hwnd, &Source);

            }

            /**********************************************************/
            /* These affect the SimDup field.                         */
            /**********************************************************/
            else if ( WindowId == DB_RAD_SIMPLEX )
                pDMSettings->SimDup = DUPLEX_MODE_SIMPLEX;

            else if ( WindowId == DB_RAD_NORMAL )
                pDMSettings->SimDup = DUPLEX_MODE_NORMAL;

            else if ( WindowId == DB_RAD_TUMBLE )
                pDMSettings->SimDup = DUPLEX_MODE_TUMBLE;

        }
        /*...if ( NotifyCode == BN_CLICKED )..........................*/

        break;

      case DB_ADD_FORM:
      case DB_CHANGE_FORM:
      case DB_ADD_FORM_MARGIN:
      case DB_CHANGE_FORM_MARGIN:
        /**************************************************************/
        /* Switch according to which window originated the message.   */
        /**************************************************************/
        switch ( WindowId )
        {
            case DB_LST_FORMS_LIST:
                /******************************************************/
                /* We come through this branch for Add and Change.    */
                /******************************************************/
                if ( NotifyCode == LN_SELECT )
                {
                    /**************************************************/
                    /* A form has been selected so find out its       */
                    /* number and then call prdm_PaintForm to put its */
                    /* dimensions into the text boxes.                */
                    /**************************************************/
                    FormIndex = (USHORT) WinSendDlgItemMsg(
                                           hwnd,
                                           DB_LST_FORMS_LIST,
                                           LM_QUERYSELECTION,
                                           (MPARAM)(ULONG)LIT_FIRST,
                                           (MPARAM)FNULL );

                   /***************************************************/
                   /* There are two versions of prdm_PaintForm.  The  */
                   /* "template" version handles only the             */
                   /* pre-defined forms - these are the only ones     */
                   /* which can be selected as form templates when    */
                   /* DDT_FORM_TEMPLATES is set on.  The "non-        */
                   /* template" version can handle all forms.         */
                   /* The template version also records in DMData the */
                   /* form no.used as a template.                     */
                   /***************************************************/
#ifdef DDT_FORM_TEMPLATES
                    prdm_PaintFormTemplate( hwnd,
                                            SHORT1FROMMR(FormIndex) );
#else
                    /**************************************************/
                    /* The form name is not "painted".                */
                    /**************************************************/
                    prdm_PaintForm( hwnd,
                                    SHORT1FROMMR(FormIndex),
                                    FALSE );
#endif

                    /**************************************************/
                    /* Set the focus to the selected form name        */
                    /**************************************************/
                    (void)WinSetFocus( HWND_DESKTOP,
                                       WinWindowFromID(hwnd,
                                                       DB_LST_FORMS_LIST));

                }
                /*.. if ( NotifyCode == LN_SELECT ) ..................*/


#ifdef DDT_FORM_TEMPLATES
                /******************************************************/
                /* Check if the list of form templates has received   */
                /* focus.                                             */
                /******************************************************/
                if ( NotifyCode == LN_SETFOCUS )
                {
                    /**************************************************/
                    /* Check if a template has been selected. If the  */
                    /* user has tabbed to the list of templates  no   */
                    /* template may be selected - if so we should     */
                    /* highlight the first template.                  */
                    /**************************************************/
                    FormIndex = (USHORT) WinSendDlgItemMsg(
                                             hwnd,
/* CON3201 -  FORMS_LIST is not defined */   FORMS_LIST,
                                             LM_QUERYSELECTION,
                                             (MPARAM)(ULONG)LIT_FIRST,
                                             (MPARAM)FNULL );

                    if ( FormIndex == (USHORT)LIT_NONE )
                    {
                        DlgResult = WinSendDlgItemMsg(
                                                 hwnd,
                                                 FORMS_LIST,
                                                 LM_SELECTITEM,
                                                 (MPARAM)(ULONG)0,
                                                 (MPARAM)(ULONG)TRUE );
                    }
                }
#endif /* DDT_FORM_TEMPLATES */

                break;

            default:
                break;
        }
        /*.. switch ( WindowId) .....................................*/

        break;
    }
    /*.. switch ( DialogId) ..........................................*/


    TRACE4( TFUNC, "Exit OK", FNULL, 0);
    return(OK);
}
#undef TFUNC






/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prdm_InitFormsDlg                                      */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   HWND      hwnd;         Handle of the dialog box                 */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   This function sets up the dialog box to the current values.      */
/*   For ADD_FORM/CHANGE_FORM it sets up the text entry limits in     */
/*   the text boxes and then for ADD_FORM it displays the defined     */
/*   forms names and selects the current form or for CHANGE_FORM it   */
/*   simply selects the current form.                                 */
/*                                                                    */
/**********************************************************************/
void prdm_InitFormsDlg(HWND hwnd )


{
#define TFUNC "prdm_InitFrmDlg"

    /******************************************************************/
    /* Local Variables                                                */
    /******************************************************************/
    MRESULT       DlgResult;   /* Result of a call to Win.. function  */
    USHORT        WndId;       /* ID for selecting items              */
    lpDDTType     pDDT;        /* Pointer to DDT                      */

    /******************************************************************/
    /* Set up pointer to the DDT.                                     */
    /******************************************************************/
    pDDT = DDT[pDMSettings->PrinterType];

    /******************************************************************/
    /* Turn off 'Close' and 'Task Manager' options on the system      */
    /* menu. No longer do this.                                       */
    /******************************************************************/
//  prdm_RemoveMenuOptions( hwnd );

    /******************************************************************/
    /* Set up the text entry limits in the entry boxes.               */
    /* First do the form name entry field and then do all the         */
    /* dimension entry fields.                                        */
    /* Only allow 31 characters to be entered. The 32nd is            */
    /* used if necessary for the name delimiter.                      */
    /******************************************************************/
    WinSendDlgItemMsg( hwnd,
                       DB_TXT_FORM_NAME,
                       EM_SETTEXTLIMIT,
                       MPFROM2SHORT((FORM_NAME_LENGTH-1), 0),
                       (MPARAM)0 );

    /******************************************************************/
    /* Loop through each textual window. They are assumed to be       */
    /* sequential.                                                    */
    /******************************************************************/
    for ( WndId  = DB_TXT_FORM_WIDTH;
          WndId <= DB_TXT_TOP_CLIP_LIMIT;
          WndId += 1    )
    {
        WinSendDlgItemMsg( hwnd,
                           WndId,
                           EM_SETTEXTLIMIT,
                           MPFROM2SHORT(NUMBER_LENGTH, 0),
                           (MPARAM)0 );
    }

    /******************************************************************/
    /* Display the defined forms names.  They are two versions of     */
    /* prdm_InitFormlist.  The "template" version displays only the   */
    /* pre-defined forms - these are the only ones which can be       */
    /* selected as form templates when DDT_FORM_TEMPLATES is set on.  */
    /* The "non- template" version displays all defined forms.        */
    /******************************************************************/

#ifdef DDT_FORM_TEMPLATES
    prdm_InitFormListTemplate( hwnd, DB_LST_FORMS_LIST );
#else
    prdm_InitFormList( hwnd, DB_LST_FORMS_LIST );
#endif

    /******************************************************************/
    /* Select the current form - this ensures we always have the      */
    /* source type (paper/envelope) and the units                     */
    /* (inches/millimetres) set up.  The form is then "painted"       */
    /* (under the WM_CONTROL processing) but without displaying the   */
    /* form name.                                                     */
    /******************************************************************/
    DlgResult = WinSendDlgItemMsg(
                        hwnd,
                        DB_LST_FORMS_LIST,
                        LM_SELECTITEM,
                        (MPARAM)(ULONG)pDMSettings->SelectedForm,
                        (MPARAM)(ULONG)TRUE );

    if ( DMData.DialogId == DB_CHANGE_FORM ||
         DMData.DialogId == DB_CHANGE_FORM_MARGIN )
    {
        /**************************************************************/
        /* The form name is displayed here - it is not changed        */
        /* when a new form is later selected.                         */
        /**************************************************************/
        prdm_PaintForm( hwnd,
                        (USHORT)pDMSettings->SelectedForm,
                        TRUE );
    }

    /******************************************************************/
    /* Set the active window                                          */
    /* PD00263 : Remove set active window. Now window always appears  */
    /* in the same place.                                             */
    /******************************************************************/
//  WinSendMsg( DMData.hwndHelp,
//              HM_SET_ACTIVE_WINDOW,
//              hwnd,
//              hwnd );

    /******************************************************************/
    /* Set focus to the form name                                     */
    /******************************************************************/
/*  DlgResult = WinSetFocus( HWND_DESKTOP,                            CON3201 */
                WinSetFocus( HWND_DESKTOP,
                             WinWindowFromID(hwnd, DB_TXT_FORM_NAME) );

}
#undef TFUNC





/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prdm_InitFormListTemplate                              */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   HWND   hwnd;      The handle for the dialog window we are in     */
/*   USHORT WndId;     The window ID for the window to put the forms  */
/*                     in (this function is called from the CURRENT_  */
/*                     OPTIONS dialog box and the ADD_FORMS dialog    */
/*                     box)                                           */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   This function sends messages to the window specified by WindId   */
/*   (a listbox) to insert all the pre-defined form names into it.    */
/*                                                                    */
/**********************************************************************/
void prdm_InitFormListTemplate(HWND hwnd, USHORT
                                             WndId )


{
#define TFUNC "prdm_IntFrmLsTm"

    /******************************************************************/
    /* Local Variables                                                */
    /******************************************************************/
    USHORT      Form;        /* Loop variable - form count            */
    PCHAR       cp;          /* Pointer for accessing the text        */
    MRESULT     DlgResult;   /* The result of a Win.. call            */
    lpDDTType   pDDT;        /* Pointer to DDT                        */


    /******************************************************************/
    /* Set up pointer to the DDT.                                     */
    /******************************************************************/
    pDDT = DDT[pDMSettings->PrinterType];

    /******************************************************************/
    /* For each of the pre-defined forms pick up the name from        */
    /* resources and display it.                                      */
    /******************************************************************/
    for ( Form = 0;
          Form < pDDT->DDTNoOfDefinedForms;
          Form++ )
    {
        WinLoadString( hab,
                       DMData.HModule,
                       pDDT->DDTDefinedForms[Form].FormNameId,
                       SLEN_BOX_MESSAGE,
                       (PSZ)szMessage );

       for ( cp = szMessage; *cp != '\0'; cp++ )
       {
            if ( *cp == ALT_POINT )
                *cp = DMData.DecimalPoint;
       }

       DlgResult = WinSendDlgItemMsg( hwnd,
                                      WndId,
                                      LM_INSERTITEM,
                                      (MPARAM)(ULONG)LIT_END,
                                      MPFROMP(szMessage) );
    }
}
#undef TFUNC







/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prdm_InitFormList                                      */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   HWND   hwnd;      The handle for the dialog window we are in     */
/*   USHORT WndId;     The window ID for the window to put the forms  */
/*                     in (this function is called from the CURRENT_  */
/*                     OPTIONS dialog box and the ADD_FORMS dialog    */
/*                     box)                                           */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   This function sends messages to the window specified by WindId   */
/*   (a listbox) to insert all the defined forms.                     */
/*                                                                    */
/**********************************************************************/
void prdm_InitFormList( HWND hwnd,
                             USHORT  WndId )


{
#define TFUNC "prdm_InitFrmLst"

    /******************************************************************/
    /* Local Variables                                                */
    /******************************************************************/
    sForm     *  Form;        /* Pointer to form data structure for   */
                              /* stepping through the forms           */
    char     *   cp;          /* Pointer for accessing the form text  */
    MRESULT      DlgResult;   /* The result of a Win.. call           */

    /******************************************************************/
    /* Make each form name null terminated, call WinSendDlgItemMsg to */
    /* insert the name and then restore the space.                    */
    /******************************************************************/
    for ( Form = DMData.Forms; Form; Form = Form->NextForm )
    {
        for ( cp = (char  *)Form->FormData; *cp != '\1'; cp++ );

        *cp = '\0';
        DlgResult = WinSendDlgItemMsg( hwnd,
                                       WndId,
                                       LM_INSERTITEM,
                                       (MPARAM)(ULONG)LIT_END,
                                       MPFROMP(Form->FormData) );
        *cp = '\1';
    }
}
#undef TFUNC






/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prdm_PaintFormTemplate                                 */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   HWND   hwnd;      The handle for the dialog window we are in     */
/*   USHORT FormNum;   Form number to display details of              */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   This function displays the details of the given form.            */
/*   The form must be one of the pre-defined ones.                    */
/*                                                                    */
/**********************************************************************/
void prdm_PaintFormTemplate (HWND hwnd,
                                 USHORT FormNum )


{
#define TFUNC "prdm_PaintFrmTm"

    /******************************************************************/
    /* Local Variables                                                */
    /******************************************************************/
    char     * ItemPtr;        /* Pointer to step through form data   */
    MRESULT    DlgResult;      /* Result of calls to Win..            */
    USHORT     MsgId;          /* Resource string Id                  */
    USHORT     WndId;          /* Window IDs for accessing the text   */
                               /* fields                              */
    BYTE       FormDim[NUMBER_LENGTH + 1];
                               /* Buffer for the form dimension       */
    USHORT     i;              /* Loop variable                       */
    lpDDTType  pDDT;           /* Pointer to DDT                        */


    /******************************************************************/
    /* Set up pointer to the DDT.                                     */
    /******************************************************************/
    pDDT = DDT[pDMSettings->PrinterType];


    /******************************************************************/
    /* Get the selected form data and set PtrItemStart.               */
    /******************************************************************/
    ItemPtr = pDDT-> DDTDefinedForms[FormNum].FormData;

    /******************************************************************/
    /* Set the units text field.                                      */
    /******************************************************************/
    if ( *ItemPtr++ == (BYTE)INCHES )
        MsgId = IDS_INCHES;
    else
        MsgId = IDS_MILLIMETERS;

    WinLoadString( hab,
                   DMData.HModule,
                   MsgId,
                   SLEN_BOX_MESSAGE,
                   (PSZ)szMessage );

/*  DlgResult = WinSetDlgItemText( hwnd,                              CON3201 */
                WinSetDlgItemText( hwnd,
                                   DB_TXT_UNITS_TEXT,
                                   (PSZ)szMessage );

    /******************************************************************/
    /* Set the paper/envelope type text field.                        */
    /******************************************************************/
    if ( pDDT-> DDTDefinedForms[FormNum].FormType == DDT_PAPER_FORM )
        MsgId = IDS_PAPER_TEXT;
    else
        MsgId = IDS_ENV_TEXT;

    WinLoadString( hab,
                   DMData.HModule,
                   MsgId,
                   SLEN_BOX_MESSAGE,
                   (PSZ)szMessage );

                WinSetDlgItemText( hwnd,
                                   DB_TXT_PE_TYPE_TEXT,
                                   (PSZ)szMessage );

    /******************************************************************/
    /* Print the rest of the forms dimensions.  Turn each one in turn */
    /* into a null terminated string, print it and restore the        */
    /* terminating space.                                             */
    /******************************************************************/
    for ( WndId  = DB_TXT_FORM_WIDTH;
          WndId <= DB_TXT_TOP_CLIP_LIMIT; WndId +=1 )
    {
        ItemPtr++;

        for ( i = 0; *ItemPtr != ' '; ItemPtr++ )
        {
            FormDim[i++] = (*ItemPtr == ALT_POINT)
                                      ? DMData.DecimalPoint : *ItemPtr;
        }

        FormDim[i] = '\0';

/*      DlgResult = WinSetDlgItemText( hwnd,                          CON3201 */
                    WinSetDlgItemText( hwnd,
                                       WndId,
                                       (PSZ)(FormDim) );
    }
    /******************************************************************/
    /* Send EM_QUERYCHANGED messages to the width & height fields.    */
    /* This is so that the change from blank to filled will not be    */
    /* interpreted as a change when a subsequent EM_QUERY is posted.  */
    /******************************************************************/
    WinSendDlgItemMsg( hwnd,
                       DB_TXT_FORM_WIDTH,
                       EM_QUERYCHANGED,
                       NULL,
                       NULL   );
    WinSendDlgItemMsg( hwnd,
                       DB_TXT_FORM_HEIGHT,
                       EM_QUERYCHANGED,
                       NULL,
                       NULL   );

    /******************************************************************/
    /* Save the number of the template in the global data structure.  */
    /******************************************************************/
    DMData.FormTemplateNum = FormNum;
}
#undef TFUNC






/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prdm_PaintForm                                         */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   HWND   hwnd;          The handle for the dialog window we are in */
/*   USHORT FormNum;       The number of the form to print            */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   This function displays the dimensions for a specified form.      */
/*                                                                    */
/**********************************************************************/
/*CON3201
void pascal prdm_PaintForm ( hwnd,
                             FormNum,
                             PaintName )

HWND        hwnd;
USHORT      FormNum;
BOOL        PaintName;
                       */
void prdm_PaintForm (HWND        hwnd,
                     USHORT      FormNum,
                     BOOL        PaintName)

{
#define TFUNC "prdm_PaintForm"

    /******************************************************************/
    /* Local Variables                                                */
    /******************************************************************/
    PBYTE       pItemStart;    /* Pointer to the start of an item in  */
                               /* the form data                       */
    PBYTE       pItemHeight;   /* Pointer to the start of the height  */
                               /* in the form data                    */
    PBYTE       pItemTopClip;  /* Pointer to the start of the top     */
                               /* clip in the form data               */
    PBYTE       pItem;         /* Pointer to step through form data   */
    PBYTE       pRightItem;    /* Pointer to right clip data          */
    MRESULT     DlgResult;     /* Result of calls to Win..            */
    USHORT      WndId;         /* Window IDs for accessing the text   */
                               /* fields                              */
    USHORT      LastWndId;     /* Last window ID to display "simply"  */
    BYTE        Units;         /* Inches or millimetres               */
    USHORT      i;             /* Loop control variable               */
    USHORT      MsgId;         /* Resource Id                         */
    sForm     * Form;          /* Pointer to form data structures     */

    lpDVTSourceList   pSourceInfo;
                                /* Current source configuration       */
    BOOL        AdjTopClip;     /* Set on if there is a minimum top   */
                                /* clip                               */
    BYTE        ClipBuffer[10]; /* Used to display new top clip value */
    USHORT      FormHeight;     /* Variables used to adjust the top   */
    USHORT      FormTopClip;    /* clip limit for the current         */
    USHORT      FormBottomClip; /* source configuration               */
    USHORT      TopMargin;           /*       ....                    */
    USHORT      MaxDecPlaces;        /*           ....                */
    USHORT      DecPlacesHeight;     /*               ....            */
    USHORT      DecPlacesTopClip;    /*                   ....        */
    USHORT      DecPlacesBottomClip; /*                       ....    */
    USHORT      DecPlacesFactor;     /*                           ....*/
    USHORT      FormRight;      /* Used to adjust right clip limit    */
    USHORT      RightMargin;    /* to MaxPrintWidth in DDT data.      */
    USHORT      DecPlacesRight; /*                 ....               */
    lpDDTType  pDDT;           /* Pointer to DDT                        */


    /******************************************************************/
    /* Set up pointer to the DDT.                                     */
    /******************************************************************/
    pDDT = DDT[pDMSettings->PrinterType];

    /******************************************************************/
    /* Get the selected form data and set PtrItemStart.               */
    /******************************************************************/
    Form = DMData.Forms;

    for ( i = 0; i < FormNum; i++ )
        Form = Form->NextForm;

    pItemStart = Form->FormData;


    /******************************************************************/
    /* Print the form name if requested; otherwise just               */
    /* position the pointer at the start the dimension info.          */
    /******************************************************************/
    for ( pItem = pItemStart; *pItem != '\1'; pItem++ );

    if ( PaintName )
    {
        *pItem = '\0';
/*      DlgResult = WinSetDlgItemText( hwnd,                          CON3201 */
                    WinSetDlgItemText( hwnd,
                                       DB_TXT_FORM_NAME,
                                       (PSZ)(pItemStart) );
        *pItem = '\1';
    }

    pItem++;

    /******************************************************************/
    /* Set the units text field.                                      */
    /******************************************************************/
    Units = *pItem++;

    if ( Units == (BYTE)INCHES )
        MsgId = IDS_INCHES;
    else
        MsgId = IDS_MILLIMETERS;

    WinLoadString( hab,
                   DMData.HModule,
                   MsgId,
                   SLEN_BOX_MESSAGE,
                   (PSZ)szMessage );

/*  DlgResult = WinSetDlgItemText( hwnd,                              CON3201 */
                WinSetDlgItemText( hwnd,
                                   DB_TXT_UNITS_TEXT,
                                   (PSZ)szMessage );

    /******************************************************************/
    /* Set the paper/envelope type text field.                        */
    /******************************************************************/
    if ( Form->FormType == DDT_PAPER_FORM )
        MsgId = IDS_PAPER_TEXT;
    else
        MsgId = IDS_ENV_TEXT;

    WinLoadString( hab,
                   DMData.HModule,
                   MsgId,
                   SLEN_BOX_MESSAGE,
                   (PSZ)szMessage );

                WinSetDlgItemText( hwnd,
                                   DB_TXT_PE_TYPE_TEXT,
                                   (PSZ)szMessage );

    /******************************************************************/
    /* Depending on the source configuration we may need to adjust    */
    /* the top clip value - this is because there is a minimum top    */
    /* margin for some sources so that the printer can "grab" the     */
    /* form.  Pick up a pointer to the data for the current source    */
    /* configuration and set the flag AdjTopClip.                     */
    /******************************************************************/
    pSourceInfo = pDDT->DDTSourceList;
    pSourceInfo += pDMSettings->SourceIndex;

    /******************************************************************/
    /* Note: no need to correct for envelope/multi-media, as the      */
    /* TopMargin is zero in all these cases.                          */
    /******************************************************************/

    AdjTopClip = ( pSourceInfo->TopMargin != 0 );

    /******************************************************************/
    /* Print the rest of the forms dimensions.  Turn each one in turn */
    /* into a null terminated string, print it and restore the        */
    /* terminating space.  Do not display the top clip limit yet      */
    /* if we need to check it.                                        */
    /******************************************************************/
    if ( AdjTopClip && ( !(pDDT->DDTFormFlags & DDT_VAR_BOTTOM_CLIP) ) )
        LastWndId = DB_TXT_BTM_CLIP_LIMIT;
    else
        LastWndId = DB_TXT_TOP_CLIP_LIMIT;

    for ( WndId = DB_TXT_FORM_WIDTH; WndId <= LastWndId; WndId+=1 )
    {
        /**************************************************************/
        /* Move pItem past the space up to the first numeral.         */
        /**************************************************************/
        pItemStart = ++pItem;

        if ( WndId == DB_TXT_RHT_CLIP_LIMIT )
        {
            FormRight = prdm_ReadWordFromDecText( pItemStart,
                                                  &DecPlacesRight );

            if ( Units == (BYTE)INCHES )
            {
                RightMargin = pDDT->DDTMaxPrintWidth * 10;
                MaxDecPlaces = MAX_DEC_PLACES_INCHES;

                /******************************************************/
                /* MaxPrintWidth units are tenths of inches.          */
                /* Now RightMargin is in hundredths of inches, so     */
                /* convert FormRight into same units.                 */
                /******************************************************/
                for ( i = 0 ; i < 2 - DecPlacesRight ; i++ )
                {
                    FormRight *= 10;
                }
            }
            else
            {
                RightMargin = (pDDT->DDTMaxPrintWidth * 254) / 10;
                MaxDecPlaces = MAX_DEC_PLACES_MM;

                /******************************************************/
                /* Now RightMargin is in tenths of millimeters.       */
                /******************************************************/
                for ( i = 0 ; i < 1 - DecPlacesRight ; i++ )
                {
                    FormRight *= 10;
                }
            }

            /**********************************************************/
            /* If MaxPrintWidth exceeded ( and is not a dummy value ) */
            /**********************************************************/
            if ( FormRight > RightMargin &&
                 pDDT->DDTMaxPrintWidth != DDT_DUMMY_VALUE )
            {
                FormRight = RightMargin;
            }

            for ( i = 0; i < 10; i++ )
                ClipBuffer[i] = '\0';

            pRightItem = ClipBuffer;

            prdm_TextFromNumeric( (ULONG)FormRight,
                                  &pRightItem,
                                  MaxDecPlaces );

/*          DlgResult = WinSetDlgItemText( hwnd,                      CON3201 */
                        WinSetDlgItemText( hwnd,
                                           DB_TXT_RHT_CLIP_LIMIT,
                                           (PSZ)ClipBuffer );

            while ( *pItem != ' ' )
                pItem++;

        }
        else if ( ( WndId == DB_TXT_BTM_CLIP_LIMIT ) &&
                  ( pDDT->DDTFormFlags & DDT_VAR_BOTTOM_CLIP )  &&
                  AdjTopClip )
        {
            /******************************************************************/
            /*  INKJET : Check for a value in the bottom clip limit           */
            /******************************************************************/
            /**************************************************************/
            /* Get the bottom clip values.                                */
            /**************************************************************/
            FormBottomClip = prdm_ReadWordFromDecText( pItemStart,
                                                       &DecPlacesBottomClip );

            if ( Units == (BYTE)INCHES )
            {
                TopMargin = pSourceInfo->TopMargin;
                DecPlacesFactor = MAX_DEC_PLACES_INCHES - MaxDecPlaces;
            }
            else
            {
                /**********************************************************/
                /* Convert the minimum top margin value from inches       */
                /* 2 dec. places) to millimetres (1 dec. place).          */
                /* Note that if the minimum top margin is greater than    */
                /* about 2.5 this calculation will overflow a word.       */
                /**********************************************************/
                TopMargin = (pSourceInfo->TopMargin * 254) / 100;
                DecPlacesFactor = MAX_DEC_PLACES_MM - MaxDecPlaces;
            }

            for ( i = 0; i < DecPlacesFactor; i++ )
                TopMargin = TopMargin / 10;

            if ( FormBottomClip < TopMargin )
            {
               FormBottomClip = TopMargin;
            }

            /**********************************************************/
            /* Convert the new value to a text string and display it. */
            /* First initialise our buffer.                           */
            /**********************************************************/
            for ( i = 0; i < 10; i++ )
                ClipBuffer[i] = '\0';

            /**********************************************************/
            /* Use pItem as a working pointer as the function         */
            /* prdm_TextFromNumeric alters the value of the           */
            /* pointer passed into it.                                */
            /**********************************************************/
            pItem = ClipBuffer;
            prdm_TextFromNumeric( (ULONG)FormBottomClip,
                                  &pItem,
                                  MaxDecPlaces );

/*          DlgResult = WinSetDlgItemText( hwnd,                      CON3201 */
                        WinSetDlgItemText( hwnd,
                                           DB_TXT_BTM_CLIP_LIMIT,
                                           (PSZ)ClipBuffer );

            pItem = pItemStart;
            while ( *pItem != ' ' )
                pItem++;

        }
        else  /* WndId != RIGHT_CLIP_LIMIT */
        {
            /**********************************************************/
            /* Store the start of the height entry for later use.     */
            /**********************************************************/
            if ( ( AdjTopClip && (WndId == DB_TXT_FORM_HEIGHT) ) &&
                 ( !(pDDT->DDTFormFlags & DDT_VAR_BOTTOM_CLIP) ) )
                pItemHeight = pItemStart;

            /**********************************************************/
            /* Put a '\0' at the end of the entry and display it.     */
            /**********************************************************/
            while ( *pItem != ' ' )
                pItem++;

            *pItem = '\0';
/*          DlgResult = WinSetDlgItemText( hwnd,                     CON3201 */
                        WinSetDlgItemText( hwnd,
                                           WndId,
                                           (PSZ)(pItemStart) );
            *pItem = ' ';
        }
    }


    /******************************************************************/
    /* Do the special handling of the top clip limit.                 */
    /******************************************************************/
    if ( AdjTopClip && ( !(pDDT->DDTFormFlags & DDT_VAR_BOTTOM_CLIP) ) )
    {
        /**************************************************************/
        /* Get the height and top clip values.                        */
        /**************************************************************/
        FormHeight = prdm_ReadWordFromDecText( pItemHeight,
                                               &DecPlacesHeight );

        pItemTopClip = ++pItem;
        FormTopClip = prdm_ReadWordFromDecText( pItemTopClip,
                                                &DecPlacesTopClip );

        /**************************************************************/
        /* Ensure both values are held with the same number of        */
        /* decimal places.                                            */
        /**************************************************************/
        MaxDecPlaces = max( DecPlacesHeight, DecPlacesTopClip );

        for ( i = 0; i < MaxDecPlaces - DecPlacesHeight; i++ )
            FormHeight *= 10;

        for ( i = 0; i < MaxDecPlaces - DecPlacesTopClip; i++ )
            FormTopClip *= 10;

        /**************************************************************/
        /* Get the minimum top margin value from the source           */
        /* info and convert it to the same units as the height and    */
        /* the top clip.  The top margin is stored in inches x 100.   */
        /*                                                            */
        /* Note the assumption that MaxDecPlaces will be :            */
        /*   <= MAX_DEC_PLACES_INCHES (2) for inches                  */
        /*   <= MAX_DEC_PLACES_MM (1) for millimetres                 */
        /**************************************************************/
        if ( Units == (BYTE)INCHES )
        {
            TopMargin = pSourceInfo->TopMargin;
            DecPlacesFactor = MAX_DEC_PLACES_INCHES - MaxDecPlaces;
        }
        else
        {
            /**********************************************************/
            /* Convert the minimum top margin value from inches       */
            /* 2 dec. places) to millimetres (1 dec. place).          */
            /* Note that if the minimum top margin is greater than    */
            /* about 2.5 this calculation will overflow a word.       */
            /**********************************************************/
            TopMargin = (pSourceInfo->TopMargin * 254) / 100;
            DecPlacesFactor = MAX_DEC_PLACES_MM - MaxDecPlaces;
        }

        for ( i = 0; i < DecPlacesFactor; i++ )
            TopMargin = TopMargin / 10;

        /**************************************************************/
        /* Everything is now in the same units and with the same no.  */
        /* of decimal places (MaxDecPlaces) so we can now check       */
        /* if the top clip value needs to be tweaked down.            */
        /**************************************************************/
        if ( (FormHeight - FormTopClip) < TopMargin )
        {
            FormTopClip = FormHeight - TopMargin;

            /**********************************************************/
            /* Convert the new value to a text string and display it. */
            /* First initialise our buffer.                           */
            /**********************************************************/
            for ( i = 0; i < 10; i++ )
                ClipBuffer[i] = '\0';

            /**********************************************************/
            /* Use pItem as a working pointer as the function         */
            /* prdm_TextFromNumeric alters the value of the           */
            /* pointer past into it.                                  */
            /**********************************************************/
            pItem = ClipBuffer;
            prdm_TextFromNumeric( (ULONG)FormTopClip,
                                  &pItem,
                                  MaxDecPlaces );

/*          DlgResult = WinSetDlgItemText( hwnd,                      CON3201 */
                        WinSetDlgItemText( hwnd,
                                           DB_TXT_TOP_CLIP_LIMIT,
                                           (PSZ)ClipBuffer );
        }
        else
        {
            /**********************************************************/
            /* The value for the top clip is OK as it is - display    */
            /* in the same way as before.                             */
            /**********************************************************/
            pItem = pItemTopClip;

            while ( *pItem != ' ' )
                pItem++;

            *pItem = '\0';
/*          DlgResult = WinSetDlgItemText( hwnd,                      CON3201 */
                        WinSetDlgItemText( hwnd,
                                           DB_TXT_TOP_CLIP_LIMIT,
                                           (PSZ)(pItemTopClip) );
            *pItem = ' ';
        }
    }

    /******************************************************************/
    /* Send EM_QUERYCHANGED messages to the width & height fields.    */
    /* This is so that the change from blank to filled will not be    */
    /* interpreted as a change when a subsequent EM_QUERY is posted.  */
    /******************************************************************/
    WinSendDlgItemMsg( hwnd,
                       DB_TXT_FORM_WIDTH,
                       EM_QUERYCHANGED,
                       NULL,
                       NULL   );
    WinSendDlgItemMsg( hwnd,
                       DB_TXT_FORM_HEIGHT,
                       EM_QUERYCHANGED,
                       NULL,
                       NULL   );

    /******************************************************************/
    /* Get the number of the template that was used for the form -    */
    /* the template number must be one of the pre-defined forms.      */
    /******************************************************************/
    if ( FormNum < pDDT->DDTNoOfDefinedForms )
    {
        DMData.FormTemplateNum = FormNum;
    }
    else
    {
        for ( i = 0;
              i < pDDT->DDTNoOfDefinedForms;
              i++ )
        {
            if ( (Form->FormType == pDDT->
                                         DDTDefinedForms[i].FormType) &&
                 (Form->FormID == pDDT->
                                         DDTDefinedForms[i].FormId) )
            {
                DMData.FormTemplateNum = i;
                break;
            }
        }
    }

}
#undef TFUNC





/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prdm_DeleteForm                                        */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   HWND   hwnd;      The handle for the dialog window we are in     */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   This function deletes the currently selected form.               */
/*                                                                    */
/**********************************************************************/
void prdm_DeleteForm( HWND hwnd )


{
#define TFUNC "prdm_DeleteForm"

    /******************************************************************/
    /* Local Variables                                                */
    /******************************************************************/
    MRESULT       DlgResult;   /* The result of calls to Win...       */
                               /* functions                           */
    SHORT         Count;       /* Loop control variable for stepping  */
                               /* through list of froms               */
    sForm     *   Form;        /* Pointers to form data structures for*/
    sForm     *   PrevForm;    /* stepping through the list of defined*/
                               /* forms                               */
    USHORT        i;           /* Loop control                        */
    USHORT        MsgID;       /* ID of string for error message      */
    USHORT        CurrForm;    /* Currently selected form             */
    lpDDTType     pDDT;        /* Pointer to DDT                        */


    /******************************************************************/
    /* Set up pointer to the DDT.                                     */
    /******************************************************************/
    pDDT = DDT[pDMSettings->PrinterType];


    /******************************************************************/
    /* Prevent the user from deleting one of the                      */
    /* pre-defined forms.                                             */
    /******************************************************************/
    MsgID = 0;

    if ( pDMSettings->SelectedForm <
                   pDDT->DDTNoOfDefinedForms )
        MsgID = IDS_DELETE_PRE;

    /******************************************************************/
    /* If necessary put up an error message                           */
    /******************************************************************/
    if ( MsgID )
    {
        prdm_DispMessageBox( hwnd,
                             MsgID,
                             SLEN_BOX_MESSAGE,
                             DB_PSH_DELETE_FORM,
                             MB_OK  | MB_ICONEXCLAMATION);
        return;
    }

    Form = DMData.Forms;
    PrevForm = NULL;

    /******************************************************************/
    /* Step through the list of forms till we reach the current one.  */
    /******************************************************************/
    for ( Count = 0;
          Count < (USHORT)pDMSettings->SelectedForm;
          Count++ )
    {
        PrevForm = Form;
        Form = Form->NextForm;
    }

    /******************************************************************/
    /* Before we delete the form we must check it is not              */
    /* currently selected in a paper source.                          */
    /* All possible source trays are checked even if they are         */
    /* not supported on the current printer.  This is                 */
    /* OK since the default form in all the trays (paper and          */
    /* envelope) is a pre-defined form.                               */
    /* Since we have already trapped the case of a pre-defined        */
    /* form MsgID will never be set below when testing against a      */
    /* source tray which is not supported.                            */
    /******************************************************************/

    /******************************************************************/
    /* Note: If a form is connected to a configurable source          */
    /* (eg multi-media tray or tray 2 on Heritage) which is then      */
    /* deselected, then it is not possible to delete this form. If it */
    /* were allowed, then when the source was reselected, the form    */
    /* connection would be invalid, or would always have to be reset  */
    /* to the default.                                                */
    /******************************************************************/
    CurrForm = pDMSettings->SelectedForm;

    if ( Form->FormType == DDT_PAPER_FORM )
    {
        /**************************************************************/
        /* First of all check the paper trays and the tractor feed.   */
        /**************************************************************/
        for ( i = 0; i < MAX_NO_OF_PAPER_TRAYS + 1; i++ )
        {
            if ( DMData.ConnsInfo.AutoTrayForm[i] == CurrForm )
                MsgID = IDS_FORM_IN_SOURCE;
        }

        /**************************************************************/
        /* Now check the manual paper forms                           */
        /**************************************************************/
        for ( i = 0; i < DMData.ConnsInfo.NoOfManualPaper; i++ )
        {
            if ( DMData.ConnsInfo.pManualPaper[i] == CurrForm )
                MsgID = IDS_FORM_IN_SOURCE;
        }

        /**************************************************************/
        /* And check the multimedia tray forms.                       */
        /* Note CS_100_SHEET = CS_TRACTOR_FEED.                       */
        /**************************************************************/
        if ( pDDT->DDTSourceFlags &
                                           DDT_MULTIMEDIA_TRAY_SUPPORT )
        {
           if (DMData.ConnsInfo.AutoTrayForm[CS_100_SHEET] == CurrForm)
                MsgID = IDS_FORM_IN_SOURCE;
        }
    }
    else
    {
        /**************************************************************/
        /* Check the envelope feed                                    */
        /**************************************************************/
        if ( DMData.ConnsInfo.AutoTrayForm[CS_ENVELOPE_TRAY]
                                                          == CurrForm )
            MsgID = IDS_FORM_IN_SOURCE;

        /**************************************************************/
        /* Now check the manual envelope forms                        */
        /**************************************************************/
        for ( i = 0; i < DMData.ConnsInfo.NoOfManualEnv; i++ )
        {
            if ( DMData.ConnsInfo.pManualEnvelope[i] == CurrForm )
                MsgID = IDS_FORM_IN_SOURCE;
        }
        /**************************************************************/
        /* And check the multimedia tray forms.                       */
        /* Note CS_MULTIMEDIA = CS_PAPER_TRAY_3.                      */
        /**************************************************************/
        if ( pDDT->DDTSourceFlags &
                                           DDT_MULTIMEDIA_TRAY_SUPPORT )
        {
            if (DMData.ConnsInfo.AutoTrayForm[CS_MULTIMEDIA]== CurrForm)
                MsgID = IDS_FORM_IN_SOURCE;
        }
    }

    /******************************************************************/
    /* If necessary put up an error message                           */
    /******************************************************************/
    if ( MsgID )
    {
        prdm_DispMessageBox( hwnd,
                             MsgID,
                             SLEN_BOX_MESSAGE,
                             DB_PSH_DELETE_FORM,
                             MB_OK | MB_ICONEXCLAMATION );
        return;
    }

    /******************************************************************/
    /* Confirm the deletion of the form.                              */
    /******************************************************************/
    if ( prdm_DispMessageBox( hwnd,
                              IDS_CONFIRM_DELETE,
                              SLEN_BOX_MESSAGE,
                              DB_PSH_PPCANCEL,
                              MB_YESNO | MB_ICONQUESTION ) == MBID_NO )
        return;

    /******************************************************************/
    /* Now we know we can delete the form, see if any of the form     */
    /* numbers selected in any of the sources need to be adjusted.    */
    /* NOTE do not need to check the form type - check ALL trays.     */
    /******************************************************************/

    /**************************************************************/
    /* First of all check the paper trays and the tractor feed.   */
    /**************************************************************/
    for ( i = 0; i < NO_OF_AUTO_TRAYS; i++ )
    {
        if ( DMData.ConnsInfo.AutoTrayForm[i] > CurrForm )
            DMData.ConnsInfo.AutoTrayForm[i]--;
    }

    /**************************************************************/
    /* Now check the manual paper forms                           */
    /**************************************************************/
    for ( i = 0; i < DMData.ConnsInfo.NoOfManualPaper; i++ )
    {
        if ( DMData.ConnsInfo.pManualPaper[i] > CurrForm )
            DMData.ConnsInfo.pManualPaper[i]--;
    }

    /**************************************************************/
    /* Now check the manual envelope forms                        */
    /**************************************************************/
    for ( i = 0; i < DMData.ConnsInfo.NoOfManualEnv; i++ )
    {
        if ( DMData.ConnsInfo.pManualEnvelope[i] > CurrForm )
           DMData.ConnsInfo.pManualEnvelope[i]--;
    }


    /******************************************************************/
    /* Make a link across the form to be deleted then                 */
    /* free the memory the form occupied.                             */
    /******************************************************************/
    if ( PrevForm )
        PrevForm->NextForm = Form->NextForm;
    else
        DMData.Forms = Form->NextForm;

/*  SSFREESEG(SELECTOROF( Form ));                                   CON3201 */
    SSFREEMEM(Form);

    /******************************************************************/
    /* Delete the form name from the list in the defined forms list   */
    /* box and select the first form in the listbox.                  */
    /******************************************************************/
    DlgResult = WinSendDlgItemMsg( hwnd,
                                   DB_LST_DEFINED_FORMS,
                                   LM_DELETEITEM,
                                   (MPARAM)pDMSettings->SelectedForm,
                                   (MPARAM)NULL );

    DlgResult = WinSendDlgItemMsg( hwnd,
                                   DB_LST_DEFINED_FORMS,
                                   LM_SELECTITEM,
                                   (MPARAM)(ULONG)0,
                                   (MPARAM)(ULONG)TRUE );

    /******************************************************************/
    /* Decrement the number of forms.                                 */
    /******************************************************************/
    pDMSettings->NumberOfForms--;

}
#undef TFUNC






/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prdm_DigitToASCII                                      */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   ULONG       Data;         The number to be converted             */
/*   PBYTE far * pDestStr;     The destination to put the text        */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   This function converts the rightmost (decimal) digit of a        */
/*   number to the ASCII digit 0..9. If the number is bigger than 10, */
/*   ie. there are further digits to left of the one converted, then  */
/*   the function is called recursively to continue converting to     */
/*   ASCII                                                            */
/*                                                                    */
/**********************************************************************/
/*CON3201
void pascal prdm_DigitToASCII( Data,
                               pDestStr )

ULONG       Data;
PBYTE far * pDestStr;
                         */

void prdm_DigitToASCII(ULONG       Data,
                       PBYTE     * pDestStr)

//{
//  /******************************************************************/
//  /* Local variables                                                */
//  /******************************************************************/
//  BYTE          Digit;
//  USHORT        ShortDataLo;
//  USHORT        ShortDataHi;
//  USHORT        HiRem;
//  USHORT        LoRem;
//  USHORT        LoData;
//
//
//  /******************************************************************/
//  /* Get the rightmost digit and add '0' to get the ASCII code      */
//  /******************************************************************/
//  /* Cannot make a far call to the C library routine to do division */
//  /* of longs so get the rightmost digit by taking the least        */
//  /* significant word of Data and getting the modulus of this       */
//  /* rather than of the whole long value                            */
//  /******************************************************************/
//
//  /******************************************************************/
//  /* If there are digits to the left of the rightmost (Data >9 )    */
//  /* then divide Data by 10 to move the digits right and make a     */
//  /* recursive call                                                 */
//  /******************************************************************/
//  /* Cannot make a far call to the C library routine to do division */
//  /* of longs so do the division in-line if Data is bigger than     */
//  /* 65535 (most significant word is non zero)                      */
//  /******************************************************************/
//  if ( Data >= 10 )
//  {
//      if ( !SELECTOROF(Data) )
//      {
//          Digit = (BYTE)( OFFSETOF(Data) % 10 ) + (BYTE)'0';
//          prdm_DigitToASCII( (ULONG)( OFFSETOF(Data) / 10 ),
//                             pDestStr );
//      }
//      else
//      {
//          /**********************************************************/
//          /* First divide by the high word by 10 and keep the       */
//          /* remainder                                              */
//          /**********************************************************/
//          ShortDataHi = SELECTOROF(Data);
//          HiRem = ShortDataHi % 10;
//          ShortDataHi /= 10;
//          SELECTOROF(Data) = ShortDataHi;
//
//          /**********************************************************/
//          /* Rem contains the multiples of 65536 (0x10000) carried  */
//          /* from the high word after dividing by 10. This must     */
//          /* be added to the low word and the sum divided by 10.    */
//          /* However, 65536*Rem is clearly bigger than 16 bits so   */
//          /* multiply Rem by 6553 (65536/10) then multiply Rem by 6 */
//          /* (65536%10), divide the second product by 10 (ie.       */
//          /* Rem*0.6). Add all this to the low word divided by 10   */
//          /* and the correct answer pops out.                       */
//          /**********************************************************/
//          ShortDataLo = OFFSETOF(Data);
//          LoData = HiRem * 6;
//          LoRem = LoData % 10;
//          Digit = (BYTE)( LoRem + ShortDataLo%10 );
//          LoData /= 10;
//          OFFSETOF(Data) = LoData + ShortDataLo/10 +
//                                             (Digit)/10 + HiRem*6553;
//
//          Digit = Digit%10 + (BYTE)'0';
//          prdm_DigitToASCII( Data,
//                             pDestStr );
//      }
//  }
//  else    /* Data < 10                                              */
//  {
//      Digit = (BYTE)( OFFSETOF(Data) % 10 ) + (BYTE)'0';
//  }
//
//  *(*pDestStr)++ = Digit;

/* CON3201 *** Start new decmial to ascii conversion routine */
{

    /******************************************************************/
    /* Local variables                                                */
    /******************************************************************/
    static char scConvertTable[10] = {'0','1','2','3','4','5','6','7','8','9'};
    char cTemp[32];
    short i;

    for (i = 0; i < 32 ; i++)               /* CON3201 - iterate from 0 to 31 */
    {                                       /* converting data mod ten to a   */
        cTemp[i] = scConvertTable[Data%10]; /* char and store in temp array   */
        Data = Data / 10;                   /* Divide data by 10 and do       */
    }                                       /* mod again                      */

    i = 31;                                 /* CON3201 - find the end of the  */
//  while (cTemp[i] == '0' && i >= 0)       /* leading zeros                  */
    while ( (cTemp[i] == '0') && (i >= 0) ) /* leading zeros                  */
    {
        i--;
    }

    if (i == 0)                             /* CON3201 - if all are zero then */
    {                                       /* put one zero in pDestStr       */
        *(*pDestStr)++ = '0';
    }
    else
    {
        for (i ; i >= 0; i--)               /* CON3201 - else iterate down to */
        {                                   /* zero putting the char values in*/
//          *(*pDestStr)++ = cTemp[Data%10];/* pDestStr                       */
            *(*pDestStr)++ = cTemp[i];      /* pDestStr                       */
         }
    }
}





/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prdm_TextFromNumeric                                   */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   ULONG       Data           The number to be converted            */
/*   PBYTE far * pDestStr       The destination to put the text into  */
/*   USHORT      NoOfDecPlaces  The units the number is in            */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   This function converts a number (which is left shifted a number  */
/*   of decimal places) into a text string.                           */
/*                                                                    */
/**********************************************************************/
/*CON3201
void pascal prdm_TextFromNumeric( Data,
                                  pDestStr,
                                  NoOfDecPlaces )

ULONG       Data;
PBYTE     * pDestStr;
USHORT      NoOfDecPlaces;
                      */
void  prdm_TextFromNumeric(ULONG       Data,
                           PBYTE     * pDestStr,
                           USHORT      NoOfDecPlaces)

{
#define TFUNC "prdm_TextFrmNum"

    /******************************************************************/
    /* Local Variables                                                */
    /******************************************************************/
    char     * sp;             /* Pointers for accessing the text     */
    char     * dp;             /* strings                             */
    USHORT     i;              /* Loop variable                       */


    TRACE4(TFUNC, "Form Data", (PBYTE)NULL, 0 );

    /******************************************************************/
    /* Treat single digit as a special case.                          */
    /******************************************************************/
    if ( Data < 10 )
    {
        *(*pDestStr)++ = '0';
        *(*pDestStr)++ = DMData.DecimalPoint;

        for ( i = 0; i < NoOfDecPlaces; i++ )
            *(*pDestStr)++ = '0';

/*      *(*pDestStr - 1) = (BYTE)( OFFSETOF(Data) ) + (BYTE)'0';      CON3201 */
        *(*pDestStr - 1) = (BYTE)(Data) + (BYTE)'0';
        return;
    }

    /******************************************************************/
    /* Set sp to the start of our destination.                        */
    /******************************************************************/
    sp = *pDestStr;

    /******************************************************************/
    /* Do the conversion from numeric to ASCII.                       */
    /******************************************************************/
    prdm_DigitToASCII( Data,
                       (PBYTE     *)&sp );

    /******************************************************************/
    /* Return the first character after the string (allowing for the  */
    /* decimal point we are about to insert).                         */
    /******************************************************************/
    *pDestStr = sp + 1;

    /******************************************************************/
    /* Shift the figures which come after the point right one place.  */
    /******************************************************************/
    dp = sp--;

    while ( NoOfDecPlaces-- )
        *dp-- = *sp--;

    /******************************************************************/
    /* And insert the point.                                          */
    /******************************************************************/
    *dp = DMData.DecimalPoint;
}
#undef TFUNC





/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prdm_ReadWordFromDecText                               */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   PBYTE    pItem;          Points to the start of the text string  */
/*                            to be converted to a value.             */
/*   PUSHORT  pNoOfDecPlaces  The number of decimal places is         */
/*                            returned here.                          */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   Returns the value of a number written as text.  The text         */
/*   number is terminated by a space and may contain a decimal part.  */
/*                                                                    */
/**********************************************************************/
/*CON3201
USHORT  prdm_ReadWordFromDecText( pItem,
                                        pNoOfDecPlaces )

PBYTE     pItem;
PUSHORT   pNoOfDecPlaces;
                     */
USHORT  prdm_ReadWordFromDecText(PBYTE     pItem,
                                 PUSHORT   pNoOfDecPlaces)


{
#define TFUNC "prde_RdWrdDcTxt"

    /******************************************************************/
    /* Local Variables                                                */
    /******************************************************************/
    BOOL      DecPtFound;
    USHORT    ItemValue;
    USHORT    NoOfDecPlaces;


    DecPtFound    = FALSE;
    NoOfDecPlaces = 0;

    /******************************************************************/
    /* The number is terminated by a space.                           */
    /******************************************************************/
    for ( ItemValue = 0; *pItem != ' '; pItem++ )
    {
        if ( *pItem != DMData.DecimalPoint )
        {
            ItemValue = (ItemValue * 10) + (*pItem - '0');

            if ( DecPtFound )
                NoOfDecPlaces++;
        }
        else
        {
            /**********************************************************/
            /* Skip over the decimal point and remember we've found   */
            /* it.                                                    */
            /**********************************************************/
            DecPtFound = TRUE;
        }
    }

    *pNoOfDecPlaces = NoOfDecPlaces;

    return (ItemValue);
}
#undef TFUNC

