Solved

I have a text file that has PCL5 code in it...how do I print it?

Posted on 1997-04-04
6
243 Views
Last Modified: 2013-11-20
I need to print a text file that has pcl5 code in it.
Is there any easy way to print out this file out to the
default printer?
Or do I have to take care of the pcl5 code myself?  If this is the case where can I get all the information about pcl5
codes that I need to know?
Thanks in advance....
0
Comment
Question by:lwc
  • 3
  • 3
6 Comments
 

Accepted Solution

by:
billcarter earned 70 total points
Comment Utility
Assuming Win32 - you need to use the following api calls

1 OpenPrinter()
2. AddJob()
3. CreateFile()
4. ClosePrinter()
5. ScheduleJob()
0
 

Author Comment

by:lwc
Comment Utility
I'm having some trouble trying to get those 5 functions to work.

I'm trying to get the default printer settings with CPrintDialog....
like this:


HDC    hdcPrn ;

    // Instantiate a CPrintDialog.
    CPrintDialog *printDlg = new CPrintDialog(FALSE, PD_ALLPAGES | PD_RETURNDC, NULL);

BOOL got_defaults = printDlg->GetDefaults();
      if(got_defaults == 0)
      {
            i = MessageBox("There was an error when looking for the default printer!!!", "Error 1", MB_OK);
            EndDialog(1);
            return;
      }

    // Obtain a handle to the device context.
    hdcPrn = printDlg->GetPrinterDC();
    if (hdcPrn == NULL)
      {
            i = MessageBox("There was an error when looking for the default printer!!!", "Error 2", MB_OK);
            EndDialog(1);
            return;
      }


// here is where I would like to use the functions you
// recommended


// NEW STUFF
      CString printer_name = printDlg->GetDeviceName();
      BOOL hope;

      hope = OpenPrinter(printer_name ,hdcPrn, NULL);
      if(hope == FALSE)
      {
            i = MessageBox("There was an error when trying to access the printer!!!", "Error 3", MB_OK);
            EndDialog(1);
            return;

      }

      ADDJOB_INFO_1 jobid;
      //strcpy(jobid.Path, "c:\\jobstore.txt");
      //CString stp1 = "c:\\jobstore.txt";
      //jobid.Path = stp1;
      
      jobid.JobId = 1;
      hope = AddJob(hdcPrn, 1, jobid, 100000, 100000);
      if(hope == FALSE)
      {
            i = MessageBox("There was an error when trying to addjob to print!!!", "Error 4", MB_OK);
            EndDialog(1);
            return;

      }

      CreateFile(pstring, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, hdcPrn);

                       
               
    hope = ClosePrinter(hdcPrn);
      if(hope == FALSE)
      {
            i = MessageBox("There was an error when trying to close the printer!!!", "Error 5", MB_OK);
            EndDialog(1);
            return;

      }


    hope = ScheduleJob(hdcPrn, 1);
      if(hope == FALSE)
      {
            i = MessageBox("There was an error when trying to schedule a job", "Error 6", MB_OK);
            EndDialog(1);
            return;

      }




I also keep getting these errors:
print7Dlg.cpp
C:\print72\print7Dlg.cpp(494) : error C2664: 'OpenPrinterA' : cannot convert parameter 1 from 'class CString' to 'char *' (new behavior; please see help)
C:\print72\print7Dlg.cpp(509) : error C2664: 'AddJobA' : cannot convert parameter 3 from 'struct _ADDJOB_INFO_1A' to 'unsigned char *' (new behavior; please see help)
Error executing cl.exe.
print7.exe - 2 error(s), 0 warning(s)


Am I on the right track here?  How do I fix the error above?
Now will this also print standard printer init strings too?
0
 

Expert Comment

by:billcarter
Comment Utility
This is just rough - but it should get you going.

1. C:\print72\print7Dlg.cpp(494) : error C2664: 'OpenPrinterA' : cannot convert
parameter 1 from 'class CString' to 'char *' (new behavior; please see help)

Is basically just telling you that CString is not a char* ...
Easy enough to fix - just cast it as in (char*)(const char*)

2. C:\print72\print7Dlg.cpp(509) : error C2664: 'AddJobA' : cannot convert
parameter 3 from 'struct _ADDJOB_INFO_1A' to 'unsigned char *'
(new behavior; please see help)

A couple of things -

a) AddJob returns it's information in a variable sized
buffer - it's defined as follows...

typedef struct _ADDJOB_INFO_1 { // aji1  
    LPTSTR  Path;
    DWORD   JobId;
} ADDJOB_INFO_1;
 
and it requires _you_ to provide room for the string Path, so how big should it
be?  The answer is to call the function twice - the first time with a known too
small buffer - the size of the buffer required will be place in pcbNeeded variable.
Then allocate a new buffer of at least this size and call the function again.

b) Again use a cast so that the compiler knows what you trying to do.

I've included some code that should (hopefully) make this a little clearer.
The function bcAddJob() - just does the double call to AddJob

3. Now will this also print standard printer init strings too?
   Nope - you bypass all of that - also this only works for local
   printers _and_ the printer cannot be configured for direct printing.


char* bcAddJob(HANDLE hPrinter)
{
      DWORD pcbNeeded;
      char* buffer = new char[16];
      ADDJOB_INFO_1* addBuf;
      
      // This first call is intended to fail - but returns
      // the size of the buffer required as pcbNeeded
      addBuf = (ADDJOB_INFO_1*)buffer;
      BOOL bResult = AddJob(hPrinter,
            1,
            (LPBYTE)&buffer[0],
            8,
            &pcbNeeded);

      if (bResult) {            // Should never happen...
            return buffer;
      }
      else {
            DWORD err_value = GetLastError();
            if (err_value != ERROR_INSUFFICIENT_BUFFER) {  // Some other error....
                  return NULL;
            }
      }

      ASSERT (!bResult);                                    
      delete [] buffer;                                    

      // Make the call with correctly sized buffer.

      buffer = new char[pcbNeeded];
      addBuf = (ADDJOB_INFO_1*)buffer;
      bResult = AddJob(hPrinter,
            1,
            (LPBYTE)&buffer[0],
            pcbNeeded,
            &pcbNeeded);
      
      if (!bResult) {
            LogEvent("Fail add job"," ");
            delete [] buffer;
            ClosePrinter(hPrinter);
            return NULL;
      }

      return buffer;
}

// QueuePrintJob

BOOL QueuePrintJob(CString& printer_name, CString& file_path)
{
      HANDLE hPrinter;

      BOOL bResult = ::OpenPrinter((char*)(const char*)printer_name,
            &hPrinter,
            NULL);
      if (!bResult) {
            // Handle fail to open printer
            return FALSE;
      }

      char* buffer = bcAddJob(hPrinter);
      ADDJOB_INFO_1* addBuf =  (ADDJOB_INFO_1*)buffer;

      if (addBuf == (ADDJOB_INFO_1*)NULL) {
            // Handle fail AddJob
            return FALSE;
      }

      CopyDiskFileToPrinter(addBuf->Path,file_path);

      bResult = CloseHandle(fHnd);
      if (!bResult) {
            // Handle fail CloseHandle
      }

      bResult = ScheduleJob(hPrinter,
            addBuf->JobId);
      if (!bResult) {
            // Handle fail ScehduleJob
            delete buffer;
            return FALSE;
      }

      ClosePrinter(hPrinter);
      delete [] buffer;
      return TRUE;
}

      

0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 

Author Comment

by:lwc
Comment Utility
I'm trying to follow what you wrote down in your example code.
I'm having some trouble with some of it.  It appears that there
is some code between the two functions bcAddJob and
QueuePrintJob.....is that the function CopyDiskFileToPrinter?
But it returns buffer....and doesn't seem to match.

0
 

Expert Comment

by:billcarter
Comment Utility
Sorry about that.  I didn't supply the code for CopyDiskFileToPrinter. (you seem to have a good handle on how to do that). The extra lines where left in from an errant cut & paste.
0
 

Author Comment

by:lwc
Comment Utility
Hmmmm I got the above to code to compile....but it doesn't
seem to do anything.  It seems to return NULL in the
bcAddJob function.  It happens in this code:

            DWORD err_value = GetLastError();
            if (err_value != ERROR_INSUFFICIENT_BUFFER)
            { // Some other error....
message_int = MessageBox("false", "FALSE---other error", MB_OK);

                  return NULL;
            }


pcbNeeded should equal the file size in bytes correct?  If thats
true....it returns 44 when the file size is 478 bytes.

0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Suggested Solutions

In this article, I'll describe -- and show pictures of -- some of the significant additions that have been made available to programmers in the MFC Feature Pack for Visual C++ 2008.  These same feature are in the MFC libraries that come with Visual …
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.
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…

763 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

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now