[Last Call] Learn about multicloud storage options and how to improve your company's cloud strategy. Register Now

x
?
Solved

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

Posted on 1997-04-04
6
Medium Priority
?
286 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
[X]
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
  • 3
  • 3
6 Comments
 

Accepted Solution

by:
billcarter earned 210 total points
ID: 1300855
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
ID: 1300856
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
ID: 1300857
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
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 

Author Comment

by:lwc
ID: 1300858
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
ID: 1300859
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
ID: 1300860
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

[Webinar] Lessons on Recovering from Petya

Skyport is working hard to help customers recover from recent attacks, like the Petya worm. This work has brought to light some important lessons. New malware attacks like this can take down your entire environment. Learn from others mistakes on how to prevent Petya like worms.

Question has a verified solution.

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

Introduction: Finishing the grid – keyboard support for arrow keys to manoeuvre, entering the numbers.  The PreTranslateMessage function is to be used to intercept and respond to keyboard events. Continuing from the fourth article about sudoku. …
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
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.
In this video, Percona Solution Engineer Dimitri Vanoverbeke discusses why you want to use at least three nodes in a database cluster. To discuss how Percona Consulting can help with your design and architecture needs for your database and infras…

650 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