Link to home
Start Free TrialLog in
Avatar of s1desh0w
s1desh0w

asked on

C++ output to default printer

Hi

I have written a simple console application in Visual C++ v6 that generates an invoice, the invoice has to go to screen, append to log file, and out to printer as well. I have the out to screen using a "cout" in a loop, similarly, appending the log is done like this:

#INCLUDE <fstream.h>
ofstream outfp;
void main()
{
outfp.open("c:log.txt", ios::app);
outfp << "OUTPUT TEXT";
outfp.close();
}

I want an output to the default printer in a similar way, it needs to be SIMPLE as i'm a TOTAL BEGINNER in C++. I think the problem lies in discovering the default printer, it may be a network printer for example, or USB etc. I've read there is a method using "Document.PrintOut" that will allow to print a text file, but can't find how. The SIMPLEST WORKING SOLUTION is what i'm after!

Thanks all, in advance

s1desh0w
Avatar of Gary Benade
Gary Benade
Flag of South Africa image

If you are writing a windows app (since you mention default printers I assume you are) this will work

  TPrinter * Prntr = Printer();
  TRect r = Rect(200,200,Prntr->PageWidth-200,Prntr->PageHeight-200);
  Prntr->BeginDoc();
  Prntr->Canvas->TextRect(r, 200, 200, "Text");  // use any TCanvas methods on the printers canvas
  Prntr->EndDoc();
Have a sneaky feeling that VC++ doesnt support the TPrinter object

In that case you can always resort to this

#include <stdio.h>

FILE *fp = fopen("LPT1", "w");
fprintf(fp,"What's up, Doc?\n");
fclose(fp);
or with streams

    ofstream optr("LPT1", ios::out);
    optr << "Hello\n" << "\f" << flush;  // with a formfeed
    optr.close();
Avatar of s1desh0w
s1desh0w

ASKER

hi Hobbit

thanks for your reply, it's not a windows app i should have said it is a console app. I tried your second bit of code, but it just hung. same on the 3rd, havn't tried the 1st. I'm on a networked printer here, attached to a server via usb, but this would obviously vary from machine to machine.

The code showed no errors but is that all the code needed or might i have to include more? i.e. includes etc, i have stdio.h there already... is lpt1 a virtual port, i.e. it will always get sent to the default, or rather is it a physical port? I'm rather confused and have very limited knowledge of C++.

Thanks


LPT1 is a physical port, so you waould have to have something plugged in for it to work. Does your console app run under windows, or is it DOS based?

If its a windows app, give example one a try, it should work if VC++ ships with the TPrinter object
with the 1st code i get 14 errors, i checked about 6 of them and they are all "undeclared identifier", must i include more headers etc? The app is a win32 console app.

Thanks
you need to #include "printers.hpp"
hi, Hobbit

I tried

#include "printers.hpp"
#include <printers.hpp>
#include <"printers.hpp">

no good, i just discovered as well that i don't have the Cstring.h file either which i needed for string concatination, i guess thats a whole other question!! I guess there is no easy way of addressing the default printer like you can a port?
this uses nothing but standard windows functions

  HANDLE hOwner = NULL;  // you can assign the handle of you application here instead of NULL.
  PRINTDLG pd;
  DOCINFO docinfo;
  docinfo.cbSize = sizeof( docinfo);
  docinfo.lpszDatatype = (LPTSTR) NULL;
  docinfo.lpszOutput = NULL;
  docinfo.lpszDocName = "Job Name";
  docinfo.fwType = 0;
  memset( &pd, 0, sizeof(PRINTDLG));
  pd.lStructSize = sizeof(PRINTDLG);
  pd.hwndOwner = hOwner;
  pd.Flags = PD_RETURNDC;
  char str[10];
  strcpy( str,"test");
  if (PrintDlg( &pd) != 0)
  {
    StartDoc(pd.hDC, &docinfo);
    StartPage(pd.hDC);
    TextOut( pd.hDC, 1, 1, str, strlen( str));
    EndPage(pd.hDC);
    EndDoc(pd.hDC);
    DeleteDC(pd.hDC);
  }
why bother with Cstrings, just use the standard c functions

  char str[10];
  strcpy( str,"test");
  strcat( str, "Gary");  // str now contains testGary
you may need some( or all) of these headers to make things work

#include <windows.h>
#include <winbase.h>
#include <commdlg.h>
#include <string.h>
#include <stdio.h>
thanks very much for the strings tip, that works fine. I'm scared by that code above, is it really necessary? I don't like using code i don't understand myself, it leads to bigger problems in the future i find.

If i have to use this can you tell me exactly what i'd have to do with it? Really i was hoping for an easy way to address the default printer like you suggested with streams to "LPT1", if only!!
to make it less scary ;) I have commented the code. Play around with it a bit and you'll soon get the hang of things

  HANDLE hOwner = NULL;  // you can assign the handle of you application here instead of NULL.
  PRINTDLG pd;                  // a windows print dialog structure
  DOCINFO docinfo;            // a windows document info structure
  docinfo.cbSize = sizeof( docinfo);        // windows wants to know the size of the structure
  docinfo.lpszDatatype = (LPTSTR) NULL;  // NULL means default
  docinfo.lpszOutput = NULL;             // NULL means default
  docinfo.lpszDocName = "Job Name";     // give the job a name that will show in the windows spooler, you can use the invoice number
  docinfo.fwType = 0;                  
  memset( &pd, 0, sizeof(PRINTDLG));   // clear the buffer by setting it all to 0's
  pd.lStructSize = sizeof(PRINTDLG); // windows wants to know the size of the structure
  pd.hwndOwner = hOwner;         // a dialog needs an owner, just like a puppy
  pd.Flags = PD_RETURNDC;         // tell windows that we want a device context (a way to talk ) to the printer the user selects
  char str[1025];                           // our string buffer
  if (PrintDlg( &pd) != 0)              // show the windows select printer dialogue to set options and select destination printer
  {                                             // if the user selected print
    StartDoc(pd.hDC, &docinfo);    // start a new document for the printer
    StartPage(pd.hDC);                 // start a new page in that document
    strcpy( str,"INVOICE: 10243");    
    TextOut( pd.hDC, 1, 1, str, strlen( str));  // print it a x=1, y=1
    strcpy( str,"NAME: BOB");
    TextOut( pd.hDC, 1, 50, str, strlen( str));  // print it a x=1, y=50
    strcpy( str,"ADDR: 1 SNAKE RD");
    TextOut( pd.hDC, 1, 100, str, strlen( str));  // print it a x=1, y=100
    EndPage(pd.hDC);                    // end the page
    EndDoc(pd.hDC);                     // end the document and send it to the windows spooler
    DeleteDC(pd.hDC);                   // close the device context to free resources
  }
Thanks for your reply, i have pasted this lot into a function ( void out_to_printer() ) and added the includes above void main, as you would. It is showing me 1 error at the following line:

pd.hwndOwner = hOwner;

The error reads:

error C2440: '=' : cannot convert from 'void *' to 'struct HWND__ *'

Further to this i'm not sure how to get the data output in this way, for invoice to screen i have used cout << "all my variables and text with endl's and all that kind of thing", for output to file i have similarly used a stream called outfp, so outfp << "an exact copy of what goes to screen". It would be great to use this method, but the data to output is not stored in a variable, rather it is constructed at the point of output, in runtime, so i don't know how to pass or reference the output using this code.

Sorry if i am waffling here but i am doing my best to explain with limited knowledge of C++ and programming lingo!

Again, thanks for all your help!
ASKER CERTIFIED SOLUTION
Avatar of Gary Benade
Gary Benade
Flag of South Africa image

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
Thanks for all your help, i have not actually tested the code above but i am accepting this as the answer. I have opted for naming the port.

Regards

s1desh0w