It does not work because serial communication involves a bit more than
blasting out bytes. Both partners need to use the same baud rate, the same
parity and data bit settings etc.. Then there is the question of
handshake and communication protocol. And what you do is a crime in Windows
anyway.
Install the Generic/Text only printer driver, create a printer in the
Printers applet for it, assign it the COM port and configure the port as
appropriate (consult the printers docs). Then select the printer with
Printer.PrinterIndex (or make it the default), open a textfile with
AssignPrn and write your text to that file.
The alternative would be to use one of the many serial comm components
around (or the API, not that easy) and use it to talk to the printer
directly.
Peter Below (TeamB) 10011...@compuserve.com)
No e-mail responses, please, unless explicitly requested!
Godfrey Fletcher <g...@mweb.co.za> wrote in message
news:7u7emr$kd...@forums.borland.com...
> I have been using assignfile to send text files to a printer on lpt1 which
> is working fine. Now I need to send the same text file to a printer
> connected to Com1. I changed the assignfile command to send the text file
> to Com1 but it just printers out junk.
> "AssignFile(PrintText, 'COM1'); Why doesnt this work? Win98. D5.
> Thanks
>
>
Your printer (or the driver) seems to interpret the standard lineend
character sequence #13#10, which a WriteLn will send to the printer, as two
linefeeds. If you cannot find a way to switch this off at the printer itself
try to use Write instead of WriteLn. This allows you to send a single #10 or
#13 character at the end of a line (you have to do this explicitely). You
may also have the problem that the lines you send are just long enough to
wrap on their own (the printer code used by AssignPrn wraps lines that are
longer than the page width), so the extra #13#10 WriteLn adds yields the
empty lines you see. If the lines can contain spaces at the end try to trim
them off before sending the line to the printer (see TrimRight in online
help).
Godfrey,
there seems to be some interference from the generic driver, i could reproduce
your problem on my system and directing the output to a file revealed that
somehow each #13 had been replaced by a #10, so instead of #13#10 the printer
sees a #10#10.
The only way i found to get around this is to not use AssignPrn but bypass the
driver completely by using WinSpool.WritePrinter.
Const
GenericPrinter: Pchar = 'Universal/Nur Text';
// Change to systems generic drivers name. Case matters!
procedure PrintFileToGeneric(const sFileName: string; ejectPage: boolean );
const
BufSize = 16384;
var
Count : Integer;
BytesWritten: DWORD;
hPrinter: THandle;
DocInfo: TDocInfo1;
f: file;
Buffer: Pointer;
ch: Char;
begin
if not WinSpool.OpenPrinter(GenericPrinter, hPrinter, nil) then
raise exception.create('Printer not found');
try
DocInfo.pDocName := 'MyDocument';
DocInfo.pOutputFile := Nil;
DocInfo.pDatatype := 'RAW';
if StartDocPrinter(hPrinter, 1, @DocInfo) = 0 then
Abort;
try
if not StartPagePrinter(hPrinter) then
Abort;
System.Assign(f, sFileName);
try
Reset(f, 1);
GetMem(Buffer, BufSize);
try
while not eof(f) do begin
Blockread(f, Buffer^, BufSize, Count);
if Count > 0 then begin
if not WritePrinter(hPrinter, Buffer, Count, BytesWritten) then
Abort;
end;
end;
finally
if ejectPage then begin
ch:= #12; //formfeed
WritePrinter( hPrinter, @ch, 1, BytesWritten );
end;
FreeMem(Buffer, BufSize);
end;
finally
EndPagePrinter(hPrinter);
System.Closefile( f );
end;
finally
EndDocPrinter(hPrinter);
end;
finally
WinSpool.ClosePrinter(hPrinter);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
printfiletogeneric( extractfilepath( paramstr(0))+'unit1.pas', true );
end;
Godfrey, try this function:
{+------------------------------------------------------------
| Function SetPrinterToPort
|
| Parameters :
| hPrinter: handle of printer to change, obtained from OpenPrinter
| port : port name to use, e.g. LPT1:, COM1:, FILE:
| Returns :
| the name of the previous port the printer was attached
| to.
| Description:
| Changes the port a printer is attached to using Win32 API
| functions. The changes made are NOT local to this process,
| they will affect all other processes that try to use this
| printer! It is recommended to set the port back to the
| old port returned by this function after the end of the
| print job.
| Error Conditions:
| Will raise EWin32Error exceptions if SetPrinter or GetPrinter
| fail.
| Created: 21.10.99 by P. Below
+------------------------------------------------------------}
Function SetPrinterToPort( hPrinter: THandle; Const port: String ): String;
Var
pInfo: PPrinterInfo2;
bytesNeeded: DWORD;
Begin
{ Figure out how much memory we need for the data buffer. Note that
GetPrinter is supposed to fail with a specific error code here.
The amount of memory will be larger than Sizeof(TPrinterInfo2)
since variable amounts of data are appended to the record! }
SetLastError( NO_ERROR );
GetPrinter( hPrinter, 2, Nil, 0, @bytesNeeded );
If GetLastError <> ERROR_INSUFFICIENT_BUFFER Then
RaiseLastWin32Error;
pInfo := AllocMem( bytesNeeded );
try
If not GetPrinter( hPrinter, 2, pInfo, bytesNeeded, @bytesNeeded ) Then
RaiseLastWin32Error;
With pInfo^ Do Begin
Result := pPortname;
pPortname := @port[1];
End;
If not SetPrinter( hPrinter, 2, pInfo, 0 ) Then
RaiseLastWin32Error;
finally
FreeMem( pInfo );
end;
End;
I am having some difficulty in getting the code you gave me to print, to
compile. I keep getting compliler errors. Some the errors are:
Undeclared identifier: TDocInfo1, Winspool, and
others related to printing.
Is there something missing in my uses section that I need to add?
Thanks
Well, you need to add Winspool <g>. That is the import unit for the
print-spooler related parts of the Windows API.
The *screen* resolution should have no effect on the printout. The printer
resolution may have one, however. Are all the machines using the same kind
of printer? How big are the deviations in spacing you see?
Have you tried to assign a specific font to Printer.Canvas.font after the
AssignPrn/Reset? If not it will use a default font (MS SansSerif 8 pt
usually) and that may indeed vary a bit between machines since it is not a
TrueType font. Try to use a true type font, Times New Roman or Arial, for
example.
The Graphics NG is also the Printing NG, though it doesn't show in the name.
You might try there. This is very mysterious...
PhR
Not really... Its based in part by the excellent piece of work
called Graphics.pas.
Joe
--
Borland Delphi and BCB TForm printing got you down? Try my
TExcellentFormPrinter!
Joe C. Hecht
http://home1.gte.net/joehecht/index.htm
So, what's the answer?
PhR
This is highly suspicious, since Courier is a fixed pitch font the space
character should have the same width than any other character in this font.
I never saw or heard of some problem like that and cannot think of a possible
cause, sorry.
Buy Joe's TExcellentWhatever component, for $99 (or $199 including source).
--
Rudy Velthuis
smart**s
Joe
--
>Rudy Velthuis wrote:
>> Buy Joe's TExcellentWhatever component, for $99 (or $199 including source).
>
>smart**s
Gee, thanks! I thought I was only smart at the other end.
--
Rudy Velthuis
If you are using the printer canvas, and setting the font
size using font.size, it doesn't always work correctly
across different printers. Go to the following link
http://www.efg2.com/lab/library/delphi/printing/default.htm
Question 5 deals directly with this, and you will find a
-LOT- of useful information on trying to make output printer
independent (even though this is virtually impossible, even
in the most trivial cases).
Thanks to Earl F. Glynn II for providing the site.
Jeff.
Probably the Font.PixelsPerInch problem...
Joe
--
Borland Delphi and BCB TForm printing got you down? Try my
TExcellentFormPrinter!
Peter's code is simply --
While not Eof( sourcefile ) Do Begin
ReadLn( sourcefile, S );
WriteLn( printfile, S );
End;
No canvas, no form, no DC, no nothin'. What pixels?
PhR