Serieller Drucker und api
-
thx,
letzte Frage:if( (dwJob = StartDocPrinter( hPrinter, 1, (LPSTR)&DocInfo )) == 0 )
error C2664: 'StartDocPrinterW' : cannot convert parameter 3 from 'LPSTR' to 'LPBYTE'
-
ähh, hab die Lösung:
if( (dwJob = StartDocPrinter( hPrinter, 1, (LPBYTE)&DocInfo )) == 0 )Der Compiler gibt mir grünes Licht
Wenn ich auf meinem Knopf(Test Druck) drücke kommt:
Run-Time Check Failure #3 - The variable 'dwCount' is being used without being initialized.
if( (dwJob = StartDocPrinter( hPrinter, 1, (LPBYTE)&DocInfo )) == 0 ) //<- stop
ok, nochmal alles abgecheckt:
meine veränderung:LPBYTE lpData = NULL;
DWORD dwCount = 1;First-chance exception at 0x72f77954 in mein_drucker.exe: 0xC0000005: Access violation reading location 0x00000000.
Unhandled exception at 0x72f77954 in mein_drucker.exe: 0xC0000005: Access violation reading location 0x00000000.dann öffnet sich eine winocc.cpp in Zeile:
BOOL CWnd::IsDialogMessage(LPMSG lpMsg) { ASSERT(::IsWindow(m_hWnd)); if (m_nFlags & WF_OLECTLCONTAINER) return afxOccManager->IsDialogMessage(this, lpMsg); else return ::IsDialogMessage(m_hWnd, lpMsg); } <--- Hier steht der Pfeil.
-
Warum denn der ganze Aufwand, wenn Du gar nichts (lpData = NULL)drucken willst
'lpData' sollte auf die Daten zeigen die Du drucken willst
'dwCount' sollte die Anzahl Bytes enthalten welche gedruckt werden sollenHerzliche Grüsse
Walter
-
Ich will nur hallo Welt drucken mehr nicht.
pldata = "hallo welt"?
dwCount <- Anzahl der Zeichen?
hab ich was vergessen?
-
Hallo,
ich bin mir nicht ganz sicher. Bei der Doku zu WritePrinter steht nichts über Unicode, aber mit grösster Wahrscheinlichkeit nimmt auch diese Funktion einen Unicode string.
Darum würde ich es zuerst mal so versuchen:
TCHAR str[] = _T("Hallo Welt!"); lpData = (LPVOID)str; dwCount = _tcslen (str) * sizeof(TCHAR);
Herzliche Grüsse
Walter
-
DWORD dwCount; LPBYTE lpData; TCHAR str[] = _T("Hallo Welt!"); lpData = (LPVOID)str; //zeile 164 dwCount = _tcslen (str) * sizeof(TCHAR);
nächstes Prob.
mein_druckerdlg.cpp(164) : error C2440: '=' : cannot convert from 'LPVOID' to 'LPBYTE'
-
Steht doch da. LPVOID ist eben kein LPBYTE.
Wenn Du schon casten musst warum incht gleich in den entsprechen Typ?
-
LPWSTR szPrinterName = _T("pdf24"); //von mir erstellt TCHAR str[] = _T("Hallo Welt!"); //von mir erstellt lpData = (LPBYTE)str; //von mir erstellt DWORD dwCount = _tcslen (str) * sizeof(TCHAR); //von mir erstellt HANDLE hPrinter; DOC_INFO_1 DocInfo; DWORD dwJob; DWORD dwBytesWritten; // Need a handle to the printer. if( ! OpenPrinter( szPrinterName, &hPrinter, NULL ) ) return FALSE; // Fill in the structure with info about this "document." DocInfo.pDocName = _T("My Document"); //von mir erstellt _T() hinzugefügt DocInfo.pOutputFile = NULL; DocInfo.pDatatype = _T("RAW"); //von mir erstellt _T() hinzugefügt // Inform the spooler the document is beginning. if( (dwJob = StartDocPrinter( hPrinter, 1, (LPBYTE)&DocInfo )) == 0 ) //von LPSTR in LPBYTE umg. { ClosePrinter( hPrinter ); return FALSE; } // Start a page. if( ! StartPagePrinter( hPrinter ) ) { EndDocPrinter( hPrinter ); ClosePrinter( hPrinter ); return FALSE; } // Send the data to the printer. if( ! WritePrinter( hPrinter, lpData, dwCount, &dwBytesWritten ) ) { EndPagePrinter( hPrinter ); EndDocPrinter( hPrinter ); ClosePrinter( hPrinter ); return FALSE; } // End the page. if( ! EndPagePrinter( hPrinter ) ) { EndDocPrinter( hPrinter ); ClosePrinter( hPrinter ); return FALSE; } // Inform the spooler that the document is ending. if( ! EndDocPrinter( hPrinter ) ) { ClosePrinter( hPrinter ); return FALSE; } // Tidy up the printer handle. ClosePrinter( hPrinter ); // Check to see if correct number of bytes were written. if( dwBytesWritten != dwCount ) return FALSE; return TRUE;
Der Serial Drcuker macht kein Mux.
Wenn ich pdf24 eintragen, dann öffnet sich pdf24 mit einem leeren Blatt.
Der Compiler zeigt auch keine Warnung an, und jetzt?
-
hat keiner eine Idee? oder Ansatz?
-
tomycat2009 schrieb:
hat keiner eine Idee? oder Ansatz?
Ja, lerne Grundlagen.
tomycat2009 schrieb:
TCHAR str[] = _T("Hallo Welt!"); //von mir erstellt
Das ist mit ziemlicher Sicherheit falsch. Solche Drucker arbeiten meist mit ANSI-Daten, nicht mit Unicode.
tomycat2009 schrieb:
Der Serial Drcuker macht kein Mux.
Wenn ich pdf24 eintragen, dann öffnet sich pdf24 mit einem leeren Blatt.Dann heißt dein Drucker wohl nicht "pdf24". In szPrinterName muss der Name des Druckers stehen, so wie Windows ihn unter "Drucker und Faxgeräte" anzeigt.
tomycat2009 schrieb:
Der Compiler zeigt auch keine Warnung an, und jetzt?
Nochmal: Grundlagen lernen.
Geh mit dem Debugger Schritt für Schritt durch den Code durch und schau, ob er da bei einem if rausspringt, dann siehst du, wo das Problem liegt.
Läuft der Code durch, dann sendest du halt einfach die falschen Daten.
-
Hier mal ein Beispiel mit einem Hello World auf einem Etikettendrucker:
using namespace std; BOOL RawDataToPrinter(LPSTR szPrinterName, LPBYTE lpData, DWORD dwCount) { // Unverändert aus dem MSDN übernommen } } int _tmain(int argc, _TCHAR* argv[]) { string s; s += "m m\r\n"; s += "J\r\n"; s += "H 100\r\n"; s += "O R\r\n"; s += "S l1;0,0,29,31,55\r\n"; s += "T 10,10,0,3,8;Hallo !\r\n"; s += "A 1\r\n"; RawDataToPrinter("CAB A4+/300", (LPBYTE)s.c_str(), s.length()); return 0; }
Im Rest deines Programm kannst du mit Unicode und _T arbeiten, aber die Daten, die zum Drucker gehen sind kein Unicode, da muss du eben umwandeln.
-
ok,
ich habe deinen Code 1 zu 1 übernommen.error C2664: 'OpenPrinterW' : cannot convert parameter 1 from 'LPSTR' to 'LPWSTR'
schritt 2:
original:
BOOL RawDataToPrinter(LPSTR szPrinterName, LPBYTE lpData, DWORD dwCount)
in
BOOL RawDataToPrinter(LPWSTR szPrinterName, LPBYTE lpData, DWORD dwCount)neu Compiliert, dann kommt das nächste Problem:
error C2440: '=' : cannot convert from 'const char [12]' to 'LPWSTR'Original:
DocInfo.pDocName = "My Document";
DocInfo.pOutputFile = NULL;
DocInfo.pDatatype = "RAW";zu:
DocInfo.pDocName = _T("My Document");
DocInfo.pOutputFile = NULL;
DocInfo.pDatatype = _T("RAW");neu Compiliert, dann kommt das nächste Problem:
error C2664: 'StartDocPrinterW' : cannot convert parameter 3 from 'LPSTR' to 'LPBYTE'von
if( (dwJob = StartDocPrinter( hPrinter, 1, (LPSTR)&DocInfo )) == 0 )
zu
if( (dwJob = StartDocPrinter( hPrinter, 1, (LPBYTE)&DocInfo )) == 0 )neu Compiliert, dann kommt das nächste Problem:
error C2065: 'string' : undeclared identifierWarum soll ich mit string arbeiten?
Warum nicht mit CString?
Ich arbeite in Visual Studio 2008 und habe ein MFC Projekt.
-
tomycat2009 schrieb:
ok,
ich habe deinen Code 1 zu 1 übernommen.Ok, ich hätte noch ausführlicher werden sollen.
Das Beispiel stammt noch von Visual Studio 2003, da ist standardmäßig kein Unicode eingestellt. Ich habe es genommen, weil ich kurzfristig nichts anderes gefunden habe. Und ich habe nicht gemeint, du sollst die Funktion ungeändert übernehmen.
Die jetzt vom Compiler angemeckerten Teile solltest du schon von LPSTR auf LPTSTR ändern, aber nicht die Daten, die zum Drucker gehen.
Du hast es in deinem Programm mit zwei unterschiedlichen Stringformaten zu tun. Der Druckername und der Dokumentenname sind Teil der Interaktion deines Programmes mit Windows.
Die Daten, die zum Drucker gesendet werden, sind davon unabhängig. Deren Format hat der Druckerhersteller festgelegt und dem ist es egal, ob du in deinen Windowsprogramm Unicode verwendest oder nicht.
Weiterhin sollte das Beispiel zeigen, dass es meist nicht reicht nur "Hallo" zum Drucker zu senden, sondern, je nach Hersteller, weiter Befehle erforderlich sind. Mehr dazu findest du, hoffentlich, in der Anleitung zu deinem Drucker.
tomycat2009 schrieb:
ok,
neu Compiliert, dann kommt das nächste Problem:
error C2065: 'string' : undeclared identifierDa haben wir es wieder. Grundlagen lernen.
Das ist der std::string von C++. Ein #include <string> in der stdafx.h könnte Wunder wirken ...
tomycat2009 schrieb:
Warum nicht mit CString?
Du must auf jeden Fall zwischen Stringdaten innerhalb deines Programm und denen im Druckerformat unterscheiden. Da bieten sich CStringA (nicht CString) oder std::string für die Druckerdaten an. Letzter kommt auf jeden Fall auch mit Binärdaten zurecht.
-
So, hier noch eine mit Visual Studio 2008 getestete Version, der Kürze halber als Kommandozeilenanwendung.
Die stdafx.h
// stdafx.h : Includedatei für Standardsystem-Includedateien // oder häufig verwendete projektspezifische Includedateien, // die nur in unregelmäßigen Abständen geändert werden. // #pragma once #include "targetver.h" #include <stdio.h> #include <tchar.h> // TODO: Hier auf zusätzliche Header, die das Programm erfordert, verweisen. #include <atlstr.h>
und das Hauptprogramm
// CStringTest.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung. // #include "stdafx.h" using namespace std; BOOL RawDataToPrinter(LPTSTR szPrinterName, LPVOID lpData, DWORD dwCount) { HANDLE hPrinter; DOC_INFO_1 DocInfo; DWORD dwJob; DWORD dwBytesWritten; // Need a handle to the printer. if( ! OpenPrinter( szPrinterName, &hPrinter, NULL ) ) return FALSE; // Fill in the structure with info about this "document." DocInfo.pDocName = _T("My Document"); DocInfo.pOutputFile = NULL; DocInfo.pDatatype = _T("RAW"); // Inform the spooler the document is beginning. if( (dwJob = StartDocPrinter( hPrinter, 1, (LPBYTE)&DocInfo )) == 0 ) { ClosePrinter( hPrinter ); return FALSE; } // Start a page. if( ! StartPagePrinter( hPrinter ) ) { EndDocPrinter( hPrinter ); ClosePrinter( hPrinter ); return FALSE; } // Send the data to the printer. if( ! WritePrinter( hPrinter, lpData, dwCount, &dwBytesWritten ) ) { EndPagePrinter( hPrinter ); EndDocPrinter( hPrinter ); ClosePrinter( hPrinter ); return FALSE; } // End the page. if( ! EndPagePrinter( hPrinter ) ) { EndDocPrinter( hPrinter ); ClosePrinter( hPrinter ); return FALSE; } // Inform the spooler that the document is ending. if( ! EndDocPrinter( hPrinter ) ) { ClosePrinter( hPrinter ); return FALSE; } // Tidy up the printer handle. ClosePrinter( hPrinter ); // Check to see if correct number of bytes were written. if( dwBytesWritten != dwCount ) { return FALSE; } return TRUE; } int _tmain(int argc, _TCHAR* argv[]) { CString drucker = _T("DerDrucker"); // <=== Da kommt der Name deines Druckers rein CString text = _T("Hallo"); // <== Hier kommen die Druckdaten rein. CStringA ansi(text); RawDataToPrinter(drucker.GetBuffer(), ansi.GetBuffer(), ansi.GetLength()); return 0; }
-
Danke,
statt...
int _tmain(int argc, _TCHAR* argv[])
habe ich meinen Knopf genommen.
Compiliert und er hat mir keine Fehler gemeldet.Dann habe ich 4 mal auf "drucken" gedrückt, er hat nicht reagiert.
Bei 5ten mal hat er
hallohallohallohallo gedruckt.Idee?
-
habs hingekommen
ich muss noch \r\n hinzufügen:-)tomycat <---- (brüllt wie ein Irrer ich der Wohnung herum und immer wieder"ER DRUCKT ER DRUCKT ERDRUCKT !!!")
-
ok,
noch eine Frage:was muss ich tun dass er mit das hallo in Fettbuchstaben schreibt und das das Papier abschndet.
Er druckt mir immer z.b. ESC q e eins zu eins aufs Papier, aber \r\n kennt er?!
TMT88ii Epson ist sein Name.
Idee?
-
tomycat2009 schrieb:
Idee?
Google ?
Schon die Suche nach "Epson TMT88i Control Codes" fördert u.a.
http://webpages.charter.net/dperr/links/esc_p2.htm
http://www.dragon-it.co.uk/links/epson_printer_codes.htm
zu Tage
-
Ich setzte voraus, dass ihr beschied wisst,dass ich google nutze und mehrere Stunden herum probiert habe.
Aber das hättest du auch nicht wissen können
Dein erster Link:
1.Versuch:
CString text = _T("10123123\r\n"); // <== Hier kommen die Druckdaten rein.
text += "\27EM\1";10123123
EM10123123
2.Versuch:
CString text = _T("10123123\r\n"); // <== Hier kommen die Druckdaten rein.
text += "\ESCk\001";ESCEM10123123
ESCk101231233.Versuch:
CString text = _T("10123123\r\n"); // <== Hier kommen die Druckdaten rein.
text += "\ESC-\001";ESC-10123123
Es folgten ca. 30 versuche.Aber nicht zum Ziel
Idee?(goggle habe ich schon benützt)
-
tomycat2009 schrieb:
Idee?
Yoh, hab ich schon mehrmals geschrieben:
Grundlagen lernen.
tomycat2009 schrieb:
Es folgten ca. 30 versuche.Aber nicht zum Ziel
Das ist auch gut so, da du dich weigerst zu verstehen, was der Code eigentlich tut.
Ich hab in diesem Thread schon mal geschrieben:
nn schrieb:
Du hast es in deinem Programm mit zwei unterschiedlichen Stringformaten zu tun.
und
nn schrieb:
Du must auf jeden Fall zwischen Stringdaten innerhalb deines Programm und denen im Druckerformat unterscheiden. Da bieten sich CStringA (nicht CString) oder std::string für die Druckerdaten an. Letzter kommt auf jeden Fall auch mit Binärdaten zurecht.
Die Daten in deinem CString sind in UTF-16 codiert.
http://de.wikipedia.org/wiki/UTF-16
Denk mal darüber nach, wo du da versuchst ein Escape hinzuzufügen ...Anschliessend kannst du mal zu Escapesequenzen googlen und unter anderem das finden:
http://www.cppreference.com/wiki//language/escape?redirect=1
http://msdn.microsoft.com/de-de/library/h21280bw.aspxDann kannst du darüber nachdenken, ob \ESC oder \27 die richtige Schreibweise sind.