通过调用dos下的ECHO命令来管道输出到打印机来实现,在win9x下调用dos是command.com,而在win2000下是用CMD.EXE 
可以试一下下面的语句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;Sleep(150);//这句话可以不要,不过如果是在pos销售时连接扣条码机,不用这句可能会出现
打印顺序错乱的情况    

解决方案 »

  1.   

    你是做POS机吧?这种程序一般是直接向打印机发送打印指令,多使用文本打印方式。完成打印机的初始化之后,直接把需要打印的文本写往打印端口就可以了。
      

  2.   

    随便挑了一段,自己改改吧procedure Tfrm_report.SBnClick(Sender: TObject);
    var
      Items: TStringList;
      tt   :string;
      i    : integer;
    begin
      printer.getprinter(adevice,adriver,aport,devicehandle);
      devmode:=globallock(devicehandle);
      with  devmode^ do
      begin  dmfields:=dmfields;
      dmpapersize :=DMPAPER_B4;  dmfields:=dmfields;
      dmorientation :=dmorient_portrait;{ dmfields:=dmfields;
      dmorientation :=dmorient_landscape;
      dmfields:=dmfields;
      dmpapersize :=DMPAPER_B5;
      dmfields:=dmPaperLength;
      dmPaperLength :=1820;
      dmfields:=dmPaperwidth;
      dmPaperwidth  :=2570;
    }
      end;   marginleft :=8;   fieldwd[0]:=2;
       fieldwd[1]:=12;
       fieldwd[2]:=6;
       fieldwd[3]:=5;
       fieldwd[4]:=6;
       fieldwd[5]:=5;
       fieldwd[6]:=5;
       fieldwd[7]:=6;
       fieldwd[8]:=5;
       fieldwd[9]:=6;
       fieldwd[10]:=6;
       fieldwd[11]:=6;
       fieldwd[12]:=6;
       fieldwd[13]:=6;    Items := TStringList.Create;
        // Determine pixels per inch horizontally
        PixelsInInchx := GetDeviceCaps(Printer.Handle, LOGPIXELSX);
        TenthsOfInchPixelsY := GetDeviceCaps(Printer.Handle,LOGPIXELSY) div 10;
        AmountPrinted := 0;
          Printer.BeginDoc;
          LineHeight := Printer.Canvas.TextHeight('X')+TenthsOfInchPixelsY;
          PrintHeader;
          PrintColumnNames;
          printtotal;
          recordprinted :=1;
          query_1.First;
          while (not query_1.Eof) do
          begin
            with Items do
            begin
    //          AddObject(tblClients.FieldByName('ZIP').AsString,
    //                        pointer(StrToInt(edtZip.Text)));
              AddObject(query_1.Fields.Fields[0].AsString,pointer(fieldwd[0]));
              AddObject(query_1.Fields.Fields[1].AsString,pointer(fieldwd[1]));
              AddObject(query_1.Fields.Fields[2].AsString,pointer(fieldwd[2]));
              for i := 3 to 13 do
              begin
              if query_1.Fields.Fields[i].asfloat <> 0 then
                  tt:=formatfloat('0.00',query_1.Fields.Fields[i].asfloat)
              else
                  tt:=' ';
              AddObject(tt,pointer(fieldwd[i]));
              end;
    {         AddObject(query_1.Fields.Fields[3].AsString,pointer(fieldwd[3]));
               .
               .
              AddObject(query_1.Fields.Fields[13].AsString,pointer(fieldwd[13]));
    }        end;
            PrintLine(Items);
            recordprinted :=recordprinted +1;
            if recordprinted  >= 16 then
    //        if AmountPrinted + LineHeight > Printer.PageHeight then
            begin
              AmountPrinted := 0;
              Printer.NewPage;
              PrintHeader;
              PrintColumnNames;
              recordprinted :=1;
            end;
            Items.Clear;
            query_1.Next;
          end;
            Printer.EndDoc;
        Items.Free;
    end;
      

  3.   

    补充:sSysdir和sWinDir实际上分别指window的system目录
      

  4.   

    好吧,我把我的贴一贴:
    提供一个98下的打印(Dos中断){*******************************************************}
    {                                                       }
    {       Musicwind Delphi Development Package            }
    {                  CommData Unit                        }
    {                                                       }
    {       Copyright ( c ) 2000,2005 Musicwind             }
    {                                                       }
    { History:                                              }
    {                                                       }
    {    Build with Delphi5, Musicwind    [2000-03-??]      }
    {                                                       }
    {    TDosPrinter - a class use with Comm32.dll          }
    {                                                       }
    {*******************************************************}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.
    //interfaceuses 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;
      
    implementationvar
       _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;initializationfinalizationend.
      

  5.   

    再贴一个 Win2000, Nt 下的并口打印:{*******************************************************}
    {                                                       }
    {       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
    //                                      interfaceuses 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;  if _Epson300k1 <> nil then _Epson300k1.Free;
      if _Epson300k2 <> nil then _Epson300k2.Free;end.