WinAPI Function: WritePrinter

Chris Kelleher

Administrator
Staff member
I have stumbled over de api call WritePrinter (winspool.drv) which
should be able to dump raw data to a printer. Has anyone tried using
this one succesfully (that is: the printer accecpting the pcl-codes
included in the output send to the printer.)

I'm trying to get those parameters right for 4gl, but if someone already
has done this .... :)

the WritePrinter call is closely related to:
OpenPrinter, StartDocPrinter, EndDocPrinter, ClosePrinter

all functions of winspool.drv

Thanks for anyone thinking with me.

Alexander
 

Chris Kelleher

Administrator
Staff member
Hi,
Here is some code I used to send file to printer. File was created when
printer port in windows was set to "FILE:".
I hope this can help.

Nenad Orlovic
*************************************
<BLOCKQUOTE><font size="1" face="Arial, Verdana">code:</font><HR><pre>
DEFINE INPUT PARAMETER PrinterName AS CHAR NO-UNDO. /* As set in Prineter
properties */
DEFINE INPUT PARAMETER FileName AS CHAR NO-UNDO.


DEFINE VARIABLE x AS INT NO-UNDO.
DEFINE VARIABLE pPrinter AS MEMPTR NO-UNDO.
DEFINE VARIABLE hPrinter AS INT NO-UNDO.
DEFINE VARIABLE hFile AS INT NO-UNDO.
DEFINE VARIABLE pBuf AS MEMPTR NO-UNDO.
DEFINE VARIABLE FileSize AS INT NO-UNDO.
DEFINE VARIABLE xSize AS INT NO-UNDO.
DEFINE VARIABLE pSize AS MEMPTR NO-UNDO.
DEFINE VARIABLE pFileName AS MEMPTR NO-UNDO.
DEFINE VARIABLE OutFileName AS CHAR NO-UNDO.
DEFINE VARIABLE pOutFileName AS MEMPTR NO-UNDO.
DEFINE VARIABLE DataType AS CHAR NO-UNDO.
DEFINE VARIABLE pDataType AS MEMPTR NO-UNDO.
DEFINE VARIABLE pDocInfo AS MEMPTR NO-UNDO.

SET-SIZE(pPrinter) = 4.

RUN OpenPrinterA (PrinterName,input-output pPrinter,0, output x).
IF x = 0
THEN MESSAGE "Error opening printer: " PrinterName VIEW-AS ALERT-BOX.
ELSE DO:
hPrinter = GET-LONG(pPrinter,1).

RUN CreateFileA (FileName , -2147483648,0,0,3,128,0,output hFile). /*
-2147483648 = $80000000 */
IF hFile = -1
THEN MESSAGE "Error opening file: " FileName VIEW-AS ALERT-BOX.
ELSE DO:
RUN GetFileSize (hFile,0,output FileSize).
IF FileSize = -1
THEN MESSAGE "Wrong file size" VIEW-AS ALERT-BOX.
ELSE DO:
SET-SIZE(pBuf) = FileSize.
SET-SIZE(pSize) = 4.

RUN ReadFile(hFile,pBuf,FileSize,pSize,0, output x).
IF x = 0
THEN MESSAGE "Error reading file: " FileName VIEW-AS ALERT-BOX.
ELSE DO:
xSize = GET-LONG(pSize,1).
IF xSize = 0
THEN MESSAGE "Attempt to read beyond end of file:" FileName
VIEW-AS ALERT-BOX.
ELSE DO:
OutFileName = "".
DataType = "RAW".
SET-SIZE(pDocInfo) = 12.
SET-SIZE(pFileName) = length(FileName) + 1.
PUT-STRING(pFileName,1) = FileName.
SET-SIZE(pOutFileName) = length(OutFileName) + 1.
PUT-STRING(pOutFileName,1) = OutFileName.
SET-SIZE(pDataType) = length(DataType) + 1.
PUT-STRING(pDataType,1) = DataType.
PUT-LONG(pDocInfo,1) = get-pointer-value(pFileName).
PUT-LONG(pDocInfo,5) = get-pointer-value(pOutFileName).
PUT-LONG(pDocInfo,9) = get-pointer-value(pDataType).

RUN StartDocPrinterA (hPrinter,1,pDocInfo,output x).
IF x = 0 THEN DO:
RUN GetLastError(output x).
MESSAGE "Error : " x VIEW-AS ALERT-BOX.
END.
RUN WritePrinter(hPrinter,pBuf,xSize,pSize,output x).
IF x = 0 THEN DO:
RUN GetLastError(output x).
MESSAGE "Error writing to printer: " PrinterName
get-long(pSize,1) xsize x VIEW-AS ALERT-BOX.
END.
RUN EndDocPrinter(hPrinter,output x).
END.
END.
END.
RUN CloseHandle(hFile,output x).
IF x = 0 THEN MESSAGE "Error closing file: " FileName.
END.


RUN ClosePrinter(hPrinter,output x).
IF x = 0
THEN MESSAGE "Error closing printer: " PrinterName VIEW-AS ALERT-BOX.
END.

/******************/
/* DLL Procedures */
/******************/
PROCEDURE GetLastError EXTERNAL "KERNEL32.DLL":
DEFINE RETURN PARAMETER x AS LONG.
END PROCEDURE.
PROCEDURE StartDocPrinterA EXTERNAL "WINSPOOL.DLL":

DEFINE INPUT PARAMETER hPrinter AS LONG.
DEFINE INPUT PARAMETER Level AS LONG.
DEFINE INPUT PARAMETER pDocInfo AS MEMPTR.
DEFINE RETURN PARAMETER x AS LONG.
END PROCEDURE.
PROCEDURE EndDocPrinter EXTERNAL "WINSPOOL.DLL":

DEFINE INPUT PARAMETER hPrinter AS LONG.
DEFINE RETURN PARAMETER x AS LONG.
END PROCEDURE.
PROCEDURE CreateFileA EXTERNAL "KERNEL32.DLL":

DEFINE INPUT PARAMETER lpFileName AS CHAR.
DEFINE INPUT PARAMETER dwDesiredAccess AS LONG.
DEFINE INPUT PARAMETER dwShareMode AS LONG.
DEFINE INPUT PARAMETER lpSecurityAttributes AS LONG.
DEFINE INPUT PARAMETER dwCreationDistribution AS LONG.
DEFINE INPUT PARAMETER dwFlagsAndAttributes AS LONG.
DEFINE INPUT PARAMETER hTemplateFile AS LONG.
DEFINE RETURN PARAMETER hFile AS LONG.
END PROCEDURE.
PROCEDURE ReadFile EXTERNAL "KERNEL32.DLL":

DEFINE INPUT PARAMETER hFile AS LONG.
DEFINE INPUT PARAMETER lpBuffer AS MEMPTR.
DEFINE INPUT PARAMETER nNumberOfBytesToRead AS LONG.
DEFINE INPUT PARAMETER lpNumberOfBytesRead AS MEMPTR.
DEFINE INPUT PARAMETER lpOverlapped AS LONG.
DEFINE RETURN PARAMETER x AS LONG.
END PROCEDURE.
PROCEDURE WritePrinter EXTERNAL "WINSPOOL.DLL":

DEFINE INPUT PARAMETER hPrinter AS LONG.
DEFINE INPUT PARAMETER pBuf AS MEMPTR.
DEFINE INPUT PARAMETER cbBuf AS LONG.
DEFINE INPUT PARAMETER lpdwWritten AS MEMPTR.
DEFINE RETURN PARAMETER x AS LONG.
END PROCEDURE.
PROCEDURE OpenPrinterA EXTERNAL "WINSPOOL.DLL":

DEFINE INPUT PARAMETER pPrinterName AS CHAR.
DEFINE INPUT-OUTPUT PARAMETER phPrinter AS MEMPTR.
DEFINE INPUT PARAMETER pDefault AS LONG.
DEFINE RETURN PARAMETER x AS LONG.
END PROCEDURE.
PROCEDURE ClosePrinter EXTERNAL "WINSPOOL.DLL":

DEFINE INPUT PARAMETER hPrinter AS LONG.
DEFINE RETURN PARAMETER x AS LONG.
END PROCEDURE.
PROCEDURE GetFileSize EXTERNAL "KERNEL32.DLL":

DEFINE INPUT PARAMETER hFile AS LONG.
DEFINE INPUT PARAMETER lpFileSizeHigh AS LONG.
DEFINE RETURN PARAMETER FileSize AS LONG.
END PROCEDURE.
PROCEDURE CloseHandle EXTERNAL "KERNEL32.DLL":

DEFINE INPUT PARAMETER hObject AS LONG.
DEFINE RETURN PARAMETER x AS LONG.
END PROCEDURE.
[/code]
 

LBaliao

Member
Hi Chris,

I tried this code and a file was created when the port was assigned as "FILE". However, when I sent it to a printer, it created a print job, status is "Printing" but nothing is happening with the printer. I am positive the printer is connected and working as I can use it to print other documents. Any ideas why this is happening? Thanks in advance.

Liza
 

StuartT

Member
This original code was posted 9 years ago and there have been many new versions of progress released in those 9 years, it is possible that the code no longer works with more modern versions of progress and newer printers
 

sdjensen

Member
I have just tested the code and on my XP it works if I replace winspool.dll with winspool.drv.

Tested on xp with OpenEdge 10.2A with a text file.
 
Top