zoukankan      html  css  js  c++  java
  • Delphi 直接打印代码(不需要装打印机驱动)

    转:https://bbs.csdn.net/topics/127642

    {*******************************************************}
    {                                                       }
    {       Musicwind Delphi Development Package            }
    {                DosPrinter Unit                        }
    {                                                       }
    {       Copyright ( c ) 2000,2005 Musicwind             }
    {                                                       }
    { History:                                              }
    {                                                       }
    {    Build with Delphi5, Musicwind    [2000-03-??]      }
    {                                                       }
    {    TDosPrinter                                        }
    {                                                       }
    {*******************************************************}
    
    unit DosPrinter;
    
    //  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 );
    
      // 错误类别, ( 未联机, 缺纸, 超时 )  
      TErrType = ( etLinkLost, etLackPaper, etTimeout );
    
      // 打印错误事件
      TErrMsgEvent = procedure(Sender: TObject; ErrType: TErrType;
                         var Retry: Boolean ) of object;
    
      TDosPrinter = class
      private
         FLptPort: TDosLptPort;
         FOnErr: TErrMsgEvent;
         FblActive: Boolean;
      protected
    
      public
         Constructor Create;
    
         procedure BeginDoc;
         procedure EndDoc;
         procedure DoDoubleWidth( bl: Boolean );
         procedure DoDoubleHeight( bl: Boolean );
         procedure DoBold( bl: Boolean );
         procedure ChineseMode;
         procedure DoExpress( bl: Boolean );
         procedure CR;
         procedure Writeln( sLine: string );
         procedure Write( sLine: string );
         function WriteChar( Achar: char ): Boolean;
         procedure MovePaper( iSize: integer );
    
         property Active: Boolean read FblActive;
         property LptPort: TDosLptPort read FLptPort write FLptPort;
         property OnErr: TErrMsgEvent read FOnErr write FOnErr;
    
      end;
    
    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.
    
    
    
    {*******************************************************}
    {                                                       }
    {       Musicwind Delphi Development Package            }
    {                    Lpt Unit                           }
    {                                                       }
    {       Copyright ( c ) 2000,2005 Musicwind             }
    {                                                       }
    { History:                                              }
    {                                                       }
    {    Build with Delphi5, Musicwind    [2000-12-18]      }
    {                                                       }
    {    TLpt
    {    TLptStream
    {    TEpson300K
    {                                                       }
    {*******************************************************}
    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
    //                                      
    
    interface
    
    uses Classes, SysUtils, Windows, SyncObjs;
    
    type
    
      TLPT = class
      protected
        FDeviceName: string;
        FHandle: THandle;
        FEvent: TSimpleEvent;
        FOverlap: TOverlapped;
        procedure SetActive(Value: Boolean);
        procedure SetDeviceName(AName: string);
        function  GetActive: Boolean;
      public
        constructor Create; virtual;
        destructor Destroy; override;
        procedure Open;
        procedure Close;
        procedure WriteBuf(const Buf: PChar; Len: Integer);
        procedure Write(const AString: string);
        procedure WriteLn(const AString: string);
        procedure WriteFmt(const FmtStr: string; Args: array of const);
        property Active: Boolean read GetActive write SetActive;
        property Handle: THandle read FHandle;
      published
        property DeviceName: string read FDeviceName write SetDeviceName;
      end;
    
       TLPTStream = class(TStream)
      public
        function Read(var Buffer; Count: Longint): Longint; override;
        function Write(const Buffer; Count: Longint): Longint; override;
        function Seek(Offset: Longint; Origin: Word): Longint; override;
        procedure WriteLn(const S: string);
      end;
    
      TEpson300K = class ( TLpt )
      private
        FiPageHeight: integer; // 一页的高度( 单位:英寸 )
        FblChinese: Boolean;   // 汉字打印模式
        FblExpress: Boolean;   // 高速打印模式
        procedure SetFiPageHeight(const Value: integer); // 页长度, 单位( 英寸 )
    
      public
        constructor Create; override;
    
        procedure BeginDoc;  // 开始一个文档
        procedure EndDoc;    // 结束....
        procedure BeginPage; // 开始页
        procedure EndPage;   // 结束页
        procedure BeginBold; // 开始粗体
        procedure EndBold;   // 结束粗体
    
        procedure MovePaper( iHeight: integer );
        procedure DoubleHeight(bl: Boolean);
        procedure DoubleWidth(bl: Boolean);
    
    
        property PageHeight: integer read FiPageHeight write SetFiPageHeight;
        property ChineseMode: Boolean read FblChinese write FblChinese;
        property ExpressMode: Boolean read FblExpress write FblExpress;
      end;
    
    function LPT1: TLPT;
    function LPT2: TLPT;
    
    function Epson300k1: TEpson300k;
    function Epson300k2: TEpson300k;
    
    
    implementation  // ===========================================================
    
    var
    
      _LPT1: TLPT = nil;
      _LPT2: TLPT = nil;
      _Epson300k1: TEpson300k = nil;
      _Epson300k2: TEpson300k = nil;
    
    
    { TLPT }
    
    constructor TLPT.Create;
    begin
      FDeviceName := 'LPT1';
      FEvent := TSimpleEvent.Create;
      FOverlap.hEvent := FEvent.Handle;
    end;
    
    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
    
      WriteBuf(PChar(AString), Length(AString));
      WriteBuf(CRLF, 2);
    end;
    
    procedure TLPT.WriteFmt(const FmtStr: string; Args: array of const);
    begin
      Write(Format(FmtStr, Args));
    end;
    
    function TLPTStream.Read(var Buffer; Count: Longint): Longint;
    begin
      Result := 0;
    end;
    
    function TLPTStream.Write(const Buffer; Count: Longint): Longint;
    begin
      Result := Count;
      if Count > 0 then
        LPT1.WriteBuf(PChar(@Buffer), Count);
    end;
    
    function TLPTStream.Seek(Offset: Longint; Origin: Word): Longint;
    begin
      Result := 0;
    end;
    
    procedure TLPTStream.WriteLn(const S: string);
    begin
      LPT1.WriteLn(S);
    end;
    
    
    //  ==========================================================================
    
    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;
    
    //  ==========================================================================
    
    { TEpson300K }
    
    procedure TEpson300K.BeginBold;
    begin
       Write( #27 + 'E' );
    end;
    
    procedure TEpson300K.DoubleWidth( bl: Boolean );
    begin
       if bl then
          Write( #27 + 'W' + #1 )
       else
          Write( #27 + 'W' + #0 );
    end;
    
    procedure TEpson300K.DoubleHeight( bl: Boolean );
    begin
       if bl then
          Write( #27 + 'w' + #1 )
       else
          Write( #27 + 'w' + #0 );
    
    end;
    
    procedure TEpson300K.BeginDoc;
    begin
       Active := True;
       if FblChinese then
          Write( #28 + '&' ) ; // 设定汉字打印模式
       if FblExpress then
          Write( #28 + 'x' + #1 )
       else
          Write( #28 + 'x' + #0 );
    end;
    
    procedure TEpson300K.BeginPage;
    begin
       if ( FiPageHeight >= 1 ) and ( FiPageHeight <= 22 ) then
       begin
          Write( #27 + 'C' + #0 + Char( FiPageHeight ) ) ;
          Write( #27 + '$' + #0 + #0 ); // 设定绝对位置为 y=0, x=0
       end;
    end;
    
    constructor TEpson300K.Create;
    begin
       inherited;
       FiPageHeight := 0;
       FblChinese := True;
       FblExpress := False;
    end;
    
    procedure TEpson300K.EndBold;
    begin
       Write( #27 + 'F' );
    end;
    
    procedure TEpson300K.EndDoc;
    begin
       Active := False;
    end;
    
    procedure TEpson300K.EndPage;
    begin
       if FiPageHeight <> 0 then
          Write( #12 );  
    end;
    
    procedure TEpson300K.MovePaper(iHeight: integer);
    begin
       Writeln( #27 + 'J' + char( iHeight mod 255 ) );
    end;
    
    procedure TEpson300K.SetFiPageHeight(const Value: integer);
    begin
       FiPageHeight := Value mod 22;
    end;
    
    initialization
    finalization
      if _LPT1 <> nil then _LPT1.Free;
      if _LPT2 <> nil then _LPT2.Free;
    
      // new added by Musicwind , at 2000-12-18 13:16 于宁海京都
      if _Epson300k1 <> nil then _Epson300k1.Free;
      if _Epson300k2 <> nil then _Epson300k2.Free;
    
    end.

    {*******************************************************}
    {                                                       }
    {       Musicwind Delphi Development Package            }
    {                DosPrinter Unit                        }
    {                                                       }
    {       Copyright ( c ) 2000,2005 Musicwind             }
    {                                                       }
    { History:                                              }
    {                                                       }
    {    Build with Delphi5, Musicwind    [2000-03-??]      }
    {                                                       }
    {    TDosPrinter                                        }
    {                                                       }
    {*******************************************************}

    unit DosPrinter;

    //  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 );

      // 错误类别, ( 未联机, 缺纸, 超时 )  
      TErrType = ( etLinkLost, etLackPaper, etTimeout );

      // 打印错误事件
      TErrMsgEvent = procedure(Sender: TObject; ErrType: TErrType;
                         var Retry: Boolean ) of object;

      TDosPrinter = class
      private
         FLptPort: TDosLptPort;
         FOnErr: TErrMsgEvent;
         FblActive: Boolean;
      protected

      public
         Constructor Create;

         procedure BeginDoc;
         procedure EndDoc;
         procedure DoDoubleWidth( bl: Boolean );
         procedure DoDoubleHeight( bl: Boolean );
         procedure DoBold( bl: Boolean );
         procedure ChineseMode;
         procedure DoExpress( bl: Boolean );
         procedure CR;
         procedure Writeln( sLine: string );
         procedure Write( sLine: string );
         function WriteChar( Achar: char ): Boolean;
         procedure MovePaper( iSize: integer );

         property Active: Boolean read FblActive;
         property LptPort: TDosLptPort read FLptPort write FLptPort;
         property OnErr: TErrMsgEvent read FOnErr write FOnErr;

      end;

    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.



    {*******************************************************}
    {                                                       }
    {       Musicwind Delphi Development Package            }
    {                    Lpt Unit                           }
    {                                                       }
    {       Copyright ( c ) 2000,2005 Musicwind             }
    {                                                       }
    { History:                                              }
    {                                                       }
    {    Build with Delphi5, Musicwind    [2000-12-18]      }
    {                                                       }
    {    TLpt
    {    TLptStream
    {    TEpson300K
    {                                                       }
    {*******************************************************}
    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
    //                                      

    interface

    uses Classes, SysUtils, Windows, SyncObjs;

    type

      TLPT = class
      protected
        FDeviceName: string;
        FHandle: THandle;
        FEvent: TSimpleEvent;
        FOverlap: TOverlapped;
        procedure SetActive(Value: Boolean);
        procedure SetDeviceName(AName: string);
        function  GetActive: Boolean;
      public
        constructor Create; virtual;
        destructor Destroy; override;
        procedure Open;
        procedure Close;
        procedure WriteBuf(const Buf: PChar; Len: Integer);
        procedure Write(const AString: string);
        procedure WriteLn(const AString: string);
        procedure WriteFmt(const FmtStr: string; Args: array of const);
        property Active: Boolean read GetActive write SetActive;
        property Handle: THandle read FHandle;
      published
        property DeviceName: string read FDeviceName write SetDeviceName;
      end;

       TLPTStream = class(TStream)
      public
        function Read(var Buffer; Count: Longint): Longint; override;
        function Write(const Buffer; Count: Longint): Longint; override;
        function Seek(Offset: Longint; Origin: Word): Longint; override;
        procedure WriteLn(const S: string);
      end;

      TEpson300K = class ( TLpt )
      private
        FiPageHeight: integer; // 一页的高度( 单位:英寸 )
        FblChinese: Boolean;   // 汉字打印模式
        FblExpress: Boolean;   // 高速打印模式
        procedure SetFiPageHeight(const Value: integer); // 页长度, 单位( 英寸 )

      public
        constructor Create; override;

        procedure BeginDoc;  // 开始一个文档
        procedure EndDoc;    // 结束....
        procedure BeginPage; // 开始页
        procedure EndPage;   // 结束页
        procedure BeginBold; // 开始粗体
        procedure EndBold;   // 结束粗体

        procedure MovePaper( iHeight: integer );
        procedure DoubleHeight(bl: Boolean);
        procedure DoubleWidth(bl: Boolean);


        property PageHeight: integer read FiPageHeight write SetFiPageHeight;
        property ChineseMode: Boolean read FblChinese write FblChinese;
        property ExpressMode: Boolean read FblExpress write FblExpress;
      end;

    function LPT1: TLPT;
    function LPT2: TLPT;

    function Epson300k1: TEpson300k;
    function Epson300k2: TEpson300k;


    implementation  // ===========================================================

    var

      _LPT1: TLPT = nil;
      _LPT2: TLPT = nil;
      _Epson300k1: TEpson300k = nil;
      _Epson300k2: TEpson300k = nil;


    { TLPT }

    constructor TLPT.Create;
    begin
      FDeviceName := 'LPT1';
      FEvent := TSimpleEvent.Create;
      FOverlap.hEvent := FEvent.Handle;
    end;

    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

      WriteBuf(PChar(AString), Length(AString));
      WriteBuf(CRLF, 2);
    end;

    procedure TLPT.WriteFmt(const FmtStr: string; Args: array of const);
    begin
      Write(Format(FmtStr, Args));
    end;

    function TLPTStream.Read(var Buffer; Count: Longint): Longint;
    begin
      Result := 0;
    end;

    function TLPTStream.Write(const Buffer; Count: Longint): Longint;
    begin
      Result := Count;
      if Count > 0 then
        LPT1.WriteBuf(PChar(@Buffer), Count);
    end;

    function TLPTStream.Seek(Offset: Longint; Origin: Word): Longint;
    begin
      Result := 0;
    end;

    procedure TLPTStream.WriteLn(const S: string);
    begin
      LPT1.WriteLn(S);
    end;


    //  ==========================================================================

    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;

    //  ==========================================================================

    { TEpson300K }

    procedure TEpson300K.BeginBold;
    begin
       Write( #27 + 'E' );
    end;

    procedure TEpson300K.DoubleWidth( bl: Boolean );
    begin
       if bl then
          Write( #27 + 'W' + #1 )
       else
          Write( #27 + 'W' + #0 );
    end;

    procedure TEpson300K.DoubleHeight( bl: Boolean );
    begin
       if bl then
          Write( #27 + 'w' + #1 )
       else
          Write( #27 + 'w' + #0 );

    end;

    procedure TEpson300K.BeginDoc;
    begin
       Active := True;
       if FblChinese then
          Write( #28 + '&' ) ; // 设定汉字打印模式
       if FblExpress then
          Write( #28 + 'x' + #1 )
       else
          Write( #28 + 'x' + #0 );
    end;

    procedure TEpson300K.BeginPage;
    begin
       if ( FiPageHeight >= 1 ) and ( FiPageHeight <= 22 ) then
       begin
          Write( #27 + 'C' + #0 + Char( FiPageHeight ) ) ;
          Write( #27 + '$' + #0 + #0 ); // 设定绝对位置为 y=0, x=0
       end;
    end;

    constructor TEpson300K.Create;
    begin
       inherited;
       FiPageHeight := 0;
       FblChinese := True;
       FblExpress := False;
    end;

    procedure TEpson300K.EndBold;
    begin
       Write( #27 + 'F' );
    end;

    procedure TEpson300K.EndDoc;
    begin
       Active := False;
    end;

    procedure TEpson300K.EndPage;
    begin
       if FiPageHeight <> 0 then
          Write( #12 );  
    end;

    procedure TEpson300K.MovePaper(iHeight: integer);
    begin
       Writeln( #27 + 'J' + char( iHeight mod 255 ) );
    end;

    procedure TEpson300K.SetFiPageHeight(const Value: integer);
    begin
       FiPageHeight := Value mod 22;
    end;

    initialization
    finalization
      if _LPT1 <> nil then _LPT1.Free;
      if _LPT2 <> nil then _LPT2.Free;

      // new added by Musicwind , at 2000-12-18 13:16 于宁海京都
      if _Epson300k1 <> nil then _Epson300k1.Free;
      if _Epson300k2 <> nil then _Epson300k2.Free;

    end.

  • 相关阅读:
    springboot Quartz 定时任务工具类
    java 发邮件 代码
    spring boot 整合 shiro 权限框架
    java 读取xml
    flowable 报错 Waiting for changelog lock....
    微服务 springcloud Alibaba 阿里组件 项目源码
    Java 读取汉字拼音
    syslog how to
    c++ 字符串总结
    aptget 总结
  • 原文地址:https://www.cnblogs.com/CipherLab/p/13064307.html
Copyright © 2011-2022 走看看