TIP: Click on subject to list as thread! ANSI
echo: os2prog
to: Gary Chambers
from: Peter Fitzsimmons
date: 1996-02-28 17:40:32
subject: Printing

GC> Hi All...

 GC> I just created a PM amortization calculator.  I have 
 GC> written the amortized loan to a listbox (yes, Peter, 
 GC> I'm lazy!!).  I wish to print the contents of this 
 GC> listbox, and a couple other things like page headers, 
 GC> footers, etc.  What method(s) can I use to do this?  I

If you just want to print plain text,  and you don't mind pissing off
people with postscript printers,  simply use fopen("prn",
"wt") with fprintf().

Otherwise,  you've got to jump headfirst into PM fonts & printing,which
is not easy the first time through.  I was so pissed off that I couldn't
find a "no noise" sample,  I wrote one:

 Since I wrote this sample,  I have learned:

         1) I didn't have to query the current form to find the default
            page size;  I could have simply used GpiQueryPS() to query
            the size of the presentation space.

         2) It is sometimes better to use TWIPS instead of PELS for the
            presentation units -- since a twip is 1/20 of a point, you
            can select font point sizes without having to find out the
            pels/meter of the device.

 /*
  * This sample program contains the least amount of code I could write
  * to do PM text printing,  to the system default printer.
  *
  * I purposefully wrote most of the code in one huge function so that
  * you can see the steps that are required -- I was unable to find such a
  * sampe when _I_ needed one.
  *
  * I have also removed much of the error detection code.
  *
  * This sample follows recommendations for WARP;  it will probably work
  * with OS/2 2.1 but NOT 2.0.
  *
  * Peter Fitzsimmons, Fri  95-09-29 02:47:16am.
  *
  * IBM   : icc /Q /Kb /W3 /SS /O printsam.c /B"/pm:pm"
  * Watcom: wcl386 /Ox /W4 /Zq /Zp4 /s /k0x4000 printsam.c /l=os2v2_pm
  */

 #define INCL_PM
 #define INCL_SPL
 #define INCL_SPLDOSPRINT
 #define INCL_ERRORS
 #include 
 #include 
 #include 
 #include 
 #include 

 static HAB gHab;
 static FONTDLG gFontDlg;

 static int Print(void);
 static int Font(HPS hpsPrinter);
 static void gputs(HPS hps, int yInc, LONG yTop, int line, char *string);

 #define pmassert assert

 int main(void)
 {
     HMQ hmq;

     if ((gHab = WinInitialize(0)) == 0L)
         return 1;

     if ((hmq = WinCreateMsgQueue(gHab, 0)) == 0L)
         return 1;

     Print();

     WinDestroyMsgQueue(hmq);
     WinTerminate(gHab);
     return 0;
 }

 static int Print(void)
 {
     HDC hdc;
     HPS hps;
     DEVOPENSTRUC dos;
     APIRET rc;
     ULONG cReturned;
     ULONG cTotal;
     ULONG cbNeeded;
     PRQINFO3 *prq3;
     unsigned i, defq = 0;
     char *p;
     SIZEL sizel;
     int yChar;
     long yTop;                          // top of page (size of page in PELs)
     FONTMETRICS *pfm = NULL;
     LONG cForms;
     HCINFO hci;                         // info on current form.
     SIZEF sizef;
     LONG caps[2];

     /*
      * 1.find default printer
      */
     // count queues & get number of bytes needed for buffer
     rc = SplEnumQueue(NULL, 3, NULL, 0L, &cReturned, &cTotal, &cbNeeded,
                       NULL);

     if (!(rc == ERROR_MORE_DATA || rc == NERR_BufTooSmall))
         return 1;                       // error

     prq3 = malloc(cbNeeded);

     // enum the queues
     rc = SplEnumQueue(NULL, 3, prq3, cbNeeded, &cReturned, &cTotal,
                       &cbNeeded, NULL);

     // search for default queue;
     for (i = 0; i < cReturned; i++) {
         if (prq3[i].fsType & PRQ3_TYPE_APPDEFAULT) {
             defq = i;
             break;
         }
     }


     /*
      * 2.create printer device context
      */
     memset(&dos, 0, sizeof(dos));

     p = strrchr(prq3[defq].pszDriverName, '.');
     if (p)
         *p = 0;                         // del everything after '.'

     dos.pszLogAddress = prq3[defq].pszName;
     dos.pszDriverName = prq3[defq].pszDriverName;
     dos.pdriv = prq3[defq].pDriverData;
     dos.pszDataType = "PM_Q_STD";
     hdc = DevOpenDC(gHab, OD_QUEUED, "*", 4L, (PDEVOPENDATA)
& dos, 0);
     pmassert(DEV_ERROR != hdc);
     free(prq3);

     /*
      * So that we can calculate a meaningful Character Cell (GpiSetCharBox),
      * query the resolution of the device.  It is returned in pels per inch.
      */
     DevQueryCaps(hdc, CAPS_HORIZONTAL_FONT_RES, 2, caps);


     /*
      * 3.Find default FORM,  so we know its dimensions (in pels)
      *
      */
     cForms = DevQueryHardcopyCaps(hdc, 0L, 0L, &hci);   // Get form count
     pmassert(cForms != 0);

     for (i = 0; i < cForms; i++) {
         rc = DevQueryHardcopyCaps(hdc, i, 1L, &hci);    // Get info for this
                                                         // form
         if (rc == 1) {                  // Got info
             if (hci.flAttributes & HCAPS_CURRENT) {     // Have current form
                 printf("form=%s\n", hci.szFormname);
                 break;
             }
         }
     }
     pmassert(i != cForms);              // ie: there wasn't a default form

     /*
      * 4.create presentation space
      */
     sizel.cx = 0;
     sizel.cy = 0;
     hps = GpiCreatePS(gHab, hdc, &sizel,
                       PU_PELS | GPIA_ASSOC | GPIT_NORMAL);
     pmassert(hps != GPI_ERROR);


     /*
      * 5. Select Font.
      */
     Font(hps);

     // important: we must do a STARTDOC before we use the printer HPS.
     DevEscape(hdc, DEVESC_STARTDOC, strlen("Doc Title"),
"Doc Title",
               0L, 0L);

     /* use black color for text */
     GpiSetColor(hps, CLR_BLACK);

     GpiSetCharSet(hps, 0);
     pmassert(GPI_ERROR != GpiCreateLogFont(hps, NULL, 1, &gFontDlg.fAttrs));
     GpiSetCharSet(hps, 1);

     /*
      * 6. Figure out size of font.
      */
     sizef.cx = MAKEFIXED((caps[0] * FIXEDINT(gFontDlg.fxPointSize)) / 72, 0);
     sizef.cy = MAKEFIXED((caps[1] * FIXEDINT(gFontDlg.fxPointSize)) / 72, 0);
     GpiSetCharBox(hps, &sizef);
     pfm = malloc(sizeof(*pfm));
     GpiQueryFontMetrics(hps, sizeof(FONTMETRICS), pfm);
     yChar = (int) pfm->lMaxBaselineExt; // height of a line
     yTop = hci.yPels + pfm->lMaxDescender;      // top of page
     free(pfm);

     /*
      * 7.Draw some text.
      */

     gputs(hps, yChar, yTop, 1, "Get warped");
     gputs(hps, yChar, yTop, 2, "Do not delay");
     gputs(hps, yChar, yTop, 3, "Get warped today");

     /*
      * 8. Cleanup
      */
     DevEscape(hdc, DEVESC_ENDDOC, 0L, 0L, 0, NULL);

     GpiAssociate(hps, NULLHANDLE);
     GpiDestroyPS(hps);
     DevCloseDC(hdc);

     return 0;
 }

 // ask the user to chose a font.
 static int Font(HPS hpsPrinter)
 {

     char Family[90];

     memset(&gFontDlg, 0, sizeof(FONTDLG));
     gFontDlg.cbSize = sizeof(FONTDLG);
     gFontDlg.usFamilyBufLen = sizeof(Family);
     gFontDlg.pszFamilyname = Family;
     gFontDlg.pfnDlgProc = NULL;
     gFontDlg.clrFore = CLR_BLACK;
     gFontDlg.clrBack = CLR_WHITE;
     gFontDlg.ulUser = 0;
     gFontDlg.usWeight = 0;
     gFontDlg.fAttrs.usCodePage = 850;
     gFontDlg.fl = FNTS_CENTER | FNTS_INITFROMFATTRS | FNTS_VECTORONLY;
     gFontDlg.flFlags = 0; //FNTF_NOVIEWSCREENFONTS;
     gFontDlg.hpsScreen = WinGetScreenPS(HWND_DESKTOP);
     gFontDlg.hpsPrinter = hpsPrinter;

     WinFontDlg(HWND_DESKTOP, HWND_DESKTOP, &gFontDlg);

     WinReleasePS(gFontDlg.hpsScreen);
     return 0;
 }

 // print a line of text.
 static void gputs(HPS hps, int yInc, LONG yTop, int line, char *string)
 {
     POINTL pt;

     pt.x = 0;
     pt.y = yTop - (yInc * line);
     GpiCharStringAt(hps, &pt, strlen(string), string);
 }


--- Maximus/2 3.00
* Origin: Sol 3 * Toronto * V.32 * (905)858-8488 (1:259/414)
SEEN-BY: 50/99 78/0 270/101 620/243 711/401 409 410 413 430 808 809 934 955
SEEN-BY: 712/407 515 517 628 713/888 800/1 7877/2809
@PATH: 259/414 400 99 250/99 3615/50 396/1 270/101 712/515 711/808 809 934

SOURCE: echomail via fidonet.ozzmosis.com

Email questions or comments to sysop@ipingthereforeiam.com
All parts of this website painstakingly hand-crafted in the U.S.A.!
IPTIA BBS/MUD/Terminal/Game Server List, © 2025 IPTIA Consulting™.