Annotation of ntddk/src/print/pscrptui/pscrptui.c, revision 1.1

1.1     ! root        1: //--------------------------------------------------------------------------
        !             2: //
        !             3: // Module Name:  PSCRPTUI.C
        !             4: //
        !             5: // Brief Description:  This module contains the PSCRIPT driver's User
        !             6: // Interface functions and related routines.
        !             7: //
        !             8: // Author:  Kent Settle (kentse)
        !             9: // Created: 11-Jul-1991
        !            10: //
        !            11: // Copyright (c) 1991-1992 Microsoft Corporation
        !            12: //
        !            13: // This module contains routines supporting the setting of Printer and
        !            14: // Job Property dialogs for the NT Windows PostScript printer driver.
        !            15: //
        !            16: // The general outline for much of the code was taken from the NT RASDD
        !            17: // printer driver's user interface code, which was written by Steve
        !            18: // Cathcart (stevecat).
        !            19: //--------------------------------------------------------------------------
        !            20: 
        !            21: #define _HTUI_APIS_
        !            22: 
        !            23: #include <stddef.h>
        !            24: #include <stdlib.h>
        !            25: #include <string.h>
        !            26: #include "pscript.h"
        !            27: #include "shellapi.h"
        !            28: #include <winspool.h>
        !            29: #include "dlgdefs.h"
        !            30: #include "pscrptui.h"
        !            31: #include "help.h"
        !            32: 
        !            33: #define UNINITIALIZED_FORM  -1
        !            34: #define TRANSLATED_TRAYS    0x00000001
        !            35: #define TRANSLATED_FORMS    0x00000002
        !            36: #define INITIAL_FORM_DELTA      16384
        !            37: 
        !            38: // declarations of routines defined within this module.
        !            39: 
        !            40: LONG PrtPropDlgProc( HWND, UINT, DWORD, LONG );
        !            41: LONG AboutDlgProc( HWND, UINT, DWORD, LONG );
        !            42: BOOL InitComboBoxes(HWND, PRINTDATA *);
        !            43: BOOL bAbout(HWND, PNTPD);
        !            44: VOID GetPrinterForm(PNTPD, FORM_INFO_1 *, PWSTR);
        !            45: 
        !            46: // external routines and data.
        !            47: 
        !            48: extern LONG  FontInstDlgProc( HWND, UINT, DWORD, LONG);
        !            49: extern LONG TTFontDialogProc(HWND, UINT, DWORD, LONG);
        !            50: extern TT_FONT_MAPPING TTFontTable[]; // ..\pscript\tables.h.
        !            51: extern PFORM_INFO_1 GetFormsDataBase(HANDLE, DWORD *, PNTPD);
        !            52: extern int NameComp(CHAR *, CHAR *);
        !            53: 
        !            54: extern
        !            55: void
        !            56: vDoDeviceHTDataUI(
        !            57:     LPSTR   pDeviceName,
        !            58:     BOOL    ColorDevice,
        !            59:     BOOL    bUpdate
        !            60:     );
        !            61: 
        !            62: extern
        !            63: void
        !            64: vGetDeviceHTData(
        !            65:     HANDLE      hPrinter,
        !            66:     PDEVHTINFO  pDefaultDevHTInfo
        !            67:     );
        !            68: 
        !            69: 
        !            70: extern
        !            71: BOOL
        !            72: bSaveDeviceHTData(
        !            73:     HANDLE  hPrinter,
        !            74:     BOOL    bForce              // TRUE if always update
        !            75:     );
        !            76: 
        !            77: // global Data
        !            78: 
        !            79: DWORD   Type=1;
        !            80: 
        !            81: BYTE    PP_AnsiDeviceName[128];
        !            82: 
        !            83: #define MAX_TRAYS       9
        !            84: #define INVALID_TRAY    -1L
        !            85: #define INVALID_FORM    -1L
        !            86: #define MAX_SKIP        5
        !            87: #define SMALL_BUF       32
        !            88: 
        !            89: #define  RESOURCE_STRING_LENGTH   128
        !            90: 
        !            91: //--------------------------------------------------------------------------
        !            92: // BOOL PrinterProperties(HWND  hwnd, LPPRINTER lpPrinter)
        !            93: //
        !            94: // This function first retrieves and displays the current set of printer
        !            95: // properties for the printer.  The user is allowed to change the current
        !            96: // printer properties from the displayed dialog box.
        !            97: //
        !            98: // Returns:
        !            99: //   This function returns -1L if it fails in any way.  If the dialog is
        !           100: //   actually displayed, it returns either IDOK or IDCANCEL, depending on
        !           101: //   what the user chose.   If no dialog box was displayed and the function
        !           102: //   is successful, IDOK is returned.
        !           103: //
        !           104: // History:
        !           105: //   11-Jul-1991     -by-     Kent Settle     (kentse)
        !           106: //  Wrote it.
        !           107: //--------------------------------------------------------------------------
        !           108: 
        !           109: BOOL PrinterProperties(HWND  hwnd, HANDLE hPrinter)
        !           110: {
        !           111:     int         nResult;
        !           112:     PRINTDATA   printdata;
        !           113:     WCHAR       wcbuf[32];
        !           114:     DWORD       dwTmp;
        !           115:     DWORD       rc;
        !           116: 
        !           117:     // fill in PRINTDATA structure.
        !           118: 
        !           119:     printdata.hPrinter = hPrinter;
        !           120:     printdata.iFreeMemory = 0;
        !           121:     printdata.pntpd = (PNTPD)NULL;
        !           122:     printdata.psetforms = (PLONG)NULL;
        !           123:     printdata.bHostHalftoning = TRUE;
        !           124: 
        !           125:     // simply try to write out to the registry to see if the caller
        !           126:     // has permission to change anything.
        !           127: 
        !           128:     LoadString(hModule, (IDS_PERMISSION + STRING_BASE), wcbuf,
        !           129:                (sizeof(wcbuf) / sizeof(wcbuf[0])));
        !           130: 
        !           131:     dwTmp = 1;
        !           132: 
        !           133:     rc = SetPrinterData(hPrinter, wcbuf, REG_DWORD, (LPBYTE)&dwTmp,
        !           134:                         sizeof(DWORD));
        !           135: 
        !           136:     if (rc == ERROR_SUCCESS)
        !           137:         printdata.bPermission = TRUE;
        !           138:     else
        !           139:         printdata.bPermission = FALSE;
        !           140: 
        !           141:     // call the printer properties dialog routine.
        !           142: 
        !           143:     nResult = DialogBoxParam (hModule, MAKEINTRESOURCE(PRINTER_PROP), hwnd,
        !           144:                               (DLGPROC)PrtPropDlgProc, (LPARAM)&printdata);
        !           145: 
        !           146:     return(nResult);
        !           147: }
        !           148: 
        !           149: 
        !           150: //--------------------------------------------------------------------------
        !           151: // LONG APIENTRY AboutDlgProc (HWND hDlg, UINT message, DWORD wParam,
        !           152: //                             LONG lParam)
        !           153: //
        !           154: // This function processes messages for the "About" dialog box.
        !           155: //
        !           156: // Returns:
        !           157: //   This function returns TRUE if successful, FALSE otherwise.
        !           158: //
        !           159: // History:
        !           160: //   11-Jul-1991     -by-     Kent Settle     (kentse)
        !           161: //  Wrote it.
        !           162: //--------------------------------------------------------------------------
        !           163: 
        !           164: LONG AboutDlgProc(
        !           165:     HWND    hDlg,
        !           166:     UINT    message,
        !           167:     DWORD   wParam,
        !           168:     LONG    lParam
        !           169: )
        !           170: {
        !           171:     UNREFERENCED_PARAMETER (lParam);
        !           172: 
        !           173:     switch (message)
        !           174:     {
        !           175:         case WM_INITDIALOG:
        !           176:             return (TRUE);
        !           177: 
        !           178:         case WM_COMMAND:
        !           179:             if ((LOWORD(wParam) == IDOK) || (LOWORD(wParam) == IDCANCEL))
        !           180:             {
        !           181:                 EndDialog (hDlg, IDOK);
        !           182:                 return (TRUE);
        !           183:             }
        !           184:             break;
        !           185:     }
        !           186:     return (FALSE);
        !           187: }
        !           188: 
        !           189: 
        !           190: //--------------------------------------------------------------------------
        !           191: // LONG APIENTRY PrtPropDlgProc(HWND hwnd, UINT usMsg, DWORD wParam,
        !           192: //                              LONG  lParam)
        !           193: //
        !           194: // This function processes messages for the "About" dialog box.
        !           195: //
        !           196: // Returns:
        !           197: //   This function returns TRUE if successful, FALSE otherwise.
        !           198: //
        !           199: // History:
        !           200: //   11-Jul-1991     -by-     Kent Settle     (kentse)
        !           201: //  Wrote it.
        !           202: //--------------------------------------------------------------------------
        !           203: 
        !           204: LONG APIENTRY PrtPropDlgProc(HWND hwnd, UINT usMsg, DWORD wParam,
        !           205:                              LONG  lParam)
        !           206: {
        !           207:     LPWSTR          pwDeviceName;
        !           208:     int             i, rc;
        !           209:     int             iSelect;
        !           210:     WCHAR           wcbuf1[SMALL_BUF];
        !           211:     WCHAR           wcbuf2[MAX_FONTNAME * 2];
        !           212:     WCHAR           wcbuf3[MAX_FONTNAME];
        !           213:     DWORD           cbNeeded, cbTrayForm;
        !           214:     int             cTrays;
        !           215:     int             iForm, iTray;
        !           216:     LONG            lReturn;
        !           217:     BOOL            bTmp;
        !           218:     DWORD           returnvalue;
        !           219:     WCHAR           SlotName[MAX_SLOT_NAME];
        !           220:     WCHAR           FormName[CCHFORMNAME];
        !           221:     WCHAR           PrinterForm[CCHFORMNAME];
        !           222:     PRINTDATA      *pdata;
        !           223:     PLONG           psetform;
        !           224:     WCHAR          *pwstr;
        !           225:     WCHAR          *pwstrsave;
        !           226:     FORM_INFO_1    *pForm;
        !           227: 
        !           228:     switch (usMsg)
        !           229:     {
        !           230:         case WM_INITDIALOG:
        !           231:             pdata = (PRINTDATA *)lParam;
        !           232: 
        !           233:             if (!pdata)
        !           234:             {
        !           235:                 RIP("PSCRPTUI!PrtPropDlgProc: null pdata.\n");
        !           236:                 return(FALSE);
        !           237:             }
        !           238: 
        !           239:             // save the PRINTDATA.
        !           240: 
        !           241:             SetWindowLong(hwnd, GWL_USERDATA, lParam);
        !           242: 
        !           243:             if (!(pdata->pntpd = MapPrinter(pdata->hPrinter)))
        !           244:             {
        !           245:                 RIP("PSCRPTUI!PrtPropDlgProc: MapPrinter failed.\n");
        !           246:                 return(FALSE);
        !           247:             }
        !           248: 
        !           249:             //
        !           250:             // Make up ANSI version of the device name for later halftone
        !           251:             // UI to use
        !           252:             //
        !           253: 
        !           254:             pwDeviceName = (LPWSTR)((PSTR)pdata->pntpd +
        !           255:                                     pdata->pntpd->lowszPrinterName);
        !           256: 
        !           257:             WideCharToMultiByte(CP_ACP,
        !           258:                                 0,
        !           259:                                 (LPWSTR)pwDeviceName,
        !           260:                                 (INT)(wcslen(pwDeviceName) + 1),
        !           261:                                 PP_AnsiDeviceName,
        !           262:                                 sizeof(PP_AnsiDeviceName),
        !           263:                                 NULL,
        !           264:                                 NULL);
        !           265: 
        !           266:     //
        !           267:     // First read in the current DEVHTINFO data
        !           268:     //
        !           269:     // !!! If you can read the DEVHTINFO from MINI DRIVERS, then pass that
        !           270:     // !!! pointer to the GetDeviceHTData(), the DEVHTINFO is at end of
        !           271:     // !!! winddi.h, it includes COLORINFO, DevPelSize, HTPatternSize and
        !           272:     // !!! so on.  If a NULL is passed then standard halftone default will
        !           273:     // !!! be used to set in the registry at first time
        !           274:     //
        !           275: 
        !           276:             vGetDeviceHTData(pdata->hPrinter, NULL);
        !           277: 
        !           278: 
        !           279:             // fill in the default printer memory configuration.  first
        !           280:             // check to see if a value has been saved in the registry.
        !           281:             // if so, use it, otherwise, get the default value from
        !           282:             // the PPD file.
        !           283: 
        !           284:             LoadString(hModule, (IDS_FREEMEM + STRING_BASE),
        !           285:                        wcbuf2, (sizeof(wcbuf2) / sizeof(wcbuf2[0])));
        !           286: 
        !           287:             returnvalue = GetPrinterData(pdata->hPrinter, wcbuf2, &Type,
        !           288:                                          (LPBYTE)&pdata->iFreeMemory,
        !           289:                                          sizeof(pdata->iFreeMemory), &cbNeeded);
        !           290: 
        !           291:             if (returnvalue != NO_ERROR)
        !           292:                 pdata->iFreeMemory = pdata->pntpd->cbFreeVM;
        !           293: 
        !           294:             SetDlgItemInt(hwnd, IDD_MEMORY_EDIT_BOX, pdata->iFreeMemory, FALSE);
        !           295: 
        !           296:             // initialize the printer model name.
        !           297: 
        !           298:             SetDlgItemText(hwnd, IDD_MODEL_TEXT,
        !           299:                            (PWSTR)((PSTR)pdata->pntpd + pdata->pntpd->lowszPrinterName));
        !           300: 
        !           301:             // initialize the paper tray and paper size list boxes.
        !           302: 
        !           303:             if (!InitComboBoxes(hwnd, pdata))
        !           304:                 RIP("PrtPropDlgProc: InitComboBoxes failed.\n");
        !           305: 
        !           306: 
        !           307:             // Get the current setting of the PS_HALFTONING flag from the
        !           308:             // registry and initialize the check button.
        !           309: 
        !           310:             LoadString(hModule, (IDS_HALFTONE + STRING_BASE),
        !           311:                        wcbuf3, (sizeof(wcbuf3) / sizeof(wcbuf3[0])));
        !           312: 
        !           313:             returnvalue = GetPrinterData(pdata->hPrinter,
        !           314:                                          wcbuf3,
        !           315:                                          &Type,
        !           316:                                          (LPBYTE)&(pdata->bHostHalftoning),
        !           317:                                          sizeof(pdata->bHostHalftoning),
        !           318:                                          &cbNeeded);
        !           319: 
        !           320:             // printer halftoning is OFF by default.  ie, use system halftoning.
        !           321: 
        !           322:             if (returnvalue != NO_ERROR)
        !           323:             {
        !           324:                pdata->bHostHalftoning = TRUE;
        !           325:             }
        !           326: 
        !           327:             CheckDlgButton(hwnd,
        !           328:                            IDD_USE_HOST_HALFTONING,
        !           329:                            !((pdata->bHostHalftoning)));
        !           330: 
        !           331:             // if the user has selected printer halfoning, disable the system halftoning
        !           332:             // push button.
        !           333: 
        !           334:             if (pdata->bHostHalftoning)
        !           335:                 EnableWindow(GetDlgItem(hwnd, IDD_HALFTONE_PUSH_BUTTON), TRUE);
        !           336:             else
        !           337:                 EnableWindow(GetDlgItem(hwnd, IDD_HALFTONE_PUSH_BUTTON), FALSE);
        !           338: 
        !           339:             // intialize the help stuff.
        !           340: 
        !           341:             vHelpInit();
        !           342: 
        !           343:             // disable a bunch of stuff if the user does not have
        !           344:             // permission to change it.
        !           345: 
        !           346:             if (!pdata->bPermission)
        !           347:             {
        !           348:                 EnableWindow(GetDlgItem(hwnd, IDD_PAPER_LIST_BOX), FALSE);
        !           349:                 EnableWindow(GetDlgItem(hwnd, IDD_MEMORY_EDIT_BOX), FALSE);
        !           350:                 EnableWindow(GetDlgItem(hwnd, IDD_USE_HOST_HALFTONING), FALSE);
        !           351:             }
        !           352:             return TRUE;
        !           353:             break;
        !           354: 
        !           355:         case WM_COMMAND:
        !           356:             pdata = (PRINTDATA *)GetWindowLong(hwnd, GWL_USERDATA);
        !           357: 
        !           358:             switch (LOWORD(wParam))
        !           359:             {
        !           360:                 case IDD_ABOUT_BUTTON:
        !           361:                     return(bAbout(hwnd, pdata->pntpd));
        !           362: 
        !           363:                 case IDD_FONTS_BUTTON:
        !           364:                     lReturn = DialogBoxParam (hModule, MAKEINTRESOURCE(FONTINST), hwnd,
        !           365:                                               (DLGPROC)FontInstDlgProc,
        !           366:                                               (LPARAM)pdata);
        !           367: 
        !           368:                     if (lReturn == -1)
        !           369:                     {
        !           370:                         RIP("PSCRPTUI!PrtPropDlgProc: DialogBoxParam for FONTINST failed.\n");
        !           371:                         return(FALSE);
        !           372:                     }
        !           373: 
        !           374:                     return (TRUE);
        !           375: 
        !           376:                 case IDD_FONT_SUBST_PUSH_BUTTON:
        !           377:                     lReturn = DialogBoxParam(hModule, MAKEINTRESOURCE(IDD_TT_DIALOG),
        !           378:                                              hwnd, (DLGPROC)TTFontDialogProc,
        !           379:                                              (LPARAM)pdata);
        !           380: 
        !           381:                     if (lReturn == -1)
        !           382:                     {
        !           383:                         RIP("PSCRPTUI!PrtPropDlgProc: DialogBoxParam for TTFONTS failed.\n");
        !           384:                         return(FALSE);
        !           385:                     }
        !           386: 
        !           387:                     return (TRUE);
        !           388: 
        !           389:                 //
        !           390:                 // Button for toggling host versus device halftoning mode.
        !           391:                 // -- DJS
        !           392:                 case IDD_USE_HOST_HALFTONING:
        !           393: 
        !           394:                     if(IsDlgButtonChecked(hwnd, IDD_USE_HOST_HALFTONING))
        !           395:                     {
        !           396:                         pdata->bHostHalftoning = FALSE;
        !           397:                         EnableWindow(GetDlgItem(hwnd, IDD_HALFTONE_PUSH_BUTTON),
        !           398:                                                 FALSE);
        !           399:                     }
        !           400:                     else
        !           401:                     {
        !           402:                         pdata->bHostHalftoning = TRUE;
        !           403:                         EnableWindow(GetDlgItem(hwnd, IDD_HALFTONE_PUSH_BUTTON),
        !           404:                                                 TRUE);
        !           405:                     }
        !           406: 
        !           407:                     break;
        !           408: 
        !           409:                    return(TRUE);
        !           410: 
        !           411:                 case IDD_HALFTONE_PUSH_BUTTON:
        !           412: 
        !           413:                     vDoDeviceHTDataUI(PP_AnsiDeviceName,
        !           414:                                       (pdata->pntpd->flFlags & COLOR_DEVICE),
        !           415:                                       pdata->bPermission);
        !           416: 
        !           417:                     return(TRUE);
        !           418: 
        !           419:                 case IDD_TRAY_LIST_BOX:
        !           420:                     if (HIWORD (wParam) != CBN_SELCHANGE)
        !           421:                         return (FALSE);
        !           422: 
        !           423:                     // get the index for the currently selected tray.
        !           424: 
        !           425:                     iTray = SendDlgItemMessage(hwnd, IDD_TRAY_LIST_BOX,
        !           426:                                                CB_GETCURSEL, (WPARAM)0,
        !           427:                                                (LPARAM)0);
        !           428: 
        !           429:                     // get the index of the corresponding form.
        !           430: 
        !           431:                     iForm = SendDlgItemMessage(hwnd, IDD_TRAY_LIST_BOX,
        !           432:                                                CB_GETITEMDATA,
        !           433:                                                (WPARAM)iTray,
        !           434:                                                (LPARAM)0);
        !           435: 
        !           436:                     // highlight the form that has previously been
        !           437:                     // associated with this tray.
        !           438: 
        !           439:                     SendDlgItemMessage(hwnd, IDD_PAPER_LIST_BOX, CB_SETCURSEL,
        !           440:                                        (WPARAM)iForm, (LPARAM)0);
        !           441: 
        !           442:                     // write this association to our selected forms list.
        !           443: 
        !           444:                     psetform = pdata->psetforms;
        !           445: 
        !           446:                     psetform[iTray] = iForm;
        !           447: 
        !           448:                     break;
        !           449: 
        !           450:                 case IDD_PAPER_LIST_BOX:
        !           451:                     if (HIWORD (wParam) != CBN_SELCHANGE)
        !           452:                         return (FALSE);
        !           453: 
        !           454:                     // get the index for the currently selected tray.
        !           455: 
        !           456:                     iTray = SendDlgItemMessage (hwnd, IDD_TRAY_LIST_BOX,
        !           457:                                                 CB_GETCURSEL, (WPARAM)0,
        !           458:                                                 (LPARAM)0);
        !           459: 
        !           460:                     // get the index for the currently selected form.
        !           461: 
        !           462:                     iForm = SendDlgItemMessage (hwnd, IDD_PAPER_LIST_BOX,
        !           463:                                                        CB_GETCURSEL, (WPARAM)0,
        !           464:                                                        (LPARAM)0);
        !           465: 
        !           466:                     // associate the current form with the current tray.
        !           467: 
        !           468:                     SendDlgItemMessage(hwnd, IDD_TRAY_LIST_BOX, CB_SETITEMDATA,
        !           469:                                        (WPARAM)iTray, (LPARAM)iForm);
        !           470: 
        !           471:                     // write this association to our selected forms list.
        !           472: 
        !           473:                     psetform = pdata->psetforms;
        !           474: 
        !           475:                     psetform[iTray] = iForm;
        !           476: 
        !           477:                     break;
        !           478: 
        !           479:                 case IDD_HELP_BUTTON:
        !           480:                     vShowHelp(hwnd, HELP_CONTEXT, HLP_PRINTER_SETUP,
        !           481:                               pdata->hPrinter);
        !           482:                     return(TRUE);
        !           483: 
        !           484:                 case IDOK:
        !           485:                     if (pdata->bPermission)
        !           486:                     {
        !           487:                         // get the new value from the memory edit box.
        !           488: 
        !           489:                         i = GetDlgItemInt(hwnd, IDD_MEMORY_EDIT_BOX, &bTmp, FALSE);
        !           490: 
        !           491:                         // if the user has changed the memory setting,
        !           492:                         // pop up a message box.
        !           493: 
        !           494:                         if (i != (int)pdata->iFreeMemory)
        !           495:                         {
        !           496:                             // warn the user that changing the memory setting
        !           497:                             // is dangerous.
        !           498: 
        !           499:                             LoadString(hModule,
        !           500:                                        (IDS_MEMWARN + STRING_BASE),
        !           501:                                        (LPWSTR)wcbuf2,
        !           502:                                        (sizeof(wcbuf2) / sizeof(wcbuf2[0])));
        !           503: 
        !           504:                             LoadString(hModule,
        !           505:                                        (IDS_CAUTION + STRING_BASE),
        !           506:                                        (LPWSTR)wcbuf1,
        !           507:                                        (sizeof(wcbuf1) / sizeof(wcbuf1[0])));
        !           508: 
        !           509:                             iSelect = MessageBox(hwnd, wcbuf2, wcbuf1,
        !           510:                                                  MB_DEFBUTTON2 |
        !           511:                                                  MB_ICONEXCLAMATION | MB_YESNO);
        !           512: 
        !           513:                             if (iSelect == IDYES)
        !           514:                                 pdata->iFreeMemory = i;
        !           515:                             else
        !           516:                             {
        !           517:                                 // reset the memory edit box.
        !           518: 
        !           519:                                 SendDlgItemMessage(hwnd, IDD_MEMORY_EDIT_BOX,
        !           520:                                                    EM_SETSEL, 0, 0x7FFF0000);
        !           521: 
        !           522:                                 SetDlgItemInt(hwnd, IDD_MEMORY_EDIT_BOX,
        !           523:                                               pdata->iFreeMemory, FALSE);
        !           524: 
        !           525:                                 break;
        !           526:                             }
        !           527:                         }
        !           528: 
        !           529:                         // output the free memory to the .INI file.
        !           530: 
        !           531:                         LoadString(hModule, (IDS_FREEMEM + STRING_BASE),
        !           532:                                    wcbuf2, (sizeof(wcbuf2) / sizeof(wcbuf2[0])));
        !           533: 
        !           534: #if DBG
        !           535:                         if (SetPrinterData(pdata->hPrinter, wcbuf2, REG_BINARY,
        !           536:                                        (LPBYTE)&pdata->iFreeMemory,
        !           537:                                        sizeof(pdata->iFreeMemory)))
        !           538:                             RIP("PSCRPTUI!PrtPropDlgProc: SetPrinterData FreeMem failed.\n");
        !           539: #else
        !           540:                         SetPrinterData(pdata->hPrinter, wcbuf2, REG_BINARY,
        !           541:                                        (LPBYTE)&pdata->iFreeMemory,
        !           542:                                        sizeof(pdata->iFreeMemory));
        !           543: #endif
        !           544: 
        !           545: 
        !           546:                          // Set Halftone flag in Registry
        !           547: 
        !           548:                           LoadString(hModule, (IDS_HALFTONE + STRING_BASE),
        !           549:                                     wcbuf3, (sizeof(wcbuf3) / sizeof(wcbuf3[0])));
        !           550: 
        !           551:                           SetPrinterData(pdata->hPrinter,
        !           552:                                          wcbuf3,
        !           553:                                          REG_BINARY,
        !           554:                                          (LPBYTE)&(pdata->bHostHalftoning),
        !           555:                                          sizeof(pdata->bHostHalftoning));
        !           556: 
        !           557:                         // output the corresponding tray - form pairs to the
        !           558:                         // registry.
        !           559: 
        !           560:                         cTrays = SendDlgItemMessage(hwnd, IDD_TRAY_LIST_BOX,
        !           561:                                                     CB_GETCOUNT, (WPARAM)0,
        !           562:                                                     (LPARAM)0);
        !           563: 
        !           564:                         psetform = pdata->psetforms;
        !           565: 
        !           566:                         // first calculate what size buffer we need.
        !           567:                         // allow room for double NULL terminator.
        !           568: 
        !           569:                         cbTrayForm = 1;
        !           570: 
        !           571:                         for (i = 0; i < cTrays; i++)
        !           572:                         {
        !           573:                             // only output the pair if it has been selected by
        !           574:                             // the user.
        !           575: 
        !           576:                             if (*psetform++ != UNINITIALIZED_FORM)
        !           577:                             {
        !           578:                                 // get the tray name.
        !           579: 
        !           580:                                 SendDlgItemMessage(hwnd, IDD_TRAY_LIST_BOX,
        !           581:                                                    CB_GETLBTEXT, (WPARAM)i,
        !           582:                                                    (LPARAM)SlotName);
        !           583: 
        !           584:                                 // now get the corresponding form name.
        !           585: 
        !           586:                                 iForm = SendDlgItemMessage(hwnd, IDD_TRAY_LIST_BOX,
        !           587:                                                            CB_GETITEMDATA, (WPARAM)i,
        !           588:                                                            (LPARAM)0);
        !           589: 
        !           590:                                 if (iForm != CB_ERR)
        !           591:                                 {
        !           592:                                     // get the form name, and write the tray-form
        !           593:                                     // pair to the registry.
        !           594: 
        !           595:                                     rc = SendDlgItemMessage(hwnd, IDD_PAPER_LIST_BOX,
        !           596:                                                             CB_GETLBTEXT, (WPARAM)iForm,
        !           597:                                                             (LPARAM)FormName);
        !           598: 
        !           599:                                     // now that we have the selected form name
        !           600:                                     // match it to a form which the printer
        !           601:                                     // supports, and save the printer form
        !           602:                                     // name as well.
        !           603: 
        !           604:                                     // first, get the metrics for the selected
        !           605:                                     // form from the forms database.
        !           606: 
        !           607:                                     GetForm(pdata->hPrinter, FormName, 1,
        !           608:                                             NULL, 0, &cbNeeded);
        !           609: 
        !           610:                                     if(GetLastError() != ERROR_INSUFFICIENT_BUFFER)
        !           611:                                     {
        !           612: #if DBG
        !           613:                                         DbgPrint("PSCRPTUI!PrinterPropDlgProc: GetForm returns error %x\n",
        !           614:                                                  GetLastError());
        !           615: #endif
        !           616:                                         return(FALSE);
        !           617:                                     }
        !           618: 
        !           619:                                     pForm = (FORM_INFO_1 *)GlobalAlloc(GMEM_FIXED |
        !           620:                                                                        GMEM_ZEROINIT,
        !           621:                                                                        cbNeeded);
        !           622:                                     if (pForm == NULL)
        !           623:                                         return(FALSE);
        !           624: 
        !           625:                                     GetForm(pdata->hPrinter, FormName, 1,
        !           626:                                             (BYTE *)pForm, cbNeeded, &cbNeeded);
        !           627: 
        !           628:                                     GetPrinterForm(pdata->pntpd, pForm,
        !           629:                                                    PrinterForm);
        !           630: 
        !           631:                                     GlobalFree((HGLOBAL)pForm);
        !           632: 
        !           633:                                     if (rc != CB_ERR)
        !           634:                                     {
        !           635:                                         cbTrayForm += (wcslen(SlotName) + 1);
        !           636:                                         cbTrayForm += (wcslen(FormName) + 1);
        !           637:                                         cbTrayForm += (wcslen(PrinterForm) + 1);
        !           638:                                     }
        !           639:                                 }
        !           640:                             }
        !           641:                         }
        !           642: 
        !           643:                         cbTrayForm *= sizeof(WCHAR);
        !           644: 
        !           645:                         // allocate a buffer.
        !           646: 
        !           647:                         if (!(pwstr = (WCHAR *)GlobalAlloc(GMEM_FIXED |
        !           648:                                                            GMEM_ZEROINIT,
        !           649:                                                            cbTrayForm)))
        !           650:                         {
        !           651:                             RIP("PSCRPTUI!PrtPropDialogProc: GlobalAlloc pwstr failed.\n");
        !           652:                             return(FALSE);
        !           653:                         }
        !           654: 
        !           655:                         psetform = pdata->psetforms;
        !           656: 
        !           657:                         pwstrsave = pwstr;
        !           658: 
        !           659:                         // write the tray form pairs in the following form:
        !           660:                         // a NULL terminated UNICODE Tray (Slot) name followed
        !           661:                         // by the matching NULL terminated form name, then
        !           662:                         // followed by the matching NULL terminated printer
        !           663:                         // for name. this sequence is repeated until a double
        !           664:                         // NULL terminator ends the table.
        !           665: 
        !           666:                         for (i = 0; i < cTrays; i++)
        !           667:                         {
        !           668:                             // only output the triplet if it has been selected by
        !           669:                             // the user.
        !           670: 
        !           671:                             if (*psetform++ != UNINITIALIZED_FORM)
        !           672:                             {
        !           673:                                 // get the tray name.
        !           674: 
        !           675:                                 SendDlgItemMessage(hwnd, IDD_TRAY_LIST_BOX,
        !           676:                                                    CB_GETLBTEXT, (WPARAM)i,
        !           677:                                                    (LPARAM)SlotName);
        !           678: 
        !           679:                                 // now get the corresponding form name.
        !           680: 
        !           681:                                 iForm = SendDlgItemMessage(hwnd, IDD_TRAY_LIST_BOX,
        !           682:                                                            CB_GETITEMDATA, (WPARAM)i,
        !           683:                                                            (LPARAM)0);
        !           684: 
        !           685:                                 if (iForm != CB_ERR)
        !           686:                                 {
        !           687:                                     // get the form name, and write the tray-form
        !           688:                                     // pair to the registry.
        !           689: 
        !           690:                                     rc = SendDlgItemMessage(hwnd, IDD_PAPER_LIST_BOX,
        !           691:                                                             CB_GETLBTEXT, (WPARAM)iForm,
        !           692:                                                             (LPARAM)FormName);
        !           693: 
        !           694:                                     // first, get the metrics for the selected
        !           695:                                     // form from the forms database.
        !           696: 
        !           697:                                     GetForm(pdata->hPrinter, FormName, 1,
        !           698:                                             NULL, 0, &cbNeeded);
        !           699: 
        !           700:                                     if(GetLastError() != ERROR_INSUFFICIENT_BUFFER)
        !           701:                                     {
        !           702: #if DBG
        !           703:                                         DbgPrint("PSCRPTUI!PrinterPropDlgProc: GetForm returns error %x\n",
        !           704:                                                  GetLastError());
        !           705: #endif
        !           706:                                         return(FALSE);
        !           707:                                     }
        !           708: 
        !           709:                                     pForm = (FORM_INFO_1 *)GlobalAlloc(GMEM_FIXED |
        !           710:                                                                        GMEM_ZEROINIT,
        !           711:                                                                        cbNeeded);
        !           712:                                     if (pForm == NULL)
        !           713:                                         return(FALSE);
        !           714: 
        !           715:                                     GetForm(pdata->hPrinter, FormName, 1,
        !           716:                                             (BYTE *)pForm, cbNeeded, &cbNeeded);
        !           717: 
        !           718:                                     GetPrinterForm(pdata->pntpd, pForm,
        !           719:                                                    PrinterForm);
        !           720: 
        !           721:                                     GlobalFree((HGLOBAL)pForm);
        !           722: 
        !           723:                                     if (rc != CB_ERR)
        !           724:                                     {
        !           725:                                         // write pair to the buffer.
        !           726: 
        !           727:                                         wcscpy(pwstr, SlotName);
        !           728:                                         pwstr += (wcslen(SlotName) + 1);
        !           729:                                         wcscpy(pwstr, FormName);
        !           730:                                         pwstr += (wcslen(FormName) + 1);
        !           731:                                         wcscpy(pwstr, PrinterForm);
        !           732:                                         pwstr += (wcslen(PrinterForm) + 1);
        !           733:                                     }
        !           734:                                 }
        !           735:                             }
        !           736:                         }
        !           737: 
        !           738:                         // add the last NULL terminator.
        !           739: 
        !           740:                         *pwstr = (WCHAR)'\0';
        !           741: 
        !           742:                         // now output the tray-form table to the registry.
        !           743: 
        !           744:                         LoadString(hModule, (IDS_TRAY_FORM_TABLE + STRING_BASE),
        !           745:                                   wcbuf3, (sizeof(wcbuf3) / sizeof(wcbuf3[0])));
        !           746: 
        !           747:                         SetPrinterData(pdata->hPrinter, wcbuf3, REG_BINARY,
        !           748:                                        (LPBYTE)pwstrsave, cbTrayForm);
        !           749: 
        !           750:                         // now output the table size to the registry.
        !           751: 
        !           752:                         LoadString(hModule, (IDS_TRAY_FORM_SIZE + STRING_BASE),
        !           753:                                   wcbuf3, (sizeof(wcbuf3) / sizeof(wcbuf3[0])));
        !           754: 
        !           755:                         SetPrinterData(pdata->hPrinter, wcbuf3, REG_DWORD,
        !           756:                                        (LPBYTE)&cbTrayForm, sizeof(cbTrayForm));
        !           757: 
        !           758:                         // free up buffer.
        !           759: 
        !           760:                         GlobalFree((HGLOBAL)pwstrsave);
        !           761: 
        !           762:                         //
        !           763:                         // save that halftone device data back into registry
        !           764:                         //
        !           765: 
        !           766:                         bSaveDeviceHTData(pdata->hPrinter, FALSE);
        !           767:                     }
        !           768: 
        !           769:                     if (pdata->pntpd)
        !           770:                     {
        !           771:                         GlobalFree((HGLOBAL)pdata->pntpd);
        !           772:                         pdata->pntpd = NULL;
        !           773:                     }
        !           774: 
        !           775:                     if (pdata->psetforms)
        !           776:                     {
        !           777:                         GlobalFree((HGLOBAL)pdata->psetforms);
        !           778:                         pdata->psetforms = NULL;
        !           779:                     }
        !           780: 
        !           781:                     EndDialog (hwnd, IDOK);
        !           782:                     return TRUE;
        !           783: 
        !           784:                 case IDCANCEL:
        !           785:                     if (pdata->pntpd)
        !           786:                     {
        !           787:                         GlobalFree((HGLOBAL)pdata->pntpd);
        !           788:                         pdata->pntpd = NULL;
        !           789:                     }
        !           790: 
        !           791:                     if (pdata->psetforms)
        !           792:                     {
        !           793:                         GlobalFree((HGLOBAL)pdata->psetforms);
        !           794:                         pdata->psetforms = NULL;
        !           795:                     }
        !           796: 
        !           797:                     EndDialog (hwnd, IDCANCEL);
        !           798:                     return TRUE;
        !           799: 
        !           800:                 default:
        !           801:                     return (FALSE);
        !           802:             }
        !           803:             break;
        !           804: 
        !           805:         case WM_DESTROY:
        !           806:             // clean up any used help stuff.
        !           807: 
        !           808:             vHelpDone(hwnd);
        !           809:             return (TRUE);
        !           810: 
        !           811:         default:
        !           812:             return (FALSE);   /* didn't process the message */
        !           813:     }
        !           814: }
        !           815: 
        !           816: 
        !           817: //--------------------------------------------------------------------------
        !           818: // BOOL InitComboBoxes(hwnd, pdata)
        !           819: // HWND       hwnd;        // handle to dialog window
        !           820: // PRINTDATA *pdata;
        !           821: //
        !           822: // Parameters
        !           823: //
        !           824: // Returns:
        !           825: //   This routine returns TRUE for success, FALSE otherwise.
        !           826: //
        !           827: // History:
        !           828: //   10-Apr-1991    -by-    Kent Settle     (kentse)
        !           829: // Made it use PNTPD instead of PPRINTER.
        !           830: //   21-Jan-1991    -by-    Kent Settle     (kentse)
        !           831: // Brought in from Windows 3.1, modified for NT, and clean up.
        !           832: //--------------------------------------------------------------------------
        !           833: 
        !           834: BOOL InitComboBoxes(hwnd, pdata)
        !           835: HWND        hwnd;        // handle to dialog window
        !           836: PRINTDATA  *pdata;
        !           837: {
        !           838:     WCHAR           SlotName[MAX_SLOT_NAME];
        !           839:     WCHAR           SearchName[MAX_SLOT_NAME + 4];
        !           840:     WCHAR           FormName[CCHFORMNAME];
        !           841:     WCHAR           wcbuf[MAX_FONTNAME];
        !           842:     DWORD           i, j, dwType, cbTrayForm;
        !           843:     DWORD           cbNeeded, dwTmp, count;
        !           844:     int             rc, DefaultForm, iForm;
        !           845:     PSFORM         *pPSForm;
        !           846:     FORM_INFO_1    *pFormI1, *pFormI1Save;
        !           847:     FORM_INFO_1    *pdbForm, *pdbForms;
        !           848:     PWSTR           pwstrName, pwstrSave;
        !           849:     PSINPUTSLOT    *pslots;
        !           850:     PNTPD           pntpd;
        !           851:     PLONG           psetform;
        !           852:     PSTR            pstr, pstrSave, pstrDefault;
        !           853:     BOOL            bFound;
        !           854: 
        !           855:     // clear out the tray and form list boxes before we begin.
        !           856: 
        !           857:     SendDlgItemMessage(hwnd, IDD_PAPER_LIST_BOX, CB_RESETCONTENT, 0, 0L);
        !           858:     SendDlgItemMessage(hwnd, IDD_TRAY_LIST_BOX, CB_RESETCONTENT, 0, 0L);
        !           859: 
        !           860:     // limit the length of the strings allowed.
        !           861: 
        !           862:     SendDlgItemMessage(hwnd, IDD_PAPER_LIST_BOX, CB_LIMITTEXT,
        !           863:                        (WPARAM)CCHFORMNAME, (LPARAM)0);
        !           864:     SendDlgItemMessage(hwnd, IDD_TRAY_LIST_BOX, CB_LIMITTEXT,
        !           865:                        (WPARAM)MAX_SLOT_NAME, (LPARAM)0);
        !           866: 
        !           867:     // here is a brief overview of how we will fill in the forms list
        !           868:     // box:  firstly, call AddForm for each form in the ppd file, if
        !           869:     // this has not been done yet.  then enumerate the forms database.
        !           870:     // then for each form in the database, see if there is a form
        !           871:     // defined in the PPD file which is large enough to print on.  if
        !           872:     // there is, this form gets added to the list box.
        !           873: 
        !           874:     // start out by setting up a FORM_INFO_1 structure for each form
        !           875:     // defined in the NTPD structure.
        !           876: 
        !           877:     // point to the start of the array of PSFORM structures within
        !           878:     // the NTPD structure.
        !           879: 
        !           880:     pntpd = pdata->pntpd;
        !           881: 
        !           882:     pPSForm = (PSFORM *)((CHAR *)pntpd + pntpd->loPSFORMArray);
        !           883: 
        !           884:     // allocate memory for all the FORM_INFO_1 structures.
        !           885: 
        !           886:     if (!(pFormI1 = (FORM_INFO_1 *)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
        !           887:                                                (pntpd->cPSForms *
        !           888:                                                sizeof(FORM_INFO_1)))))
        !           889:     {
        !           890:         RIP("PSCRPTUI!InitComboBoxes: GlobalAlloc for pFormI1 failed.\n");
        !           891:         return(FALSE);
        !           892:     }
        !           893: 
        !           894:     // keep a copy of the pointer to the first structure.
        !           895: 
        !           896:     pFormI1Save = pFormI1;
        !           897: 
        !           898:     // allocate memory for the form name buffers.
        !           899: 
        !           900:     if (!(pwstrName = (PWSTR)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
        !           901:                             (pntpd->cPSForms * CCHFORMNAME * sizeof(WCHAR)))))
        !           902:     {
        !           903:         RIP("PSCRPTUI:InitComboBoxes: GlobalAlloc for pwstrName failed.\n");
        !           904:         GlobalFree((HGLOBAL)pFormI1);
        !           905:         return(FALSE);
        !           906:     }
        !           907: 
        !           908:     // keep a copy of the pointer to the first form name.
        !           909: 
        !           910:     pwstrSave = pwstrName;
        !           911: 
        !           912:     // add each form defined in the NTPD structure to the forms
        !           913:     // database.  AddForm should simply do nothing if this form
        !           914:     // already exists in the database.
        !           915: 
        !           916:     for (i = 0; i < pntpd->cPSForms; i++)
        !           917:     {
        !           918:         // get the form name from the PSFORM structure and convert it
        !           919:         // to UNICODE.  you might think "hey, you should store the
        !           920:         // name as UNICODE in the PSFORM structure!"  however, the
        !           921:         // PSFORM structures get calculated on every EnablePDEV, which
        !           922:         // will probably happen much more often then this dialog gets
        !           923:         // displayed.
        !           924: 
        !           925:         // check to see if there is a translation string to worry about,
        !           926:         // for each form.
        !           927: 
        !           928:         pstrSave = (CHAR *)pntpd + pPSForm->loFormName;
        !           929: 
        !           930:         XLATESTRING(pstr);
        !           931: 
        !           932:         // pstr now points to the form name we want.
        !           933: 
        !           934:         strcpy2WChar(pwstrName, pstr);
        !           935: 
        !           936:         pFormI1->pName = pwstrName;
        !           937: 
        !           938:         // copy the form size and imageable area.
        !           939:         // the PSFORM structure stores the form size and the
        !           940:         // imageable area in postscript USER coordinate (1/72 inch).
        !           941:         // the forms database stores these values in .001mm.
        !           942: 
        !           943:         pFormI1->Size.cx = USERTO001MM(pPSForm->sizlPaper.cx);
        !           944:         pFormI1->Size.cy = USERTO001MM(pPSForm->sizlPaper.cy);
        !           945: 
        !           946:         pFormI1->ImageableArea.left = USERTO001MM(pPSForm->imagearea.left);
        !           947:         pFormI1->ImageableArea.top = USERTO001MM(pPSForm->sizlPaper.cy) -
        !           948:                                      USERTO001MM(pPSForm->imagearea.top);
        !           949:         pFormI1->ImageableArea.right = USERTO001MM(pPSForm->imagearea.right);
        !           950:         pFormI1->ImageableArea.bottom = USERTO001MM(pPSForm->sizlPaper.cy) -
        !           951:                                         USERTO001MM(pPSForm->imagearea.bottom);
        !           952: 
        !           953:         // point to the next PSFORM structure in the NTPD.  point to the
        !           954:         // next FORM_INFO_1 structure we are filling in.  point to the next
        !           955:         // form name buffer.
        !           956: 
        !           957:         pPSForm++;
        !           958:         pFormI1++;
        !           959:         pwstrName += CCHFORMNAME;
        !           960:     }
        !           961: 
        !           962:     LoadString(hModule, (IDS_FORMS + STRING_BASE), SearchName,
        !           963:                (sizeof(SearchName) / sizeof(SearchName[0])));
        !           964: 
        !           965:     rc = GetPrinterData(pdata->hPrinter, SearchName, &dwType, (PBYTE)&dwTmp,
        !           966:                         sizeof(dwTmp), &cbNeeded);
        !           967: 
        !           968:     // if we have marked in the registry that we have already added all
        !           969:     // the forms for this printer to the forms database, then we do not
        !           970:     // need to do it again.
        !           971: 
        !           972:     if (rc != NO_ERROR)
        !           973:     {
        !           974:         // add each form defined in the NTPD structure to the forms
        !           975:         // database.  AddForm should simply do nothing if this form
        !           976:         // already exists in the database.
        !           977: 
        !           978:         pFormI1 = pFormI1Save;
        !           979: 
        !           980:         for (i = 0; i < pntpd->cPSForms; i++)
        !           981:             AddForm(pdata->hPrinter, 1, (PBYTE)pFormI1++);
        !           982: 
        !           983:         // mark that we have added all the forms to the forms database
        !           984:         // for this printer.
        !           985: 
        !           986:         dwTmp = 1;
        !           987:         SetPrinterData(pdata->hPrinter, SearchName, REG_DWORD, (PBYTE)&dwTmp,
        !           988:                        sizeof(dwTmp));
        !           989:     }
        !           990: 
        !           991:     // we now know that all of the forms in the NTPD structure have been
        !           992:     // added to the forms database.  now enumerate the database.
        !           993: 
        !           994:     if (!(pdbForms = GetFormsDataBase(pdata->hPrinter, &count, pntpd)))
        !           995:     {
        !           996:         RIP("PSCRPTUI!InitComboBoxes: GetFormsDataBase failed.\n");
        !           997: 
        !           998:         GlobalFree((HGLOBAL)pwstrSave);
        !           999:         GlobalFree((HGLOBAL)pFormI1Save);
        !          1000: 
        !          1001:         return(FALSE);
        !          1002:     }
        !          1003:     else
        !          1004:     {
        !          1005:         // put the form in the list box if it is valid for this printer.
        !          1006: 
        !          1007:         pdbForm = pdbForms;
        !          1008: 
        !          1009:         for (i = 0; i < count; i++)
        !          1010:         {
        !          1011:             if (pdbForm->Flags & PSCRIPT_VALID_FORM)
        !          1012:             {
        !          1013:                 // add the form to the list box.
        !          1014: 
        !          1015:                 SendDlgItemMessage(hwnd, IDD_PAPER_LIST_BOX, CB_INSERTSTRING,
        !          1016:                                    (WPARAM)-1, (LPARAM)pdbForm->pName);
        !          1017:             }
        !          1018: 
        !          1019:             pdbForm++;
        !          1020:         }
        !          1021: 
        !          1022:         SendDlgItemMessage(hwnd, IDD_PAPER_LIST_BOX, CB_SETCURSEL, 0, 0L);
        !          1023:     }
        !          1024: 
        !          1025:     // free up resources.
        !          1026: 
        !          1027:     GlobalFree((HGLOBAL)pdbForms);
        !          1028:     GlobalFree((HGLOBAL)pwstrSave);
        !          1029:     GlobalFree((HGLOBAL)pFormI1Save);
        !          1030: 
        !          1031:     // if the only inputslot defined is the default inputslot, cInputSlots
        !          1032:     // will be zero.  in this case, let's simply let the user know that
        !          1033:     // this is the only paper tray.
        !          1034: 
        !          1035:     // NOTE!  CB_INSERTSTRING is used rather that CB_ADDSTRING.  This will
        !          1036:     // keep the order of the paper trays the same as in the PPD file, and
        !          1037:     // the same as Win31.  CB_ADDSTRING would sort the list.
        !          1038: 
        !          1039:     if (pntpd->cInputSlots == 0)
        !          1040:     {
        !          1041:         LoadString(hModule, (SLOTS_BASE + SLOT_ONLYONE),
        !          1042:                    SlotName, (sizeof(SlotName) / sizeof(SlotName[0])));
        !          1043: 
        !          1044:         rc = SendDlgItemMessage(hwnd, IDD_TRAY_LIST_BOX, CB_INSERTSTRING,
        !          1045:                                 (WPARAM)-1, (LPARAM)SlotName);
        !          1046:     }
        !          1047:     else
        !          1048:     {
        !          1049:         // add each input slot defined in the NTPD to the list box.
        !          1050: 
        !          1051:         pslots = (PSINPUTSLOT *)((CHAR *)pntpd + pntpd->loPSInputSlots);
        !          1052: 
        !          1053:         for (i = 0; i < (DWORD)pntpd->cInputSlots; i++)
        !          1054:         {
        !          1055:             // check to see if there is a translation string to worry about,
        !          1056:             // for each form.
        !          1057: 
        !          1058:             pstrSave = (CHAR *)pntpd + pslots->loSlotName;
        !          1059: 
        !          1060:             XLATESTRING(pstr);
        !          1061: 
        !          1062:             // pstr now points to the form name we want.
        !          1063: 
        !          1064:             strcpy2WChar(SlotName, pstr);
        !          1065: 
        !          1066:             SendDlgItemMessage(hwnd, IDD_TRAY_LIST_BOX, CB_INSERTSTRING,
        !          1067:                                (WPARAM)-1, (LPARAM)SlotName);
        !          1068: 
        !          1069:             pslots++;
        !          1070:         }
        !          1071:     }
        !          1072: 
        !          1073:     // check to see if the current printer supports manual feed.  to do
        !          1074:     // this, check to see if a string to turn on manual feed was found.
        !          1075: 
        !          1076:     if (pntpd->loszManualFeedTRUE != 0)
        !          1077:     {
        !          1078:         // this printer does support manual feed, so insert this as the
        !          1079:         // last choice in the list box.
        !          1080: 
        !          1081:         LoadString(hModule, (SLOT_MANUAL + SLOTS_BASE),
        !          1082:                    SlotName, (sizeof(SlotName) / sizeof(SlotName[0])));
        !          1083: 
        !          1084:         rc = SendDlgItemMessage(hwnd, IDD_TRAY_LIST_BOX, CB_INSERTSTRING,
        !          1085:                                 (WPARAM)-1, (LPARAM)SlotName);
        !          1086:     }
        !          1087: 
        !          1088:     // all of the paper trays have been added to the list box.  now
        !          1089:     // associate each paper tray with a form.  this will be done in the
        !          1090:     // following manner:  for each paper tray, see if an entry exists in
        !          1091:     // the registry (eg, "TrayUpper Letter").  if it does, use the form
        !          1092:     // specified there, and associate the tray with the index into the
        !          1093:     // form list box.  if no entry exists in the registry for the tray,
        !          1094:     // associate it with the default form.
        !          1095: 
        !          1096:     // first, find the index to the default form.
        !          1097: 
        !          1098:     // now see if there is a translation string to worry about.
        !          1099:     // do this by checking each device form name, to see if there
        !          1100:     // is a match of the "non-translation string" portion of the
        !          1101:     // name.  This code is confusing; as an example, if Letter is the
        !          1102:     // default form, the form name in the PPD file may have a
        !          1103:     // translation string such as Letter/US Letter.  In this case, we
        !          1104:     // want US Letter, not Letter, to be chosen as the default in the
        !          1105:     // list box.
        !          1106: 
        !          1107:     pPSForm = (PSFORM *)((CHAR *)pntpd + pntpd->loPSFORMArray);
        !          1108:     bFound = FALSE;
        !          1109:     pstrDefault = (CHAR *)pntpd + pntpd->loDefaultForm;
        !          1110: 
        !          1111:     for (i = 0; i < pntpd->cPSForms; i++)
        !          1112:     {
        !          1113:         pstr = (CHAR *)pntpd + pPSForm->loFormName;
        !          1114: 
        !          1115:         dwTmp = strlen(pstr);
        !          1116: 
        !          1117:         for (j = 0; j < dwTmp; j++)
        !          1118:         {
        !          1119:             // if we found the translation string deliminator '/',
        !          1120:             // then we will substitute the translation string for
        !          1121:             // the default.
        !          1122: 
        !          1123:             if (*pstr == '/')
        !          1124:             {
        !          1125:                 pstr++;
        !          1126:                 pstrDefault = pstr;
        !          1127:                 bFound = TRUE;
        !          1128:                 break;
        !          1129:             }
        !          1130: 
        !          1131:             if (*pstr++ != *pstrDefault++)
        !          1132:                 break;
        !          1133:         }
        !          1134: 
        !          1135:         // if we found a translation string, we are done.
        !          1136: 
        !          1137:         if (bFound)
        !          1138:             break;
        !          1139:         else
        !          1140:             pstrDefault = (CHAR *)pntpd + pntpd->loDefaultForm;
        !          1141: 
        !          1142:         // otherwise go on to the next form.
        !          1143: 
        !          1144:         pPSForm++;
        !          1145:     }
        !          1146: 
        !          1147:     strcpy2WChar(FormName, pstrDefault);
        !          1148: 
        !          1149:     DefaultForm = SendDlgItemMessage(hwnd, IDD_PAPER_LIST_BOX, CB_FINDSTRING,
        !          1150:                                      (WPARAM)-1, (LPARAM)FormName);
        !          1151: 
        !          1152:     // if there was a problem finding the default form, use the first one
        !          1153:     // in the list box.
        !          1154: 
        !          1155:     if (DefaultForm == CB_ERR)
        !          1156:         DefaultForm = 0;
        !          1157: 
        !          1158:     // now see if a registry entry exists for each tray, and associate it
        !          1159:     // with the specified form if so.
        !          1160: 
        !          1161:     count = SendDlgItemMessage(hwnd, IDD_TRAY_LIST_BOX, CB_GETCOUNT,
        !          1162:                                    (WPARAM)0, (LPARAM)0);
        !          1163: 
        !          1164:     // initialize the list of forms selected by the user to be in each
        !          1165:     // paper tray.  fill each form index with -1, then fill in the default
        !          1166:     // tray with the default form index.
        !          1167: 
        !          1168:     // allocate memory for all trays.
        !          1169: 
        !          1170:     if (!(pdata->psetforms = (PLONG)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
        !          1171:                                                   (count * sizeof(LONG)))))
        !          1172:     {
        !          1173:         RIP("PSCRPTUI!InitComboBoxes: GlobalAlloc for psetforms failed.\n");
        !          1174:         return(FALSE);
        !          1175:     }
        !          1176: 
        !          1177:     // now initialize each entry to -1.
        !          1178: 
        !          1179:     psetform = pdata->psetforms;
        !          1180: 
        !          1181:     for (i = 0; i < count; i++)
        !          1182:         *psetform++ = UNINITIALIZED_FORM;
        !          1183: 
        !          1184:     // point back to first entry.
        !          1185: 
        !          1186:     psetform = pdata->psetforms;
        !          1187: 
        !          1188:     // first find out the size of the tray-form buffer and copy it from
        !          1189:     // the registry.
        !          1190: 
        !          1191:     // now get the table size from the registry.
        !          1192: 
        !          1193:     LoadString(hModule, (IDS_TRAY_FORM_SIZE + STRING_BASE),
        !          1194:               wcbuf, (sizeof(wcbuf) / sizeof(wcbuf[0])));
        !          1195: 
        !          1196:     GetPrinterData(pdata->hPrinter, wcbuf, &dwType, (LPBYTE)&cbTrayForm,
        !          1197:                    sizeof(cbTrayForm), &cbNeeded);
        !          1198: 
        !          1199:     if (cbTrayForm)
        !          1200:     {
        !          1201:         // allocate a buffer.
        !          1202: 
        !          1203:         if (!(pwstrName = (WCHAR *)GlobalAlloc(GMEM_FIXED |
        !          1204:                                                GMEM_ZEROINIT,
        !          1205:                                                cbTrayForm)))
        !          1206:         {
        !          1207:             RIP("PSCRPTUI!InitComboBoxes: GlobalAlloc pwstrName failed.\n");
        !          1208:             return(FALSE);
        !          1209:         }
        !          1210: 
        !          1211:         pwstrSave = pwstrName;
        !          1212: 
        !          1213:         // now grab the table itself from the registry.
        !          1214: 
        !          1215:         LoadString(hModule, (IDS_TRAY_FORM_TABLE + STRING_BASE),
        !          1216:                   wcbuf, (sizeof(wcbuf) / sizeof(wcbuf[0])));
        !          1217: 
        !          1218:         rc = GetPrinterData(pdata->hPrinter, wcbuf, &dwType, (LPBYTE)pwstrName,
        !          1219:                             cbTrayForm, &cbNeeded);
        !          1220: 
        !          1221:         if (rc != ERROR_SUCCESS)
        !          1222:         {
        !          1223:             RIP("PSCRPTUI!InitComboBoxes: GetPrinterData pwstrName failed.\n");
        !          1224:             GlobalFree((HGLOBAL)pwstrSave);
        !          1225:             return(FALSE);
        !          1226:         }
        !          1227: 
        !          1228:         for (i = 0; i < count; i++)
        !          1229:         {
        !          1230:             // get the tray name.
        !          1231: 
        !          1232:             SendDlgItemMessage(hwnd, IDD_TRAY_LIST_BOX, CB_GETLBTEXT,
        !          1233:                                (WPARAM)i, (LPARAM)SlotName);
        !          1234: 
        !          1235:             pwstrName = pwstrSave;
        !          1236: 
        !          1237:             // search the tray-form table for a matching tray.
        !          1238: 
        !          1239:             bFound = FALSE;
        !          1240: 
        !          1241:             while (*pwstrName)
        !          1242:             {
        !          1243:                 if (!(wcscmp(pwstrName, SlotName)))
        !          1244:                 {
        !          1245:                     // we found the inplut slot, now get the matching form.
        !          1246: 
        !          1247:                     pwstrName += (wcslen(pwstrName) + 1);
        !          1248:                     wcsncpy(FormName, pwstrName,
        !          1249:                             (sizeof(FormName) / sizeof(FormName[0])));
        !          1250:                     bFound = TRUE;
        !          1251:                     break;
        !          1252:                 }
        !          1253:                 else
        !          1254:                 {
        !          1255:                     // this was not the form in question.  skip over both form names.
        !          1256: 
        !          1257:                     pwstrName += (wcslen(pwstrName) + 1);
        !          1258:                     pwstrName += (wcslen(pwstrName) + 1);
        !          1259:                     pwstrName += (wcslen(pwstrName) + 1);
        !          1260:                 }
        !          1261:             }
        !          1262: 
        !          1263:             if (bFound)
        !          1264:             {
        !          1265:                 // get the index of the specified form.
        !          1266: 
        !          1267:                 rc = SendDlgItemMessage(hwnd, IDD_PAPER_LIST_BOX, CB_FINDSTRING,
        !          1268:                                         (WPARAM)-1, (LPARAM)FormName);
        !          1269: 
        !          1270:                 if (rc == CB_ERR)
        !          1271:                     rc = DefaultForm;
        !          1272:             }
        !          1273:             else
        !          1274:                 rc = DefaultForm;
        !          1275: 
        !          1276:             // save tray form association until we write out to registry.
        !          1277: 
        !          1278:             psetform[i] = rc;
        !          1279: 
        !          1280:             // we now have the index of a form to associate with the current tray.
        !          1281: 
        !          1282:             SendDlgItemMessage(hwnd, IDD_TRAY_LIST_BOX, CB_SETITEMDATA,
        !          1283:                                (WPARAM)i, (LPARAM)rc);
        !          1284:         }
        !          1285: 
        !          1286:         // free up the tray-form table buffer.
        !          1287: 
        !          1288:         GlobalFree((HGLOBAL)pwstrSave);
        !          1289:     }
        !          1290: 
        !          1291:     // highlight the default paper tray, and the corresponding form.
        !          1292:     // get the default paper tray from the NTPD structure.
        !          1293: 
        !          1294:     // now see if there is a translation string to worry about.
        !          1295:     // do this by checking each device input slot, to see if there
        !          1296:     // is a match of the "non-translation string" portion of the
        !          1297:     // name.
        !          1298: 
        !          1299:     pslots = (PSINPUTSLOT *)((CHAR *)pntpd + pntpd->loPSInputSlots);
        !          1300:     bFound = FALSE;
        !          1301:     pstrDefault = (CHAR *)pntpd + pntpd->loDefaultSlot;
        !          1302: 
        !          1303:     for (i = 0; i < pntpd->cInputSlots; i++)
        !          1304:     {
        !          1305:         pstr = (CHAR *)pntpd + pslots->loSlotName;
        !          1306: 
        !          1307:         dwTmp = strlen(pstr);
        !          1308: 
        !          1309:         for (j = 0; j < dwTmp; j++)
        !          1310:         {
        !          1311:             // if we found the translation string deliminator '/',
        !          1312:             // then we will substitute the translation string for
        !          1313:             // the default.
        !          1314: 
        !          1315:             if (*pstr == '/')
        !          1316:             {
        !          1317:                 pstr++;
        !          1318:                 pstrDefault = pstr;
        !          1319:                 bFound = TRUE;
        !          1320:                 break;
        !          1321:             }
        !          1322: 
        !          1323:             if (*pstr++ != *pstrDefault++)
        !          1324:                 break;
        !          1325:         }
        !          1326: 
        !          1327:         // if we found a translation string, we are done.
        !          1328: 
        !          1329:         if (bFound)
        !          1330:             break;
        !          1331:         else
        !          1332:             pstrDefault = (CHAR *)pntpd + pntpd->loDefaultSlot;
        !          1333: 
        !          1334:         // otherwise go on to the next form.
        !          1335: 
        !          1336:         pslots++;
        !          1337:     }
        !          1338: 
        !          1339:     strcpy2WChar(FormName, pstrDefault);
        !          1340:     strcpy2WChar(SlotName, (CHAR *)pntpd + pntpd->loDefaultSlot);
        !          1341: 
        !          1342:     rc = SendDlgItemMessage(hwnd, IDD_TRAY_LIST_BOX, CB_FINDSTRING,
        !          1343:                                      (WPARAM)-1, (LPARAM)SlotName);
        !          1344: 
        !          1345:     // highlight the first tray if there was a problem getting the default
        !          1346:     // tray.
        !          1347: 
        !          1348:     if (rc == CB_ERR)
        !          1349:         rc = 0;
        !          1350: 
        !          1351:     SendDlgItemMessage(hwnd, IDD_TRAY_LIST_BOX, CB_SETCURSEL,
        !          1352:                        (WPARAM)rc, (LPARAM)0);
        !          1353: 
        !          1354:     // get the index of the corresponding form.
        !          1355: 
        !          1356:     iForm = SendDlgItemMessage(hwnd, IDD_TRAY_LIST_BOX, CB_GETITEMDATA,
        !          1357:                             (WPARAM)rc, (LPARAM)0);
        !          1358: 
        !          1359:     if (iForm == CB_ERR)
        !          1360:         iForm = DefaultForm;
        !          1361: 
        !          1362:     SendDlgItemMessage(hwnd, IDD_PAPER_LIST_BOX, CB_SETCURSEL,
        !          1363:                        (WPARAM)iForm, (LPARAM)0);
        !          1364: 
        !          1365:     return TRUE;
        !          1366: }
        !          1367: 
        !          1368: 
        !          1369: //--------------------------------------------------------------------------
        !          1370: // BOOL bAbout(hwnd, pntpd)
        !          1371: // HWND    hwnd;
        !          1372: // PNTPD   pntpd;
        !          1373: //
        !          1374: // This routine invokes the common About dialog.
        !          1375: //
        !          1376: // Returns:
        !          1377: //   This routine returns TRUE for success, FALSE otherwise.
        !          1378: //
        !          1379: // History:
        !          1380: //   22-Apr-1993    -by-    Kent Settle     (kentse)
        !          1381: // Borrowed from Rasdd, and modified.
        !          1382: //--------------------------------------------------------------------------
        !          1383: 
        !          1384: BOOL bAbout(hwnd, pntpd)
        !          1385: HWND    hwnd;
        !          1386: PNTPD   pntpd;
        !          1387: {
        !          1388:     HANDLE          hCursor, hIcon;
        !          1389:     WCHAR           wszTitle[RESOURCE_STRING_LENGTH];
        !          1390:     WCHAR           wszModel[RESOURCE_STRING_LENGTH];
        !          1391:     WCHAR          *pwstr;
        !          1392: 
        !          1393:     hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
        !          1394: 
        !          1395:     hIcon = LoadIcon(hModule, MAKEINTRESOURCE(ICO_PRINTER));
        !          1396: 
        !          1397:     pwstr = (PWSTR)((PSTR)pntpd + pntpd->lowszPrinterName);
        !          1398: 
        !          1399:     // fill in the device name string.
        !          1400: 
        !          1401:     LoadString(hModule, IDS_MODEL_STRING + STRING_BASE, wszModel,
        !          1402:                sizeof(wszModel) / sizeof(wszModel[0]));
        !          1403: 
        !          1404:     // fill in the model name itself.
        !          1405: 
        !          1406:     pwstr = wszModel + wcslen(wszModel);
        !          1407: 
        !          1408:     wcsncpy(pwstr, (LPWSTR)((PSTR)pntpd + pntpd->lowszPrinterName),
        !          1409:             RESOURCE_STRING_LENGTH - wcslen(wszModel));
        !          1410: 
        !          1411:     // get our name.
        !          1412: 
        !          1413:     LoadString(hModule, IDS_PSCRIPT_VERSION + STRING_BASE,
        !          1414:                wszTitle, sizeof(wszTitle) / sizeof(wszTitle[0]));
        !          1415: 
        !          1416:     // call off to the common about dialog.
        !          1417: 
        !          1418:     ShellAbout(hwnd, wszTitle, wszModel, hIcon);
        !          1419: 
        !          1420:     SetCursor(hCursor);
        !          1421: 
        !          1422:     return(TRUE);
        !          1423: }
        !          1424: 
        !          1425: 
        !          1426: //--------------------------------------------------------------------------
        !          1427: // VOID GetPrinterForm(pntpd, pFormName, pPrinterForm);
        !          1428: // PNTPD       pntpd;
        !          1429: // PWSTR       pFormName;
        !          1430: // PWSTR       pPrinterForm;
        !          1431: //
        !          1432: // This routine invokes the common About dialog.
        !          1433: //
        !          1434: // Returns:
        !          1435: //   This routine returns TRUE for success, FALSE otherwise.
        !          1436: //
        !          1437: // History:
        !          1438: //   22-Apr-1993    -by-    Kent Settle     (kentse)
        !          1439: // Borrowed from Rasdd, and modified.
        !          1440: //--------------------------------------------------------------------------
        !          1441: 
        !          1442: VOID GetPrinterForm(pntpd, pForm, pPrinterForm)
        !          1443: PNTPD           pntpd;
        !          1444: FORM_INFO_1    *pForm;
        !          1445: PWSTR           pPrinterForm;
        !          1446: {
        !          1447:     PSFORM         *pPSForm;
        !          1448:     DWORD           i;
        !          1449:     BOOL            bFound;
        !          1450:     SIZEL           sizldelta, sizltmp;
        !          1451:     CHAR            szForm[CCHFORMNAME];
        !          1452: 
        !          1453:     // find the printer's form metrics from the NTPD.
        !          1454: 
        !          1455:     pPSForm = (PSFORM *)((CHAR *)pntpd + pntpd->loPSFORMArray);
        !          1456: 
        !          1457:     // first try to match a form by name.
        !          1458: 
        !          1459:     // get ANSI version of form name.
        !          1460: 
        !          1461:     WideCharToMultiByte(CP_ACP, 0, (LPWSTR)pForm->pName,
        !          1462:                         (INT)(wcslen(pForm->pName) + 1), szForm,
        !          1463:                         sizeof(szForm), NULL, NULL);
        !          1464: 
        !          1465:     for (i = 0; i < pntpd->cPSForms; i++)
        !          1466:     {
        !          1467:         if (!(NameComp(szForm, (CHAR *)pntpd + pPSForm->loFormName)))
        !          1468:         {
        !          1469:             // in this case, the printer form name and the database form
        !          1470:             // name are the same.
        !          1471: 
        !          1472:             wcsncpy(pPrinterForm, pForm->pName, CCHFORMNAME);
        !          1473:             return;
        !          1474:         }
        !          1475: 
        !          1476:         // point to the next PSFORM.
        !          1477: 
        !          1478:         pPSForm++;
        !          1479:     }
        !          1480: 
        !          1481:     // if we did not find a name match, try to locate a form by size.
        !          1482: 
        !          1483:     // get pointer to first form in NTPD.
        !          1484: 
        !          1485:     pPSForm = (PSFORM *)((CHAR *)pntpd + pntpd->loPSFORMArray);
        !          1486: 
        !          1487:     // sizldelta is used to hold the difference between form sizes.
        !          1488:     // initialize to large value.
        !          1489: 
        !          1490:     sizldelta.cx = sizldelta.cy = INITIAL_FORM_DELTA;
        !          1491: 
        !          1492:     bFound = FALSE;
        !          1493: 
        !          1494:     for (i = 0; i < pntpd->cPSForms; i++)
        !          1495:     {
        !          1496:         sizltmp.cx = USERTO001MM(pPSForm->sizlPaper.cx) - pForm->Size.cx;
        !          1497:         sizltmp.cy = USERTO001MM(pPSForm->sizlPaper.cy) - pForm->Size.cy;
        !          1498: 
        !          1499:         // see if we have an exact match on size (within 1mm).
        !          1500: 
        !          1501:         if (((DWORD)abs(sizltmp.cx) <= 1000) &&
        !          1502:              ((DWORD)abs(sizltmp.cy) <= 1000))
        !          1503:         {
        !          1504:             // we have an exact match on size, so overwrite the form
        !          1505:             // name with the name the printer knows about.
        !          1506: 
        !          1507:             strcpy2WChar(pPrinterForm, (CHAR *)pntpd + pPSForm->loFormName);
        !          1508:             return;
        !          1509:         }
        !          1510: 
        !          1511:         // not an exact match, but see if we could fit on this form.
        !          1512: 
        !          1513:         if ((sizltmp.cx >= 0) && (sizltmp.cy >= 0))
        !          1514:         {
        !          1515:             // we can fit on this form.  let's see if it is the smallest.
        !          1516: 
        !          1517:             if ((sizltmp.cx <= sizldelta.cx) &&
        !          1518:                 (sizltmp.cy <= sizldelta.cy))
        !          1519:             {
        !          1520:                 // this form is the smallest yet.
        !          1521: 
        !          1522:                 sizldelta = sizltmp;
        !          1523:                 strcpy2WChar(pPrinterForm, (CHAR *)pntpd + pPSForm->loFormName);
        !          1524:                 bFound = TRUE;
        !          1525:             }
        !          1526:         }
        !          1527: 
        !          1528:         // point to the next PSFORM.
        !          1529: 
        !          1530:         pPSForm++;
        !          1531:     }
        !          1532: 
        !          1533:     // set to default if no form was found.
        !          1534: 
        !          1535:     strcpy2WChar(pPrinterForm, (CHAR *)pntpd + pntpd->loDefaultForm);
        !          1536: }

unix.superglobalmegacorp.com

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