Zebra P640, P640i Programmer's Manual

Programmer’s Manual
For
Zebra P640/P640i Photo ID Printers
P/N: 980552-001 Zebra Card Solutions 6/15/2005 Page 1 of 40 www.zebracard.com
Zebra Technologies has made every effort to document this product fully and accurately. The software and documentation is, nevertheless, provided and licensed “as is.” Developer acknowledges and agrees that it has no rights to any upgrades, modifications, enhancements or revisions which Zebra Technologies may make to the software or documentation.
Developer assumes all risk, and Zebra Technologies makes no representation, warranty or guarantee whatsoever, express or implied, as to functionality, utility, error free operation, absence of any virus, or any other aspect of the software’s operation or performance, or the accuracy, completeness or adequacy of the documentation. Developer agrees that its use of the software and documentation is at developer’s own risk.
ZEBRA TECHNOLOGIES SPECIFICALLY DISCLAIMS ANY AND ALL WARRANTIES OF ANY NATURE IN CONNECTION WITH THE SOFTWARE AND DOCUMENTATION, TO INCLUDE, BUT NOT BE LIMITED TO, ANY WARRANTY OF MERCHANTABILITY OF FITNESS FOR A PARTICULAR PURPOSE.
Neither Zebra Technologies nor any of its agents, consultants, distributors or dealers shall, under any circumstances, be liable for any indirect, incidental or consequential damages arising from the use of this publication. Zebra Technologies reserves the right to make improvements and/or changes in the products and programs as described in this manual at any time without notice.
Copyright © Zebra Technologies 2005 All rights reserved.
Trademarks
Zebra Technologies is a registered trademark of Zebra Technologies, Inc.
P/N: 980552-001 Zebra Card Solutions 6/15/2005 Page 2 of 40 www.zebracard.com
1 Introduction
This document describes the programming interface to control Zebra Technologies P640 and P640i card printers. This manual along with the code and the reference distributed with it are known as the Zebra Technologies P640 Programmer’s Manual. This manual is intended as a reference for the developer wishing to write drivers or applications that control a Zebra Technologies P640 or P640i printer.
This manual is organized to assist the developer in rapidly becoming familiar with the P640/P640i printer. The first section gives an overview describing the driver architecture. The next section describes the programming steps necessary to carry out specific functions. Following this is a brief discussion of the code.
Developers using this manual should have a working knowledge of printers in general and a working knowledge of Ethernet networks, and USB and parallel interfaces.
P/N: 980552-001 Zebra Card Solutions 6/15/2005 Page 3 of 40 www.zebracard.com
1
DRIVER ARCHITECTURE 5
1.1 USER INTERFACE DLL 5
1.2 K
1.3 L
1.4 P
2
ERNEL/USER MODE DLL 5 ANGUAGE MONITOR 5 ORT MONITORS 5
SENDING COMMANDS TO THE PRINTER THROUGH THE DRIVER 6
2.1 EXAMPLE CODE – SENDING COMMAND TO PRINTER 7
2.2 O
2.3 C
2.4 G
2.4.1 E
2.5 S
2.6 S
3
PENPRINTER 8
LOSEPRINTER 8
ETPRINTERDATA 9
XCERPT FROM MESSAGES.H HEADER FILE 9
ETPRINTERDATA 25 ETPRINTERDATAEX 26
PRINTING A DOCUMENT 27
3.1 S
3.2 E
3.3 S
3.4 I
3.5 S
3.6 T
3.7 O
TARTDOC DEFINITION 27 NDDOC DEFINITION 27 TARTPAGE, ENDPAGE DEFINITION 28
MAGE DATA 28
ETDIBITSTODEVICE DEFINITION 29 EXTOUT DEFINITION 30
UTPUT DEFINITION 31
3.8 PIXEL DEFINITION 32
3.9 D
3.10 B
EVICEBITMAPBITS DEFINITION 33
ITBLT DEFINITION 34
4 MAGNETIC ENCODER DATA 36
4.1 SENDING MAGNETIC ENCODER DATA METHOD 36
4.2 T
4.3 ISO
ESTING MAGNETIC ENCODER FUNCTIONALITY 37
VERSUS AAMVA DATA FORMAT 38
P/N: 980552-001 Zebra Card Solutions 6/15/2005 Page 4 of 40 www.zebracard.com
2 Driver Architecture
2.1 User Interface dll
The user interface (UI) dll handles the display of the property sheets to the user when the user selects either Printing Preferences… or Properties | Device Settings. The UI gets the configuration information from the printer and displays it to the user. It also sends commands to the printer depending on user actions. The UI is responsible for updating the DevMode structure with driver configuration information. The DevMode structure is stored by the operating system in the registry, and is passed to the driver dlls whenever they are called.
2.2 Kernel/User mode dll
The kernel/user mode dll (DRV) handles the GDI (Graphical Device Interface) calls that are made by application programs to send print data to the printer. The DRV formats the print data for the printer performing such operations as black extraction and image rotation. It then writes the data to the spooler.
2.3 Language Monitor
The language monitor dll (LM) is called by the spooler when a print job is sent to the printer. The LM passes the print job along to the appropriate port monitor. The LM then monitors the status of the job as it prints and is responsible for communicating any errors that occur, to the user. The LM displays error dialogs explaining the corrective action to be taken to correct the error and handles reprinting jobs as necessary.
The language monitor also receives the GetPrinterData and SetPrinterData calls made by application programs. It passes these commands to the printer and passes any data returned from the printer back to the calling application.
2.4 Port Monitors
There are port monitor dlls (PMs) for each communication type that the P640 supports, parallel, USB, and Ethernet. The PMs are called by the language monitor and are used to pass the data between the LM and the printer using the appropriate protocol.
P/N: 980552-001 Zebra Card Solutions 6/15/2005 Page 5 of 40 www.zebracard.com
3 Sending Commands to the Printer through the Driver
An application program can send commands to the printer through the Language Monitor, using the GetPrinterData function. The command sent can be either a simple command or a request for the printer to return data. If data is to be returned, the caller must provide a buffer to store the returned data. If the returned data is variable in length, GetPrinterData can be called first with pData set to NULL and nSize set to 0. The function will fail, but the buffer size needed will be returned in pcbNeeded. See section 3.4 below for further explanation of these parameters.
It is good practice to call SetPrinterData with a NULL text string before calling GetPrinterData to ensure that all data from previous commands is erased.
To pass data to the printer, such as for setting the printer’s configuration (i.e. SMARTCARD_DATA), the application must first call SetPrinterDataEx with the data to be sent. This will store the data in the registry for retrieval by the Language Monitor. A GetPrinterData command is then issued to tell the Language Monitor to retrieve the data and send it to the printer.
The header file messages.h contains #defines for all of the messages that can be send to the Language Monitor by the driver or an application program. The header file printerdefs.h contains the data structure definitions for data being send to the printer and data being received from the printer. The structures make it easy to format the data correctly for the printer and to parse messages coming back from the printer.
P/N: 980552-001 Zebra Card Solutions 6/15/2005 Page 6 of 40 www.zebracard.com
3.1 Example Code – Sending command to printer
#define UNICODE #define _UNICODE
#include “printerdefs.h” #include “messages.h”
HANDLE hPrinter=NULL; DWORD dwType=0; DWORD dwRead=0; int retValue, count; TCHAR Data[ERROR_TEXT_SIZE];
PRINTER_DEFAULTS pd; pd.DesiredAccess = PRINTER_ALL_ACCESS; pd.pDatatype = NULL; pd.pDevMode = NULL;
if(OpenPrinter(TEXT(“Zebra P640”),&hPrinter,&pd)) { //Before Get, do dummy set to clear cached data SetPrinterData(hPrinter,COMMAND,REG_SZ,(LPBYTE)TEXT(""),
_tcslen(TEXT(""))*sizeof(TCHAR));
// if the command’s entry in messages.h says “Data: Yes”, set Data SetPrinterDataEx(hPrinter,ATL_MESSAGE_KEY,DATANAME,REG_SZ,
(LPBYTE)DATABUFFER, DATABUFFER_LENGTH));
// Data buffer MUST be at least ERROR_TEXT_SIZE TCHARs long // to receive results dwRet = GetPrinterData(hPrinter,Command,&dwType,(LPBYTE)Data,
ERROR_TEXT_SIZE*sizeof(TCHAR),&dwRead); if (!(_tcsncmp(Data,ERROR_SUCCESS_TEXT, ERROR_TEXT_SIZE))) { // success }
if (!(_tcsncmp(Data,ERROR_FAIL_TEXT, ERROR_TEXT_SIZE))) { // failure } else if (!(_tcsncmp(Data,ERROR_BUSY_TEXT, ERROR_TEXT_SIZE))) { // printer busy } ClosePrinter(hPrinter); } else { // failure }
P/N: 980552-001 Zebra Card Solutions 6/15/2005 Page 7 of 40 www.zebracard.com
3.2 OpenPrinter
Before making any other calls to the printer, you must first call OpenPrinter to establish a connection with the printer.
BOOL OpenPrinter(LPTSTR pPrinterName,LPHANDLE phPrinter,
LPPRINTER_DEFAULTS pDefaults);
pPrinterName
Pointer to a null-terminated string that specifies the name of the printer.
phPrinter
Pointer to a variable that receives a handle to the open printer object.
pDefaults
Pointer to a PRINTER_DEFAULTS structure. This value can be NULL
Return Values
If the function succeeds, the return value is a nonzero value.
If the function fails, the return value is zero. To get extended error information, call GetLastError.
3.3 ClosePrinter
After completing your calls to the printer, call ClosePrinter to free the connection.
BOOL ClosePrinter(HANDLE hPrinter);
hPrinter
handle to the printer returned from OpenPrinter
Return Values
If the function succeeds, the return value is a nonzero value.
If the function fails, the return value is zero. To get extended error information, call GetLastError.
P/N: 980552-001 Zebra Card Solutions 6/15/2005 Page 8 of 40 www.zebracard.com
3.4 GetPrinterData
DWORD GetPrinterData(HANDLE hPrinter,LPTSTR pValueName, LPDWORD pType,LPBYTE pData,DWORD nSize, LPDWORD pcbNeeded);
hPrinter handle to a printer from OpenPrinter pValueName
pointer to a string of TCHAR type. UNICODE should be defined in the project. Make sure it is NUL terminated. This is the command to execute. In some cases, an argument can come after the command. If such a command is entered, the remainder of the string after the command will be converted to single byte characters and sent to the printer.
pType
Type of data. This is ignored in our implementation so it should be NULL.
pData
Output Data buffer. If the command does not need data back, this may be NULL. The data is returned exactly as returned from the printer, so no big endian->little endian conversion is done, so if you need to cast it to something you need to do that yourself.
nSize
size of pData. If pData is NULL, this should be 0
pcbNeeded
the number of bytes read into pData. Note that, in general if GetPrinterData returns FALSE, the data here is invalid. It is NOT set to the number of bytes needed. However, there is an exception to this in the GET commands for paths and strings. In this case, it will be set to the needed number of bytes.
Return Values
ERROR_SUCCESS if the function succeeds, otherwise an error value.
3.4.1 Excerpt from messages.h header file
Listed below are the commands that can be sent to the printer. These are pulled from the messages.h header file used by the driver and IDPrint. For further explanation of any command’s function, see section 2 above. Each command is defined in the following format:
Command Name (ESC Code sent to printer by Language Monitor) #define for the command – this will be the pValueName parameter Input = function expects arguments following the command string input arguments should be
concatenated to the command Output = function returns data in pData Data = Data is to be put in the registry ahead of time by the SetPrinterDataEx command
¾NOTE: The data structures listed for input and output are defined in printerdefs.h
P/N: 980552-001 Zebra Card Solutions 6/15/2005 Page 9 of 40 www.zebracard.com
These few defines are used by multiple commands:
#define BOOL_NO_TEXT TEXT("0") #define BOOL_YES_TEXT TEXT("1") #define REDUCED_TEXT TEXT("2") #define BOOL_NO 0 #define BOOL_YES 1 #define REDUCED 2
¾NOTE: all REG_SZ type values should be Unicode Strings
Get Sense Data #define REQUEST_SENSE TEXT("REQUESTSENSE") Input: No Output: Yes – SENSEDATA structure Data: No
typedef struct tagSENSEDATA
{
union
{
BYTE byte;
// these are backwards because this compiler does bitfields backwards
struct
{
BYTE RESERVED03:2;
BYTE SCARD_PROBE_OK:1;
BYTE LAM_HEATING:1;
BYTE AC_FREQ:1;
BYTE BUSY_FABR_BOX:1;
BYTE BUSY_PRINTING:1;
BYTE MAG_DATA_READY:1;
} bits;
} bFlags;
BYTE bRibbonSensorValue;
BYTE bRibbonSensorThreshold;
BYTE bLaminationRibbonSensorThreshold;
WORD wRibbonEncCt1;
DWORD dwRcvBufSize;
DWORD dwDramSize;
WORD wPrintheadTemp;
WORD wPrintVoltage;
DWORD dwRibbonEncPer1;
DWORD dwRibbonEncPer2;
WORD wCleanStepCount;
WORD wTopTemp;
WORD wBotTemp;
WORD wNextPrintJob;
WORD wPrintJobInReceiveBuffer;
WORD wPrintJobPrinting;
WORD wRfidPanelCount;
P/N: 980552-001 Zebra Card Solutions 6/15/2005 Page 10 of 40 www.zebracard.com
} SENSEDATA, far *LPSENSEDATA;
Feed Ribbon #define RIBBON_FEED TEXT("RIBBONFEED") Input: No Output: No Data: No
Clean Cycle #define CLEAN_CYCLE TEXT("CLEANCYCLE") Input: No Output: No Data: No
Eject Card #define EJECT_CARD TEXT("EJECTCARD") Input: No Output: No Data: No
P/N: 980552-001 Zebra Card Solutions 6/15/2005 Page 11 of 40 www.zebracard.com
Request Sensor Data #define REQUEST_SENSOR_DATA TEXT("SENSORDATA") Input: No Output: Yes – SENSORDATA structure Data: No
typedef struct tagSENSORDATA
{
union {
WORD wFlipLift;
struct {
// NOTE: this assumes that you will be doing a big->little endian conversion
// on this word, since wFlipLift needs it!!
// these are backwards because this compiler does bitfields backwards
struct {
BYTE iButtonDone:1; // bit 0 - Write to iButton is complete
BYTE CarriageNearHopper:1; // bit 1 - Carriage is near // card hopper - 0 = Away, 1 = Near
BYTE HopperDoorOpen:1; // bit 2 - Hopper door open - 0 =
// Closed, 1 = Open BYTE CardLamExit:1; // bit 3 - Card Laminator Exiting // Sensor - 0 = No card, 1 = Card BYTE CardLamEnter:1; // bit 4 - Card Laminator Entering //Sensor - 0 = No card, 1 = Card BYTE ElevatorDown:1; // bit 5 - Elevator Down - 0 = Up, 1 =
// Down
BYTE CarriageHome:1; // bit 6 - Carriage Home Position - 0
// = Out of home, 1 = At home
BYTE DoorOpen:1; // bit 7 - Door Open Sensor - 0 =
// Closed, 1 = Open } LoByte; // these are backwards because this compiler does bitfields backwards struct {
BYTE JumperSelect1:1; // bit 8 - Jumper selection 1
// (reserved) BYTE ACLoss:1; // bit 9 - Loss of AC - 0 = power, 1 = no
//power BYTE HeadUp:1; // bit 10 - head state - 0 = down, 1 = up BYTE Reserved11:1; // bit 11 - reserved BYTE Reserved12:1; // bit 12 - reserved BYTE OvlAdvButton:1; // bit 13 - overlay advance button BYTE RibAdvButton:1; // bit 14 - ribbon advance button BYTE PrintButton:1; // bit 15 - print button } HiByte; } BooleanSensorsBits;
} Sensors_FlipLift; WORD wCardPresence; WORD wPrintStationSyncMark; WORD wTopLam; WORD wBottomLam; WORD wLamPresentThresh; WORD wLamAbsentThresh; WORD wReserved3; } SENSORDATA, far *LPSENSORDATA;
P/N: 980552-001 Zebra Card Solutions 6/15/2005 Page 12 of 40 www.zebracard.com
Loading...
+ 28 hidden pages