home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / NOTEPAD2.ZIP / NPPRINT.C < prev    next >
C/C++ Source or Header  |  1989-02-08  |  12KB  |  349 lines

  1. /***************************************************************************\
  2. * npprint.c -- This file contains the code necessary to print the text.
  3. *
  4. * Created by Microsoft Corporation, 1989
  5. \***************************************************************************/
  6.  
  7. #define INCL_WIN
  8. #define INCL_GPI
  9. #define INCL_DEV
  10. #include <os2.h>
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include <opendlg.h>
  14. #include "notepad.h"
  15. #include "npcmd.h"
  16.  
  17. /******************** Globals to module ********************/
  18.  
  19. static SHORT sXPrinterRes;
  20. static SHORT sYPrinterRes;
  21. static LONG  lPrinterHeight;
  22. static LONG  lPrinterWidth;
  23. static LONG  lMaxBaselineExt;
  24. static VOID  PrintEndPage(HPS hps, HDC hdc);
  25. static VOID  PrintTextLine(HPS, IPT, IPT);
  26.  
  27. /***************************************************************************\
  28. * BOOL SetPrinterFont(HPS hps, HDC hdc)
  29. *
  30. * Sets the printer font to match the font currently used for screen display.
  31. * If no matching font can be found, then the user is notified and the
  32. * function returns FALSE, effectively terminating printing.
  33. \***************************************************************************/
  34.  
  35. static BOOL SetPrinterFont(HPS hps, HDC hdc)
  36. {
  37.         FONTMETRICS fmDefault;
  38.         PFONTMETRICS pfm;
  39.         LONG cFonts, cRemFonts, i;
  40.         SHORT cBytes;
  41.         SHORT sReturn;
  42.         FATTRS fattrs;
  43.         BOOL brc;
  44.         LONG ldevcaps[2];
  45.  
  46.         /* determine the font resolution of the printer DC */
  47.         brc = DevQueryCaps(hdc, CAPS_HORIZONTAL_RESOLUTION, 2L, ldevcaps);
  48.  
  49.         GpiQueryFontMetrics(hps, (LONG) sizeof(fmDefault),
  50.                 (PFONTMETRICS)&fmDefault);
  51.  
  52.         cFonts = 0;
  53.         cRemFonts = GpiQueryFonts(hps, QF_PUBLIC | QF_PRIVATE,
  54.                 CurrFaceName(),
  55.                 (PLONG)&cFonts,
  56.                 (LONG) 0,
  57.                 NULL);
  58.         if (cRemFonts == 0) {
  59.                 WinMessageBox(HWND_DESKTOP,
  60.                         hwndNP,
  61.                         "Current font doesn't exist for printer",
  62.                         NULL,
  63.                         0,
  64.                         MB_CANCEL | MB_ICONEXCLAMATION | MB_APPLMODAL);
  65.                 return(FALSE);
  66.         }
  67.         cBytes = (SHORT) (cRemFonts * sizeof(FONTMETRICS));
  68.         pfm = (PFONTMETRICS)WinAllocMem(hhAppHeap, cBytes);
  69.         cFonts = cRemFonts;
  70.         cRemFonts = GpiQueryFonts(hps, QF_PUBLIC | QF_PRIVATE,
  71.                 CurrFaceName(),
  72.                 (PLONG)&cFonts,
  73.                 (LONG)sizeof(FONTMETRICS),
  74.                 pfm);
  75.  
  76.         for (i=0; i<cFonts; i++) {
  77.                 if (((pfm+i)->sNominalPointSize == CurrFaceSize())  &&
  78.                     ((pfm+i)->sXDeviceRes == sXPrinterRes) &&
  79.                     ((pfm+i)->sYDeviceRes == sYPrinterRes))
  80.                         break;
  81.         }
  82.         if (i >= cFonts) {
  83.                 WinFreeMem(hhAppHeap, (NPBYTE) OFFSETOF(pfm), (USHORT) cBytes);
  84.                 sReturn = WinMessageBox(HWND_DESKTOP,
  85.                         hwndNP,
  86.                         "Current font doesn't exist for printer",
  87.                         NULL,
  88.                         0,
  89.                         MB_OKCANCEL | MB_ICONEXCLAMATION | MB_APPLMODAL);
  90.                 if (sReturn == MBID_CANCEL) {
  91.                         return(FALSE);
  92.                 }
  93.         } else {
  94.                 fattrs.usRecordLength = sizeof(fattrs);
  95.                 fattrs.fsSelection = 0;
  96.                 fattrs.lMatch = (pfm+i)->lMatch;
  97.                 lstrcpy(fattrs.szFacename,(pfm+i)->szFacename);
  98.                 fattrs.idRegistry = 0;
  99.                 fattrs.usCodePage = 0;
  100.                 fattrs.lMaxBaselineExt = 0;
  101.                 fattrs.lAveCharWidth = 0;
  102.                 fattrs.fsType = 0;
  103.                 fattrs.fsFontUse = 0;
  104.                 WinFreeMem(hhAppHeap, (NPBYTE) OFFSETOF(pfm), (USHORT) cBytes);
  105.                 if (!GpiCreateLogFont(hps,(PSTR8)"DUMMY",(LONG) 3, &fattrs)) {
  106.                         WinMessageBox(HWND_DESKTOP,
  107.                                 hwndNP,
  108.                                 "Error in GpiCreateLogFont; aborting",
  109.                                 NULL,
  110.                                 0,
  111.                                 MB_CANCEL | MB_ICONEXCLAMATION | MB_APPLMODAL);
  112.                         return(FALSE);
  113.                 }
  114.                 if (!GpiSetCharSet(hps, (LONG) 3)) {
  115.                         WinMessageBox(HWND_DESKTOP,
  116.                                 hwndNP,
  117.                                 "Error in GpiSetCharSet; aborting",
  118.                                 NULL,
  119.                                 0,
  120.                                 MB_CANCEL | MB_ICONEXCLAMATION | MB_APPLMODAL);
  121.                         return(FALSE);
  122.                 }
  123.         }
  124.  
  125.         GpiQueryFontMetrics(hps, (LONG) sizeof(fmDefault),
  126.                 (PFONTMETRICS)&fmDefault);
  127.         lMaxBaselineExt = fmDefault.lMaxBaselineExt;
  128.         return(TRUE);
  129. }
  130.  
  131. /***************************************************************************\
  132. * VOID PrintTextLine(HPS hps, IPT iptStart, IPT iptEnd)
  133. *
  134. * Prints the text to the PS provided.  Returns FALSE if there is any problem;
  135. * TRUE otherwise.
  136. \***************************************************************************/
  137.  
  138. static VOID PrintTextLine(HPS hps, IPT iptStart, IPT iptEnd)
  139. {
  140.         LONG cch, chlen;
  141.         PCHAR pch;
  142.  
  143.         cch = iptEnd - iptStart;
  144.         while (cch > 0) {
  145.                 chlen = cch;
  146.                 pch = PVOIDFROMMR(WinSendMsg(hwndNPEdit, EM_GETTEXT, (MPARAM)iptStart, MPFROMP(&chlen)));
  147.                 chlen=(chlen>cch)?cch:chlen;
  148.                 GpiCharString(hps, chlen, pch);
  149.                 cch -= chlen;
  150.                 iptStart += chlen;
  151.         }
  152. }
  153.  
  154. /***************************************************************************\
  155. * BOOL PrintSetDevParms(DEVOPENSTRUC *dvo, DRIVDATA *drv,
  156. *                       LONG *lDevMode, LONG *lDevOpCount)
  157. *
  158. * Creates a PS and hDC for printing, and sets up a few useful globals.
  159. \***************************************************************************/
  160.  
  161. static BOOL PrintSetDevParms(DEVOPENSTRUC *dvo, DRIVDATA *drv,
  162.                              LONG *lDevMode, LONG *lDevOpCount)
  163. {
  164.         BOOL fSpoolerOn;
  165.         CHAR szPrinterName[NP_PROFILESIZE];
  166.         CHAR szPrinterConn[NP_PROFILESIZE];
  167.         CHAR szSpoolerOn[NP_PROFILESIZE];
  168.         PSZ pszPortField, pszDriverField, pszQueueField, pszEnd;
  169.  
  170.         drv->cb = 4;
  171.         drv->lVersion = 0L;
  172.         lstrcpy(drv->szDeviceName,"");
  173.         drv->abGeneralData[0]='?';
  174.  
  175.         WinQueryProfileString(hab, "PM_SPOOLER", "SPOOL", "0;", szSpoolerOn, NP_PROFILESIZE);
  176.         fSpoolerOn = (0 == strcmp("1;",szSpoolerOn));
  177.         if (!WinQueryProfileString(hab, "PM_SPOOLER", "PRINTER", "", szPrinterName, NP_PROFILESIZE)) {
  178.                 return(FALSE);
  179.         }
  180.         *pszEnd = '\0';
  181.  
  182.         if (!WinQueryProfileString(hab, "PM_SPOOLER_PRINTER", szPrinterName, "", szPrinterConn, NP_PROFILESIZE)) {
  183.                 return(FALSE);
  184.         }
  185.  
  186.  
  187.         pszPortField = szPrinterConn;
  188.         *(pszDriverField++) = '\0';
  189.         *(pszQueueField++) = '\0';
  190.         *pszEnd = '\0';
  191.  
  192.         if (fSpoolerOn) {
  193.                 *lDevMode = OD_QUEUED;
  194.                 dvo->pszLogAddress = pszQueueField;
  195.         } else {
  196.                 *lDevMode = OD_DIRECT;
  197.                 dvo->pszLogAddress = pszPortField;
  198.         }
  199.  
  200.         dvo->pszDriverName = pszDriverField;
  201. /*      dvo->pdriv = drv; */
  202.         dvo->pdriv = NULL;
  203.         dvo->pszDataType = "PM_Q_RAW";
  204.         dvo->pszComment = "";
  205.         dvo->pszQueueProcName = NULL;
  206.         dvo->pszQueueProcParams = NULL;
  207.         dvo->pszSpoolerParams = NULL;
  208.         dvo->pszNetworkParams = NULL;
  209.  
  210.         *lDevOpCount = 5L;
  211.  
  212.         return(TRUE);
  213. }
  214.  
  215. /***************************************************************************\
  216. * BOOL PrintStartPage(HPS *hps, HDC *hdc)
  217. *
  218. * Creates a PS and hDC for printing, and sets up a few useful globals.
  219. \***************************************************************************/
  220.  
  221. static BOOL PrintStartPage(HPS *hps, HDC *hdc)
  222. {
  223.         DEVOPENSTRUC devop;
  224.         DRIVDATA drivdata;
  225.         LONG    ldevcaps[2];
  226.         SIZEL   sizel;
  227.         BOOL    brc;
  228.         LONG    lDevMode, lDevOpCount;
  229.  
  230.         /* open the device context */
  231.  
  232.         if (!PrintSetDevParms(&devop, &drivdata, &lDevMode, &lDevOpCount))
  233.                 return(FALSE);
  234.  
  235.         *hdc = DevOpenDC(hab,
  236.                          lDevMode,
  237.                          (PSZ)"*",
  238.                          lDevOpCount,
  239.                          (PDEVOPENDATA)&devop,
  240.                          (HDC) NULL);
  241.  
  242.         if (*hdc == NULL) {
  243.                 return(FALSE);
  244.         }
  245.  
  246.         /* determine the height of the printer display area */
  247.  
  248.         brc = DevQueryCaps(*hdc, CAPS_WIDTH, 2L, ldevcaps);
  249.  
  250.         sizel.cx = 0L;
  251.         sizel.cy = 0L;
  252.         lPrinterHeight = ldevcaps[1];
  253.         lPrinterWidth = ldevcaps[0];
  254.  
  255.         /* create the PS */
  256.         *hps = GpiCreatePS(hab,
  257.                            *hdc,
  258.                            (PSIZEL)&sizel,
  259.                            (ULONG)(PU_PELS | GPIA_ASSOC | GPIT_NORMAL));
  260.  
  261.         if (*hps == NULL) {
  262.                 DevCloseDC(*hdc);
  263.                 return(FALSE);
  264.         }
  265.  
  266.         DevEscape(*hdc, DEVESC_STARTDOC, (LONG)lstrlen(szFileName),
  267.                 szFileName, NULL, NULL);
  268.  
  269.         GpiSetBackMix(*hps, BM_LEAVEALONE);
  270.  
  271.  
  272.         if (!SetPrinterFont(*hps, *hdc)) {
  273.                 PrintEndPage(*hps,*hdc);
  274.                 return(FALSE);
  275.         }
  276.  
  277.         return(TRUE);
  278.  
  279. }
  280.  
  281.  
  282. /***************************************************************************\
  283. * VOID PrintEndPage(HPS hps, HDC hdc)
  284. *
  285. * Given a ps/dc pair, closes them.
  286. \***************************************************************************/
  287.  
  288. static VOID PrintEndPage(HPS hps, HDC hdc)
  289. {
  290.     DevEscape(hdc, DEVESC_ENDDOC, 0L, NULL, 0L, NULL);
  291.     GpiAssociate(hps, NULL);
  292.     GpiDestroyPS(hps);
  293.     DevCloseDC(hdc);
  294. }
  295.  
  296. /***************************************************************************\
  297. * BOOL NPPrint()
  298. *
  299. * This function does everything that is necessary to print.  The essence
  300. * is that in order to print the following steps are required.
  301. *
  302. *   Returns:
  303. *       TRUE  if printing completed successfully (i.e. no bad return codes)
  304. *       FALSE if printing failed.
  305. \***************************************************************************/
  306.  
  307. BOOL NPPrint()
  308. {
  309.     BOOL fToReturn;
  310.     LONG lTextLength;
  311.     IPT ipt, iptEnd;
  312.     LONG lLine;
  313.     HPS hps;
  314.     HDC hdc;
  315.     POINTL ptl;
  316.     HPOINTER hptrSave;
  317.  
  318.     lTextLength = LONGFROMMR(WinSendMsg(hwndNPEdit, EM_QTL, NULL, NULL));
  319.     lLine = 0;
  320.  
  321.     if (!PrintStartPage(&hps, &hdc)) {
  322.             return(FALSE);
  323.     }
  324.  
  325.     hptrSave = WinQueryPointer (HWND_DESKTOP);
  326.     WinSetPointer(HWND_DESKTOP, WinQuerySysPointer (HWND_DESKTOP, SPTR_WAIT, FALSE));
  327.  
  328.     ptl.x = 0;
  329.     ptl.y = lPrinterHeight;
  330.     iptEnd = LONGFROMMR(WinSendMsg(hwndNPEdit, EM_CHARFROMLINE, MPFROMLONG(lLine),NULL));
  331.  
  332.     do {
  333.             ipt = iptEnd;
  334.             iptEnd = LONGFROMMR(WinSendMsg(hwndNPEdit, EM_CHARFROMLINE, MPFROMLONG(lLine+1),NULL));
  335.             ptl.y -= lMaxBaselineExt;
  336.             if (ptl.y <= 0) {
  337.                     DevEscape( hdc, DEVESC_NEWFRAME, 0L, (PBYTE)NULL, 0L, (PBYTE)NULL);
  338.                     ptl.y = lPrinterHeight - lMaxBaselineExt;
  339.             }
  340.             GpiMove(hps,(PPOINTL)&ptl);
  341.             PrintTextLine(hps,ipt,((ipt != iptEnd)?(iptEnd-1):lTextLength));
  342.             lLine++;
  343.     } while (ipt != iptEnd);
  344.     PrintEndPage(hps, hdc);
  345.     WinSetPointer (HWND_DESKTOP, hptrSave);
  346.  
  347.     return (fToReturn);
  348. }
  349.