How to set printers fonts while printing using TextOut

Posted on 1997-05-21
Last Modified: 2013-12-03
    How can I do this? I'm reading a file from disk line-by-line and then spitting to the printer spooler using TextOut. On a couple of line nums I need to reduce the point size to 5. It needs to start at 6. Here's the code that prints it all at about 11-12 point. Thanks.

Michael A Knight

      // create the print object (display print dlg set, print all pages w/o page numbers, hide print to file, disable selection)

      // display the Print Dialog where user can select their preferred settings if Print button was pressed
      if (ShowPrintDlg)
            int return_value = PrintTheReportDlg->DoModal();
            // if dialog did not return IDOK, then check for an error occurance
            if (return_value != IDOK)
                  if (return_value != IDCANCEL)
                        AfxMessageBox("The Printer Dialog Returned An Error.\nCannot Print Report.",MB_OK | MB_ICONEXCLAMATION);
                  delete PrintTheReportDlg;
      // on AutoPrint for problem batches (when selected in the Property Pages), we just call for the default printer info

      // get a handle to the selected printer device context
      HDC PrinterHandle = PrintTheReportDlg->GetPrinterDC();

      // if we have a NULL handle, display error to user and return
      if (PrinterHandle == NULL)
            AfxMessageBox("Error Getting Handle For Printer.\nCannot Print Report.",MB_OK | MB_ICONEXCLAMATION);
            delete PrintTheReportDlg;
      // if we have a good handle, let's keep going and try to print this thing
            CDC        *PrinterCDCHandle = new CDC;        // declare a device context object
            DOCINFO    ReportDocumentInformation;          // structure to contain document (report) info
            TEXTMETRIC PrinterMetrics;                     // structure to contain printer page info (for GetTextMetrics)
            int        NumberOfLinesPrinted;               // used for looping through the number of available lines per page (set to 60)
            int        EndOfFileFound = FALSE;             // flag to tell page loop when we have reached the end of the document
            FILE       *ReportFile;                        // file handle for the report data file

            // attach to the printer handle

            // set the map mode (what are we printing- determines metrics sizing)

            // get the printer metrics (exact printable space on page)

            // initialize the DOCINFO structure to all zeroes (do this when you have a structure with a size member)

            // set up the document info structure
            ReportDocumentInformation.lpszDocName = "Solid Test " + StationID + " EOT Report";
            ReportDocumentInformation.lpszOutput = NULL;
            ReportDocumentInformation.cbSize = sizeof(DOCINFO);

            // open report file for reading
            sprintf(TempStr,"d:\\report.dat");  // construct the filename
            ReportFile = fopen(TempStr,"r");                      // open file
            // if there was an error opening the file, then display error to user, clear mem and return
            if (ReportFile == NULL)
                  AfxMessageBox("Error Opening Report File.\nCannot Print Report.",MB_OK | MB_ICONEXCLAMATION);
            // if we opened the file okay, then continue
                  // tell the system that we are starting the document
                  if (PrinterCDCHandle->StartDoc(&ReportDocumentInformation) == -1)
                        AfxMessageBox("Error Starting Document.\nCannot Print Report.",MB_OK | MB_ICONEXCLAMATION);

                  // cycle through the pages (should only be one page, but I'm ready for more <g>)
                  for (;;)
                        // if we have found the end of the file, then break outta main for loop
                        if (EndOfFileFound)

                        // set the system to start the page
                        if (PrinterCDCHandle->StartPage() < 0)
                              AfxMessageBox("Error Starting Page.\nCannot Print Report.",MB_OK | MB_ICONEXCLAMATION);

                        // cycle through the number of available lines on a page
                        for (NumberOfLinesPrinted = 1; NumberOfLinesPrinted <= 60; NumberOfLinesPrinted++)
                              // get new line of data and check for end of file
                              if (fgets(TempStr,900,ReportFile) == NULL)
                                    EndOfFileFound = TRUE;                       // set the end of file flag for main page loop
                                    break;                                       // break outta line per page loop

                              // strip any newlines from text read in
                              char *pdest = strchr(TempStr,'\n');
                              int result = pdest - TempStr;
                              if(pdest != NULL)
                                    TempStr[result] = 0;

                              // send the data to the printer spool
                              if (PrinterCDCHandle->TextOut(0,((PrinterMetrics.tmHeight+PrinterMetrics.tmExternalLeading)*NumberOfLinesPrinted),
                                                                    TempStr,strlen(TempStr)) == 0)
                                    AfxMessageBox("Error Writing To Device.\nCannot Print Report.",MB_OK | MB_ICONEXCLAMATION);
                                    EndOfFileFound = TRUE;
                        // set the system to the end of page
                        if (PrinterCDCHandle->EndPage() < 0)
                              AfxMessageBox("Error Ending Page.\nA Page May Print.\nCannot Print Report.",MB_OK | MB_ICONEXCLAMATION);

                  // close the report file

                  // tell system to end the document (close spool)
                  if (PrinterCDCHandle->EndDoc() < 0)
                        AfxMessageBox("Error Closing Document.\nCannot Print Report.",MB_OK | MB_ICONEXCLAMATION);

            // delete the device context handle got by GetPrinterDC
            if (PrinterCDCHandle->Detach() == NULL)
                  AfxMessageBox("Error Detaching Handle For Printer.\nReport May Print.",MB_OK | MB_ICONEXCLAMATION);

            // delete CDC class created with new operator
            delete PrinterCDCHandle;

      // delete CPrintDialog class created with new operator
      delete PrintTheReportDlg;
Question by:maknight
LVL 10

Accepted Solution

RONSLOW earned 100 total points
ID: 1301691
You just need to set up a LOGFONT structure with the required font sizes and select it into the DC beofre calling TextOut.

You can get the currently selected font and from that get its logfont structure, then just change the height (and width) appropriately for the size that you want.

If you require more help on this, let me know.



Author Comment

ID: 1301692
I create the CFont object below (I don't use the LOGFONT method, is this the only way?) How do I "select it into the DC". I just can't seem to find how/where to do this. Thanks.

// create the FONTs used by the Solid Test Program
CFont LargeTextFont,SmallTextFont,MediumTextFont;
MediumTextFont.CreatePointFont(60,"KEMET Medium Report",PrinterCDCHandle);


Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction: Displaying information on the statusbar.   Continuing from the third article about sudoku.   Open the project in visual studio. Status bar – let’s display the timestamp there.  We need to get the timestamp from the document s…
Introduction: Database storage, where is the exe actually on the disc? Playing a game selected randomly (how to generate random numbers).  Error trapping with try..catch to help the code run even if something goes wrong. Continuing from the seve…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…

856 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question