CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - Komendy drukowania

Komendy drukowania

dział ogólny

Komendy drukowania

Postprzez duf » poniedziałek, 17 października 2011, 09:58

Jak wysłać komendę do drukarki, żeby drukowała w określonej pozycji? Z komend Epsona ( emulacja Epson FX ) znalazłem trzy, które powinny to robić ale drukarka nie drukuje: Print Position, Execute current print position from left margin and Set print position. Komendy wysyłam tak:
KOD cpp:     UKRYJ  
LPBYTE cSendBuf = NULL;
int textSize = 9;
cSendBuf = (LPBYTE) malloc ( textSize*sizeof(BYTE) );
cSendBuf[0] = 0x18; //clear print buffer
 
cSendBuf[1] = 0x1B; // Set left margin
cSendBuf[2] = 0x6C;
cSendBuf[3] = 0x1;
 
cSendBuf[4] = 0x1B; // Print position, it doesn`t work
cSendBuf[5] = 0x5C;
cSendBuf[6] = 0x40;
cSendBuf[7] = 0x14;
 
cSendBuf[8] = 'T';
 
if( !RawDataToPrinter( L"\\\\AGO\\Oki ML 520 Elite (IBM)", cSendBuf, textSize ) ) ShowMessage("Error");
 
free(cSendBuf);
Avatar użytkownika
duf
Intelektryk
Intelektryk
 
Posty: 175
Dołączył(a): czwartek, 9 października 2008, 13:02
Podziękował : 17
Otrzymał podziękowań: 2
System operacyjny: Windows 10
Kompilator: XE8
Gadu Gadu: 0
    Windows XPFirefox

Re: Komendy drukowania

Postprzez Cyfrowy Baron » poniedziałek, 17 października 2011, 11:36

Chodzi o sterowanie drukarką igłową?

Nie znajduję u siebie funkcji RawDataToPrinter. Użyłeś funkcji zaprezentowanej na tej stronie: http://msdn.microsoft.com/en-us/library/dd162959%28VS.85%29.aspx?
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Komendy drukowania

Postprzez duf » poniedziałek, 17 października 2011, 11:49

Cyfrowy Baron napisał(a):Chodzi o sterowanie drukarką igłową?

Nie znajduję u siebie funkcji RawDataToPrinter. Użyłeś funkcji zaprezentowanej na tej stronie: http://msdn.microsoft.com/en-us/library/dd162959%28VS.85%29.aspx?


Tak, drukarka igłowa OKI ML 520. Funkcja pochodzi z tej strony.
Avatar użytkownika
duf
Intelektryk
Intelektryk
 
Posty: 175
Dołączył(a): czwartek, 9 października 2008, 13:02
Podziękował : 17
Otrzymał podziękowań: 2
System operacyjny: Windows 10
Kompilator: XE8
Gadu Gadu: 0
    Windows XPFirefox

Re: Komendy drukowania

Postprzez Cyfrowy Baron » poniedziałek, 17 października 2011, 11:59

Natknąłem się na taki kod z wykorzystaniem tej funkcji dla aplikacji konsolowej. Może jego analiza okaże się dla Ciebie pomocna:

KOD cpp:     UKRYJ  
#include "stdafx.h"
#include "stdio.h"
#include "conio.h"
#include "windows.h"
#include "string.h"

bool RawDataToPrinter(LPSTR szPrinterName, LPBYTE lpData, DWORD dwCount);

int _tmain(int argc, _TCHAR* argv[])
{
 std::string sUploadData;

 sUploadData += "print page line1";

 int nTotalLen = sUploadData.length();

 std::string sPrinterName = "PS-Printer";

 LPBYTE pData = new BYTE[nTotalLen];

 if (pData != NULL)
 {
  memcpy(pData, sUploadData.c_str(), nTotalLen);

  char szPrinter[MAX_PATH];
  strcpy(szPrinter, sPrinterName.c_str());

  RawDataToPrinter(szPrinter, pData, nTotalLen);

  delete[] pData;
 }

 return 0;
}

bool RawDataToPrinter(LPSTR szPrinterName, LPBYTE lpData, DWORD dwCount)
{
 HANDLE hPrinter;
 DOC_INFO_1 DocInfo;
 DWORD dwJob;
 DWORD dwBytesWritten;

 if( ! OpenPrinter( szPrinterName, &hPrinter, NULL ) )
 {
  printf("RawDataToPrinter: OpenPrinter failed");
  return FALSE;
 }

 DocInfo.pDocName = "My Document";
 DocInfo.pOutputFile = NULL;
 DocInfo.pDatatype = "RAW";

 LPBYTE;

 if( (dwJob = StartDocPrinter( hPrinter, 1, (LPBYTE)&DocInfo )) == 0 )
 {
  ClosePrinter( hPrinter );
  printf("RawDataToPrinter: StartDocPrinter failed");
  return FALSE;
 }

 if( ! StartPagePrinter( hPrinter ) )
 {
  EndDocPrinter( hPrinter );
  ClosePrinter( hPrinter );
  printf("RawDataToPrinter: StartPagePrinter failed");
  return FALSE;
 }

 if( !WritePrinter( hPrinter, lpData, dwCount, &dwBytesWritten ) )
 {
  EndPagePrinter( hPrinter );
  EndDocPrinter( hPrinter );
  ClosePrinter( hPrinter );
  printf("RawDataToPrinter: WritePrinter failed");
  return FALSE;
 }

 if( ! EndPagePrinter( hPrinter ) )
 {
  EndDocPrinter( hPrinter );
  ClosePrinter( hPrinter );
  printf("RawDataToPrinter: EndPagePrinter failed");
  return FALSE;
 }

 if( ! EndDocPrinter( hPrinter ) )
 {
  ClosePrinter( hPrinter );
  printf("RawDataToPrinter: EndDocPrinter failed");
  return FALSE;
 }

 ClosePrinter( hPrinter );

 if( dwBytesWritten != dwCount )
 {
  printf("RawDataToPrinter: Number of bytes written are wrong.");
  return FALSE;
 }

 return TRUE;
}
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Komendy drukowania

Postprzez duf » poniedziałek, 17 października 2011, 12:08

Dzięki za chęci takich przykładów w necie jest dość sporo ( ten akurat drukuje "print page line1" ), które przekazują dane do sterownika. Nie mogę znaleźć choć jednego, który pokazałby jak przesyłać komendy a szczególnie te, które ustawiają współrzędne wydruku.
Avatar użytkownika
duf
Intelektryk
Intelektryk
 
Posty: 175
Dołączył(a): czwartek, 9 października 2008, 13:02
Podziękował : 17
Otrzymał podziękowań: 2
System operacyjny: Windows 10
Kompilator: XE8
Gadu Gadu: 0
    Windows XPFirefox

Re: Komendy drukowania

Postprzez Cyfrowy Baron » wtorek, 18 października 2011, 08:44

Myślałem, że drukowanie wogóle Tobie nie działa i dlatego ten kod...

Być może masz złą tablicę cSendBuf. Stwórz ją jako typ char, coś w tym stylu:

KOD cpp:     UKRYJ  
char cSendBuf[9];

cSendBuf[0] = 0x18; //clear print buffer
 
cSendBuf[1] = 0x1B; // Set left margin
cSendBuf[2] = 0x6C;
cSendBuf[3] = 0x1;
 
cSendBuf[4] = 0x1B; // Print position, it doesn`t work
cSendBuf[5] = 0x5C;
cSendBuf[6] = 0x40;
cSendBuf[7] = 0x14;

cSendBuf[8] = 'T';

if( !RawDataToPrinter( L"\\\\AGO\\Oki ML 520 Elite (IBM)", (void *)cSendBuf, strlen(cSendBuf)) ) ShowMessage("Error");
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Komendy drukowania

Postprzez duf » wtorek, 18 października 2011, 09:08

Nie chodzi mi o drukowanie z klasy TPrinter tylko bezpośrednio ze sterownika. Problem polega na tym, że nie każda komenda działa. Problem mam z drukowaniem w konkretnej pozycji ( print position kod: 1B 5C N1 N2 )
Avatar użytkownika
duf
Intelektryk
Intelektryk
 
Posty: 175
Dołączył(a): czwartek, 9 października 2008, 13:02
Podziękował : 17
Otrzymał podziękowań: 2
System operacyjny: Windows 10
Kompilator: XE8
Gadu Gadu: 0
    Windows XPFirefox

Re: Komendy drukowania

Postprzez Cyfrowy Baron » wtorek, 18 października 2011, 10:38

duf napisał(a):Nie chodzi mi o drukowanie z klasy TPrinte


A gdzie ja napisałem, że masz używać klasy TPrinter?!
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Komendy drukowania

Postprzez polymorphism » wtorek, 18 października 2011, 11:05

Być może masz złą tablicę cSendBuf. Stwórz ją jako typ char, coś w tym stylu:

Przecież LPBYTE to to samo co unsigned char*. Sprawą dyskusyjną jest fakt, dlaczego duf tworzy tę tablicę na stercie, no ale to już jego sprawa...

Błąd w kodzie:
KOD cpp:     UKRYJ  
char cSendBuf[9];

...

cSendBuf[8] = 'T'; //<--- !!!

if( !RawDataToPrinter( ..., strlen(cSendBuf)) ) //<--- to nie jest c-string!


A nie prościej dać tak:
KOD cpp:     UKRYJ  
const char* cSendBuf = "\x18\x1B\x6c\x1\x1b\x5c\x40\x14T";
/* lub */
char cSendBuf[] = { 0x18, 0x1B, 0x6c, 0x1, 0x1b, 0x5c, 0x40, 0x14, 'T' };

if( !RawDataToPrinter(..., (void *)cSendBuf, 9) )

:?:

Problem mam z drukowaniem w konkretnej pozycji ( print position kod: 1B 5C N1 N2 )

A jesteś pewny, że parametry tej komendy są poprawne? Bo według dokumentacji, którą znalazłem, jeśli pozycja przekracza lewy lub prawy margines, komenda jest ignorowana.
C++ Reference - opis wszystkich klas STL-a i funkcji C.

Za ten post autor polymorphism otrzymał podziękowanie od:
duf
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Komendy drukowania

Postprzez duf » środa, 19 października 2011, 12:10

polymorphism napisał(a):Sprawą dyskusyjną jest fakt, dlaczego duf tworzy tę tablicę na stercie, no ale to już jego sprawa...

Jeżeli nie na stercie to na stosie. W czym jest różnica w tym przypadku?

polymorphism napisał(a):A nie prościej dać tak:
KOD cpp:     UKRYJ  
const char* cSendBuf = "\x18\x1B\x6c\x1\x1b\x5c\x40\x14T";
/* lub */
char cSendBuf[] = { 0x18, 0x1B, 0x6c, 0x1, 0x1b, 0x5c, 0x40, 0x14, 'T' };
if( !RawDataToPrinter(..., (void *)cSendBuf, 9) )

Tu jest problem przy kompilacji:

cannot convert void* to unsigned char*


Właściwa forma:
KOD cpp:     UKRYJ  
if( !RawDataToPrinter(..., cSendBuf, 9) )

Natomiast problem leży przy innej ilości elementów tablicy. Nie wiem dlaczego ale jak wysyłam tylko dwa elementy 0x18 i 'T' lub inną ilość następuje błąd systemowy. Uprzedzę pytanie: Tak zmieniłem wartość z 9 na 2.

polymorphism napisał(a):A jesteś pewny, że parametry tej komendy są poprawne? Bo według dokumentacji, którą znalazłem, jeśli pozycja przekracza lewy lub prawy margines, komenda jest ignorowana.

Dzięki za ten link. Poszukiwałem takiego szerszego opisu.
Avatar użytkownika
duf
Intelektryk
Intelektryk
 
Posty: 175
Dołączył(a): czwartek, 9 października 2008, 13:02
Podziękował : 17
Otrzymał podziękowań: 2
System operacyjny: Windows 10
Kompilator: XE8
Gadu Gadu: 0
    Windows XPFirefox

Re: Komendy drukowania

Postprzez polymorphism » środa, 19 października 2011, 13:48

Jeżeli nie na stercie to na stosie. W czym jest różnica w tym przypadku?

W sensie funkcjonalnym różnicy nie ma, ale każde działanie powinno mieć jakiś sens. W przypadku stałej, lokalnej tablicy tworzenie jej na stercie nie ma uzasadnienia. A jeśli można coś zrobić prościej i z sensem, to dlaczego nie?

Tu jest problem przy kompilacji: cannot convert void* to unsigned char* (...)
Właściwa forma: (...)

Przekleiłem wywołanie od CB, więc to nie moja wina ;)

Nie wiem dlaczego ale jak wysyłam tylko dwa elementy 0x18 i 'T' lub inną ilość następuje błąd systemowy.

Błąd systemowy, czyli co? Błąd dostępu do pamięci? Pokaż kod.

Poszukiwałem takiego szerszego opisu.

Przecież w sieci jest tego cała masa. To był opis pierwszy z brzegu.

I coś się tak uparł na te komendy drukarkowe, przecież z poziomu GDI to samo zrobisz?
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Komendy drukowania

Postprzez duf » środa, 19 października 2011, 14:09

Muszę czasami wypełniać druk w formacie A4 przez kalkę (kilka stron). Zszyty jest on jak książka i nazywa się karnet TIR. W drukarce igłowej przy standardowej funkcji Print() papier jest wypluwany po skończonym druku. Mnie zależało żeby wałek przewinął włożoną kartkę do początku. Czyli wkładam kartkę do drukarki drukuję do określonego miejsca teksty w różnych polach i wracam do początku strony. Dlatego klasa TPrint jest mi nie przydatna. Szukałem rozwiązania i trafiłem na funkcje opisaną wyżej.
Właśnie Twojemu linkowi udało mi się rozwiązać problem z przewinięciem strony do początku po zakończeniu drukowania :D . Zostanę jednak przy swojej formie tablicy:
KOD cpp:     UKRYJ  
LPBYTE cSendBuf = NULL;
int textSize = 38;
cSendBuf = (LPBYTE) malloc ( textSize*sizeof(BYTE) );
cSendBuf[0] = 0x18; //clear print buffer


ale według Twojej sugestii nie mam pojęcia jak zadeklarować tą tablicę jako lokalną.
Mam jeszcze problem z szerokościa wydruku. Maksymalnie mogę ustawić pozycję drukowania od lewej strony na wartości 255. A to jest tylko 3/4 szerokości formatu A4. Jak rozszerzyć drukowanie na pozostałą część strony?

KOD cpp:     UKRYJ  
cSendBuf[20] = 0x1b; // pozycja drukowania od lewej
cSendBuf[21] = 0x24;
cSendBuf[22] = 0xff; // 255
cSendBuf[23] = 0x0;
Avatar użytkownika
duf
Intelektryk
Intelektryk
 
Posty: 175
Dołączył(a): czwartek, 9 października 2008, 13:02
Podziękował : 17
Otrzymał podziękowań: 2
System operacyjny: Windows 10
Kompilator: XE8
Gadu Gadu: 0
    Windows XPFirefox

Re: Komendy drukowania

Postprzez polymorphism » środa, 19 października 2011, 14:45

ale według Twojej sugestii nie mam pojęcia jak zadeklarować tą tablicę jako lokalną.

No przecież teraz masz zadeklarowaną jako lokalną! Ja nie pisałem o tym, że ta tablica powinna być lokalna, bo przecież jest, tylko o sposobie jej tworzenia. Ponieważ niewielkie tablice o stałym i znanym w czasie kompilacji rozmiarze, które są użyte tylko na potrzeby lokalne, np. wewnątrz funkcji, powinny być tworzone na stosie.

Jak rozszerzyć drukowanie na pozostałą część strony?

Czytając dokumentację? Przecież komenda 24h jest dwuargumentowa, to znaczy te dwa argumenty składają się na jedną wartość 16-bitową:
TeX: \frac{n1 + (n2 * 256)}{120}
n1 to młodsze osiem bitów, n2 - starsze osiem bitów.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Komendy drukowania

Postprzez duf » czwartek, 20 października 2011, 11:19

polymorphism napisał(a):
Jak rozszerzyć drukowanie na pozostałą część strony?

Czytając dokumentację? Przecież komenda 24h jest dwuargumentowa, to znaczy te dwa argumenty składają się na jedną wartość 16-bitową:
TeX: \frac{n1 + (n2 * 256)}{120}
n1 to młodsze osiem bitów, n2 - starsze osiem bitów.

Mimo szczerych chęci nie rozumiem jak ustawić stronę. Co to znaczy młodsze/starsze
Avatar użytkownika
duf
Intelektryk
Intelektryk
 
Posty: 175
Dołączył(a): czwartek, 9 października 2008, 13:02
Podziękował : 17
Otrzymał podziękowań: 2
System operacyjny: Windows 10
Kompilator: XE8
Gadu Gadu: 0
    Windows XPFirefox

Re: Komendy drukowania

Postprzez polymorphism » czwartek, 20 października 2011, 12:48

duf, zajrzyj do książek. To są podstawy podstaw.


--- dodane ---

Dla jasności dodam tylko, że wzór, który podałem wyżej, wzięty jest z dokumentacji opisującej komendy drukarki. Czym jest wartość otrzymana z tego wzoru, w jakich jednostkach jest wyrażona - nie wiem, nie chce mi się w to teraz zagłębiać. W każdym razie, żeby wyliczyć n1 i n2, wystarczy przekształcić ten wzór (problemów być nie powinno, wszak to matematyka na poziomie gimnazjum ;)).


--- jeszcze raz dodane ---

Fuck! pomyliłem wzory :evil: Przy opisie komendy 24h wzór jest inny niż ten, który podałem. Pomyliłem go ze wzorem z komendy 5Ch. Powinien być taki: TeX: n_1 + \frac{(n_2 * 256)}{120}. Czyli przy założeniu, że jednostką jest 1/60 cala(?), wtedy dla n1 = 255 głowica powinna przesunąć się nieco ponad 10cm względem lewego marginesu.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Następna strona

  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Ogólne problemy z programowaniem

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 3 gości