home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ool.zip / OOL / source / xprint.CPP < prev    next >
C/C++ Source or Header  |  1997-04-05  |  15KB  |  664 lines

  1. /* Printer code. Code based on the Maverik class library by Fabrizio Aversa */
  2. /* ported by Stefan von Brauk */
  3.  
  4.  
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include "XCheckBx.h"
  9. #include "XListBox.h"
  10. #include "XEntry.h"
  11. #include "XCntrevn.h"
  12. #include "xfont.h"
  13. #include "XFrmwnd.h"
  14. #include "xmsgbox.h"
  15. #include "XReslib.h"
  16. #include "XRes.h"
  17. #include "XExcept.h"
  18. #include "oolprint.h"
  19. #include "xcountry.h"
  20. #include "xprint.h"
  21. #include "xgraphob.h"
  22.  
  23. /*@ 
  24. @class XPrinterDevice
  25. @parent XGraphicDevice
  26. @type overview
  27. @symbol _
  28. */
  29.  
  30.  
  31. class PrinterDialog:public XFrameWindow
  32. {
  33.     friend XPrinterDevice;
  34.         public:
  35.         PrinterDialog(XFrameWindow *, char *, PRINTERSETUP *, XResource *, LONG *);
  36.        ~PrinterDialog();
  37.         private:
  38.         LONG * result;
  39.     PRINTERSETUP backup;
  40.     PPRINTERSETUP pSetup, pTarget;
  41.     void FillFields();
  42.     BOOL DoCommand(LONG com);
  43.     void DoControl(XControlEvent *);
  44.     XCheckBox *check;
  45.     XEntryField *entry;
  46.     XListBox *list;
  47. };
  48.  
  49.  
  50. PrinterDialog :: PrinterDialog(XFrameWindow * owner, char *title, PRINTERSETUP * p1, XResource * r, LONG * res): XFrameWindow(r, title, XFrameWindow :: defaultDialogStyle | FRM_CENTER, NULL, NULL, TRUE, FALSE)
  51. {
  52.     result = res;
  53.     memcpy(&backup, p1, sizeof(PRINTERSETUP));
  54.     pSetup = &backup;
  55.     pTarget = p1;
  56.  
  57.     check = (XCheckBox *) GetWindow(IDC_TOFILE);
  58.     entry = (XEntryField *) GetWindow(IDC_ENTRY);
  59.     list = (XListBox *) GetWindow(IDC_LISTBOX);
  60.  
  61.     FillFields();
  62. }
  63.  
  64.  
  65. PrinterDialog :: ~PrinterDialog()
  66. {
  67.     delete check;
  68.     delete entry;
  69.     delete list;
  70. }
  71.  
  72.  
  73. void PrinterDialog::FillFields()
  74. {
  75.     LONG j, i, selected = 0;
  76.     char *psz;
  77.  
  78.     for (i = 0; i < pSetup->cQueues; i++)
  79.     {
  80.         psz = (*pSetup->pQueueInfo[i].pszComment ?
  81.             pSetup->pQueueInfo[i].pszComment : pSetup->pQueueInfo[i].pszName);
  82.  
  83.         for (j = 0; j < strlen(psz); j++)
  84.             if (psz[j] == 13 || psz[j] == 10)
  85.                 psz[j] = ' ';
  86.  
  87.         list->InsertItem(psz);
  88.  
  89.         if (0 == strcmp(pSetup->pQueueInfo[i].pszName, pSetup->szPreferredQueue))
  90.             selected = i;
  91.     }
  92.  
  93.     if (list->GetCount())
  94.         list->SelectItem(selected);
  95.  
  96.     if (!pSetup->fToFile)
  97.     {
  98.         check->Select(FALSE);
  99.         entry->Enable(FALSE);
  100.     }
  101.     else
  102.         check->Select();
  103.  
  104.     if (0 == strlen(pSetup->szFileName))
  105.         strcpy(pSetup->szFileName, "PRINTER.OUT");
  106.  
  107.     entry->SetText(pSetup->szFileName);
  108. }
  109.  
  110.  
  111. BOOL PrinterDialog::DoCommand(LONG command)
  112. {
  113.     CHAR szDeviceName[48];
  114.     CHAR szDriverName[64];
  115.     PPRQINFO3 pqi;
  116.  
  117.     pqi = &pSetup->pQueueInfo[list->GetSelection()];
  118.     char *pch;
  119.  
  120.     *result = command;
  121.     switch (command)
  122.     {
  123.     case DID_OK:
  124.         strcpy(pSetup->szPreferredQueue, pqi->pszName);
  125.         if (check->IsSelected())
  126.         {
  127.             pSetup->fToFile = TRUE;
  128.             XString buffer;
  129.  
  130.             entry->GetText(&buffer);
  131.             strcpy(pSetup->szFileName, (char *) buffer);
  132.         }
  133.         else
  134.         {
  135.             pSetup->fToFile = FALSE;
  136.             *pSetup->szFileName = 0;
  137.         }
  138.         memcpy(pTarget, pSetup, sizeof(PRINTERSETUP));
  139.         break;
  140.     case DID_CANCEL:
  141.         break;
  142.     case IDC_JOBPROP:
  143.         strcpy(szDriverName, pqi->pszDriverName);
  144.         pch = strchr(szDriverName, '.');
  145.         if (pch)
  146.         {
  147.             strcpy(szDeviceName, pch + 1);
  148.             *pch = 0;
  149.         }
  150.         else
  151.             *szDeviceName = 0;
  152.  
  153.         pch = strchr(pqi->pszPrinters, ',');
  154.         if (pch)
  155.             *pch = 0;
  156.  
  157.         if (DevPostDeviceModes(pSetup->hab, pqi->pDriverData, szDriverName, szDeviceName, pqi->pszPrinters, DPDM_POSTJOBPROP) == DPDM_ERROR)
  158.         {
  159.             XMessageBox msgbox("Impostazione stampante", "DevPostDeviceModes", MB_OK | MB_ERROR | MB_MOVEABLE, this);
  160.         }
  161.  
  162.         return TRUE;
  163.  
  164.     }
  165.     delete this;
  166.  
  167.     return TRUE;
  168. }
  169.  
  170.  
  171. void PrinterDialog::DoControl(XControlEvent * event)
  172. {
  173.     switch (event->GetWindowID())
  174.     {
  175.         case IDC_TOFILE:
  176.         if (check->IsSelected())
  177.             entry->Enable();
  178.         else
  179.             entry->Enable(FALSE);
  180.         break;
  181.     }
  182. }
  183.  
  184.  
  185. /* XPrinterDevice::SetupPrinter(char *title, XFrameWindow * owner, XString * queueName, XString * fileName)
  186. @remarks Let the user select the printer-queue in a dialog. The dialog is loaded from OOLRES.DLL which must be installed.
  187. @parameters 
  188. <t '°' c=2>
  189. °char *title                °the title of the dialog
  190. °XFrameWindow * owner    °owner window
  191. °XString * queueName        °default queue-name (can be null)
  192. °XString * fileName        °buffer for a fileName if the user wants to print to a file (if NULL no fiflenames is stored)
  193. </t>
  194. @returns BOOL success
  195. */
  196. BOOL XPrinterDevice::SetupPrinter(char *title, XFrameWindow * owner, XString * queueName, XString * fileName)
  197. {
  198.     BOOL fOK;
  199.     CHAR szDefaultQueue[196];
  200.     CHAR szSavedQueue[196];
  201.     CHAR szWork[196];
  202.     PCHAR pch;
  203.     PPRQINFO3 pqi;
  204.     SIZEL sizel;
  205.     ULONG cReturned;
  206.     ULONG cTotal;
  207.     ULONG cbNeeded;
  208.     ULONG ul;
  209.     ULONG ulrc;
  210.  
  211.     // Caller must set these items before calling.
  212.     if (!pSetup->hab || !pSetup->lWorldCoordinates)
  213.         return FALSE;
  214.  
  215.     // no good unless I can open a PS
  216.     pSetup->pDevOpenData = NULL;
  217.  
  218.     // Close the info DC's and PS's from any previous call.
  219.     if (pSetup->hpsPrinterInfo)
  220.     {
  221.         GpiAssociate(pSetup->hpsPrinterInfo, (HDC) 0);
  222.         GpiDestroyPS(pSetup->hpsPrinterInfo);
  223.         pSetup->hpsPrinterInfo = (HPS) 0;
  224.     }
  225.  
  226.     if (pSetup->hdcPrinterInfo)
  227.     {
  228.         DevCloseDC(pSetup->hdcPrinterInfo);
  229.         pSetup->hdcPrinterInfo = (HDC) 0;
  230.     }
  231.  
  232.     if (pSetup->pQueueInfo)
  233.     {
  234.         // Free the array of PRQINFO3 from previous call.
  235.         free(pSetup->pQueueInfo);
  236.         pSetup->pQueueInfo = NULL;
  237.     }
  238.  
  239.     // Query how many queues exist on this computer and the
  240.     // number of bytes needed to hold the array.
  241.     ul = SplEnumQueue(NULL, 3, NULL, 0, &cReturned, &cTotal, &cbNeeded, NULL);
  242.     if (cTotal == 0)
  243.     {
  244.         // There are no queues on this computer!
  245.         pSetup->cQueues = 0;
  246.         return FALSE;
  247.     }
  248.  
  249.     // Allocate memory to store the newly enumerated queue information.
  250.     pSetup->pQueueInfo = (PRQINFO3 *) malloc(cbNeeded);
  251.     if (!pSetup->pQueueInfo)
  252.         return FALSE;
  253.  
  254.     // Call system again to get the array of PRQINFO3 structures.
  255.     ul = SplEnumQueue(NULL, 3, pSetup->pQueueInfo, cbNeeded, &cReturned, &cTotal, &cbNeeded, NULL);
  256.     if (ul != 0 ||
  257.         cReturned != cTotal)
  258.         return FALSE;
  259.     pSetup->cQueues = cReturned;
  260.  
  261.     // Establish a default queue -- might need it.
  262.     // Profiled queue name ends with a semicolon.
  263.     ul = PrfQueryProfileString(HINI_PROFILE, "PM_SPOOLER", "QUEUE", NULL, szDefaultQueue, 196);
  264.     if (ul > 1)
  265.     {
  266.         // Trim off semicolon.
  267.         pch = strchr(szDefaultQueue, ';');
  268.         *pch = 0;
  269.     }
  270.     else
  271.     {
  272.         // Hmmmm. Use the first one queue from the enumeration.
  273.         strcpy(szDefaultQueue, pSetup->pQueueInfo->pszName);
  274.     }
  275.     if (!strlen(szDefaultQueue))
  276.         return FALSE;
  277.  
  278.     if (0 == strlen(pSetup->szPreferredQueue))
  279.     {
  280.         // No queue preference; use default.
  281.         strcpy(pSetup->szPreferredQueue, szDefaultQueue);
  282.  
  283.         // Don't expect to see DRIVDATA without queue name.
  284.         // if(! pSetup->pDriverData ) return FALSE;
  285.     }
  286.  
  287.     if (queueName)
  288.     {
  289.         if (!queueName->IsEmpty())
  290.         {
  291.             pSetup->fToFile = FALSE;
  292.             strcpy(pSetup->szPreferredQueue, (char *) *queueName);
  293.         }
  294.         if (fileName)
  295.         {
  296.             if (!fileName->IsEmpty())
  297.             {
  298.                 pSetup->fToFile = TRUE;
  299.                 strcpy(pSetup->szFileName, (char *) *fileName);
  300.             }
  301.         }
  302.     }
  303.  
  304.     pqi = FindQueue(pSetup);
  305.     if (!pqi)
  306.     {
  307.         strcpy(pSetup->szPreferredQueue, szDefaultQueue);
  308.         if (pSetup->pDriverData)
  309.         {
  310.             free(pSetup->pDriverData);
  311.             pSetup->pDriverData = NULL;
  312.         }
  313.     }
  314.     else
  315.     {
  316.         fOK = TRUE;
  317.  
  318.         if (pSetup->pDriverData)
  319.         {
  320.             fOK = fOK && (pqi->pDriverData->cb == pSetup->pDriverData->cb);
  321.             fOK = fOK && (0 == strcmp(pqi->pDriverData->szDeviceName, pSetup->pDriverData->szDeviceName));
  322.         }
  323.  
  324.         if (!fOK)
  325.         {
  326.             free(pSetup->pDriverData);
  327.             pSetup->pDriverData = NULL;
  328.         }
  329.     }
  330.  
  331.     pqi = FindQueue(pSetup);
  332.  
  333.     if (!pSetup->pDriverData)
  334.     {
  335.         pSetup->pDriverData = (DRIVDATA *) malloc(pqi->pDriverData->cb);
  336.         if (!pSetup->pDriverData)
  337.         {
  338.             ulrc = FALSE;
  339.             return ulrc;
  340.         }
  341.         memcpy(pSetup->pDriverData, pqi->pDriverData, pqi->pDriverData->cb);
  342.     }
  343.  
  344.     if (!pSetup->pDriverData || pSetup->pDriverData->cb <= 0 || pSetup->pDriverData->cb != pqi->pDriverData->cb || strcmp(pqi->pDriverData->szDeviceName, pSetup->pDriverData->szDeviceName))
  345.         return FALSE;
  346.  
  347.     memcpy(pqi->pDriverData, pSetup->pDriverData, pSetup->pDriverData->cb);
  348.  
  349.     strcpy(szSavedQueue, pSetup->szPreferredQueue);
  350.  
  351.     if (owner)
  352.     {
  353.         XCountryInfo info;
  354.         XResourceLibrary lib(owner->GetProcess(), "oolres");
  355.         LONG dlgID, stringID;
  356.  
  357.         switch (info.GetCountry())
  358.         {
  359.         case 39:                // italy
  360.             dlgID = ID_PICKQ_IT;
  361.             stringID = ID_PICKQ_IT_TITLE;
  362.             break;
  363.         case 49:                // german
  364.             dlgID = ID_PICKQ_GER;
  365.             stringID = ID_PICKQ_GER_TITLE;
  366.             break;
  367.         default:                // english
  368.             dlgID = ID_PICKQ_E;
  369.             stringID = ID_PICKQ_E_TITLE;
  370.         }
  371.         XString title;
  372.  
  373.         lib.LoadString(&title, stringID);
  374.         XResource res(dlgID, &lib);
  375.         LONG result;
  376.         PrinterDialog *printerDialog = new PrinterDialog(owner, title, pSetup, &res, &result);
  377.  
  378.         printerDialog->SetText((char*) title);
  379.         printerDialog->ShowModal(owner);
  380.         if (result == DID_CANCEL)
  381.             return FALSE;
  382.     }
  383.     else
  384.     {
  385.         if (queueName)
  386.         {
  387.             pSetup->fToFile = FALSE;
  388.             strcpy(pSetup->szPreferredQueue, (char *) *queueName);
  389.  
  390.             if (fileName)
  391.             {
  392.                 pSetup->fToFile = TRUE;
  393.                 strcpy(pSetup->szFileName, (char *) *fileName);
  394.             }
  395.         }
  396.     }
  397.  
  398.     *queueName = "";
  399.     *fileName = "";
  400.  
  401.     pqi = FindQueue(pSetup);
  402.     if (!pqi)
  403.         return FALSE;
  404.  
  405.     if (0 != strcmp(szSavedQueue, pSetup->szPreferredQueue))
  406.     {
  407.         if (!pSetup->pDriverData)
  408.             return FALSE;
  409.         free(pSetup->pDriverData);
  410.  
  411.         pSetup->pDriverData = (DRIVDATA *) malloc(pqi->pDriverData->cb);
  412.         if (!pSetup->pDriverData)
  413.         {
  414.             ulrc = FALSE;
  415.             return ulrc;
  416.         }
  417.         pSetup->pDriverData->cb = pqi->pDriverData->cb;
  418.     }
  419.  
  420.     if (!pSetup->pDriverData || !pSetup->pDriverData->cb == pqi->pDriverData->cb)
  421.         return FALSE;
  422.     memcpy(pSetup->pDriverData, pqi->pDriverData, pqi->pDriverData->cb);
  423.  
  424.     if (pSetup->fToFile)
  425.     {
  426.         pSetup->lDCType = OD_DIRECT;
  427.         pSetup->devopenstruc.pszLogAddress = pSetup->szFileName;
  428.     }
  429.     else
  430.     {
  431.         pSetup->lDCType = OD_QUEUED;
  432.         pSetup->devopenstruc.pszLogAddress = pSetup->szPreferredQueue;
  433.     }
  434.  
  435.     strcpy(szWork, pqi->pszDriverName);
  436.     pch = strchr(szWork, '.');
  437.     if (pch)
  438.         *pch = 0;
  439.  
  440.     if (pSetup->devopenstruc.pszDriverName)
  441.         free(pSetup->devopenstruc.pszDriverName);
  442.  
  443.     pSetup->devopenstruc.pszDriverName = (PSZ) malloc(1 + strlen(szWork));
  444.     if (!pSetup->devopenstruc.pszDriverName)
  445.         return FALSE;
  446.  
  447.     strcpy(pSetup->devopenstruc.pszDriverName, szWork);
  448.  
  449.     pSetup->devopenstruc.pdriv = pSetup->pDriverData;
  450.     pSetup->devopenstruc.pszDataType = "PM_Q_STD";
  451.  
  452.     pSetup->hdcPrinterInfo = DevOpenDC(pSetup->hab, OD_INFO, "*", 4, (PDEVOPENDATA) & pSetup->devopenstruc, (HDC) 0);
  453.     if (!pSetup->hdcPrinterInfo)
  454.         return FALSE;
  455.  
  456.     sizel.cx = 0;
  457.     sizel.cy = 0;
  458.     pSetup->hpsPrinterInfo = GpiCreatePS(pSetup->hab, pSetup->hdcPrinterInfo, &sizel, pSetup->lWorldCoordinates | GPIA_ASSOC);
  459.  
  460.     if (GPI_ERROR == pSetup->hpsPrinterInfo)
  461.     {
  462.         DevCloseDC(pSetup->hdcPrinterInfo);
  463.         pSetup->hdcPrinterInfo = (HDC) 0;
  464.         pSetup->hpsPrinterInfo = (HPS) 0;
  465.         return FALSE;
  466.     }
  467.  
  468.     pSetup->pDevOpenData = (PDEVOPENDATA) & pSetup->devopenstruc;
  469.  
  470.     *queueName = pSetup->szPreferredQueue;
  471.     if (pSetup->fToFile)
  472.         *fileName = pSetup->szFileName;
  473.     return TRUE;
  474. }
  475.  
  476.  
  477. PPRQINFO3 XPrinterDevice::FindQueue(PPRINTERSETUP pSetup)
  478. {
  479.     for (LONG i = 0; i < pSetup->cQueues; i++)
  480.     {
  481.         if (0 == strcmp(pSetup->szPreferredQueue, pSetup->pQueueInfo[i].pszName))
  482.             return &pSetup->pQueueInfo[i];
  483.     }
  484.     return NULL;
  485. }
  486.  
  487.  
  488. void XPrinterDevice::CleanupPrinter()
  489. {
  490.     if (pSetup->hpsPrinterInfo)
  491.     {
  492.         GpiAssociate(pSetup->hpsPrinterInfo, (HDC) 0);
  493.         GpiDestroyPS(pSetup->hpsPrinterInfo);
  494.         pSetup->hpsPrinterInfo = (HPS) 0;
  495.     }
  496.  
  497.     if (pSetup->hdcPrinterInfo)
  498.     {
  499.         DevCloseDC(pSetup->hdcPrinterInfo);
  500.         pSetup->hdcPrinterInfo = (HDC) 0;
  501.     }
  502.  
  503.     if (pSetup->pQueueInfo)
  504.     {
  505.         free(pSetup->pQueueInfo);
  506.         pSetup->pQueueInfo = NULL;
  507.     }
  508.  
  509.     if (pSetup->pDriverData)
  510.     {
  511.         free(pSetup->pDriverData);
  512.         pSetup->pDriverData = NULL;
  513.     }
  514.  
  515.     if (pSetup->devopenstruc.pszDriverName)
  516.     {
  517.         free(pSetup->devopenstruc.pszDriverName);
  518.         pSetup->devopenstruc.pszDriverName = NULL;
  519.     }
  520. }
  521.  
  522.  
  523. /* XPrinterDevice::Draw()
  524. @remarks Draw the content of the device to the printer
  525. @returns
  526. */
  527. void XPrinterDevice::Draw(void)
  528. {
  529.     XGraphicObject *o = first;
  530.  
  531.     while (o)
  532.     {
  533.         o->Draw();
  534.         o = o->next;
  535.     }
  536. }
  537.  
  538.  
  539. /* XPrinterDevice :: XPrinterDevice(XFrameWindow * w, LONG m)
  540. @remarks Create a printer-device
  541. @parameters XFrameWindow * owner-window
  542.                 LONG mode    mode to open, see XGraphicDevice::XGraphicDevice() for details
  543. @returns TRUE
  544. */
  545. XPrinterDevice :: XPrinterDevice(XFrameWindow * w, LONG m):XGraphicDevice(m)
  546. {
  547.     pSetup = (PRINTERSETUP *) calloc(sizeof(PRINTERSETUP), 1);
  548.  
  549.     pSetup->lWorldCoordinates = m;
  550.     pSetup->hab = w->GetProcess()->hab;
  551.  
  552.     width = 0;
  553.     height = 0;
  554. }
  555.  
  556.  
  557. XPrinterDevice :: ~XPrinterDevice()
  558. {
  559.     free(pSetup);
  560. }
  561.  
  562.  
  563. /* XPrinterDevice::OpenPrinterJob(char *pszJobTitle)
  564. @remarks Open a printer job
  565. @parameters char * title        title of the printer job
  566. @returns TRUE
  567. */
  568. BOOL XPrinterDevice::OpenPrinterJob(char *pszJobTitle)
  569. {
  570.     hdc = DevOpenDC(pSetup->hab, pSetup->lDCType, "*", 9, pSetup->pDevOpenData, (HDC) 0);
  571.  
  572.     if (hdc == NULLHANDLE)
  573.         return FALSE;
  574.  
  575.     SIZEL sizel;
  576.  
  577.     sizel.cx = 0;
  578.     sizel.cy = 0;
  579.     hps = GpiCreatePS(pSetup->hab, hdc, &sizel, pSetup->lWorldCoordinates | GPIF_DEFAULT | GPIT_NORMAL | GPIA_ASSOC);
  580.  
  581.     if (GPI_ERROR == hps)
  582.     {
  583.         DevCloseDC(hdc);
  584.         hdc = (HDC) 0;
  585.         hps = (HPS) 0;
  586.         return FALSE;
  587.     }
  588.     DevEscape(hdc, DEVESC_STARTDOC, strlen(pszJobTitle), pszJobTitle, NULL, NULL);
  589.     if (!GpiSetCharMode(hps, CM_MODE2))
  590.         return FALSE;
  591.     if (!GpiSetTextAlignment(hps, TA_NORMAL_HORIZ, TA_NORMAL_VERT))
  592.         return FALSE;
  593.  
  594.     SIZEL sizPage;
  595.  
  596.     if (!GpiQueryPS(hps, &sizPage))
  597.         return FALSE;
  598.     width = sizPage.cx;
  599.     height = sizPage.cy;
  600.  
  601.     return TRUE;
  602. }
  603.  
  604.  
  605. /* XPrinterDevice::ClosePrinterJob()
  606. @remarks Close the job so it can be printed.
  607. */
  608. void XPrinterDevice::ClosePrinterJob()
  609. {
  610.     DevEscape(hdc, DEVESC_ENDDOC, 0, NULL, NULL, NULL);
  611.  
  612.     if (hps)
  613.     {
  614.         GpiSetCharSet(hps, 0);
  615.         GpiAssociate(hps, (HDC) 0);
  616.         GpiDestroyPS(hps);
  617.         hps = (HPS) 0;
  618.     }
  619.  
  620.     if (hdc)
  621.     {
  622.         DevCloseDC(hdc);
  623.         hdc = (HDC) 0;
  624.     }
  625. }
  626.  
  627.  
  628. /* XPrinterDevice::KillPrinterJob()
  629. @remarks Remove the printer job from the printer queue.
  630. */
  631. void XPrinterDevice::KillPrinterJob()
  632. {
  633.     DevEscape(hdc, DEVESC_ABORTDOC, 0, NULL, NULL, NULL);
  634.  
  635.     if (hps)
  636.     {
  637.         GpiSetCharSet(hps, 0);
  638.         GpiAssociate(hps, (HDC) 0);
  639.         GpiDestroyPS(hps);
  640.         hps = (HPS) 0;
  641.     }
  642.  
  643.     if (hdc)
  644.     {
  645.         DevCloseDC(hdc);
  646.         hdc = (HDC) 0;
  647.     }
  648. }
  649.  
  650.  
  651. /* XPrinterDevice::NewPage()
  652. @remarks Add a new page to the printer-job.
  653. @returns BOOL success
  654. */
  655. BOOL XPrinterDevice::NewPage()
  656. {
  657.     if (hdc)
  658.     {
  659.         if (DevEscape(hdc, DEVESC_NEWFRAME, 0, NULL, NULL, NULL) == DEV_OK)
  660.             return TRUE;
  661.     }
  662.     return FALSE;
  663. }
  664.