views:

1460

answers:

3

I'm trying to open a Point of Sale (POS) printer using the OPOS Drivers in Delphi (BDS2006), but don't have a clue on how to check the printer status.

How would I check for messages like Check Paper and Paper Jam from the printer?

+5  A: 

I haven't used OPOS Drivers but I have done some work with POS Drivers for an Epson receipt printer connected to a cash drawer. What I discovered was that, if the printer is installed in Windows, you can then open a direct connection to it and make it do whatever you want.

The reason the printer is so slow is that it's using the graphical font functions of Windows. When you open the printer directly, you will set the mode to RAW and it will just send text out like an old-style dot-matrix. To kick the cash drawer open, you just send it the specific control codes as if you were going to print them. The printer intercepts the codes before it prints and kicks the drawer open.

BTW, I have no idea how this would work with Unicode. The printer I had only really worked with ASCII data. There might be variants designed for international markets that would work differently.

Here's the code I've used to make it work (VxMsgBox is just a cover to MessageBox):

{***************************************************************************}
{**             PrintDirect2Printer                                       **}
{***************************************************************************}
procedure PrintDirect2Printer(PrinterName, Data:pchar; dwByteCount:DWORD);
var PrinterHandle  : THandle;
    DocInfo        : TDocInfo1;
    dwJob          : DWORD;
    dwBytesWritten : DWORD;
begin
if not OpenPrinter(PrinterName, PrinterHandle, nil) then exit; //failed to open printer, abort
DocInfo.pDocName    := 'Direct 2 Printer';
DocInfo.pOutputFile := nil;
DocInfo.pDataType   := 'RAW';
dwJob:=StartDocPrinter(PrinterHandle, 1, @DocInfo);
if dwJob=0 then //failed to start a document
   begin
   ClosePrinter(PrinterHandle);
   exit;
   end;
if not StartPagePrinter(PrinterHandle) then
   begin
   EndDocPrinter(PrinterHandle);
   ClosePrinter(PrinterHandle);
   exit;
   end;
if not WritePrinter(PrinterHandle, Data, dwByteCount, dwBytesWritten) then
   begin
   EndPagePrinter(PrinterHandle);
   EndDocPrinter(PrinterHandle);
   ClosePrinter(PrinterHandle);
   exit;
   end;
if not EndPagePrinter(PrinterHandle) then
   begin
   EndDocPrinter(PrinterHandle);
   ClosePrinter(PrinterHandle);
   exit;
   end;
if not EndDocPrinter(PrinterHandle) then
   begin
   ClosePrinter(PrinterHandle);
   exit;
   end;
ClosePrinter(PrinterHandle);
if dwBytesWritten<>dwByteCount then
   VxMsgBox('Print Direct To Printer failed.', 'Printer Error', mb_Ok);
end;

{***************************************************************************}
{**             OpenPrintDirect2Printer                                   **}
{***************************************************************************}
function OpenPrintDirect2Printer(PrinterName, DocName:pchar; var PrinterHandle:THandle):boolean;
var DocInfo        : TDocInfo1;
    dwJob          : DWORD;
begin
result:=false;
if not OpenPrinter(PrinterName, PrinterHandle, nil) then exit; //failed to open printer, abort
DocInfo.pDocName    := DocName;
DocInfo.pOutputFile := nil;
DocInfo.pDataType   := 'RAW';
dwJob:=StartDocPrinter(PrinterHandle, 1, @DocInfo);
if dwJob=0 then //failed to start a document
   begin
   ClosePrinter(PrinterHandle);
   exit;
   end;
if not StartPagePrinter(PrinterHandle) then
   begin
   EndDocPrinter(PrinterHandle);
   ClosePrinter(PrinterHandle);
   exit;
   end;
result:=true;
end;

{***************************************************************************}
{**             WritePrintDirect2Printer                                  **}
{***************************************************************************}
function WritePrintDirect2Printer(PrinterHandle:THandle; Data:pchar; dwByteCount:DWORD):boolean;
var dwBytesWritten : DWORD;
begin
result:=true;
if not WritePrinter(PrinterHandle, Data, dwByteCount, dwBytesWritten) then
   result:=false;
if dwBytesWritten<>dwByteCount then
   VxMsgBox('WritePrintDirect2Printer byte check failed.', 'Printer Error', mb_Ok);
end;


{***************************************************************************}
{**             ClosePrintDirect2Printer                                  **}
{***************************************************************************}
procedure ClosePrintDirect2Printer(var PrinterHandle:THandle);
begin
if not EndPagePrinter(PrinterHandle) then
   begin
   EndDocPrinter(PrinterHandle);
   ClosePrinter(PrinterHandle);
   PrinterHandle:=0;
   exit;
   end;
if not EndDocPrinter(PrinterHandle) then
   begin
   ClosePrinter(PrinterHandle);
   PrinterHandle:=0;
   exit;
   end;
ClosePrinter(PrinterHandle);
PrinterHandle:=0;
end;
Marshall Fryman
+1, very useful - thanks! Just in case anyone tries to get this code to work - you'll need to add "WinSpool" to your uses clause.
robsoft
I have a recent Zebra label printer here, which supports a command (`^CI`) to select character set and encoding. But even though it supports UTF-16 BE and LE it works IMHO best with UTF-8 encoding when using Delphi 2009+, since all other commands remain ASCII. Building the data to be sent in an UTF-8 encoded string is easiest by far. Oh, +1 BTW.
mghie
A: 

Are you using the ActiveX control from here: http://monroecs.com/oposccos.htm? It has an event for error status.

R Ubben
hi i am currently implementing the solution Marshall Fryman sugested, just to give an update on this site http://monroecs.com/oposccos.htm?, everything i downloaded is corrupt... i downloaded 1.12.000 CCO Runtime (Wise Install) + 1.12.000 CCO Source Code and Data Files (ZIP File) both appears to be corrupted... ami getting the wrong stuff?
A: 

First of all you have to install the right support software for your device, which you probably have to download from the manufacturer's website. Keep in mind that sometimes, many devices (like receipt printers) contain standard hardware (ex EPSON TX-88III) although the brand name might differ.

The support software usually contains the driver, configuration tools, and possibly programming examples of how to use the driver. Make sure that the following steps are correctly completed:

  1. Installation of driver, config tools is done

  2. The device is correctly connected using the right cables (I had problems finding the correct serial cable, since there are many different types of them)

  3. Your device is recognised by the configuration software (through the driver) and communicates well, at least it responds to some functions

  4. Use the ActiveX control that was installed with the driver. It should have similar name with the driver.

After the above steps you will have a control in your application that provides you with all available functions, status properties and events (for paper, or anything other).