using System;using System.Collections.Generic;using System.Text;using System.Runtime.InteropServices;
namespace Barcode_Print{ class LPTControl { [StructLayout(LayoutKind.Sequential)] private struct OVERLAPPED { int Internal; int InternalHigh; int Offset; int OffSetHigh; int hEvent; }
[DllImport("kernel32.dll")] private static extern int CreateFile( string lpFileName, uint dwDesiredAccess, int dwShareMode, int lpSecurityAttributes, int dwCreationDisposition, int dwFlagsAndAttributes, int hTemplateFile );
[DllImport("kernel32.dll")] private static extern bool WriteFile( int hFile, byte[] lpBuffer, int nNumberOfBytesToWrite, out int lpNumberOfBytesWritten, out OVERLAPPED lpOverlapped );
[DllImport("kernel32.dll")] private static extern bool CloseHandle( int hObject );
private int iHandle; public bool Open() { iHandle = CreateFile("lpt1", 0x40000000, 0, 0, 3, 0, 0); if (iHandle != -1) { return true; } else { return false; }
}
public bool Write(String Mystring) {
if (iHandle != -1) { int i; OVERLAPPED x; byte[] mybyte = System.Text.Encoding.Default.GetBytes(Mystring); return WriteFile(iHandle, mybyte, mybyte.Length, out i, out x); } else { throw new Exception("端口未打开!"); } }
public bool Close() { return CloseHandle(iHandle); }
}
//并口通讯需要一个inpout32.DLL在程序中引用class IO{
[DllImport("inpout32.dll", EntryPoint = "Out32")] public static extern void Output(int adress, int value);
[DllImport("inpout32.dll", EntryPoint = "Inp32")] public static extern int Input(int adress); }
//Dim i As Integer Open "prn" For Output As #1 Print #1, "aaaa" For i = 0 To 30 Print #1, "" Next i Print #1, Spc(50); "a" Timer1.Enabled = True Close #1/你要Dos打印还是Windows打印,并口,还是串口? 都有。 {*******************************************************} { } { 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. /需要使用WinSpool API uses SysUtils, Printers, WinSpool; function SendDataToPrinter(sDeviceName, sDocName, sData: String): Boolean; //功能描述: 发送数据到打印机 //入口参数: // sDeviceName - 打印机名称 // sDocName - 打印文档名称 // sData - 发送的数据 //出口参数: // 返回值 - True表示成功, False表示失败 var bResult : Boolean; hPrinter : Cardinal; tDocInfo : _DOC_INFO_1A; iWrited : Cardinal; begin bResult := OpenPrinter(PChar(sDeviceName), hPrinter, nil); if bResult then begin tDocInfo.pDocName := PChar(sDocName); tDocInfo.pOutputFile := nil; tDocInfo.pDatatype := nil; bResult := StartDocPrinter(hPrinter, 1, @tDocInfo) <> 0; if bResult then begin bResult := StartPagePrinter(hPrinter); bResult := bResult and WritePrinter(hPrinter, @sData[1], Length(sData), iWrited); bResult := bResult and EndPagePrinter(hPrinter); EndDocPrinter(hPrinter); end; ClosePrinter(hPrinter); end; Result := bResult; end; procedure PrinterFeed(n: Integer); begin SendDataToPrinter('LQ-1600K', 'Feed', #27#100+ chr(n)); end;
