Link to home
Start Free TrialLog in
Avatar of Michael Knight
Michael Knight

asked on

How to set printers fonts while printing using TextOut

    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)
      CPrintDialog *PrintTheReportDlg = new CPrintDialog(FALSE,PD_ALLPAGES | PD_NOPAGENUMS | PD_HIDEPRINTTOFILE | PD_NOSELECTION | PD_RETURNDC);

      // 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;
                  return;
                  }
            }
      // on AutoPrint for problem batches (when selected in the Property Pages), we just call for the default printer info
      else
            PrintTheReportDlg->GetDefaults();

      // 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;
            return;
            }
      // if we have a good handle, let's keep going and try to print this thing
      else
            {
            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
            PrinterCDCHandle->Attach(PrinterHandle);

            // set the map mode (what are we printing- determines metrics sizing)
            PrinterCDCHandle->SetMapMode(MM_TEXT);

            // get the printer metrics (exact printable space on page)
            PrinterCDCHandle->GetTextMetrics(&PrinterMetrics);

            // initialize the DOCINFO structure to all zeroes (do this when you have a structure with a size member)
            memset(&ReportDocumentInformation,0,sizeof(DOCINFO));

            // 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
            else
                  {
                  // 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)
                              break;

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

                        // 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;
                                    break;
                                    }
                              }
                  
                        // 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);
                              break;
                              }
                        }

                  // close the report file
                  _fcloseall();

                  // 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;
ASKER CERTIFIED SOLUTION
Avatar of RONSLOW
RONSLOW

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Michael Knight
Michael Knight

ASKER

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