Knowledge Base Nr: 00017 drucken.txt - http://www.swe-kaiser.de

Drucken einer Datei unter Linux und Oracle Forms und Ausgabe des Ergebnisses.
Prüft den Druckerstatus vor dem Drucken und verhindert im Gegensatz zum
Kopierbefehl 'cp' das Blockieren.wenn der Drucker nicht bereit ist.
Umgeht den Printspooler und druckt direkt auf den Druckerport.

  

/************ CHARGENBEGLEITKARTE ERSTELLEN UND DRUCKEN *****************************************/

PROCEDURE PRINT_CHARGENKARTE IS
...
BEGIN
select nvl(herstelldate,sysdate)
into vdate
from lr.fecharge
where fertnr = :PARAMETER.P_FERTNR
and cfertnr = :PARAMETER.P_CFERTNR;
...
-- Druckausgabe vorbereiten
error := PCL_SUPPORT.PCL_INIT('Palkarte.dat',1); -- Dateinamen, 1=Quer/2=Hoch
...
-- Linien, Texte und Barcodes aufbereiten
error := PCL_SUPPORT.PCL_LINEOUT(5,3,286,3,0.3);
error := PCL_SUPPORT.PCL_TEXTOUT(72,53,vVDATE,9,0,1);
error := PCL_SUPPORT.PCL_BARCODEOUT(95,30,:FEKOPF.FANR,8,150);
-- x-pos,y-pos,text,höhe mm,auflösung in dpi
...
-- Drucken mit Fehlerbehandlung
error := PCL_SUPPORT.PCL_Close;
if error != 0 then
vText := PCL_SUPPORT.GET_PRTERROR('');
HTXT.SHOW_ERROR('Druckerfehler: ' || vText,0,1);
else
HTXT.SHOW_ERROR('Drucke Chargenkarte...',2,0);
end if;
EXCEPTION WHEN OTHERS THEN
HTXT.SHOW_ERROR('Keine Daten',2,0);
END PRINT_CHARGENKARTE;

/************ DRUCKEN durch Aufruf von 'printfile' *****************************************/

FUNCTION PCL_Close RETURN PLS_INTEGER IS rc PLS_INTEGER;
...
BEGIN
...
v_text := './printfile '||v_filename||' /dev/lp0 >'||v_filename||'.log';
host (v_text);

-- Prüfen ob host-aufruf erfolgreich war
if FORM_SUCCESS then
return 0;
else
return -1;
end if;
END PCL_Close;


/************ DRUCKPROGRAMM 'printfile' **************************/

int getPrinterStatusSeriell()
{
//ACHTUNG: Die Portadressen und die zurückgelesenen Werte
// sind abhängig von Rechnerhardware und Druckertyp!
const int IOBASE = 0x2f8; //3f8,2f8,3e8,2e8
const unsigned char DRUCKER_OK = 0xa0; //Bitmuster Statusleitungen wenn alles ok.

//berechtigung freischalten
int nErr = ioperm(IOBASE, 8, 1);
if (nErr)
{
printf("\nError: ioperm(0x%04X): %d %s\n", IOBASE, errno, strerror(errno));
return -1;
}

unsigned char uc1,uc7;
uc1 = inb(IOBASE); //f.e. 0x3f8
uc7 = inb(IOBASE+6); //f.e. 0x3fe

//durch Ausprobieren ermittelt
if (((uc7 & DRUCKER_OK) == DRUCKER_OK) && (uc1 != 0))
return 1;
else
return 0;
}

int main(int argc, char *argv[])
{
...
FILE* fp = fopen(argv[1], "r");
if (!fp)
{
sprintf(szMsg, "Error: Datei <%s> kann nicht geöffnet werden -> %d %s", argv[1], errno, strerror(errno));
my_exit(-2, szMsg);
}

FILE* pr = fopen(argv[2], "w");
if (!pr)
{
sprintf(szMsg, "Error: drucker <%s> kann nicht geöffnet werden -> %d %s", argv[2], errno, strerror(errno));
my_exit(-30, szMsg);
}

int nStatus = -1;
char* pPrn = "";
if (strstr(argv[2], "tty")) //rs232 oder centronics?
{
pPrn = "seriell";
nStatus = getPrinterStatusSeriell();
}
else
{
pPrn = "parallel";
nStatus = getPrinterStatusParallel();
}

if (nStatus < 0)
{
sprintf(szMsg, "Error: Druckerstatus(%s) <%s> kann nicht abgefragt werden -> %d %s", pPrn, argv[2], errno, strerror(errno));
my_exit(-31, szMsg);
}
else if (nStatus == 0)
{
sprintf(szMsg, "Error: Drucker(%s) <%s> nicht bereit -> %d %s", pPrn, argv[2], errno, strerror(errno));
my_exit(-32, szMsg);
}

while (!feof(fp))
{
const int MAXBUFFER = 200;
unsigned char cBuffer[MAXBUFFER+1] = {0};

int n = fread(&cBuffer, 1, MAXBUFFER, fp);
if (ferror(fp))
{
sprintf(szMsg, "Error: Beim Lesen von Datei <%s> -> %d %s", argv[1], errno, strerror(errno));
my_exit(-4, szMsg);
}

if (n>0)
{
fwrite(&cBuffer, 1, n, pr);
if (ferror(pr))
{
sprintf(szMsg, "Error: Beim Drucken auf <%s> -> %d %s", argv[2], errno, strerror(errno));
my_exit(-5, szMsg);
}
}
}

fclose(fp);
fclose(pr);

sprintf(szMsg, "OK: Datei <%s> auf Drucker <%s> ausgegeben.", argv[1], argv[2]);
my_exit(0, szMsg);
}