// Note: Only Be Ok in Win98, and the printer must be in
// lpt1, lpt2 or lpt3;
// And Be Sure your Windows does not install the printer
//
// User Guide: Just add this unit into the "uses" clause, then you may
// call LPT1.Write, LPT1.WriteLn, LTP1.WriteFmt directly to
// make output on the printer. (LPT2 is also supported).
//
// Limitation: This unit does not have error checking capabilities.
// New added Guide:
// TDosPrinter;
// Can Check whether the printer is empty of paper, or
// printer does not linked, or other errors.
//
interface
uses Classes, SysUtils, Windows, MusicSys;
type
// 并口号
TDosLptPort = ( dpLpt1, dpLpt2, dpLpt3 );
function DosLpt1: TDosPrinter;
function DosLpt2: TDosPrinter;
implementation
var
_DosLpt1: TDosPrinter = nil;
_DosLpt2: TDosPrinter = nil;
function DosLpt1: TDosPrinter;
begin
if not Assigned( _DosLpt1 ) then
begin
_DosLpt1 := TDosPrinter.Create;
_DosLpt1.LptPort := dpLpt1;
end;
result := _DosLpt1;
end;
function DosLpt2: TDosPrinter;
begin
if not Assigned( _DosLpt2 ) then
begin
_DosLpt2 := TDosPrinter.Create;
_DosLpt2.LptPort := dpLpt2;
end;
result := _DosLpt2;
end;
{ TDosPrinter }
procedure TDosPrinter.BeginDoc;
begin
// Do nothing ...
end;
procedure TDosPrinter.ChineseMode;
begin
Write( #28 + '&' );
end;
procedure TDosPrinter.CR;
begin
Write( #13 );
end;
constructor TDosPrinter.Create;
begin
FLptPort := dpLpt1;
FblActive := True;
end;
procedure TDosPrinter.DoBold(bl: Boolean);
begin
if bl then
Write( #27 + 'E' )
else
Write( #27 + 'F' );
end;
procedure TDosPrinter.DoDoubleHeight(bl: Boolean);
begin
if bl then
Write( #27 + 'w' + #1 )
else
Write( #27 + 'w' + #0 );
end;
procedure TDosPrinter.DoDoubleWidth(bl: Boolean);
begin
if bl then
Write( #27 + 'W' + #1 )
else
Write( #27 + 'W' + #0 );
end;
procedure TDosPrinter.DoExpress(bl: Boolean);
begin
if bl then
Write( #28 + 'x' + #1 )
else
Write( #28 + 'x' + #0 );
end;
procedure TDosPrinter.EndDoc;
begin
// Do nothing ...
end;
procedure TDosPrinter.MovePaper(iSize: integer);
begin
Write( #27 + 'J' + char( iSize mod 255 ) );
end;
procedure TDosPrinter.Write(sLine: string);
var
index: longint;
begin
for Index := 1 to length( sLine ) do
if not WriteChar( sLine[Index] ) then
Break;
end;
function TDosPrinter.WriteChar( AChar: char): Boolean;
var
byteChar, byteStatus: Byte;
wordLpt: Word;
bPaperOut, bSelected, bIOError, bTimeOut, bOK: Boolean;
// below is new added by Musicwind, 2001-02-08
FErrType: TErrType;
Retry: Boolean;
dwTimeOut: DWORD;
begin
result := False;
if not mscIsWin98 then
begin
FblActive := result;
Exit;
end;
byteChar := byte( AChar );
if FLptPort = dpLpt1 then
wordLpt := 0 else
if FLptPort = dpLpt2 then
wordLpt := 1 else
if FLptPort = dpLpt3 then
wordLpt := 2
else
wordLpt := 0;
repeat
retry := False;
byteStatus := $40;
while (( byteStatus and $80 ) = 0 ) and (( byteStatus and $40 ) <> 0 ) do
asm
MOV AH, 0
MOV DX, wordLpt
MOV AL, byteChar
INT 17H
MOV byteStatus, AH
end;
bTimeOut := ( byteStatus and $01 ) <> 0;
bIOError := ( byteStatus and $08 ) <> 0;
bSelected := ( byteStatus and $10 ) <> 0;
bPaperOut := ( byteStatus and $20 ) <> 0;
if bTimeOut then
FErrType := etTimeOut
else
if bSelected and bPaperOut and bIOError then
FErrType := etLackPaper
else
if bSelected and bPaperOut or bIOError then
FErrType := etLinkLost
else
begin
// Print content
result := True;
end;
if not result then
begin
Retry := False;
if Assigned( FOnErr ) then
begin
Retry := True;
FOnErr( Self, FErrType, Retry );
end;
end;
until result or not Retry;
FblActive := result;
if not FblActive then
raise Exception.Create( '打印出错!' );
end;
procedure TDosPrinter.Writeln(sLine: string);
begin
Write( sLine + #13#10 );
end;
initialization
finalization
end.
unit LPT;
// Note: Only Be Ok in WinNt or later OS
// And Be Sure your Windows does not install the printer
//
// User Guide: Just add this unit into the "uses" clause, then you may
// call LPT1.Write, LPT1.WriteLn, LTP1.WriteFmt directly to
// make output on the printer. (LPT2 is also supported).
//
// Limitation: This unit does not have error checking capabilities.
// New added Guide:
// TEpson300K;
// added for Epson 300K , by Musicwind, at 2000-12-18
//
destructor TLPT.Destroy;
begin
Active := False;
inherited;
end;
procedure TLPT.SetActive(Value: Boolean);
begin
if Value = Active then exit;
if Value then begin
FHandle := CreateFile(PChar(FDeviceName), GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE, nil,
OPEN_EXISTING, FILE_FLAG_NO_BUFFERING or FILE_FLAG_OVERLAPPED, 0);
end
else begin
CloseHandle(FHandle);
FHandle := INVALID_HANDLE_VALUE;
end;
end;
procedure TLPT.SetDeviceName(AName: string);
begin
Active := False;
FDeviceName := AName;
end;
function TLPT.GetActive: Boolean;
begin
Result := FHandle <> INVALID_HANDLE_VALUE;
end;
procedure TLPT.Open;
begin
Active := True;
end;
procedure TLPT.Close;
begin
Active := False;
end;
procedure TLPT.WriteBuf(const Buf: PChar; Len: Integer);
var
Num: Integer;
begin
if Active = False then
Active := True;
if Active and (Len > 0) then
WriteFile(FHandle, Buf^, Cardinal( Len ), Cardinal( Num ), @FOverlap);
end;
procedure TLPT.Write(const AString: string);
begin
WriteBuf(PChar(AString), Length(AString));
end;
procedure TLPT.WriteLn(const AString: string);
const
CRLF: array[0..1] of Char = (#13, #10);
begin
function LPT1: TLPT;
begin
if _LPT1 = nil then begin
_LPT1 := TLPT.Create;
_LPT1.DeviceName := 'LPT1';
_LPT1.Active := True;
end;
Result := _LPT1;
end;
function Epson300k1: TEpson300k;
begin
if _Epson300k1 = nil then
begin
_Epson300k1 := TEpson300k.Create;
_Epson300k1.DeviceName := 'LPT1';
_Epson300k1.Active := True;
end;
result := _Epson300k1;
end;
function Epson300k2: TEpson300k;
begin
if _Epson300k2 = nil then
begin
_Epson300k2 := TEpson300k.Create;
_Epson300k2.DeviceName := 'LPT2';
_Epson300k2.Active := True;
end;
result := _Epson300k2;
end;
function LPT2: TLPT;
begin
if _LPT2 = nil then begin
_LPT2 := TLPT.Create;
_LPT2.DeviceName := 'LPT2';
_LPT2.Active := True;
end;
Result := _LPT2;
end;
function SysPrnStr(sPrnStr:string):Boolean;
begin
result:=false;
Case iVer of
1: //系统为Win98
begin
WinExec(PChar(sWinDir+'COMMAND.COM /C ECHO '+sPrnStr+'>PRN'),SW_HIDE);
Sleep(150);
end;
2: //系统为2000
begin
WinExec(PChar(sSysDir+'CMD.EXE /C ECHO '+sPrnStr+'>PRN'),SW_HIDE);
Sleep(150);
end;
end;
result:=true;
end;
可用CREATEFILE以PRN为文件名生成一个文件,检测返回值,若成功则打印机可用,否则显示打印机故障。生成关于PRN的文件句柄后,可象普通文件一样向文件写入内容,比如WRITE,写完后关闭文件。
//从并行端口读取打印机状态
function GetPrinterStatus:byte;
asm
MOV DX,$379;
IN AL,DX;
end;
//获取打印机是否出错
function CheckPrinter:boolean;
var
temp:byte;
begin
temp:=GetPrinterStatus;
Result:=not ( ((temp and $80)=0) //打印机忙
or ((temp and $20)<>0) //打印机缺纸
or ((temp and $10)=0) //打印机未联机
or ((temp and $08)=0) ); //打印机出错;
end;