We help IT Professionals succeed at work.

We've partnered with Certified Experts, Carl Webster and Richard Faulkner, to bring you two Citrix podcasts. Learn about 2020 trends and get answers to your biggest Citrix questions!Listen Now


How to set printers fonts while printing using TextOut

Medium Priority
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;
Watch Question

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.


Not the solution you were looking for? Getting a personalized solution is easy.

Ask the Experts
Michael KnightWMS Systems Analyst


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);

Access more of Experts Exchange with a free account
Thanks for using Experts Exchange.

Create a free account to continue.

Limited access with a free account allows you to:

  • View three pieces of content (articles, solutions, posts, and videos)
  • Ask the experts questions (counted toward content limit)
  • Customize your dashboard and profile

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.


Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.