你要Dos打印还是Windows打印,并口,还是串口? <br> 都有。 <br> <br> <br> {*******************************************************} <br> { } <br> { Musicwind Delphi Development Package } <br> { DosPrinter Unit } <br> { } <br> { Copyright ( c ) 2000,2005 Musicwind } <br> { } <br> { History: } <br> { } <br> { Build with Delphi5, Musicwind [2000-03-??] } <br> { } <br> { TDosPrinter } <br> { } <br> {*******************************************************} <br> <br> unit DosPrinter; <br> <br> // Note: Only Be Ok in Win98, and the printer must be in <br> // lpt1, lpt2 or lpt3; <br> // And Be Sure your Windows does not install the printer <br> // <br> // User Guide: Just add this unit into the "uses" clause, then you may <br> // call LPT1.Write, LPT1.WriteLn, LTP1.WriteFmt directly to <br> // make output on the printer. (LPT2 is also supported). <br> // <br> // Limitation: This unit does not have error checking capabilities. <br> <br> // New added Guide: <br> // TDosPrinter; <br> // Can Check whether the printer is empty of paper, or <br> // printer does not linked, or other errors. <br> // <br> <br> interface <br> <br> uses Classes, SysUtils, Windows, MusicSys; <br> <br> type <br> // 并口号 <br> TDosLptPort = ( dpLpt1, dpLpt2, dpLpt3 ); <br> <br> // 错误类别, ( 未联机, 缺纸, 超时 ) <br> TErrType = ( etLinkLost, etLackPaper, etTimeout ); <br> <br> // 打印错误事件 <br> TErrMsgEvent = procedure(Sender: TObject; ErrType: TErrType; <br> var Retry: Boolean ) of object; <br> <br> TDosPrinter = class <br> private <br> FLptPort: TDosLptPort; <br> FOnErr: TErrMsgEvent; <br> FblActive: Boolean; <br> protected <br> <br> public <br> Constructor Create; <br> <br> procedure BeginDoc; <br> procedure EndDoc; <br> procedure DoDoubleWidth( bl: Boolean ); <br> procedure DoDoubleHeight( bl: Boolean ); <br> procedure DoBold( bl: Boolean ); <br> procedure ChineseMode; <br> procedure DoExpress( bl: Boolean ); <br> procedure CR; <br> procedure Writeln( sLine: string ); <br> procedure Write( sLine: string ); <br> function WriteChar( Achar: char ): Boolean; <br> procedure MovePaper( iSize: integer ); <br> <br> property Active: Boolean read FblActive; <br> property LptPort: TDosLptPort read FLptPort write FLptPort; <br> property OnErr: TErrMsgEvent read FOnErr write FOnErr; <br> <br> end; <br> <br> function DosLpt1: TDosPrinter; <br> function DosLpt2: TDosPrinter; <br> <br> implementation <br> <br> var <br> _DosLpt1: TDosPrinter = nil; <br> _DosLpt2: TDosPrinter = nil; <br> <br> function DosLpt1: TDosPrinter; <br> begin <br> if not Assigned( _DosLpt1 ) then <br> begin <br> _DosLpt1 := TDosPrinter.Create; <br> _DosLpt1.LptPort := dpLpt1; <br> end; <br> result := _DosLpt1; <br> end; <br> <br> function DosLpt2: TDosPrinter; <br> begin <br> if not Assigned( _DosLpt2 ) then <br> begin <br> _DosLpt2 := TDosPrinter.Create; <br> _DosLpt2.LptPort := dpLpt2; <br> end; <br> result := _DosLpt2; <br> end; <br> <br> { TDosPrinter } <br> <br> procedure TDosPrinter.BeginDoc; <br> begin <br> // Do nothing ... <br> end; <br> <br> procedure TDosPrinter.ChineseMode; <br> begin <br> Write( #28 + '&' ); <br> end; <br> <br> procedure TDosPrinter.CR; <br> begin <br> Write( #13 ); <br> end; <br> <br> constructor TDosPrinter.Create; <br> begin <br> FLptPort := dpLpt1; <br> FblActive := True; <br> end; <br> <br> procedure TDosPrinter.DoBold(bl: Boolean); <br> begin <br> if bl then <br> Write( #27 + 'E' ) <br> else <br> Write( #27 + 'F' ); <br> end; <br> <br> procedure TDosPrinter.DoDoubleHeight(bl: Boolean); <br> begin <br> if bl then <br> Write( #27 + 'w' + #1 ) <br> else <br> Write( #27 + 'w' + #0 ); <br> end; <br> <br> procedure TDosPrinter.DoDoubleWidth(bl: Boolean); <br> begin <br> if bl then <br> Write( #27 + 'W' + #1 ) <br> else <br> Write( #27 + 'W' + #0 ); <br> end; <br> <br> procedure TDosPrinter.DoExpress(bl: Boolean); <br> begin <br> if bl then <br> Write( #28 + 'x' + #1 ) <br> else <br> Write( #28 + 'x' + #0 ); <br> end; <br> <br> procedure TDosPrinter.EndDoc; <br> begin <br> // Do nothing ... <br> end; <br> <br> procedure TDosPrinter.MovePaper(iSize: integer); <br> begin <br> Write( #27 + 'J' + char( iSize mod 255 ) ); <br> end; <br> <br> procedure TDosPrinter.Write(sLine: string); <br> var <br> index: longint; <br> begin <br> for Index := 1 to length( sLine ) do <br> if not WriteChar( sLine[Index] ) then <br> Break; <br> end; <br> <br> function TDosPrinter.WriteChar( AChar: char): Boolean; <br> var <br> byteChar, byteStatus: Byte; <br> wordLpt: Word; <br> bPaperOut, bSelected, bIOError, bTimeOut, bOK: Boolean; <br> // below is new added by Musicwind, 2001-02-08 <br> FErrType: TErrType; <br> Retry: Boolean; <br> dwTimeOut: DWORD; <br> begin <br> result := False; <br> <br> if not mscIsWin98 then <br> begin <br> FblActive := result; <br> Exit; <br> end; <br> <br> byteChar := byte( AChar ); <br> if FLptPort = dpLpt1 then <br> wordLpt := 0 else <br> if FLptPort = dpLpt2 then <br> wordLpt := 1 else <br> if FLptPort = dpLpt3 then <br> wordLpt := 2 <br> else <br> wordLpt := 0; <br> repeat <br> retry := False; <br> <br> byteStatus := $40; <br> while (( byteStatus and $80 ) = 0 ) and (( byteStatus and $40 ) <> 0 ) do <br> asm <br> MOV AH, 0 <br> MOV DX, wordLpt <br> MOV AL, byteChar <br> INT 17H <br> MOV byteStatus, AH <br> end; <br> <br> bTimeOut := ( byteStatus and $01 ) <> 0; <br> bIOError := ( byteStatus and $08 ) <> 0; <br> bSelected := ( byteStatus and $10 ) <> 0; <br> bPaperOut := ( byteStatus and $20 ) <> 0; <br> <br> if bTimeOut then <br> FErrType := etTimeOut <br> else <br> if bSelected and bPaperOut and bIOError then <br> FErrType := etLackPaper <br> else <br> if bSelected and bPaperOut or bIOError then <br> FErrType := etLinkLost <br> else <br> begin <br> // Print content <br> result := True; <br> <br> end; <br> <br> if not result then <br> begin <br> Retry := False; <br> if Assigned( FOnErr ) then <br> begin <br> Retry := True; <br> FOnErr( Self, FErrType, Retry ); <br> end; <br> end; <br> until result or not Retry; <br> FblActive := result; <br> if not FblActive then <br> raise Exception.Create( '打印出错!' ); <br> end; <br> <br> procedure TDosPrinter.Writeln(sLine: string); <br> begin <br> Write( sLine + #13#10 ); <br> end; <br> <br> initialization <br> <br> finalization <br> <br> end. <br> <br> <br> <br> {*******************************************************} <br> { } <br> { Musicwind Delphi Development Package } <br> { Lpt Unit } <br> { } <br> { Copyright ( c ) 2000,2005 Musicwind } <br> { } <br> { History: } <br> { } <br> { Build with Delphi5, Musicwind [2000-12-18] } <br> { } <br> { TLpt <br> { TLptStream <br> { TEpson300K <br> { } <br> {*******************************************************} <br> unit LPT; <br> <br> // Note: Only Be Ok in WinNt or later OS <br> // And Be Sure your Windows does not install the printer <br> // <br> // User Guide: Just add this unit into the "uses" clause, then you may <br> // call LPT1.Write, LPT1.WriteLn, LTP1.WriteFmt directly to <br> // make output on the printer. (LPT2 is also supported). <br> // <br> // Limitation: This unit does not have error checking capabilities. <br> <br> // New added Guide: <br> // TEpson300K; <br> // added for Epson 300K , by Musicwind, at 2000-12-18 <br> // <br> <br> interface <br> <br> uses Classes, SysUtils, Windows, SyncObjs; <br> <br> type <br> <br> TLPT = class <br> protected <br> FDeviceName: string; <br> FHandle: THandle; <br> FEvent: TSimpleEvent; <br> FOverlap: TOverlapped; <br> procedure SetActive(Value: Boolean); <br> procedure SetDeviceName(AName: string); <br> function GetActive: Boolean; <br> public <br> constructor Create; virtual; <br> destructor Destroy; override; <br> procedure Open; <br> procedure Close; <br> procedure WriteBuf(const Buf: PChar; Len: Integer); <br> procedure Write(const AString: string); <br> procedure WriteLn(const AString: string); <br> procedure WriteFmt(const FmtStr: string; Args: array of const); <br> property Active: Boolean read GetActive write SetActive; <br> property Handle: THandle read FHandle; <br> published <br> property DeviceName: string read FDeviceName write SetDeviceName; <br> end; <br> <br> TLPTStream = class(TStream) <br> public <br> function Read(var Buffer; Count: Longint): Longint; override; <br> function Write(const Buffer; Count: Longint): Longint; override; <br> function Seek(Offset: Longint; Origin: Word): Longint; override; <br> procedure WriteLn(const S: string); <br> end; <br> <br> TEpson300K = class ( TLpt ) <br> private <br> FiPageHeight: integer; // 一页的高度( 单位:英寸 ) <br> FblChinese: Boolean; // 汉字打印模式 <br> FblExpress: Boolean; // 高速打印模式 <br> procedure SetFiPageHeight(const Value: integer); // 页长度, 单位( 英寸 ) <br> <br> public <br> constructor Create; override; <br> <br> procedure BeginDoc; // 开始一个文档 <br> procedure EndDoc; // 结束.... <br> procedure BeginPage; // 开始页 <br> procedure EndPage; // 结束页 <br> procedure BeginBold; // 开始粗体 <br> procedure EndBold; // 结束粗体 <br> <br> procedure MovePaper( iHeight: integer ); <br> procedure DoubleHeight(bl: Boolean); <br> procedure DoubleWidth(bl: Boolean); <br> <br> <br> property PageHeight: integer read FiPageHeight write SetFiPageHeight; <br> property ChineseMode: Boolean read FblChinese write FblChinese; <br> property ExpressMode: Boolean read FblExpress write FblExpress; <br> end; <br> <br> function LPT1: TLPT; <br> function LPT2: TLPT; <br> <br> function Epson300k1: TEpson300k; <br> function Epson300k2: TEpson300k; <br> <br> <br> implementation // =========================================================== <br> <br> var <br> <br> _LPT1: TLPT = nil; <br> _LPT2: TLPT = nil; <br> _Epson300k1: TEpson300k = nil; <br> _Epson300k2: TEpson300k = nil; <br> <br> <br> { TLPT } <br> <br> constructor TLPT.Create; <br> begin <br> FDeviceName := 'LPT1'; <br> FEvent := TSimpleEvent.Create; <br> FOverlap.hEvent := FEvent.Handle; <br> end; <br> <br> destructor TLPT.Destroy; <br> begin <br> Active := False; <br> inherited; <br> end; <br> <br> procedure TLPT.SetActive(Value: Boolean); <br> begin <br> if Value = Active then exit; <br> if Value then begin <br> FHandle := CreateFile(PChar(FDeviceName), GENERIC_WRITE, <br> FILE_SHARE_READ or FILE_SHARE_WRITE, nil, <br> OPEN_EXISTING, FILE_FLAG_NO_BUFFERING or FILE_FLAG_OVERLAPPED, 0); <br> end <br> else begin <br> CloseHandle(FHandle); <br> FHandle := INVALID_HANDLE_VALUE; <br> end; <br> end; <br> <br> procedure TLPT.SetDeviceName(AName: string); <br> begin <br> Active := False; <br> FDeviceName := AName; <br> end; <br> <br> function TLPT.GetActive: Boolean; <br> begin <br> Result := FHandle <> INVALID_HANDLE_VALUE; <br> end; <br> <br> procedure TLPT.Open; <br> begin <br> Active := True; <br> end; <br> <br> procedure TLPT.Close; <br> begin <br> Active := False; <br> end; <br> <br> procedure TLPT.WriteBuf(const Buf: PChar; Len: Integer); <br> var <br> Num: Integer; <br> begin <br> if Active = False then <br> Active := True; <br> if Active and (Len > 0) then <br> WriteFile(FHandle, Buf^, Cardinal( Len ), Cardinal( Num ), @FOverlap); <br> end; <br> <br> procedure TLPT.Write(const AString: string); <br> begin <br> WriteBuf(PChar(AString), Length(AString)); <br> end; <br> <br> procedure TLPT.WriteLn(const AString: string); <br> const <br> CRLF: array[0..1] of Char = (#13, #10); <br> begin <br> <br> WriteBuf(PChar(AString), Length(AString)); <br> WriteBuf(CRLF, 2); <br> end; <br> <br> procedure TLPT.WriteFmt(const FmtStr: string; Args: array of const); <br> begin <br> Write(Format(FmtStr, Args)); <br> end; <br> <br> function TLPTStream.Read(var Buffer; Count: Longint): Longint; <br> begin <br> Result := 0; <br> end; <br> <br> function TLPTStream.Write(const Buffer; Count: Longint): Longint; <br> begin <br> Result := Count; <br> if Count > 0 then <br> LPT1.WriteBuf(PChar(@Buffer), Count); <br> end; <br> <br> function TLPTStream.Seek(Offset: Longint; Origin: Word): Longint; <br> begin <br> Result := 0; <br> end; <br> <br> procedure TLPTStream.WriteLn(const S: string); <br> begin <br> LPT1.WriteLn(S); <br> end; <br> <br> <br> // ========================================================================== <br> <br> function LPT1: TLPT; <br> begin <br> if _LPT1 = nil then begin <br> _LPT1 := TLPT.Create; <br> _LPT1.DeviceName := 'LPT1'; <br> _LPT1.Active := True; <br> end; <br> Result := _LPT1; <br> end; <br> <br> function Epson300k1: TEpson300k; <br> begin <br> if _Epson300k1 = nil then <br> begin <br> _Epson300k1 := TEpson300k.Create; <br> _Epson300k1.DeviceName := 'LPT1'; <br> _Epson300k1.Active := True; <br> end; <br> result := _Epson300k1; <br> end; <br> <br> function Epson300k2: TEpson300k; <br> begin <br> if _Epson300k2 = nil then <br> begin <br> _Epson300k2 := TEpson300k.Create; <br> _Epson300k2.DeviceName := 'LPT2'; <br> _Epson300k2.Active := True; <br> end; <br> result := _Epson300k2; <br> end; <br> <br> <br> function LPT2: TLPT; <br> begin <br> if _LPT2 = nil then begin <br> _LPT2 := TLPT.Create; <br> _LPT2.DeviceName := 'LPT2'; <br> _LPT2.Active := True; <br> end; <br> Result := _LPT2; <br> end; <br> <br> // ========================================================================== <br> <br> { TEpson300K } <br> <br> procedure TEpson300K.BeginBold; <br> begin <br> Write( #27 + 'E' ); <br> end; <br> <br> procedure TEpson300K.DoubleWidth( bl: Boolean ); <br> begin <br> if bl then <br> Write( #27 + 'W' + #1 ) <br> else <br> Write( #27 + 'W' + #0 ); <br> end; <br> <br> procedure TEpson300K.DoubleHeight( bl: Boolean ); <br> begin <br> if bl then <br> Write( #27 + 'w' + #1 ) <br> else <br> Write( #27 + 'w' + #0 ); <br> <br> end; <br> <br> procedure TEpson300K.BeginDoc; <br> begin <br> Active := True; <br> if FblChinese then <br> Write( #28 + '&' ) ; // 设定汉字打印模式 <br> if FblExpress then <br> Write( #28 + 'x' + #1 ) <br> else <br> Write( #28 + 'x' + #0 ); <br> end; <br> <br> procedure TEpson300K.BeginPage; <br> begin <br> if ( FiPageHeight >= 1 ) and ( FiPageHeight <= 22 ) then <br> begin <br> Write( #27 + 'C' + #0 + Char( FiPageHeight ) ) ; <br> Write( #27 + '$' + #0 + #0 ); // 设定绝对位置为 y=0, x=0 <br> end; <br> end; <br> <br> constructor TEpson300K.Create; <br> begin <br> inherited; <br> FiPageHeight := 0; <br> FblChinese := True; <br> FblExpress := False; <br> end; <br> <br> procedure TEpson300K.EndBold; <br> begin <br> Write( #27 + 'F' ); <br> end; <br> <br> procedure TEpson300K.EndDoc; <br> begin <br> Active := False; <br> end; <br> <br> procedure TEpson300K.EndPage; <br> begin <br> if FiPageHeight <> 0 then <br> Write( #12 ); <br> end; <br> <br> procedure TEpson300K.MovePaper(iHeight: integer); <br> begin <br> Writeln( #27 + 'J' + char( iHeight mod 255 ) ); <br> end; <br> <br> procedure TEpson300K.SetFiPageHeight(const Value: integer); <br> begin <br> FiPageHeight := Value mod 22; <br> end; <br> <br> initialization <br> finalization <br> if _LPT1 <> nil then _LPT1.Free; <br> if _LPT2 <> nil then _LPT2.Free; <br> <br> if _Epson300k1 <> nil then _Epson300k1.Free; <br> if _Epson300k2 <> nil then _Epson300k2.Free; <br> <br> end.