I need a following virtual print solution:
I configure some printer (any graphics printer) and setup in
"advanced options" -> "print processor" spoolfile format to EMF.
I redirect this printer to "FILE:"
I want to "catch" somehow EMF spool-file from printing job,
but I can't because these files are stored temporarily and deleted very
fast.
Exists any kind to do this ?
I need this EMF for display it on the screen (as picture).
I have WinDDK and I'm programist.
Must I write separate printer driver or UniDrv-minidriver
or maybe custom print-processor (to avoid from "despooling" EMF) ?
Or exists any trick to configure existing Windows printing system
to get (somewhere on disk) EMF spoolfile generated through print job?
or maybe some thirdparty freeware tool to help this ?
Regards,
Peter
As for general comments on your attempting to capture the spool file, I
would not recommend it if all you want to do is write a virtual printer
driver. I would instead recommend that you write a rendering plug-in similar
to the oemuni sample in the DDK and use the IPrintOemUni::FilterGraphics
function to dump the data to file. I am posting some additional info on
FilterGraphics below. Hope it helps.
The FilterGraphics callback is often used for implementing a bitmap printer
driver. This document is throws some light on this callback.
Basically, you get scan line data in the FilterGraphics callback.
The IPrintOemUni::FilterGraphics function allows a rendering plug-in to
modify scan line data and send it to the spooler. If you implement this,
then Unidrv would not spool your data. instead your method will be called
every time a buffer of data is sent and is ready to be spooled. The
OEMFilterGraphics callback can be used to implement a special compression
method, or to perform bit manipulation on the data stream that is sent to
the printer, or both. In either case, the driver's built-in compression
code is not used. OEMFilterGraphics is presented with a block of data and
is required to send all output the data and to emit them using
DrvWriteSpoolBuf. The driver will perform no further processing of the
raster data after calling OEMFilterGraphics.
I would recommend that you first simply experiment with the OEMUNI sample
from the DDK as is. That is, just build the sample in a Checked build
environment, enable full debug logging (through the sources file for this
sample) and install it on a test machine using the OEMDLL.inf. Then, try
printing something very simple from wordpad and observe the debug spew in
Windbg. You should see the FilterGraphics() callback spitted out a number of
times. Then you can try setting a breakpoint at the return in -
HRESULT __stdcall IOemUni::FilterGraphics( PDEVOBJ pdevobj, PBYTE
pBuf, DWORD dwLen)
{
DWORD dwResult;
DebugMsg(DLLTEXT("IOemUni::FilterGraphics() entry.\r\n"));
m_pOEMHelp->DrvWriteSpoolBuf(pdevobj, pBuf, dwLen, &dwResult);
if (dwResult == dwLen)
return S_OK;
else
return S_FALSE;
}
You might want to experiment with Paint and then with text. When you provide
the FilterGraphics callback in your OEM DLL, it will be used for sending the
raster data directly to the printer. The number of scanlines in a block is
specified through the optional parameter in the *Resolution section in the
gpd : *PinsPerPhysPass (this is explained in the DDK too under < 4.6.4.8
Option Attributes for the Resolution Feature >. This parameter is optional
and if not mentioned, it is 1, as for most of the InkJet and page printers;
else it should be a multiple of 8. In the FilterGraphics callback above,
pBuf points to the buffer containing the scanline raster data to be
manipulated by the OEM if necessary (eg compress etc) and finally sent out.
dwLen is the length of this buffer.
Examples why OEMs use the FilterGraphics callback in their plugins are: 1.
special compression techniques, 2. Bit manipulation of the incoming raster
data before sending it out to the printer etc. (which is what you seem
primararily interested in, right?) All the data should finally be sent by
FilterGraphics to the printer using the function DrvWriteSpoolBuf(). The
driver does not do any more processing on this data sent out by
FilterGraphics(). Now, if the OEM is indeed doing some special
compression/bit manipulation, he is responsible for allocation of the
buffers necessary for doing so. If you do not allocate your own buffers,
then your output will overwrite the source buffer if the compresses data is
smaller than the source.
Thus, I think, you should be able to accomplish the raster data manipulation
in the plugin using OEMFilterGraphics(). What you are given is simply a
chance to postprocess the raster data and the access to the data itself.
What you do with it is pretty much upto you and completely in your hand.
Using FilterGraphics, you will be getting a known number of scan lines (1
row of 1bpp bitmap) OR The number of scanlines is actually equal to =
*PinsPerPhysPass. For monochrome, you have 1 pixel = 1 byte. Bit depth = num
of bits/pixel = 1 for monochrome (1bpp). Thus, number of bytes in one scan
line = num of pixels/line = page width in pixels (bytes).
Number of scan lines = Height of the image; for 1bpp, thickness of each scan
line = width of 1 pixel; thus num of scan lines=height of image.
- Ashwin
This posting is provided "AS IS" with no warranties, and confers no rights.
"Piotr Galuszkiewicz" <p...@poczta.fm> wrote in message
news:#zK#IxCfCHA.348@tkmsftngp12...
Yes, a custom print processor is a solution, it must just copy (tee)
the EMF to yet another file.
Max
Thank you for your answer.
I need to develop virtual image printer driver for Win9x too.
Is IPrintOemUni::FilterGraphics callback the same as CBFilterGraphics
callback in Win9x minidrivers ?
Peter
"Ashwin Needamangala" <ash...@nospam.microsoft.com> wrote in message
news:#4NF1jIfCHA.1652@tkmsftngp09...