home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / krcls012.zip / KrClass / source / krprint.cpp < prev    next >
Text File  |  1997-02-14  |  13KB  |  367 lines

  1. // Kroni's Classes: objects for buffered twodimensional graphics
  2. // (c) 1997 Wolfgang Kronberg
  3. // file: krbwin.cpp
  4.  
  5.  
  6. #include "krprint.hpp"
  7. #include "krtrace.hpp"
  8.  
  9. #define INCL_DOSERRORS                           // Dos error constants
  10. #define INCL_SPL                                 // SplEnumQueue & Co.
  11. #define INCL_SPLERRORS                           // Spl error constants
  12. #define INCL_SPLDOSPRINT                         // PRQ* data structures
  13. #define INCL_DEV                                 // DevEscape & Co.
  14. #include <os2.h>
  15.  
  16. #include <ithread.hpp>                           // IThread
  17. #include <igrafctx.hpp>                          // IGraphicContext
  18. #include <ipushbut.hpp>                          // IPushButton
  19. #include <iframe.hpp>                            // IFrameWindow
  20. #include <imcelcv.hpp>                           // IMultiCellCanvas
  21. #include <ilistbox.hpp>                          // IListBox
  22. #include <icmdhdr.hpp>                           // ICommandHandler
  23.  
  24.  
  25.  
  26. class _KrPrHandler : public ICommandHandler
  27. {
  28.  
  29. public:
  30.  
  31.   _KrPrHandler (IWindow * win, Boolean * res, KrPrinter * prt, IListBox * lb) : ICommandHandler ()
  32.     {window = win; result = res; (*result) = false; printer = prt; listBox = lb;};
  33.                                                  // win: Dialog Window; res: Pointer to result code
  34.                                                  //   (true = OK, false = cancel)
  35.   virtual Boolean command (ICommandEvent & event);
  36.  
  37. private:
  38.  
  39.   IWindow * window;
  40.   Boolean * result;
  41.   KrPrinter * printer;
  42.   IListBox * listBox;
  43.  
  44. };
  45.  
  46.  
  47. #define pd_ok       0x1002                       // Identifier for the buttons of the print dialog
  48. #define pd_cancel   0x1003
  49. #define pd_settings 0x1004
  50.  
  51.  
  52. Boolean _KrPrHandler::command (ICommandEvent & event)
  53. {
  54.   ULONG devrc;
  55.   HAB hab = IThread::current().anchorBlock();
  56.   PSZ pszPrinter;
  57.   PDRIVDATA pOldDrivData;
  58.   PDRIVDATA pNewDrivData;
  59.   DEVOPENSTRUC dops;
  60.   LONG buflen;
  61.   _KrPrintQueueInfo * queueInfo;
  62.   static IString temp;
  63.  
  64.   switch (event.commandId ())
  65.      {
  66.      case pd_ok:
  67.         (*result) = true;
  68.         printer->selectedQueue = listBox->selection();
  69.         window->postEvent(WM_CLOSE,0,0);
  70.         return true;
  71.  
  72.      case pd_cancel:
  73.         window->postEvent(WM_CLOSE,0,0);
  74.         return true;
  75.  
  76.      case pd_settings:
  77.         queueInfo = &(printer->printQueues[listBox->selection()]);
  78.         temp = IString::remove (queueInfo->driver,queueInfo->driver.indexOf('.'));
  79.         dops.pszDriverName = temp;
  80.         pszPrinter = queueInfo->queueName;
  81.         dops.pdriv = (DRIVDATA*) (queueInfo->driverData);
  82.  
  83.         buflen = DevPostDeviceModes (hab,
  84.                                     NULL,
  85.                                     dops.pszDriverName,
  86.                                     dops.pdriv->szDeviceName,
  87.                                     pszPrinter,
  88.                                     DPDM_POSTJOBPROP
  89.                                     );
  90.  
  91.         if (buflen<=0)
  92.            _KRSYSTHROW (IDeviceError("DevPostDeviceModes() failed."));
  93.  
  94.         if (DosAllocMem((PPVOID)&pNewDrivData,buflen,fALLOC))
  95.            _KRSYSTHROW (IOutOfMemory("Could not allocate memory for printer data."));
  96.  
  97.         pOldDrivData = dops.pdriv;
  98.         dops.pdriv = pNewDrivData;
  99.         long i;
  100.         i= pOldDrivData->cb;
  101.         if (i>buflen)
  102.            i = buflen;
  103.         memcpy( (PSZ)pNewDrivData, (PSZ)pOldDrivData, i);
  104.         DosFreeMem (pOldDrivData);
  105.  
  106.         devrc = DevPostDeviceModes (hab,
  107.                                    dops.pdriv,
  108.                                    dops.pszDriverName,
  109.                                    dops.pdriv->szDeviceName,
  110.                                    pszPrinter,
  111.                                    DPDM_POSTJOBPROP
  112.                                    );
  113.         queueInfo->driverData = (_KrDrivData*)(pNewDrivData);
  114.         return true;
  115.  
  116.      default:
  117.         return false;
  118.      }
  119. };
  120.  
  121.  
  122.  
  123. KrPrinter::KrPrinter ()
  124. {
  125.   initPrintQueues ();
  126.   selectedQueue = -1;
  127.  
  128.   int i;
  129.   for (i=0; i<numberOfQueues; i++)
  130.      if (printQueues[i].defaultQueue)
  131.         selectedQueue = i;
  132.  
  133.   graphicsList = NULL;
  134. };
  135.  
  136. void KrPrinter::initPrintQueues ()
  137. {
  138.   SPLERR splerr;
  139.   ULONG  cbBuf;
  140.   ULONG  cTotal;
  141.   ULONG  cReturned;
  142.   ULONG  cbNeeded;
  143.   ULONG  ulLevel;
  144.   ULONG  i;
  145.   PSZ    pszComputerName ;
  146.   PVOID  pBuf = 0;
  147.   PPRQINFO3 prq ;
  148.  
  149.   ulLevel = 3L;                             // We only want basic infomation
  150.   pszComputerName = (PSZ)NULL ;             // Required
  151.   splerr = SplEnumQueue (                   // First call only to get required buffer size
  152.              pszComputerName, ulLevel, pBuf,
  153.              0,                             // For this call: buffer length = 0
  154.              &cReturned, &cTotal,
  155.              &cbNeeded,                     // The buffer size we need
  156.              NULL
  157.            );
  158.  
  159.   if ( splerr == ERROR_MORE_DATA || splerr == NERR_BufTooSmall )
  160.      {
  161.      DosAllocMem (&pBuf, cbNeeded, PAG_READ | PAG_WRITE | PAG_COMMIT);
  162.      printQueues = new _KrPrintQueueInfo [cTotal];
  163.  
  164.      cbBuf = cbNeeded ;
  165.      splerr = SplEnumQueue (pszComputerName, ulLevel, pBuf, cbBuf, &cReturned, &cTotal, &cbNeeded, NULL);
  166.      if (splerr == NO_ERROR)
  167.         {
  168.         numberOfQueues = cReturned;
  169.         prq = PPRQINFO3 (pBuf);
  170.         for (i=0; i < numberOfQueues; i++, prq++)
  171.             {
  172.             printQueues[i].queueName = prq->pszName;
  173.             printQueues[i].queueProcName = prq->pszPrProc;
  174.             if ( prq->fsType & PRQ3_TYPE_APPDEFAULT )
  175.                printQueues[i].defaultQueue = TRUE;
  176.             else
  177.                printQueues[i].defaultQueue = FALSE;
  178.             printQueues[i].queueDescription = prq->pszComment;
  179.             printQueues[i].driver = prq->pszDriverName;
  180.             DosAllocMem (PPVOID(&(printQueues[i].driverData)), prq->pDriverData->cb,
  181.               PAG_READ | PAG_WRITE | PAG_COMMIT
  182.             );
  183.             memcpy (printQueues[i].driverData, prq->pDriverData, prq->pDriverData->cb);
  184.             };
  185.          }
  186.      else                                        // If error occurred
  187.          _KRSYSTHROW (IAssertionFailure("SplEnumQueue() failed"));
  188.      DosFreeMem (pBuf);
  189.      }
  190.   else                                           // If error code unexpected
  191.      _KRSYSTHROW (IAssertionFailure("SplEnumQueue() failed"));
  192.  
  193. };
  194.  
  195.  
  196. HDC KrPrinter::openPrinterDc (IString title)
  197. {
  198.   if (selectedQueue<0)
  199.      _KRSYSTHROW (IAssertionFailure("Selected Queue negative"));
  200.  
  201.   HAB hab = IThread::current().anchorBlock();    // Anchor-Block handle
  202.   DEVOPENSTRUC dos;                              // Structure for device open
  203.  
  204.   dos.pszLogAddress = PSZ(printQueues[selectedQueue].queueName);
  205.                                                  // Print to this logical queue
  206.   dos.pszQueueProcName = PSZ(printQueues[selectedQueue].queueProcName);
  207.                                                  // Use this queue processor
  208.   static IString temp = IString::remove
  209.     (printQueues[selectedQueue].driver,printQueues[selectedQueue].driver.indexOf('.'));
  210.   dos.pszDriverName = temp;                      // Physical driver name, part before '.'
  211.   dos.pdriv = (DRIVDATA*) (&(printQueues[selectedQueue].driverData));
  212.                                                  // Special job properties
  213.   dos.pszDataType = PSZ("PM_Q_STD");             // Standard job (not raw format)
  214.   dos.pszComment = PSZ(title);                   // Title of the job
  215.   dos.pszQueueProcParams = PSZ("");              // Parameters for the queue (e.g. # copies). None yet.
  216.   dos.pszSpoolerParams = PSZ("");                // Parameters for the spooler (e.g. form name). None yet.
  217.   dos.pszNetworkParams = PSZ("");                // We could give our user name here (user=...)
  218.  
  219.   return DevOpenDC (
  220.            hab,                                  // Always needed
  221.            OD_QUEUED,                            // Open a queue device context
  222.            "*",                                  // OS/2 ignores this
  223.            9L,                                   // We need all 9 entries of the data area
  224.            PDEVOPENDATA(&dos),                   // Data area for opening
  225.            NULLHANDLE                            // We are compatible with the screen
  226.          );
  227.  
  228. };
  229.  
  230.  
  231. Boolean KrPrinter::print (IString title)
  232. {
  233.  
  234.   hdc = openPrinterDc(title);                    // Open device context for current printer
  235.   if (hdc == DEV_ERROR)
  236.      return FALSE;                               // Error occurred -> we couldn't print it.
  237.  
  238.   HAB hab = IThread::current().anchorBlock();    // Anchor-Block handle
  239.   SIZEL sizel;
  240.   sizel.cx = 0;                                  // Pagesize -> Null, which gives us the default size
  241.   sizel.cy = 0;                                  //   (which is full size with preserved aspect ratio)
  242.  
  243.   hps = GpiCreatePS (
  244.           hab,                                   // As always
  245.           hdc,                                   // We assign the just created device context
  246.           &sizel,
  247.           PU_TWIPS | GPIA_ASSOC                  // We want pixels, and we need the hdc (since we set size=0)
  248.         );
  249.  
  250.   if (hps == GPI_ERROR)
  251.      return FALSE;                               // Error occurred -> we couldn't print it.
  252.  
  253.   DevEscape (
  254.     hdc,                                         // As always
  255.     DEVESC_STARTDOC,                             // We start a print job
  256.     title.length(), PSZ(title),
  257.     NULL, NULL                                   // These fields are not needed for STARTDOC
  258.   );
  259.  
  260.   IPresSpaceHandle ips (hps);
  261.   IGraphicContext gc (ips);                      // This is for IOCL compatibility
  262.   if (graphicsList)
  263.      graphicsList -> drawOn (gc);
  264.  
  265.   DevEscape (
  266.     hdc,                                         // As always
  267.     DEVESC_ENDDOC,                               // We end the job normally
  268.     0, NULL, NULL, NULL                          // None of these is needed for ENDDOC
  269.   );
  270.  
  271.   GpiDestroyPS (hps);
  272.   DevCloseDC (hdc);                              // Clean up
  273.  
  274.   return TRUE;                                   // The printing worked!
  275.  
  276. };
  277.  
  278.  
  279. IGList * KrPrinter::setList (IGList & list)
  280. {
  281.   IGList * buffer = graphicsList;
  282.   graphicsList = &list;
  283.   return buffer;
  284. };
  285.  
  286.  
  287. void KrPrinter::getArea (IPoint & p1, IPoint & p2)
  288. {
  289.   hdc = openPrinterDc(IString("KrPrinter::getArea temporary"));
  290.                                                  // Open device context for current printer
  291.   if (hdc == DEV_ERROR)
  292.      _KRSYSTHROW (IDeviceError("openPrinterDc failed."));
  293.  
  294.   p1 = IPoint (0,0);                             // Currently, we don't support anything else
  295.  
  296.   LONG data[2];                                  // We need 2 LONG words of data area
  297.   BOOL rc;
  298.  
  299.   rc = DevQueryCaps (
  300.          hdc,                                    // As always
  301.          CAPS_WIDTH,                             // The first element of interest
  302.          2,                                      // We need CAPS_WIDTH and the next element
  303.          data                                    // Data array
  304.        );
  305.   if (!rc)
  306.      _KRSYSTHROW (IDeviceError("DevQueryCaps failed."));
  307.  
  308.   p2 = IPoint (data[0],data[1]);                 // CAPS_WIDTH and CAPS_HEIGHT
  309.  
  310.   DevCloseDC (hdc);                              // Clean up.
  311. };
  312.  
  313.  
  314. Boolean KrPrinter::printDialog ()
  315. {
  316.   IFrameWindow * frame;
  317.   frame = new IFrameWindow ("Choose a Printer",0x1000);
  318.   IMultiCellCanvas * canvas;
  319.   canvas = new IMultiCellCanvas (IC_FRAME_CLIENT_ID,frame,frame);
  320.   IListBox * listBox;
  321.   listBox = new IListBox (0x1001,canvas,canvas,IRectangle(IPoint(0,0),IPoint(300,100)));
  322.   canvas->addToCell (listBox,2,2,7,1);
  323.  
  324.   int i;
  325.   for (i=0; i<numberOfQueues; i++)
  326.     listBox->addAsLast (printQueues[i].queueDescription);
  327.   listBox->select (selectedQueue);
  328.  
  329.   IPushButton * ok;
  330.   ok = new IPushButton (0x1002,canvas,canvas,
  331.              IRectangle(), IPushButton::defaultStyle() | IPushButton::defaultButton);
  332.   ok->setText ("Ok");
  333.   canvas->addToCell (ok,3,4);
  334.   IPushButton * cancel;
  335.   cancel = new IPushButton (0x1003,canvas,canvas);
  336.   cancel->setText ("Cancel");
  337.   canvas->addToCell (cancel,5,4);
  338.   IPushButton * settings;
  339.   settings = new IPushButton (0x1004,canvas,canvas);
  340.   settings->setText ("Settings...");
  341.   canvas->addToCell (settings,7,4);
  342.   canvas->setColumnWidth (1,0,true);
  343.   canvas->setRowHeight (1,0,true);
  344.   canvas->setColumnWidth (9,0,true);
  345.   canvas->setRowHeight (5,0,true);
  346.   Boolean result;
  347.   _KrPrHandler handler (frame,&result,this,listBox);
  348.   handler.handleEventsFor (frame);
  349.  
  350.   frame->setClient (canvas);
  351.   frame->sizeTo (ISize(400,300));
  352.   frame->setFocus ();
  353.   frame->show ();
  354.  
  355.   IApplication::current().run();
  356.  
  357.   delete settings;
  358.   delete cancel;
  359.   delete ok;
  360.   delete listBox;
  361.   delete canvas;
  362.   delete frame;
  363.  
  364.   return result;
  365. };
  366.  
  367.