Are there any SIMPLE examples of printing?

Here is some sample code, but also check out PRINTQ12.ZIP on cdrom.com in 2_x/program. PRINTQ12.ZIP contains a DLL that encapselates alot of the messy details.

Here is the working code for allowing the user to change the printer setup. I've also included the code that I use to start and end printing, so you can see how it all works.

If you have any questions or comments, feel free to write.

PrinterSetup() is the routine that gets the printer setup information from the user.

GetPrinterHPS() is the routine that gets the DC and PS for the printer, and starts the document.

EndPrint() is the routine that ends the document, and closes the DC.

First, here's a little sample of how to use PrinterSetup(), GetPrinterHPS(), and EndPrint():

{
   HPS          hPrinterPS;
   HDC          hPrinterDC;
   DEVOPENSTRUC dops;

   ...

   dops->pszLogAddress = NULL;  // in case PrinterSetup fails, this will tell
                                // GetPrinterHPS() to use default printer info

   PrinterSetup(&dops);

   hPrinterPS = GetPrinterHPS(&dops, &hPrinterDC,
                              "Document Name", 0L, 0L);
   if (hPrinterPS != GPI_ERROR) {
      // do your printing here

      EndPrint(hPrinterPS, hPrinterDC, "Document Name");
   }

   ...
}


/*
******************************************************************************
**  FUNCTION: PrinterSetup
**  PURPOSE :   This function allows the user to change printer settings.
**
**  PARAMS  :   lpdos - the printer info
**  RETURN  :   BOOL   (TRUE = success)
**
**  DATE    :   11-Dec-1992
**  AUTHOR  :   Carl Samos
******************************************************************************
**  Modified: Date:     Description of changes
**  CNS     :   11-Dec-1992 Initial version
******************************************************************************
*/
BOOL PrinterSetup(DEVOPENSTRUC FAR *lpdos)
{
   PDRIVDATA     pDriveData;      /*  The drive data  */
   unsigned long ulSize;          /*  The buffer size required  */
   char          szPrinter[32];   /*  The printer name  */
   PSZ           pszDriver;       /*  The driver name  */
   PSZ           pszLogicalPort;  /*  The logical port  */
   char          szDeviceName[32];/*  The printer's name */


   // get the printer driver, name and logical port
   // GetPrinterInformation allocates space for pszDriver and pszLogicalPort
   if (!GetPrinterInformation(szPrinter, &pszDriver,
                              szDeviceName,&pszLogicalPort))
      return(FALSE);


   // get the size needed for the DRIVDATA struct
   ulSize = DevPostDeviceModes(habMain, NULL, pszDriver, NULL, szPrinter, 0L);


   if (ulSize != DPDM_NONE && ulSize != DPDM_ERROR) {
      pDriveData = (PDRIVDATA) _fmalloc(ulSize);
      pDriveData->cb = ulSize;

      // bring up the dialog boxes, and fill the DRIVDATA struct
      ulSize = DevPostDeviceModes(habMain, pDriveData, pszDriver, NULL,
                                  szPrinter, 0L);

      if (ulSize == DEV_OK) {
          // if there is a printer name, copy it into the DRIVDATA
          if (szDeviceName[0] != '\0')
             strcpy(pDriveData->szDeviceName, szDeviceName);

          // remove the old information
          if (lpdos->pszLogAddress != NULL) {
             _ffree(lpdos->pszLogAddress);
          }
          if (lpdos->pszDriverName != NULL) {
             _ffree(lpdos->pszDriverName);
          }
          if (lpdos->pdriv != NULL)
             _ffree(lpdos->pdriv);

          /*  Setup the DEVOPENSTRUC  */
          lpdos->pszLogAddress = pszLogicalPort;
          lpdos->pszDriverName = pszDriver;
          lpdos->pszDataType   = NULL;
          lpdos->pdriv         = pDriveData;
      }
      else {
          _ffree(pszDriver);
          _ffree(pszLogicalPort);
          _ffree(pDriveData);
      }
   }
   else {
      _ffree(pszDriver);
      _ffree(pszLogicalPort);
   }

   return(TRUE);
}


/*
******************************************************************************
**  FUNCTION:   GetPrinterInformation
**  PURPOSE :   This function gets the current printer information from the
**                    os2.ini file.
**
**  PARAMS  :   PSZ pszPrinter
**              PSZ pszDriver
**              PSZ pszDeviceName
**              PSZ pszLogicalPort
**
**  RETURN  :   void
**
**  DATE    :   11-Dec-1992
**  AUTHOR  :   Carl Samos
******************************************************************************
**  Modified: Date:     Description of changes
**  CNS     :   11-Dec-1992 Initial version
******************************************************************************
*/
BOOL GetPrinterInformation(PSZ pszPrinter, PSZ FAR *lpszDriver,
                           PSZ pszDeviceName, PSZ FAR *lpszLogicalPort)
{
   int  cb;
   char szDetails[256];
   PSZ  pszBegin;
   PSZ  pszTemp;
   char szPort[64];
   char szDriver[64];
   char szLogPort[64];

   /*  Get the printer name  */
   cb = WinQueryProfileString(habMain, "PM_SPOOLER",
                              "PRINTER", "", pszPrinter,32);
   pszPrinter[cb-2] = 0;


   /*  Get the other details  */
   WinQueryProfileString(habMain, "PM_SPOOLER_PRINTER", pszPrinter, "",
                         szDetails, 256);

   // the profile string has the following format:
   // PORT;DRIVER;LOGICAL PORT;NETWORK INFO;
   // fields can have more than one entry, separated by a comma
   // the printer's name will follow the driver, separated by a period.

   pszBegin = szDetails;

   // get the printer port
   pszTemp = strchr(pszBegin, ';');
   if (pszTemp != NULL) {
      *pszTemp = '\0';
      strcpy(szPort, pszBegin);
      *pszTemp = ';';
      pszBegin = pszTemp + 1;

      // check for a comma in the string
      pszTemp = strchr(szPort, ',');
      if (pszTemp != NULL) *pszTemp = '\0';
   }
   else {
      return(FALSE);
   }

   // now get the driver and printer name
   pszTemp = strchr(pszBegin, ';');
   if (pszTemp != NULL) {
      *pszTemp = '\0';
      strcpy(szDriver, pszBegin);
      *pszTemp = ';';
      pszBegin = pszTemp + 1;

      // check for a period (printer name follows it)
      pszTemp = strchr(szDriver, '.');
      if (pszTemp != NULL) {
         strcpy(pszDeviceName, pszTemp+1);
         *pszTemp = '\0';
      }
      else {
         pszDeviceName[0] = '\0';
      }

      // check for a comma in the string
      pszTemp = strchr(szDriver, ',');
      if (pszTemp != NULL)
        *pszTemp = '\0';
   }
   else {
      return(FALSE);
   }


   // now get the logical port
   pszTemp = strchr(pszBegin, ';');
   if (pszTemp != NULL) {
      *pszTemp = '\0';
      strcpy(szLogPort, pszBegin);
      *pszTemp = ';';
      pszBegin = pszTemp + 1;

      // check for a comma in the string
      pszTemp = strchr(szLogPort, ',');
      if (pszTemp != NULL)
        *pszTemp = '\0';
   }
   else {
      return(FALSE);
   }

   *lpszDriver = _fmalloc(sizeof(char) * (strlen(szDriver)+1));
   strcpy(*lpszDriver, szDriver);

   *lpszLogicalPort = _fmalloc(sizeof(char) * (strlen(szLogPort)+1));
   strcpy(*lpszLogicalPort, szLogPort);

   return(TRUE);
}


/*
******************************************************************************
**  FUNCTION: GetPrinterHPS
**  PURPOSE :   Gets the presentation space for a printer, and starts the doc
**  PARAMS  :   lpdos
**          :   lphDC           - the printer's hdc
**          :   pszDocName      - the name of the document
**          :   lWidth          - the width of the document
**          :   lHeight         - the height of the document
**  RETURN  : hPS
**  DATE    :   11-Dec-1992
**  AUTHOR  :   Carl Samos
******************************************************************************
**  Modified: Date:     Description of changes
**  CNS     :   11-Dec-1992 Initial version
******************************************************************************
*/
HPS GetPrinterHPS(DEVOPENSTRUC FAR *lpdos, HDC FAR* lphDC, PSZ pszDocName,
		  LONG lWidth, LONG lHeight)
{
   LONG  lReturn;
   SIZEL sizl;
   HPS   hPS;

   if (lpdops->pszLogAddress == NULL) {  // get the default settings
      char szPrinter[32];   /*  The printer name	*/
      PSZ  pszDriver;       /*  The driver name  */
      PSZ  pszLogicalPort;  /*  The logical port	*/
      char szDeviceName[32];/*  The printer's name */

      // GetPrinterInformation allocates space for pszDriver and pszLogicalPort
      if (!GetPrinterInformation(szPrinter, &pszDriver, szDeviceName,
                                 &pszLogicalPort))
      return(GPI_ERROR);

      lpdops->pszLogAddress = pszLogicalPort;
      lpdops->pszDriverName = pszDriver;
      lpdops->pszDataType   = NULL;
      lpdops->pdriv         = NULL;
   }

   // open the printer DC
   *lphDC = DevOpenDC (habMain, OD_QUEUED, "*", 4L, lpdops, (HDC) NULL);
   if (*lphDC == DEV_ERROR) {
      return(GPI_ERROR);
   }

   // start the document
   lReturn = DevEscape(*lphDC, DEVESC_STARTDOC, strlen(pszDocName),
                       pszDocName,NULL, NULL);

   // get the PS for the printer
   if (lReturn == DEV_OK) {
       sizl.cx = lWidth;
       sizl.cy = lHeight;

       if (lWidth == 0) {
          hPS =  GpiCreatePS (habMain, *lphDC, &sizl,
                              PU_LOENGLISH | GPIF_DEFAULT |
                              GPIT_NORMAL | GPIA_ASSOC);
          return(hPS);
       }
       else {
          hPS = GpiCreatePS (habMain, *lphDC, &sizl,
                              PU_ARBITRARY | PU_LOENGLISH |
                              GPIF_DEFAULT | GPIT_NORMAL |
                              GPIA_ASSOC);
          return(hPS);
      }
   }

   return(GPI_ERROR);
}


/*
******************************************************************************
**  FUNCTION: EndPrint
**  PURPOSE : To close the hdc and end the document
**  PARAMS  : hpsPrinter - the printer's presentation space
**     : hdcPrinter - the printer's device context
**     : pszDocName - the name of the document
**  RETURN  : nothing
**  DATE    :   11-Dec-1992
**  AUTHOR  :   Carl Samos
******************************************************************************
**  Modified: Date:     Description of changes
**  CNS     :   11-Dec-1992 Initial version
******************************************************************************
*/
void EndPrint(HPS hpsPrinter, HDC hdcPrinter, PSZ pszDocName)
{
DevEscape(hdcPrinter, DEVESC_ENDDOC, strlen(pszDocName),
pszDocName, NULL,NULL);
GpiAssociate(hpsPrinter, (HDC) NULL);
DevCloseDC(hdcPrinter);
GpiDestroyPS(hpsPrinter);
}

Credit: Carl Samos


[Back: Printing]
[Next: Is there an easy way to get printer output (another opinion)?]