The Joel on Software Discussion Group (CLOSED)A place to discuss Joel on Software. Now closed. |
||
|
This community works best when people use their real names. Please
register for a free account.
Other Groups: Joel on Software Business of Software Design of Software (CLOSED) .NET Questions (CLOSED) TechInterview.org CityDesk FogBugz Fog Creek Copilot The Old Forum Your hosts: Albert D. Kallal Li-Fan Chen Stephen Jones |
I am trying to print to the printer. I am using a VC++ 6.0 compiler on Win 2K, but I get an error saying that stdprn is not defined. Why is that? Is it because of Windows, I am guessing? Do I have to use only the GDI32 functions for printing under Windows? Can I not use the stdprn under Windows to print from memory to the window?
Ok, in traditional C programming for consoles and character mode devices, stdprn means "the standard printer" - right. I never really thought about this after making the transition to Windows programming, but things should work analogously to DOS.
I just did an experiment (Windows XP.) Opened a DOS window, and entered the following: C:\>copy con prn: ashdaskjhdlaksjdhaslkdh as;das;ldkja;lskdj;laksdj aslkdj;laskjd;laskdj ^Z 1 file(s) copied. C:\ And lo and behold, the printer light started to flash. Now, what is complaining that stdprn is undefined? The compiler? If so, my guess is that if you changed your code to do an fopen() of "PRN:" and fprintf()'d against the file handle, you'd see what you are wanting. (I suppose that the currently selected default Windows printer is being used as the destination of PRN:.)
Thanks for undeleting this post, Joel. And thanks for replying, BB.
Yes, I didn't fopen the printer device because the book I am reading, "Let Us C" by an Indian author, Yashwant Kanetkar, says that these five streams are always open by default. Then later, I tried doing that as well. I tried to open a network printer using the LPT1 or PRN I/O devices, but my program hung there, and I had to Ctr+C to kill the process. What's all this about?
Nice guess, BB.
From the VC++ 6.0 help.... Sending Output to a Printer Last reviewed: July 22, 1997 Article ID: Q23976 5.10 6.00 6.00a 6.00ax 7.00 | 1.00 1.50 | 1.00 2.00 2.10 4.00 MS-DOS | WINDOWS | WINDOWS NT kbprg kbfasttip The information in this article applies to: Microsoft C for MS-DOS, versions 5.1, 6.0, 6.0a, and 6.0ax Microsoft C/C++ for MS-DOS, version 7.0 Microsoft Visual C++ for Windows, versions 1.0 and 1.5 Microsoft Visual C++ 32-bit Edition, versions 1.0, 2.0, and 4.0 SUMMARY This article presents three methods an application can use to send output to a printer. MORE INFORMATION Method 1 The first method uses the fprintf() function with the preopened "stdprn" stream. The following code example demonstrates this technique: #include <stdio.h> main() { fprintf(stdprn, "a line of text\n"); } This method works only in the MS-DOS operating system because the "stdprn" stream is not defined by Microsoft Windows or Microsoft Windows NT. Method 2 Another method uses the fopen() function to open the LPT1, LPT2, or PRN device as a file and uses the fprintf() function to write data to the file handle returned by fopen(). The following code example demonstrates this technique: #include <stdio.h> main() { FILE *stream; stream = fopen("PRN", "w"); fprintf(stream, "a line of text\n"); } This method works in Windows NT as well as the MS-DOS and Windows operating systems. Method 3 Finally, in MS-DOS, an application can use the int86() or int86x() functions to call one of the following BIOS printer services provided by Interrupt 17h: service 0: send byte to the printer. service 1: initialize the printer. service 2: get printer status. REFERENCES For more information on the int86() and int86x() functions, refer to the Microsoft C "Run-Time Library Reference" manual.
Nice summary on PRN.
I believe these methods only work on locally connected (parallel port) printers. If you want to use the Windows 'Print' interface, you'll need to go through more hoops. The 'winspool.drv' DLL is where most of the helpful, low-level stuff to send to a networked printer through the Windows interface is put. Calls I've used (under VB, unfortunately) Private Declare Function OpenPrinter Lib "winspool.drv" Alias "OpenPrinterA" _ (ByVal PrinterName As String, PrinterHandleRet As Long, _ ByVal pDefault As Long) As Long Private Declare Function StartDocPrinter Lib "winspool.drv" Alias "StartDocPrinterA" _ (ByVal hPrinter As Long, ByVal Level As Long, pDocInfo As DOC_INFO_1) As Long Private Declare Function StartPagePrinter Lib "winspool.drv" _ (ByVal hPrinter As Long) As Long Private Declare Function WritePrinter Lib "winspool.drv" _ (ByVal hPrinter As Long, pBuf As Any, ByVal cdBuf As Long, pcWritten As Long) As Long Private Declare Function EndDocPrinter Lib "winspool.drv" _ (ByVal hPrinter As Long) As Long Private Declare Function EndPagePrinter Lib "winspool.drv" _ (ByVal hPrinter As Long) As Long Private Declare Function ClosePrinter Lib "winspool.drv" _ (ByVal hPrinter As Long) As Long Hopefully, that will give you a place to start.
AllanL5 Wednesday, October 06, 2004
Oy, Sathayish, just saw "print to a window". I don't know that the Windows API supports this -- others may know more.
AllanL5 Wednesday, October 06, 2004
Thanks, people. I am still trying and do not have the answers yet.
AllanL5, those are the printing and spooling API under GDI32 that I was refering to. I've used them. But I was wondering if Standard C had any provision for device I/O to a printer. The book I was reading said, "well, yes!". I tried and it did not work. I guessed the same thing, the stdprn might not work under Windows because of the Hardware Abstraction Layer of Windows, which has given us another object to refer to a printer rather than a stream or I/O device - a Device Context. But that was going to be boring, because I'd already used it. R1ch, I tried the PRN thing also last night. Didn't work. My program hung and I had to kill the process (Ctrl+C). The printer I am refering to is a network printer, and is set up as my default printer. Thanks very much for your input, friends. More input welcome.
Are you perhaps trying to open the printer in 'raw' mode? So you can send any arbitrary data to the printer? Under Windows?
This can be done. The following VB opens a printer in 'binary' or 'raw' mode: Sub BinOpen(PrnFile As Long, PrnName As String, DocName As String, _ Status As Boolean) Dim RetVal As Long Dim JobID As Long Dim DocInfo As DOC_INFO_1 Status = OpenPrinter(PrnName, PrnFile, 0) ' .DeviceName is default If Status = 0 Then Exit Sub End If DocInfo.pDocName = DocName DocInfo.pOutputFile = vbNullString DocInfo.pDatatype = vbNullString JobID = StartDocPrinter(PrnFile, 1, DocInfo) Call StartPagePrinter(PrnFile) End Sub The following line prints to the PrnFile: LocString = OutString Status = WritePrinter(PrnFile, _ ByVal LocString, Len(LocString), NumWritten) The 'DocInfo' thing is: Private Type DOC_INFO_1 pDocName As String pOutputFile As String pDatatype As String End Type Put it all together, and now you can send arbitrary bytes to the printer. Of course, now you have to do all the HPGL commands yourself -- but maybe that's what you wanted to do?
AllanL5 Wednesday, October 06, 2004
>> But I was wondering if Standard C had any provision for device I/O to a printer. The book I was reading said, "well, yes!".
Throw away that book and get one that actually knows the standard. ISO Standard C (and K&R C before that) has only ever had 3 predefined files - stdin, stdout, and stderr. Microsoft added 2 more with their original C compiler - stdaux, and stdprn. stdaux went to the first serial port and stdprn went to the first printer port. Looking at the MSDN Library, there really hasn't been any mention of stdaux or stdprn since Windows went to 32bit.
Sathyaish,
forget all they said;) If you don't have Petzold, buy it. Combine his Printing example with MetaFile example and you have it all. Create a MetaFaile, draw into it, put text, bitmaps,... end then display it on screen or send it to printer or save it to a file, move it to the clipboard and paste it in any other app. You can even save metafiles in a database. When your'e done with it all, modify the part where you put text into a metafile and save a copy of that text in another buffer, so you can even collect it into separate xml or html document. Forget stdprn.
VPC Wednesday, October 06, 2004 |
|
Powered by FogBugz


