這個功能看起來挺奇葩的, 寫這個是因為有客戶在使用驅動連接票據打印機, 但是又要開錢箱, 驅動里只能每張單據都開錢箱, 而這個打印機又不是只打印結帳單
所以就需要用軟件控制打印機開錢箱
票據打印機一般都支持ESC/POS指令, 所以就出現了如下代碼, 通過這個函數可以吧ESC/POS指令里的開錢箱指令發送給打印機控制開錢箱
同樣, 也可以發送別的什么東西, 比如響響蜂鳴器之類的
哦 補充下, 這個代碼里使用的是默認打印機, 當然稍微改動下, 就可以先彈出個打印機列表, 然后選擇打印機傳進去, 這樣就可以控制任意打印機了
OpenPrinter(PChar(Printer.Printers[0]), nD, nPPD);
uses WinSpool, Printers; function WritePrtDataForDriver(AData: string; var AErrCode: Byte): Boolean; var nD: Cardinal; nPPD: PPrinterDefaults; nDocInfo: DOC_INFO_1; nDataLength: DWORD; nSize: DWORD; nReturn: Boolean; begin Result := False; AErrCode := 1; nD := INVALID_HANDLE_VALUE; nPPD := New(PPrinterDefaults); try with nPPD^ do begin DesiredAccess := PRINTER_ACCESS_USE; pDatatype := nil; pDevMode := nil; end; OpenPrinter(PChar(Printer.Printers[0]), nD, nPPD); finally Dispose(nPPD); end; if nD = INVALID_HANDLE_VALUE then Exit; with nDocInfo do begin pDocName := 'Print Document'; pOutputFile := nil; pDatatype := 'RAW'; end; AErrCode := 2; if StartDocPrinter(nD, 1, @nDocInfo) <= 0 then Exit; AErrCode := 3; if not StartPagePrinter(nD) then Exit; AErrCode := 4; nDataLength := Length(AData); nReturn := WritePrinter(nD, PChar(AData), nDataLength, nSize); if (not nReturn) or (nSize <> nDataLength) then Exit; AErrCode := 5; if not EndPagePrinter(nD) then Exit; AErrCode := 6; if not EndDocPrinter(nD) then Exit; AErrCode := 7; if not ClosePrinter(nD) then Exit; AErrCode := 0; Result := True; end;
附: 獲取驅動打印機狀態:
var i: Integer; nPRH: THandle; PrinterName:String; nBuff: array[0..8192] of Char; nSize: DWord; pInfo: PPrinterInfo2; begin Memo1.Lines.Clear; for i := 0 to Printer.Printers.Count - 1 do begin if OpenPrinter(PChar(Printer.Printers[i]), nPRH,nil) then begin if GetPrinter(nPRH, 2, @nBuff, SizeOf(nBuff), @nSize) then begin pInfo:=PPrinterInfo2(@nBuff); Memo1.Lines.Add('Device := ' + Printer.Printers[i]); Memo1.Lines.Add('Status := ' + inttostr(pInfo.Status)); Memo1.Lines.Add(''); end; end; ClosePrinter(nPRH); end; end;
