![]() |
AW: Kassenlade öffnen
die kassenladen ist über einen thermodrucker tpg Color a795 angeschlossen und ist über com1 erreichbar. zumindest habe ich die kasse schonmal aufbekommen aber er druckte ein 2 cm streifen und machte nen cut. also com1 muss angesprochen werden.
|
AW: Kassenlade öffnen
Und wieso sagt das keiner, während hier ständig versucht wird über LPT, anstatt über COM zu gehn?
Wenn der "Steuer-Code" stimmt, dann entweder über deine ComPort-Komponente den "Text" senden, oder über meine beiden Beispielcodes, welche nicht über TPrinter gingen. (da halt "COM1", statt "LPT1") Aber wenn der Drucker die Steuerzeichen, welche eigentlich nicht für ihn sind, obwohl sie an ihn geschickt werden, nicht rausfiltert, dann kann man eben die druchausgabe nicht unterbinden. |
AW: Kassenlade öffnen
Taucht dieser Drucker den in
Delphi-Quellcode:
auf?
Printer.Printers
Und bist Du sicher,daß da wirklich ein Drucker installiert ist? Unter Windoofs muß ein angeschlossener Drucker (der Stecker ist drin!) auch im/dem System als Drucker bekannt gemacht werden. (und wenn Dein Drucker an COM1 hängt, dann funktionieren die Beispiele mit
Delphi-Quellcode:
natürlich nicht. dann solltest Du ggf. mit
assignfile(tf,'LPT1:');
rewrite(tf); write(tf,#27#.....); closefile(tf);
Delphi-Quellcode:
arbeiten.
assignfile(tf,'LPT1:');
Gruß K-H |
AW: Kassenlade öffnen
wie kriege ich das umgesetzt und wo muss ich den code hin tipseln
|
AW: Kassenlade öffnen
also mit diesem code öffnet er die kassenlade schiebt aber einen 2 cm streifen raus und cuttet ihn.
Delphi-Quellcode:
type
TPassThroughData = record nLen : Integer; Data : array[0..255] of byte; end; procedure DirectPrint(s:string); var PTBlock : TPassThroughData; begin PTBlock.nLen := length(s); StrPCopy(@PTBlock.Data, s); Escape(Printer.Handle, PASSTHROUGH, 0, @PTBlock, nil); end; procedure TForm1.Button2Click(Sender: TObject); begin Printer.BeginDoc; DirectPrint(#27 + 'p' + #0 + #50 + #50); Printer.EndDoc; end; |
AW: Kassenlade öffnen
Auf die Gefahr hin mich zu wiederholen Schau dir die Beispiele hier im Forum an!
Nix Printer.xxx es muss direkt mit dem Drucker kommuniziert werden! |
AW: Kassenlade öffnen
Deine Schublade öffnet z.Z. nur weil Du das im Druckertreiber eingestellt hast: dein Programm geht nicht!
Die Öffnet auch, wenn Du "Hallo Welt" zum Drucker schickst :cyclops: |
AW: Kassenlade öffnen
Es sollte viellecht erst einmal eine Entscheidung getroffen werden, ob jetzt über die COM Schnittstelle direkt, oder über den offenbar vorhandenen Druckertreiber kommuniziert werden soll. Das sollte auf keinen Fall vermischt werden!
|
AW: Kassenlade öffnen
am besten direkt die com schnittstelle.
|
AW: Kassenlade öffnen
Dann sind alle Zeilen, die in irgend einer Weise "Printer." beinhalten schon mal passé, und du brauchst eine Dokumentation über das Protokoll, dass der Drucker erwartet. Sonst bleibt's hier beim Rätselraten.
|
AW: Kassenlade öffnen
programming guide und die ganzen ASCII codes habe ich
um die kassenlade zu öffnen soll dieser ASCII code genommen werden ESC p m t1 t2 |
AW: Kassenlade öffnen
Dann nimm besser eine Seriell-Komponente und kommuniziere direkt über den COM-Port des Druckers.
|
AW: Kassenlade öffnen
Zitat:
Ich biete in meiner Kassensoftware an, direkte Ansteuerung von COM, Ansteuerung via separates Programm (liefern manche Ladenöffner mit), Ansteuerung via "ich drucke was aus" und die Lade öffnet sich via Druckertreiber, OPOS Ansteuerung und ich gebe direkt die Steuerbefehle via Druckertreiber an den Drucker (das ist was Natcree hier versucht -> hier im Forum gibt es aber einen guten Beitrag mit Beispiel von diesem Jahr, das genau das macht). |
AW: Kassenlade öffnen
Zitat:
s:=#27+'p'+#48'pz'; t1 und t2 sind Zeiten in msec die für Steuerung die die Schublade entriegelt wird, die Werte muss man ggf mal testen, je nach Hardware |
@Natcree
Der Record ist falsch deklariert. Natürlich funktioniert das nur, wenn ein Druckertreiber für diesen Drucker vorhanden ist und dieser auch PassThrough unterstützt. In deinem Beispiel muss der Drucker auch noch als Standard ausgewählt sein.
Delphi-Quellcode:
type
TPassThroughData = record nLen : Word; Data : array[0..255] of Byte; end; function PrinterSupport(APrinter: TPrinter; ACommand: Integer): Boolean; begin Result := (Escape(APrinter.Canvas.Handle, QUERYESCSUPPORT, SizeOf(ACommand), @ACommand, nil) > 0); end; function DirectPrint(APrinter: TPrinter; const s: AnsiString): Boolean; var PTBlock : TPassThroughData; begin Result := (Length(s) < 256); if Result then begin PTBlock.nLen := Length(s); StrPCopy(@PTBlock.Data, s); Escape(APrinter.Handle, PASSTHROUGH, 0, @PTBlock, nil); end; end; procedure TForm1.Button2Click(Sender: TObject); begin Printer.BeginDoc; try if PrinterSupport(Printer, PASSTHROUGH) then DirectPrint(Printer, {...hier Zeichenkette für den Drucker übergeben...}); finally Printer.EndDoc; end; end; |
AW: Kassenlade öffnen
blup mit deinen code öffnet er Aber schiebt einen 2 cm streiffen aus dem thermaldrucker raus und cuttet ihn.
|
AW: Kassenlade öffnen
weiss den keiner weiter?
|
AW: Kassenlade öffnen
Zitat:
(und Du bist sicher, daß er
Delphi-Quellcode:
auch ausgeführt hat?)
DirectPrint
Gruß K-H |
AW: Kassenlade öffnen
#27+'p'+#48'pz'
Habe ich übergeben direktprint muss er doch ausgeführt haben die lade ist ja geöffnet worden nur das er einen schnippsel von der papierrolle ca. 2 cm auswirft und dann cuttet |
AW: Kassenlade öffnen
Auch wenn es eigentlich nichts Anderes ist, aber man sieht irgendwie klarer
Delphi-Quellcode:
const
ESC = #27; GS = #29; { Commands } ESC_em = ESC + #33; { Select print mode } ESC_p = ESC+#112; { Generate pulse } GS_V = GS + #86; { Select cut mode and cut paper } { Parameter } Lade1 = #48; Lade2 = #49; PulsDauer100ms = #050; {* 2ms} PulsDauer200ms = #100; {* 2ms} PulsDauer300ms = #150; {* 2ms} PulsDauer400ms = #200; {* 2ms} PulsDauer500ms = #250; {* 2ms} function GetGeneratePulseSequence( m, t1, t2 : AnsiChar ) : Ansistring; begin Result := Esc_p + m + t1 + t2; end; function GetDefaultGeneratePulseSequence : AnsiString; begin Result := GetGeneratePulseSequence( {m} Lade1, {t1} PulsDauer200ms, {t2} PulsDauer200ms ); end; |
AW: Kassenlade öffnen
Warum nicht gleich die richtigen Bezeichner?
Delphi-Quellcode:
Dann kann man auf die Kommentare verzichten.
const
ESC = #27; GS = #29; { Commands } CmdSelectPrintMode = ESC + #33; CmdGeneratePulse = ESC+#112; CmdSelectCutModeAndCutPaper = GS + #86; ... |
AW: Kassenlade öffnen
Zitat:
Das Beispiel mit dem Printer.xxx ist falsch!!! Benutze mal die Suchfunktion des forums da findest du ein funktionierendes Beispiel ! Hier nun der gewünschte link ![]() |
AW: Kassenlade öffnen
Das sind jetzt nicht wirklich 7 Seiten in diesem Thread? Man, habt Ihr eine Geduld... :drunken:
|
AW: Kassenlade öffnen
Zitat:
Sherlock |
AW: Kassenlade öffnen
da muss ich dir recht geben . ;)
Danke für alle Hilfen bisher. Sir Rufo wie bekomme ich deinen Code vernünftig eingebunden habe es versucht. Er zeigt mir aber Fehler
Delphi-Quellcode:
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; const ESC = #27; GS = #29; { Commands } ESC_em = ESC + #33; { Select print mode } ESC_p = ESC+#112; { Generate pulse } GS_V = GS + #86; { Select cut mode and cut paper } { Parameter } Lade1 = #48; Lade2 = #49; PulsDauer100ms = #050; {* 2ms} PulsDauer200ms = #100; {* 2ms} PulsDauer300ms = #150; {* 2ms} PulsDauer400ms = #200; {* 2ms} PulsDauer500ms = #250; {* 2ms} var Form1: TForm1; implementation {$R *.dfm} function GetGeneratePulseSequence( m, t1, t2 ): Ansistring);//hier sagt er missing parameter type begin Result := Esc_p + m + t1 + t2;//incompatible typen string und integer end; function GetDefaultGeneratePulseSequence : AnsiString; begin Result := GetGeneratePulseSequence( {m} Lade1, {t1} PulsDauer200ms, {t2} PulsDauer200ms ); end; procedure TForm1.Button1Click(Sender: TObject); begin getDefaultGeneratePulseSequence; end; |
AW: Kassenlade öffnen
Von welchem Typ sind denn wohl die Parameter? Diesen muss man bei der Deklaration schließlich angeben.
|
AW: Kassenlade öffnen
Ansistring sicherlich
Zitat:
|
AW: Kassenlade öffnen
Wie deklariert man denn Funktionen?
Delphi-Quellcode:
function Irgendwas(Parameter: Datentyp): Rückgabedatentyp;
|
AW: Kassenlade öffnen
okay
Delphi-Quellcode:
ist den die button1 procedur so okay?
function GetGeneratePulseSequence( m, t1, t2:ansistring ): Ansistring;//hier sagt er missing parameter type
begin Result := Esc_p + m + t1 + t2;//incompatible typen string und integer end; Steuert er auch den Drucker bzw. den comport an? weiss er dann wo er den string hin schicken soll? |
AW: Kassenlade öffnen
Im Button1Click passiert ja nichts, Du rufst eine Funktion auf und machst nichts mit deren Rückgabewert.
|
AW: Kassenlade öffnen
Also habe mal wie am anfang des Threads
Die Function so eingebunden
Delphi-Quellcode:
jedoch meckert er hier
unit Unit1;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, printers, winspool; type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); procedure opendrawer(); private { Private declarations } public { Public declarations } end; const ESC = #27; GS = #29; { Commands } ESC_em = ESC + #33; { Select print mode } ESC_p = ESC+#112; { Generate pulse } GS_V = GS + #86; { Select cut mode and cut paper } { Parameter } Lade1 = #48; Lade2 = #49; PulsDauer100ms = #050; {* 2ms} PulsDauer200ms = #100; {* 2ms} PulsDauer300ms = #150; {* 2ms} PulsDauer400ms = #200; {* 2ms} PulsDauer500ms = #250; {* 2ms} var Form1: TForm1; implementation {$R *.dfm} function RawDataToPrinter(szPrinterName:PChar; lpData:PByte; dwCount:Word) : Boolean; Var hPrinter : THandle; DocInfo : DOC_INFO_1; dwJob : Word; dwBytesWritten : Cardinal; Begin Result:=False; if NOT OpenPrinter( szPrinterName, hPrinter, NIL ) then Exit; DocInfo.pDocName := 'RAWJOB'; DocInfo.pOutputFile := NIL; DocInfo.pDatatype := 'RAW'; dwJob := StartDocPrinter( hPrinter, 1, @DocInfo ); if (dwJob = 0 ) Then begin ClosePrinter( hPrinter ); Exit; end; if not StartPagePrinter( hPrinter ) then begin EndDocPrinter( hPrinter ); ClosePrinter( hPrinter ); Exit; end; if not WritePrinter( hPrinter, lpData, dwCount, dwBytesWritten ) then begin EndPagePrinter( hPrinter ); EndDocPrinter( hPrinter ); ClosePrinter( hPrinter ); Exit; end; if not EndPagePrinter( hPrinter ) then begin EndDocPrinter( hPrinter ); ClosePrinter( hPrinter ); Exit; end; if not EndDocPrinter( hPrinter ) then begin ClosePrinter( hPrinter ); Exit; end; ClosePrinter( hPrinter ); Result:=dwBytesWritten = dwCount; End; function SwitchPrinter(const APrtName : string):string; var Device, Driver, Port: array[0..255] of Char; DevMode: THandle; begin with Printer do begin PrinterIndex := Printers.IndexOf(APrtName); GetPrinter(Device, Driver, Port, DevMode); SetPrinter(Device, Driver, Port, 0); result:=Printers[printerindex]; end; end; function GetGeneratePulseSequence( m, t1, t2:ansistring ): Ansistring;//hier sagt er missing parameter type begin Result := Esc_p + m + t1 + t2;//incompatible typen string und integer end; function GetDefaultGeneratePulseSequence : AnsiString; begin Result := GetGeneratePulseSequence( {m} Lade1, {t1} PulsDauer200ms, {t2} PulsDauer200ms ); end; procedure Tform1.opendrawer(); Var FH:THandle; Buff: array[0..5] of char; RetW:DWORD; port:string; cmd:string; acmd:ansistring; p:pansichar; begin acmd:=getDefaultGeneratePulseSequence;// hier der anstring aus der Function p := PAnsiChar( acmd); p:=StrPCopy(p,acmd); switchprinter('CognitiveTPG Receipt'); //Druckername, so wie er in Windows angezeigt wird rawdatatoprinter(pwidechar('CognitiveTPG Receipt'),pbyte(p),length(acmd)); end; procedure TForm1.Button1Click(Sender: TObject); begin opendrawer; end;
Delphi-Quellcode:
invalid typcast pbyte(p)
rawdatatoprinter(pwidechar('CognitiveTPG Receipt'),pbyte(p),length(acmd));
|
AW: Kassenlade öffnen
Zitat:
Also den Sinn der Konstruktion (und der entsprechenden Zeilen davor) verstehe ich nicht. "Wenn nicht, dann A, Wenn doch, dann auch A" Das Ganze kann man also um 20 Zeilen kürzen. |
AW: Kassenlade öffnen
Zitat:
Delphi-Quellcode:
UPDATE
try
... if not EndDocPrinter( hPrinter ) then raise Exception.Create( 'EndDocPrinter fehlgeschlagen' ); finally ClosePrinter( hPrinter ); end; So müsste da langsam ein Schuh draus werden, denn nun sollte man auch bei einem Fehler auch den Grund dafür bekommen (huch, wo sind die vielen Zeilen hin, Mehrwert mit weniger Zeilen :gruebel:)
Delphi-Quellcode:
unit uRawDataPrint;
interface uses SysUtils, printers, winspool; type ERawDataToPrinterException = class( Exception ); procedure RawDataToPrinter( szPrinterName : PChar; lpData : PByte; dwCount : Word ); implementation procedure RawDataToPrinter( szPrinterName : PChar; lpData : PByte; dwCount : Word ); var hPrinter : THandle; DocInfo : DOC_INFO_1; dwJob : Word; dwBytesWritten : Cardinal; begin Win32Check( OpenPrinter( szPrinterName, hPrinter, nil ) ); try DocInfo.pDocName := 'RAWJOB'; DocInfo.pOutputFile := nil; DocInfo.pDatatype := 'RAW'; dwJob := StartDocPrinter( hPrinter, 1, @DocInfo ); if ( dwJob = 0 ) then RaiseLastWin32Error; try Win32Check( StartPagePrinter( hPrinter ) ); try Win32Check( WritePrinter( hPrinter, lpData, dwCount, dwBytesWritten ) ); if not( dwBytesWritten = dwCount ) then raise ERawDataToPrinterException.Create( 'Nicht alle Bytes geschrieben' ); finally Win32Check( EndPagePrinter( hPrinter ) ); end; finally Win32Check( EndDocPrinter( hPrinter ) ); end; finally Win32Check( ClosePrinter( hPrinter ) ); end; end; end. |
AW: Kassenlade öffnen
und wie kann ich den befehl jetzt an den Printer schicken?
|
AW: Kassenlade öffnen
Sir Rufo hat nur das zusammengefasst was vorher schon genannt wurde.
Win32Check( WritePrinter( hPrinter, lpData, dwCount, dwBytesWritten ) ); Hier mußt Du Deine Daten eintragen (den zu druckenden String übergeben). Gruß K-H Gut, Hardware lebt und ist böse, und Drucker sind zudem noch hinterhältig, aber soooo schlimm? |
AW: Kassenlade öffnen
steh gerade auf dem schlauch
welche codes soll ich nun verwenden? die Zusammenfassung von sir rufo in die uses einbinden richtig? was ist mit den Funktionen?
Delphi-Quellcode:
und das aufrufen in der buttonclick procedure
function GetGeneratePulseSequence( m, t1, t2:ansistring ): Ansistring;//hier sagt er missing parameter type
begin Result := Esc_p + m + t1 + t2;//incompatible typen string und integer end; function GetDefaultGeneratePulseSequence : AnsiString; begin Result := GetGeneratePulseSequence( {m} Lade1, {t1} PulsDauer200ms, {t2} PulsDauer200ms ); end; RawDataToPrinter( szPrinterName{1} : PChar;{2} lpData : PByte;{3} dwCount : Word ); {1} muss hier der printername rein? {2} was muss hier rein? {3} was muss hier rein? |
AW: Kassenlade öffnen
Ja so kann sie eingebunden werden.
Delphi-Quellcode:
Hiermit werden die Daten generiert die an den Drucker gehen.
function GetGeneratePulseSequence( m, t1, t2:ansistring ): Ansistring;//hier sagt er missing parameter type
begin Result := Esc_p + m + t1 + t2;//incompatible typen string und integer end; function GetDefaultGeneratePulseSequence : AnsiString; begin Result := GetGeneratePulseSequence( {m} Lade1, {t1} PulsDauer200ms, {t2} PulsDauer200ms ); end; also
Delphi-Quellcode:
{1} Ja, hier kommt der Druckername rein
Druckstring:=GetDefaultGeneratePulseSequence;
{2} Mit der Zeigerwurschtelei kenn ich mich nicht so gut aus, ich nehme an ein @Druckstring[1] könnte reichen, vllt auch ein pansichar(Druckstring); {3}
Delphi-Quellcode:
ggf. solltest Du Dir einmal die Daten anzeigen, die ankommen:
length(Druckstring)
aus dem Programming Guide für den t798 Zitat:
K-H |
AW: Kassenlade öffnen
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin RawDataToPrinter( 'CognitiveTPG Receipt',GetDefaultGeneratePulseSequence, length(GetDefaultGeneratePulseSequence) );//hier sagt er mir incompatible type string und pbyte end; |
AW: Kassenlade öffnen
Zitat:
Du solltest lieber mal einen Programmierer suchen Außer Copy und Paste wird das wohl nichts. Das Beispiel auf dem Link war fix und fertig bis auf dem Namen des Druckers, der in einer Struktur stand, dahinter war das aber Kommentiert, so das man nur seinen Namen dort hinschreiben musste :coder2: |
AW: Kassenlade öffnen
Zitat:
RawDataToPrinter erwartet als Parameter die Adresse einer Speicherstelle(Variable) und die Größe der Speicherstelle(Anzahl Byte).
Delphi-Quellcode:
Edit:
var
lData: AnsiString; begin lData := GetDefaultGeneratePulseSequence; RawDataToPrinter('CognitiveTPG Receipt', Pointer(lData), Length(lData)); end; Ob dein Drucker natürlich so heist, kannst nur du wissen... Edit: Im Prinzip passiert hier das selbe wie im Beispiel mit PASSTHROUGH. Ist die von GetDefaultGeneratePulseSequence erzeugte ESC-Sequenz korrekt, funtkionieren vermutlich beide Wege. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:07 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz