File:  [WindowsNT SDKs] / ntddk / src / print / pscrptui / pscrptui.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Thu Aug 9 18:31:12 2018 UTC (7 years, 9 months ago) by root
Branches: msft, MAIN
CVS tags: ntddk-nov-1993, HEAD
Microsoft Windows NT Build 511 (DDK SDK) 11-01-1993

//--------------------------------------------------------------------------
//
// Module Name:  PSCRPTUI.C
//
// Brief Description:  This module contains the PSCRIPT driver's User
// Interface functions and related routines.
//
// Author:  Kent Settle (kentse)
// Created: 11-Jul-1991
//
// Copyright (c) 1991-1992 Microsoft Corporation
//
// This module contains routines supporting the setting of Printer and
// Job Property dialogs for the NT Windows PostScript printer driver.
//
// The general outline for much of the code was taken from the NT RASDD
// printer driver's user interface code, which was written by Steve
// Cathcart (stevecat).
//--------------------------------------------------------------------------

#define _HTUI_APIS_

#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include "pscript.h"
#include "shellapi.h"
#include <winspool.h>
#include "dlgdefs.h"
#include "pscrptui.h"
#include "help.h"

#define UNINITIALIZED_FORM  -1
#define TRANSLATED_TRAYS    0x00000001
#define TRANSLATED_FORMS    0x00000002
#define INITIAL_FORM_DELTA      16384

// declarations of routines defined within this module.

LONG PrtPropDlgProc( HWND, UINT, DWORD, LONG );
LONG AboutDlgProc( HWND, UINT, DWORD, LONG );
BOOL InitComboBoxes(HWND, PRINTDATA *);
BOOL bAbout(HWND, PNTPD);
VOID GetPrinterForm(PNTPD, FORM_INFO_1 *, PWSTR);

// external routines and data.

extern LONG  FontInstDlgProc( HWND, UINT, DWORD, LONG);
extern LONG TTFontDialogProc(HWND, UINT, DWORD, LONG);
extern TT_FONT_MAPPING TTFontTable[]; // ..\pscript\tables.h.
extern PFORM_INFO_1 GetFormsDataBase(HANDLE, DWORD *, PNTPD);
extern int NameComp(CHAR *, CHAR *);

extern
void
vDoDeviceHTDataUI(
    LPSTR   pDeviceName,
    BOOL    ColorDevice,
    BOOL    bUpdate
    );

extern
void
vGetDeviceHTData(
    HANDLE      hPrinter,
    PDEVHTINFO  pDefaultDevHTInfo
    );


extern
BOOL
bSaveDeviceHTData(
    HANDLE  hPrinter,
    BOOL    bForce              // TRUE if always update
    );

// global Data

DWORD   Type=1;

BYTE    PP_AnsiDeviceName[128];

#define MAX_TRAYS       9
#define INVALID_TRAY    -1L
#define INVALID_FORM    -1L
#define MAX_SKIP        5
#define SMALL_BUF       32

#define  RESOURCE_STRING_LENGTH   128

//--------------------------------------------------------------------------
// BOOL PrinterProperties(HWND  hwnd, LPPRINTER lpPrinter)
//
// This function first retrieves and displays the current set of printer
// properties for the printer.  The user is allowed to change the current
// printer properties from the displayed dialog box.
//
// Returns:
//   This function returns -1L if it fails in any way.  If the dialog is
//   actually displayed, it returns either IDOK or IDCANCEL, depending on
//   what the user chose.   If no dialog box was displayed and the function
//   is successful, IDOK is returned.
//
// History:
//   11-Jul-1991     -by-     Kent Settle     (kentse)
//  Wrote it.
//--------------------------------------------------------------------------

BOOL PrinterProperties(HWND  hwnd, HANDLE hPrinter)
{
    int         nResult;
    PRINTDATA   printdata;
    WCHAR       wcbuf[32];
    DWORD       dwTmp;
    DWORD       rc;

    // fill in PRINTDATA structure.

    printdata.hPrinter = hPrinter;
    printdata.iFreeMemory = 0;
    printdata.pntpd = (PNTPD)NULL;
    printdata.psetforms = (PLONG)NULL;
    printdata.bHostHalftoning = TRUE;

    // simply try to write out to the registry to see if the caller
    // has permission to change anything.

    LoadString(hModule, (IDS_PERMISSION + STRING_BASE), wcbuf,
               (sizeof(wcbuf) / sizeof(wcbuf[0])));

    dwTmp = 1;

    rc = SetPrinterData(hPrinter, wcbuf, REG_DWORD, (LPBYTE)&dwTmp,
                        sizeof(DWORD));

    if (rc == ERROR_SUCCESS)
        printdata.bPermission = TRUE;
    else
        printdata.bPermission = FALSE;

    // call the printer properties dialog routine.

    nResult = DialogBoxParam (hModule, MAKEINTRESOURCE(PRINTER_PROP), hwnd,
                              (DLGPROC)PrtPropDlgProc, (LPARAM)&printdata);

    return(nResult);
}


//--------------------------------------------------------------------------
// LONG APIENTRY AboutDlgProc (HWND hDlg, UINT message, DWORD wParam,
//                             LONG lParam)
//
// This function processes messages for the "About" dialog box.
//
// Returns:
//   This function returns TRUE if successful, FALSE otherwise.
//
// History:
//   11-Jul-1991     -by-     Kent Settle     (kentse)
//  Wrote it.
//--------------------------------------------------------------------------

LONG AboutDlgProc(
    HWND    hDlg,
    UINT    message,
    DWORD   wParam,
    LONG    lParam
)
{
    UNREFERENCED_PARAMETER (lParam);

    switch (message)
    {
        case WM_INITDIALOG:
            return (TRUE);

        case WM_COMMAND:
            if ((LOWORD(wParam) == IDOK) || (LOWORD(wParam) == IDCANCEL))
            {
                EndDialog (hDlg, IDOK);
                return (TRUE);
            }
            break;
    }
    return (FALSE);
}


//--------------------------------------------------------------------------
// LONG APIENTRY PrtPropDlgProc(HWND hwnd, UINT usMsg, DWORD wParam,
//                              LONG  lParam)
//
// This function processes messages for the "About" dialog box.
//
// Returns:
//   This function returns TRUE if successful, FALSE otherwise.
//
// History:
//   11-Jul-1991     -by-     Kent Settle     (kentse)
//  Wrote it.
//--------------------------------------------------------------------------

LONG APIENTRY PrtPropDlgProc(HWND hwnd, UINT usMsg, DWORD wParam,
                             LONG  lParam)
{
    LPWSTR          pwDeviceName;
    int             i, rc;
    int             iSelect;
    WCHAR           wcbuf1[SMALL_BUF];
    WCHAR           wcbuf2[MAX_FONTNAME * 2];
    WCHAR           wcbuf3[MAX_FONTNAME];
    DWORD           cbNeeded, cbTrayForm;
    int             cTrays;
    int             iForm, iTray;
    LONG            lReturn;
    BOOL            bTmp;
    DWORD           returnvalue;
    WCHAR           SlotName[MAX_SLOT_NAME];
    WCHAR           FormName[CCHFORMNAME];
    WCHAR           PrinterForm[CCHFORMNAME];
    PRINTDATA      *pdata;
    PLONG           psetform;
    WCHAR          *pwstr;
    WCHAR          *pwstrsave;
    FORM_INFO_1    *pForm;

    switch (usMsg)
    {
        case WM_INITDIALOG:
            pdata = (PRINTDATA *)lParam;

            if (!pdata)
            {
                RIP("PSCRPTUI!PrtPropDlgProc: null pdata.\n");
                return(FALSE);
            }

            // save the PRINTDATA.

            SetWindowLong(hwnd, GWL_USERDATA, lParam);

            if (!(pdata->pntpd = MapPrinter(pdata->hPrinter)))
            {
                RIP("PSCRPTUI!PrtPropDlgProc: MapPrinter failed.\n");
                return(FALSE);
            }

            //
            // Make up ANSI version of the device name for later halftone
            // UI to use
            //

            pwDeviceName = (LPWSTR)((PSTR)pdata->pntpd +
                                    pdata->pntpd->lowszPrinterName);

            WideCharToMultiByte(CP_ACP,
                                0,
                                (LPWSTR)pwDeviceName,
                                (INT)(wcslen(pwDeviceName) + 1),
                                PP_AnsiDeviceName,
                                sizeof(PP_AnsiDeviceName),
                                NULL,
                                NULL);

    //
    // First read in the current DEVHTINFO data
    //
    // !!! If you can read the DEVHTINFO from MINI DRIVERS, then pass that
    // !!! pointer to the GetDeviceHTData(), the DEVHTINFO is at end of
    // !!! winddi.h, it includes COLORINFO, DevPelSize, HTPatternSize and
    // !!! so on.  If a NULL is passed then standard halftone default will
    // !!! be used to set in the registry at first time
    //

            vGetDeviceHTData(pdata->hPrinter, NULL);


            // fill in the default printer memory configuration.  first
            // check to see if a value has been saved in the registry.
            // if so, use it, otherwise, get the default value from
            // the PPD file.

            LoadString(hModule, (IDS_FREEMEM + STRING_BASE),
                       wcbuf2, (sizeof(wcbuf2) / sizeof(wcbuf2[0])));

            returnvalue = GetPrinterData(pdata->hPrinter, wcbuf2, &Type,
                                         (LPBYTE)&pdata->iFreeMemory,
                                         sizeof(pdata->iFreeMemory), &cbNeeded);

            if (returnvalue != NO_ERROR)
                pdata->iFreeMemory = pdata->pntpd->cbFreeVM;

            SetDlgItemInt(hwnd, IDD_MEMORY_EDIT_BOX, pdata->iFreeMemory, FALSE);

            // initialize the printer model name.

            SetDlgItemText(hwnd, IDD_MODEL_TEXT,
                           (PWSTR)((PSTR)pdata->pntpd + pdata->pntpd->lowszPrinterName));

            // initialize the paper tray and paper size list boxes.

            if (!InitComboBoxes(hwnd, pdata))
                RIP("PrtPropDlgProc: InitComboBoxes failed.\n");


            // Get the current setting of the PS_HALFTONING flag from the
            // registry and initialize the check button.

            LoadString(hModule, (IDS_HALFTONE + STRING_BASE),
                       wcbuf3, (sizeof(wcbuf3) / sizeof(wcbuf3[0])));

            returnvalue = GetPrinterData(pdata->hPrinter,
                                         wcbuf3,
                                         &Type,
                                         (LPBYTE)&(pdata->bHostHalftoning),
                                         sizeof(pdata->bHostHalftoning),
                                         &cbNeeded);

            // printer halftoning is OFF by default.  ie, use system halftoning.

            if (returnvalue != NO_ERROR)
            {
               pdata->bHostHalftoning = TRUE;
            }

            CheckDlgButton(hwnd,
                           IDD_USE_HOST_HALFTONING,
                           !((pdata->bHostHalftoning)));

            // if the user has selected printer halfoning, disable the system halftoning
            // push button.

            if (pdata->bHostHalftoning)
                EnableWindow(GetDlgItem(hwnd, IDD_HALFTONE_PUSH_BUTTON), TRUE);
            else
                EnableWindow(GetDlgItem(hwnd, IDD_HALFTONE_PUSH_BUTTON), FALSE);

            // intialize the help stuff.

            vHelpInit();

            // disable a bunch of stuff if the user does not have
            // permission to change it.

            if (!pdata->bPermission)
            {
                EnableWindow(GetDlgItem(hwnd, IDD_PAPER_LIST_BOX), FALSE);
                EnableWindow(GetDlgItem(hwnd, IDD_MEMORY_EDIT_BOX), FALSE);
                EnableWindow(GetDlgItem(hwnd, IDD_USE_HOST_HALFTONING), FALSE);
            }
            return TRUE;
            break;

        case WM_COMMAND:
            pdata = (PRINTDATA *)GetWindowLong(hwnd, GWL_USERDATA);

            switch (LOWORD(wParam))
            {
                case IDD_ABOUT_BUTTON:
                    return(bAbout(hwnd, pdata->pntpd));

                case IDD_FONTS_BUTTON:
                    lReturn = DialogBoxParam (hModule, MAKEINTRESOURCE(FONTINST), hwnd,
                                              (DLGPROC)FontInstDlgProc,
                                              (LPARAM)pdata);

                    if (lReturn == -1)
                    {
                        RIP("PSCRPTUI!PrtPropDlgProc: DialogBoxParam for FONTINST failed.\n");
                        return(FALSE);
                    }

                    return (TRUE);

                case IDD_FONT_SUBST_PUSH_BUTTON:
                    lReturn = DialogBoxParam(hModule, MAKEINTRESOURCE(IDD_TT_DIALOG),
                                             hwnd, (DLGPROC)TTFontDialogProc,
                                             (LPARAM)pdata);

                    if (lReturn == -1)
                    {
                        RIP("PSCRPTUI!PrtPropDlgProc: DialogBoxParam for TTFONTS failed.\n");
                        return(FALSE);
                    }

                    return (TRUE);

                //
                // Button for toggling host versus device halftoning mode.
                // -- DJS
                case IDD_USE_HOST_HALFTONING:

                    if(IsDlgButtonChecked(hwnd, IDD_USE_HOST_HALFTONING))
                    {
                        pdata->bHostHalftoning = FALSE;
                        EnableWindow(GetDlgItem(hwnd, IDD_HALFTONE_PUSH_BUTTON),
                                                FALSE);
                    }
                    else
                    {
                        pdata->bHostHalftoning = TRUE;
                        EnableWindow(GetDlgItem(hwnd, IDD_HALFTONE_PUSH_BUTTON),
                                                TRUE);
                    }

                    break;

                   return(TRUE);

                case IDD_HALFTONE_PUSH_BUTTON:

                    vDoDeviceHTDataUI(PP_AnsiDeviceName,
                                      (pdata->pntpd->flFlags & COLOR_DEVICE),
                                      pdata->bPermission);

                    return(TRUE);

                case IDD_TRAY_LIST_BOX:
                    if (HIWORD (wParam) != CBN_SELCHANGE)
                        return (FALSE);

                    // get the index for the currently selected tray.

                    iTray = SendDlgItemMessage(hwnd, IDD_TRAY_LIST_BOX,
                                               CB_GETCURSEL, (WPARAM)0,
                                               (LPARAM)0);

                    // get the index of the corresponding form.

                    iForm = SendDlgItemMessage(hwnd, IDD_TRAY_LIST_BOX,
                                               CB_GETITEMDATA,
                                               (WPARAM)iTray,
                                               (LPARAM)0);

                    // highlight the form that has previously been
                    // associated with this tray.

                    SendDlgItemMessage(hwnd, IDD_PAPER_LIST_BOX, CB_SETCURSEL,
                                       (WPARAM)iForm, (LPARAM)0);

                    // write this association to our selected forms list.

                    psetform = pdata->psetforms;

                    psetform[iTray] = iForm;

                    break;

                case IDD_PAPER_LIST_BOX:
                    if (HIWORD (wParam) != CBN_SELCHANGE)
                        return (FALSE);

                    // get the index for the currently selected tray.

                    iTray = SendDlgItemMessage (hwnd, IDD_TRAY_LIST_BOX,
                                                CB_GETCURSEL, (WPARAM)0,
                                                (LPARAM)0);

                    // get the index for the currently selected form.

                    iForm = SendDlgItemMessage (hwnd, IDD_PAPER_LIST_BOX,
                                                       CB_GETCURSEL, (WPARAM)0,
                                                       (LPARAM)0);

                    // associate the current form with the current tray.

                    SendDlgItemMessage(hwnd, IDD_TRAY_LIST_BOX, CB_SETITEMDATA,
                                       (WPARAM)iTray, (LPARAM)iForm);

                    // write this association to our selected forms list.

                    psetform = pdata->psetforms;

                    psetform[iTray] = iForm;

                    break;

                case IDD_HELP_BUTTON:
                    vShowHelp(hwnd, HELP_CONTEXT, HLP_PRINTER_SETUP,
                              pdata->hPrinter);
                    return(TRUE);

                case IDOK:
                    if (pdata->bPermission)
                    {
                        // get the new value from the memory edit box.

                        i = GetDlgItemInt(hwnd, IDD_MEMORY_EDIT_BOX, &bTmp, FALSE);

                        // if the user has changed the memory setting,
                        // pop up a message box.

                        if (i != (int)pdata->iFreeMemory)
                        {
                            // warn the user that changing the memory setting
                            // is dangerous.

                            LoadString(hModule,
                                       (IDS_MEMWARN + STRING_BASE),
                                       (LPWSTR)wcbuf2,
                                       (sizeof(wcbuf2) / sizeof(wcbuf2[0])));

                            LoadString(hModule,
                                       (IDS_CAUTION + STRING_BASE),
                                       (LPWSTR)wcbuf1,
                                       (sizeof(wcbuf1) / sizeof(wcbuf1[0])));

                            iSelect = MessageBox(hwnd, wcbuf2, wcbuf1,
                                                 MB_DEFBUTTON2 |
                                                 MB_ICONEXCLAMATION | MB_YESNO);

                            if (iSelect == IDYES)
                                pdata->iFreeMemory = i;
                            else
                            {
                                // reset the memory edit box.

                                SendDlgItemMessage(hwnd, IDD_MEMORY_EDIT_BOX,
                                                   EM_SETSEL, 0, 0x7FFF0000);

                                SetDlgItemInt(hwnd, IDD_MEMORY_EDIT_BOX,
                                              pdata->iFreeMemory, FALSE);

                                break;
                            }
                        }

                        // output the free memory to the .INI file.

                        LoadString(hModule, (IDS_FREEMEM + STRING_BASE),
                                   wcbuf2, (sizeof(wcbuf2) / sizeof(wcbuf2[0])));

#if DBG
                        if (SetPrinterData(pdata->hPrinter, wcbuf2, REG_BINARY,
                                       (LPBYTE)&pdata->iFreeMemory,
                                       sizeof(pdata->iFreeMemory)))
                            RIP("PSCRPTUI!PrtPropDlgProc: SetPrinterData FreeMem failed.\n");
#else
                        SetPrinterData(pdata->hPrinter, wcbuf2, REG_BINARY,
                                       (LPBYTE)&pdata->iFreeMemory,
                                       sizeof(pdata->iFreeMemory));
#endif


                         // Set Halftone flag in Registry

                          LoadString(hModule, (IDS_HALFTONE + STRING_BASE),
                                    wcbuf3, (sizeof(wcbuf3) / sizeof(wcbuf3[0])));

                          SetPrinterData(pdata->hPrinter,
                                         wcbuf3,
                                         REG_BINARY,
                                         (LPBYTE)&(pdata->bHostHalftoning),
                                         sizeof(pdata->bHostHalftoning));

                        // output the corresponding tray - form pairs to the
                        // registry.

                        cTrays = SendDlgItemMessage(hwnd, IDD_TRAY_LIST_BOX,
                                                    CB_GETCOUNT, (WPARAM)0,
                                                    (LPARAM)0);

                        psetform = pdata->psetforms;

                        // first calculate what size buffer we need.
                        // allow room for double NULL terminator.

                        cbTrayForm = 1;

                        for (i = 0; i < cTrays; i++)
                        {
                            // only output the pair if it has been selected by
                            // the user.

                            if (*psetform++ != UNINITIALIZED_FORM)
                            {
                                // get the tray name.

                                SendDlgItemMessage(hwnd, IDD_TRAY_LIST_BOX,
                                                   CB_GETLBTEXT, (WPARAM)i,
                                                   (LPARAM)SlotName);

                                // now get the corresponding form name.

                                iForm = SendDlgItemMessage(hwnd, IDD_TRAY_LIST_BOX,
                                                           CB_GETITEMDATA, (WPARAM)i,
                                                           (LPARAM)0);

                                if (iForm != CB_ERR)
                                {
                                    // get the form name, and write the tray-form
                                    // pair to the registry.

                                    rc = SendDlgItemMessage(hwnd, IDD_PAPER_LIST_BOX,
                                                            CB_GETLBTEXT, (WPARAM)iForm,
                                                            (LPARAM)FormName);

                                    // now that we have the selected form name
                                    // match it to a form which the printer
                                    // supports, and save the printer form
                                    // name as well.

                                    // first, get the metrics for the selected
                                    // form from the forms database.

                                    GetForm(pdata->hPrinter, FormName, 1,
                                            NULL, 0, &cbNeeded);

                                    if(GetLastError() != ERROR_INSUFFICIENT_BUFFER)
                                    {
#if DBG
                                        DbgPrint("PSCRPTUI!PrinterPropDlgProc: GetForm returns error %x\n",
                                                 GetLastError());
#endif
                                        return(FALSE);
                                    }

                                    pForm = (FORM_INFO_1 *)GlobalAlloc(GMEM_FIXED |
                                                                       GMEM_ZEROINIT,
                                                                       cbNeeded);
                                    if (pForm == NULL)
                                        return(FALSE);

                                    GetForm(pdata->hPrinter, FormName, 1,
                                            (BYTE *)pForm, cbNeeded, &cbNeeded);

                                    GetPrinterForm(pdata->pntpd, pForm,
                                                   PrinterForm);

                                    GlobalFree((HGLOBAL)pForm);

                                    if (rc != CB_ERR)
                                    {
                                        cbTrayForm += (wcslen(SlotName) + 1);
                                        cbTrayForm += (wcslen(FormName) + 1);
                                        cbTrayForm += (wcslen(PrinterForm) + 1);
                                    }
                                }
                            }
                        }

                        cbTrayForm *= sizeof(WCHAR);

                        // allocate a buffer.

                        if (!(pwstr = (WCHAR *)GlobalAlloc(GMEM_FIXED |
                                                           GMEM_ZEROINIT,
                                                           cbTrayForm)))
                        {
                            RIP("PSCRPTUI!PrtPropDialogProc: GlobalAlloc pwstr failed.\n");
                            return(FALSE);
                        }

                        psetform = pdata->psetforms;

                        pwstrsave = pwstr;

                        // write the tray form pairs in the following form:
                        // a NULL terminated UNICODE Tray (Slot) name followed
                        // by the matching NULL terminated form name, then
                        // followed by the matching NULL terminated printer
                        // for name. this sequence is repeated until a double
                        // NULL terminator ends the table.

                        for (i = 0; i < cTrays; i++)
                        {
                            // only output the triplet if it has been selected by
                            // the user.

                            if (*psetform++ != UNINITIALIZED_FORM)
                            {
                                // get the tray name.

                                SendDlgItemMessage(hwnd, IDD_TRAY_LIST_BOX,
                                                   CB_GETLBTEXT, (WPARAM)i,
                                                   (LPARAM)SlotName);

                                // now get the corresponding form name.

                                iForm = SendDlgItemMessage(hwnd, IDD_TRAY_LIST_BOX,
                                                           CB_GETITEMDATA, (WPARAM)i,
                                                           (LPARAM)0);

                                if (iForm != CB_ERR)
                                {
                                    // get the form name, and write the tray-form
                                    // pair to the registry.

                                    rc = SendDlgItemMessage(hwnd, IDD_PAPER_LIST_BOX,
                                                            CB_GETLBTEXT, (WPARAM)iForm,
                                                            (LPARAM)FormName);

                                    // first, get the metrics for the selected
                                    // form from the forms database.

                                    GetForm(pdata->hPrinter, FormName, 1,
                                            NULL, 0, &cbNeeded);

                                    if(GetLastError() != ERROR_INSUFFICIENT_BUFFER)
                                    {
#if DBG
                                        DbgPrint("PSCRPTUI!PrinterPropDlgProc: GetForm returns error %x\n",
                                                 GetLastError());
#endif
                                        return(FALSE);
                                    }

                                    pForm = (FORM_INFO_1 *)GlobalAlloc(GMEM_FIXED |
                                                                       GMEM_ZEROINIT,
                                                                       cbNeeded);
                                    if (pForm == NULL)
                                        return(FALSE);

                                    GetForm(pdata->hPrinter, FormName, 1,
                                            (BYTE *)pForm, cbNeeded, &cbNeeded);

                                    GetPrinterForm(pdata->pntpd, pForm,
                                                   PrinterForm);

                                    GlobalFree((HGLOBAL)pForm);

                                    if (rc != CB_ERR)
                                    {
                                        // write pair to the buffer.

                                        wcscpy(pwstr, SlotName);
                                        pwstr += (wcslen(SlotName) + 1);
                                        wcscpy(pwstr, FormName);
                                        pwstr += (wcslen(FormName) + 1);
                                        wcscpy(pwstr, PrinterForm);
                                        pwstr += (wcslen(PrinterForm) + 1);
                                    }
                                }
                            }
                        }

                        // add the last NULL terminator.

                        *pwstr = (WCHAR)'\0';

                        // now output the tray-form table to the registry.

                        LoadString(hModule, (IDS_TRAY_FORM_TABLE + STRING_BASE),
                                  wcbuf3, (sizeof(wcbuf3) / sizeof(wcbuf3[0])));

                        SetPrinterData(pdata->hPrinter, wcbuf3, REG_BINARY,
                                       (LPBYTE)pwstrsave, cbTrayForm);

                        // now output the table size to the registry.

                        LoadString(hModule, (IDS_TRAY_FORM_SIZE + STRING_BASE),
                                  wcbuf3, (sizeof(wcbuf3) / sizeof(wcbuf3[0])));

                        SetPrinterData(pdata->hPrinter, wcbuf3, REG_DWORD,
                                       (LPBYTE)&cbTrayForm, sizeof(cbTrayForm));

                        // free up buffer.

                        GlobalFree((HGLOBAL)pwstrsave);

                        //
                        // save that halftone device data back into registry
                        //

                        bSaveDeviceHTData(pdata->hPrinter, FALSE);
                    }

                    if (pdata->pntpd)
                    {
                        GlobalFree((HGLOBAL)pdata->pntpd);
                        pdata->pntpd = NULL;
                    }

                    if (pdata->psetforms)
                    {
                        GlobalFree((HGLOBAL)pdata->psetforms);
                        pdata->psetforms = NULL;
                    }

                    EndDialog (hwnd, IDOK);
                    return TRUE;

                case IDCANCEL:
                    if (pdata->pntpd)
                    {
                        GlobalFree((HGLOBAL)pdata->pntpd);
                        pdata->pntpd = NULL;
                    }

                    if (pdata->psetforms)
                    {
                        GlobalFree((HGLOBAL)pdata->psetforms);
                        pdata->psetforms = NULL;
                    }

                    EndDialog (hwnd, IDCANCEL);
                    return TRUE;

                default:
                    return (FALSE);
            }
            break;

        case WM_DESTROY:
            // clean up any used help stuff.

            vHelpDone(hwnd);
            return (TRUE);

        default:
            return (FALSE);   /* didn't process the message */
    }
}


//--------------------------------------------------------------------------
// BOOL InitComboBoxes(hwnd, pdata)
// HWND       hwnd;        // handle to dialog window
// PRINTDATA *pdata;
//
// Parameters
//
// Returns:
//   This routine returns TRUE for success, FALSE otherwise.
//
// History:
//   10-Apr-1991    -by-    Kent Settle     (kentse)
// Made it use PNTPD instead of PPRINTER.
//   21-Jan-1991    -by-    Kent Settle     (kentse)
// Brought in from Windows 3.1, modified for NT, and clean up.
//--------------------------------------------------------------------------

BOOL InitComboBoxes(hwnd, pdata)
HWND        hwnd;        // handle to dialog window
PRINTDATA  *pdata;
{
    WCHAR           SlotName[MAX_SLOT_NAME];
    WCHAR           SearchName[MAX_SLOT_NAME + 4];
    WCHAR           FormName[CCHFORMNAME];
    WCHAR           wcbuf[MAX_FONTNAME];
    DWORD           i, j, dwType, cbTrayForm;
    DWORD           cbNeeded, dwTmp, count;
    int             rc, DefaultForm, iForm;
    PSFORM         *pPSForm;
    FORM_INFO_1    *pFormI1, *pFormI1Save;
    FORM_INFO_1    *pdbForm, *pdbForms;
    PWSTR           pwstrName, pwstrSave;
    PSINPUTSLOT    *pslots;
    PNTPD           pntpd;
    PLONG           psetform;
    PSTR            pstr, pstrSave, pstrDefault;
    BOOL            bFound;

    // clear out the tray and form list boxes before we begin.

    SendDlgItemMessage(hwnd, IDD_PAPER_LIST_BOX, CB_RESETCONTENT, 0, 0L);
    SendDlgItemMessage(hwnd, IDD_TRAY_LIST_BOX, CB_RESETCONTENT, 0, 0L);

    // limit the length of the strings allowed.

    SendDlgItemMessage(hwnd, IDD_PAPER_LIST_BOX, CB_LIMITTEXT,
                       (WPARAM)CCHFORMNAME, (LPARAM)0);
    SendDlgItemMessage(hwnd, IDD_TRAY_LIST_BOX, CB_LIMITTEXT,
                       (WPARAM)MAX_SLOT_NAME, (LPARAM)0);

    // here is a brief overview of how we will fill in the forms list
    // box:  firstly, call AddForm for each form in the ppd file, if
    // this has not been done yet.  then enumerate the forms database.
    // then for each form in the database, see if there is a form
    // defined in the PPD file which is large enough to print on.  if
    // there is, this form gets added to the list box.

    // start out by setting up a FORM_INFO_1 structure for each form
    // defined in the NTPD structure.

    // point to the start of the array of PSFORM structures within
    // the NTPD structure.

    pntpd = pdata->pntpd;

    pPSForm = (PSFORM *)((CHAR *)pntpd + pntpd->loPSFORMArray);

    // allocate memory for all the FORM_INFO_1 structures.

    if (!(pFormI1 = (FORM_INFO_1 *)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
                                               (pntpd->cPSForms *
                                               sizeof(FORM_INFO_1)))))
    {
        RIP("PSCRPTUI!InitComboBoxes: GlobalAlloc for pFormI1 failed.\n");
        return(FALSE);
    }

    // keep a copy of the pointer to the first structure.

    pFormI1Save = pFormI1;

    // allocate memory for the form name buffers.

    if (!(pwstrName = (PWSTR)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
                            (pntpd->cPSForms * CCHFORMNAME * sizeof(WCHAR)))))
    {
        RIP("PSCRPTUI:InitComboBoxes: GlobalAlloc for pwstrName failed.\n");
        GlobalFree((HGLOBAL)pFormI1);
        return(FALSE);
    }

    // keep a copy of the pointer to the first form name.

    pwstrSave = pwstrName;

    // add each form defined in the NTPD structure to the forms
    // database.  AddForm should simply do nothing if this form
    // already exists in the database.

    for (i = 0; i < pntpd->cPSForms; i++)
    {
        // get the form name from the PSFORM structure and convert it
        // to UNICODE.  you might think "hey, you should store the
        // name as UNICODE in the PSFORM structure!"  however, the
        // PSFORM structures get calculated on every EnablePDEV, which
        // will probably happen much more often then this dialog gets
        // displayed.

        // check to see if there is a translation string to worry about,
        // for each form.

        pstrSave = (CHAR *)pntpd + pPSForm->loFormName;

        XLATESTRING(pstr);

        // pstr now points to the form name we want.

        strcpy2WChar(pwstrName, pstr);

        pFormI1->pName = pwstrName;

        // copy the form size and imageable area.
        // the PSFORM structure stores the form size and the
        // imageable area in postscript USER coordinate (1/72 inch).
        // the forms database stores these values in .001mm.

        pFormI1->Size.cx = USERTO001MM(pPSForm->sizlPaper.cx);
        pFormI1->Size.cy = USERTO001MM(pPSForm->sizlPaper.cy);

        pFormI1->ImageableArea.left = USERTO001MM(pPSForm->imagearea.left);
        pFormI1->ImageableArea.top = USERTO001MM(pPSForm->sizlPaper.cy) -
                                     USERTO001MM(pPSForm->imagearea.top);
        pFormI1->ImageableArea.right = USERTO001MM(pPSForm->imagearea.right);
        pFormI1->ImageableArea.bottom = USERTO001MM(pPSForm->sizlPaper.cy) -
                                        USERTO001MM(pPSForm->imagearea.bottom);

        // point to the next PSFORM structure in the NTPD.  point to the
        // next FORM_INFO_1 structure we are filling in.  point to the next
        // form name buffer.

        pPSForm++;
        pFormI1++;
        pwstrName += CCHFORMNAME;
    }

    LoadString(hModule, (IDS_FORMS + STRING_BASE), SearchName,
               (sizeof(SearchName) / sizeof(SearchName[0])));

    rc = GetPrinterData(pdata->hPrinter, SearchName, &dwType, (PBYTE)&dwTmp,
                        sizeof(dwTmp), &cbNeeded);

    // if we have marked in the registry that we have already added all
    // the forms for this printer to the forms database, then we do not
    // need to do it again.

    if (rc != NO_ERROR)
    {
        // add each form defined in the NTPD structure to the forms
        // database.  AddForm should simply do nothing if this form
        // already exists in the database.

        pFormI1 = pFormI1Save;

        for (i = 0; i < pntpd->cPSForms; i++)
            AddForm(pdata->hPrinter, 1, (PBYTE)pFormI1++);

        // mark that we have added all the forms to the forms database
        // for this printer.

        dwTmp = 1;
        SetPrinterData(pdata->hPrinter, SearchName, REG_DWORD, (PBYTE)&dwTmp,
                       sizeof(dwTmp));
    }

    // we now know that all of the forms in the NTPD structure have been
    // added to the forms database.  now enumerate the database.

    if (!(pdbForms = GetFormsDataBase(pdata->hPrinter, &count, pntpd)))
    {
        RIP("PSCRPTUI!InitComboBoxes: GetFormsDataBase failed.\n");

        GlobalFree((HGLOBAL)pwstrSave);
        GlobalFree((HGLOBAL)pFormI1Save);

        return(FALSE);
    }
    else
    {
        // put the form in the list box if it is valid for this printer.

        pdbForm = pdbForms;

        for (i = 0; i < count; i++)
        {
            if (pdbForm->Flags & PSCRIPT_VALID_FORM)
            {
                // add the form to the list box.

                SendDlgItemMessage(hwnd, IDD_PAPER_LIST_BOX, CB_INSERTSTRING,
                                   (WPARAM)-1, (LPARAM)pdbForm->pName);
            }

            pdbForm++;
        }

        SendDlgItemMessage(hwnd, IDD_PAPER_LIST_BOX, CB_SETCURSEL, 0, 0L);
    }

    // free up resources.

    GlobalFree((HGLOBAL)pdbForms);
    GlobalFree((HGLOBAL)pwstrSave);
    GlobalFree((HGLOBAL)pFormI1Save);

    // if the only inputslot defined is the default inputslot, cInputSlots
    // will be zero.  in this case, let's simply let the user know that
    // this is the only paper tray.

    // NOTE!  CB_INSERTSTRING is used rather that CB_ADDSTRING.  This will
    // keep the order of the paper trays the same as in the PPD file, and
    // the same as Win31.  CB_ADDSTRING would sort the list.

    if (pntpd->cInputSlots == 0)
    {
        LoadString(hModule, (SLOTS_BASE + SLOT_ONLYONE),
                   SlotName, (sizeof(SlotName) / sizeof(SlotName[0])));

        rc = SendDlgItemMessage(hwnd, IDD_TRAY_LIST_BOX, CB_INSERTSTRING,
                                (WPARAM)-1, (LPARAM)SlotName);
    }
    else
    {
        // add each input slot defined in the NTPD to the list box.

        pslots = (PSINPUTSLOT *)((CHAR *)pntpd + pntpd->loPSInputSlots);

        for (i = 0; i < (DWORD)pntpd->cInputSlots; i++)
        {
            // check to see if there is a translation string to worry about,
            // for each form.

            pstrSave = (CHAR *)pntpd + pslots->loSlotName;

            XLATESTRING(pstr);

            // pstr now points to the form name we want.

            strcpy2WChar(SlotName, pstr);

            SendDlgItemMessage(hwnd, IDD_TRAY_LIST_BOX, CB_INSERTSTRING,
                               (WPARAM)-1, (LPARAM)SlotName);

            pslots++;
        }
    }

    // check to see if the current printer supports manual feed.  to do
    // this, check to see if a string to turn on manual feed was found.

    if (pntpd->loszManualFeedTRUE != 0)
    {
        // this printer does support manual feed, so insert this as the
        // last choice in the list box.

        LoadString(hModule, (SLOT_MANUAL + SLOTS_BASE),
                   SlotName, (sizeof(SlotName) / sizeof(SlotName[0])));

        rc = SendDlgItemMessage(hwnd, IDD_TRAY_LIST_BOX, CB_INSERTSTRING,
                                (WPARAM)-1, (LPARAM)SlotName);
    }

    // all of the paper trays have been added to the list box.  now
    // associate each paper tray with a form.  this will be done in the
    // following manner:  for each paper tray, see if an entry exists in
    // the registry (eg, "TrayUpper Letter").  if it does, use the form
    // specified there, and associate the tray with the index into the
    // form list box.  if no entry exists in the registry for the tray,
    // associate it with the default form.

    // first, find the index to the default form.

    // now see if there is a translation string to worry about.
    // do this by checking each device form name, to see if there
    // is a match of the "non-translation string" portion of the
    // name.  This code is confusing; as an example, if Letter is the
    // default form, the form name in the PPD file may have a
    // translation string such as Letter/US Letter.  In this case, we
    // want US Letter, not Letter, to be chosen as the default in the
    // list box.

    pPSForm = (PSFORM *)((CHAR *)pntpd + pntpd->loPSFORMArray);
    bFound = FALSE;
    pstrDefault = (CHAR *)pntpd + pntpd->loDefaultForm;

    for (i = 0; i < pntpd->cPSForms; i++)
    {
        pstr = (CHAR *)pntpd + pPSForm->loFormName;

        dwTmp = strlen(pstr);

        for (j = 0; j < dwTmp; j++)
        {
            // if we found the translation string deliminator '/',
            // then we will substitute the translation string for
            // the default.

            if (*pstr == '/')
            {
                pstr++;
                pstrDefault = pstr;
                bFound = TRUE;
                break;
            }

            if (*pstr++ != *pstrDefault++)
                break;
        }

        // if we found a translation string, we are done.

        if (bFound)
            break;
        else
            pstrDefault = (CHAR *)pntpd + pntpd->loDefaultForm;

        // otherwise go on to the next form.

        pPSForm++;
    }

    strcpy2WChar(FormName, pstrDefault);

    DefaultForm = SendDlgItemMessage(hwnd, IDD_PAPER_LIST_BOX, CB_FINDSTRING,
                                     (WPARAM)-1, (LPARAM)FormName);

    // if there was a problem finding the default form, use the first one
    // in the list box.

    if (DefaultForm == CB_ERR)
        DefaultForm = 0;

    // now see if a registry entry exists for each tray, and associate it
    // with the specified form if so.

    count = SendDlgItemMessage(hwnd, IDD_TRAY_LIST_BOX, CB_GETCOUNT,
                                   (WPARAM)0, (LPARAM)0);

    // initialize the list of forms selected by the user to be in each
    // paper tray.  fill each form index with -1, then fill in the default
    // tray with the default form index.

    // allocate memory for all trays.

    if (!(pdata->psetforms = (PLONG)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
                                                  (count * sizeof(LONG)))))
    {
        RIP("PSCRPTUI!InitComboBoxes: GlobalAlloc for psetforms failed.\n");
        return(FALSE);
    }

    // now initialize each entry to -1.

    psetform = pdata->psetforms;

    for (i = 0; i < count; i++)
        *psetform++ = UNINITIALIZED_FORM;

    // point back to first entry.

    psetform = pdata->psetforms;

    // first find out the size of the tray-form buffer and copy it from
    // the registry.

    // now get the table size from the registry.

    LoadString(hModule, (IDS_TRAY_FORM_SIZE + STRING_BASE),
              wcbuf, (sizeof(wcbuf) / sizeof(wcbuf[0])));

    GetPrinterData(pdata->hPrinter, wcbuf, &dwType, (LPBYTE)&cbTrayForm,
                   sizeof(cbTrayForm), &cbNeeded);

    if (cbTrayForm)
    {
        // allocate a buffer.

        if (!(pwstrName = (WCHAR *)GlobalAlloc(GMEM_FIXED |
                                               GMEM_ZEROINIT,
                                               cbTrayForm)))
        {
            RIP("PSCRPTUI!InitComboBoxes: GlobalAlloc pwstrName failed.\n");
            return(FALSE);
        }

        pwstrSave = pwstrName;

        // now grab the table itself from the registry.

        LoadString(hModule, (IDS_TRAY_FORM_TABLE + STRING_BASE),
                  wcbuf, (sizeof(wcbuf) / sizeof(wcbuf[0])));

        rc = GetPrinterData(pdata->hPrinter, wcbuf, &dwType, (LPBYTE)pwstrName,
                            cbTrayForm, &cbNeeded);

        if (rc != ERROR_SUCCESS)
        {
            RIP("PSCRPTUI!InitComboBoxes: GetPrinterData pwstrName failed.\n");
            GlobalFree((HGLOBAL)pwstrSave);
            return(FALSE);
        }

        for (i = 0; i < count; i++)
        {
            // get the tray name.

            SendDlgItemMessage(hwnd, IDD_TRAY_LIST_BOX, CB_GETLBTEXT,
                               (WPARAM)i, (LPARAM)SlotName);

            pwstrName = pwstrSave;

            // search the tray-form table for a matching tray.

            bFound = FALSE;

            while (*pwstrName)
            {
                if (!(wcscmp(pwstrName, SlotName)))
                {
                    // we found the inplut slot, now get the matching form.

                    pwstrName += (wcslen(pwstrName) + 1);
                    wcsncpy(FormName, pwstrName,
                            (sizeof(FormName) / sizeof(FormName[0])));
                    bFound = TRUE;
                    break;
                }
                else
                {
                    // this was not the form in question.  skip over both form names.

                    pwstrName += (wcslen(pwstrName) + 1);
                    pwstrName += (wcslen(pwstrName) + 1);
                    pwstrName += (wcslen(pwstrName) + 1);
                }
            }

            if (bFound)
            {
                // get the index of the specified form.

                rc = SendDlgItemMessage(hwnd, IDD_PAPER_LIST_BOX, CB_FINDSTRING,
                                        (WPARAM)-1, (LPARAM)FormName);

                if (rc == CB_ERR)
                    rc = DefaultForm;
            }
            else
                rc = DefaultForm;

            // save tray form association until we write out to registry.

            psetform[i] = rc;

            // we now have the index of a form to associate with the current tray.

            SendDlgItemMessage(hwnd, IDD_TRAY_LIST_BOX, CB_SETITEMDATA,
                               (WPARAM)i, (LPARAM)rc);
        }

        // free up the tray-form table buffer.

        GlobalFree((HGLOBAL)pwstrSave);
    }

    // highlight the default paper tray, and the corresponding form.
    // get the default paper tray from the NTPD structure.

    // now see if there is a translation string to worry about.
    // do this by checking each device input slot, to see if there
    // is a match of the "non-translation string" portion of the
    // name.

    pslots = (PSINPUTSLOT *)((CHAR *)pntpd + pntpd->loPSInputSlots);
    bFound = FALSE;
    pstrDefault = (CHAR *)pntpd + pntpd->loDefaultSlot;

    for (i = 0; i < pntpd->cInputSlots; i++)
    {
        pstr = (CHAR *)pntpd + pslots->loSlotName;

        dwTmp = strlen(pstr);

        for (j = 0; j < dwTmp; j++)
        {
            // if we found the translation string deliminator '/',
            // then we will substitute the translation string for
            // the default.

            if (*pstr == '/')
            {
                pstr++;
                pstrDefault = pstr;
                bFound = TRUE;
                break;
            }

            if (*pstr++ != *pstrDefault++)
                break;
        }

        // if we found a translation string, we are done.

        if (bFound)
            break;
        else
            pstrDefault = (CHAR *)pntpd + pntpd->loDefaultSlot;

        // otherwise go on to the next form.

        pslots++;
    }

    strcpy2WChar(FormName, pstrDefault);
    strcpy2WChar(SlotName, (CHAR *)pntpd + pntpd->loDefaultSlot);

    rc = SendDlgItemMessage(hwnd, IDD_TRAY_LIST_BOX, CB_FINDSTRING,
                                     (WPARAM)-1, (LPARAM)SlotName);

    // highlight the first tray if there was a problem getting the default
    // tray.

    if (rc == CB_ERR)
        rc = 0;

    SendDlgItemMessage(hwnd, IDD_TRAY_LIST_BOX, CB_SETCURSEL,
                       (WPARAM)rc, (LPARAM)0);

    // get the index of the corresponding form.

    iForm = SendDlgItemMessage(hwnd, IDD_TRAY_LIST_BOX, CB_GETITEMDATA,
                            (WPARAM)rc, (LPARAM)0);

    if (iForm == CB_ERR)
        iForm = DefaultForm;

    SendDlgItemMessage(hwnd, IDD_PAPER_LIST_BOX, CB_SETCURSEL,
                       (WPARAM)iForm, (LPARAM)0);

    return TRUE;
}


//--------------------------------------------------------------------------
// BOOL bAbout(hwnd, pntpd)
// HWND    hwnd;
// PNTPD   pntpd;
//
// This routine invokes the common About dialog.
//
// Returns:
//   This routine returns TRUE for success, FALSE otherwise.
//
// History:
//   22-Apr-1993    -by-    Kent Settle     (kentse)
// Borrowed from Rasdd, and modified.
//--------------------------------------------------------------------------

BOOL bAbout(hwnd, pntpd)
HWND    hwnd;
PNTPD   pntpd;
{
    HANDLE          hCursor, hIcon;
    WCHAR           wszTitle[RESOURCE_STRING_LENGTH];
    WCHAR           wszModel[RESOURCE_STRING_LENGTH];
    WCHAR          *pwstr;

    hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));

    hIcon = LoadIcon(hModule, MAKEINTRESOURCE(ICO_PRINTER));

    pwstr = (PWSTR)((PSTR)pntpd + pntpd->lowszPrinterName);

    // fill in the device name string.

    LoadString(hModule, IDS_MODEL_STRING + STRING_BASE, wszModel,
               sizeof(wszModel) / sizeof(wszModel[0]));

    // fill in the model name itself.

    pwstr = wszModel + wcslen(wszModel);

    wcsncpy(pwstr, (LPWSTR)((PSTR)pntpd + pntpd->lowszPrinterName),
            RESOURCE_STRING_LENGTH - wcslen(wszModel));

    // get our name.

    LoadString(hModule, IDS_PSCRIPT_VERSION + STRING_BASE,
               wszTitle, sizeof(wszTitle) / sizeof(wszTitle[0]));

    // call off to the common about dialog.

    ShellAbout(hwnd, wszTitle, wszModel, hIcon);

    SetCursor(hCursor);

    return(TRUE);
}


//--------------------------------------------------------------------------
// VOID GetPrinterForm(pntpd, pFormName, pPrinterForm);
// PNTPD       pntpd;
// PWSTR       pFormName;
// PWSTR       pPrinterForm;
//
// This routine invokes the common About dialog.
//
// Returns:
//   This routine returns TRUE for success, FALSE otherwise.
//
// History:
//   22-Apr-1993    -by-    Kent Settle     (kentse)
// Borrowed from Rasdd, and modified.
//--------------------------------------------------------------------------

VOID GetPrinterForm(pntpd, pForm, pPrinterForm)
PNTPD           pntpd;
FORM_INFO_1    *pForm;
PWSTR           pPrinterForm;
{
    PSFORM         *pPSForm;
    DWORD           i;
    BOOL            bFound;
    SIZEL           sizldelta, sizltmp;
    CHAR            szForm[CCHFORMNAME];

    // find the printer's form metrics from the NTPD.

    pPSForm = (PSFORM *)((CHAR *)pntpd + pntpd->loPSFORMArray);

    // first try to match a form by name.

    // get ANSI version of form name.

    WideCharToMultiByte(CP_ACP, 0, (LPWSTR)pForm->pName,
                        (INT)(wcslen(pForm->pName) + 1), szForm,
                        sizeof(szForm), NULL, NULL);

    for (i = 0; i < pntpd->cPSForms; i++)
    {
        if (!(NameComp(szForm, (CHAR *)pntpd + pPSForm->loFormName)))
        {
            // in this case, the printer form name and the database form
            // name are the same.

            wcsncpy(pPrinterForm, pForm->pName, CCHFORMNAME);
            return;
        }

        // point to the next PSFORM.

        pPSForm++;
    }

    // if we did not find a name match, try to locate a form by size.

    // get pointer to first form in NTPD.

    pPSForm = (PSFORM *)((CHAR *)pntpd + pntpd->loPSFORMArray);

    // sizldelta is used to hold the difference between form sizes.
    // initialize to large value.

    sizldelta.cx = sizldelta.cy = INITIAL_FORM_DELTA;

    bFound = FALSE;

    for (i = 0; i < pntpd->cPSForms; i++)
    {
        sizltmp.cx = USERTO001MM(pPSForm->sizlPaper.cx) - pForm->Size.cx;
        sizltmp.cy = USERTO001MM(pPSForm->sizlPaper.cy) - pForm->Size.cy;

        // see if we have an exact match on size (within 1mm).

        if (((DWORD)abs(sizltmp.cx) <= 1000) &&
             ((DWORD)abs(sizltmp.cy) <= 1000))
        {
            // we have an exact match on size, so overwrite the form
            // name with the name the printer knows about.

            strcpy2WChar(pPrinterForm, (CHAR *)pntpd + pPSForm->loFormName);
            return;
        }

        // not an exact match, but see if we could fit on this form.

        if ((sizltmp.cx >= 0) && (sizltmp.cy >= 0))
        {
            // we can fit on this form.  let's see if it is the smallest.

            if ((sizltmp.cx <= sizldelta.cx) &&
                (sizltmp.cy <= sizldelta.cy))
            {
                // this form is the smallest yet.

                sizldelta = sizltmp;
                strcpy2WChar(pPrinterForm, (CHAR *)pntpd + pPSForm->loFormName);
                bFound = TRUE;
            }
        }

        // point to the next PSFORM.

        pPSForm++;
    }

    // set to default if no form was found.

    strcpy2WChar(pPrinterForm, (CHAR *)pntpd + pntpd->loDefaultForm);
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.