Annotation of ntddk/src/print/pscrptui/pscrptui.c, revision 1.1.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.