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
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
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

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
deburging in oracle form 12 112
Prevent this page from creating additional dialogs. 3 722
Window placement 17 95
wordcount challenge 11 147
Introduction: Dynamic window placements and drawing on a form, simple usage of windows registry as a storage place for information. Continuing from the first article about sudoku.  There we have designed the application and put a lot of user int…
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…
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…

726 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