DrvCopyBits and Manged Surfaces

All,

I’m working on a printer driver and have some basic questions with regards
to managing surfaces for graphics. Since I believe this is very similar to
the processing that takes place in a display driver, I figure someone in the
group can help.

The printer driver (a UniDrv rendering plugin) needs to post process all
images befores sending them to the actual printer. I would like to rely on
the GDI to do all of the drawing and then just post process the final image.
The printer only needs to deal with bit-maps.

This model that I’m referring to is a “GDI -Managed surface” - is this
correct?
In this model does the driver need to create its own surface. Do something
like hook out DrvCreateDeviceBitMap and then call something like
EngCreateDeviceBitmap()?

Since the driver needs to post process the image, I’m planning on hooking
out all of the graphics functions. Since I want the GDI to do as much of the
processing as possible (clipping, color translation, drawing, etc), I want
to call the default methods and then have the final image in the destination
surface. I would then assume that final bit map would be stored in the
pvBits member of the destination SURFOBJ. Is this how it works?

TIA.

Jimmy,

if you are planning on allowing the GDI to do all drawing to the surface, as it sounds you are, you should be able to get away with a very minimum amount of overhead.

I do not beleive that you would need to hook DrvCreateDeviceBitmap, not call EngCreateDeviceBitmap.
Since this is a rendering plug in for UniDRV, most of the “house keeping” work has been done.

You should also be able to get away without hooking ANY of the regular grunt work drawiing calls.
UniDrv will automatically pass them all on to the GDI for drawing, and your sirface bitmap should be drawn by the GDI wilth little aid or effort from you.

Since your primary concern in in post processign the entire page before sending to printer, I would think you could grt away with only hooking DrvSendPage.

In your DrvSendPage hook, the GDI will pass you the surface object which has been by that time completely drawn. You could use the provided pointers to the bits in the surface bitmap to to process and or alter your surface.

Once you have processed the surface, send it to the pritner via a call to EngWritePrinter (see documentation for details.)

I don’t see whay you would have to do much more than hooking DrvSendPage. The good thing is that by that time the entire surface has already been drawn for you and is handed to you finished.

Cary J.

Hi Cary,

Thanks a lot for your reply.

I’ve modified my driver to only hook out the DrvSendPage function. I
assuming that the page image will be stored in the pvBits member of SURFOBJ
that is passed to the function - is that correct? When I look inside this
buffer it contains all zeros. If the file being printed was just a simple
text file, would I see the text characters or would I see the text rendered
as a bit map?

Thanks,
Jim

wrote in message news:xxxxx@ntdev…
> Jimmy,
>
> if you are planning on allowing the GDI to do all drawing to the surface,
> as it sounds you are, you should be able to get away with a very minimum
> amount of overhead.
>
> I do not beleive that you would need to hook DrvCreateDeviceBitmap, not
> call EngCreateDeviceBitmap.
> Since this is a rendering plug in for UniDRV, most of the “house keeping”
> work has been done.
>
> You should also be able to get away without hooking ANY of the regular
> grunt work drawiing calls.
> UniDrv will automatically pass them all on to the GDI for drawing, and
> your sirface bitmap should be drawn by the GDI wilth little aid or effort
> from you.
>
> Since your primary concern in in post processign the entire page before
> sending to printer, I would think you could grt away with only hooking
> DrvSendPage.
>
> In your DrvSendPage hook, the GDI will pass you the surface object which
> has been by that time completely drawn. You could use the provided
> pointers to the bits in the surface bitmap to to process and or alter your
> surface.
>
> Once you have processed the surface, send it to the pritner via a call to
> EngWritePrinter (see documentation for details.)
>
> I don’t see whay you would have to do much more than hooking DrvSendPage.
> The good thing is that by that time the entire surface has already been
> drawn for you and is handed to you finished.
>
> Cary J.
>

Jimmy,

The SURFOBJ that is passed to DrvSendPage is a bitmap which has had all operations, including text calls, rasterized onto it. So there will be no text info, just a finished bitmap ready to be sent to a printer, etc.

The SURFOBJ structure has members which give you all the info you will need to “read”, “parse” or “modify” or “save” the bitmap. In particular…

pso->sizlBitmap.cx // width of bitmap, in pixels
pso->sizlBitmap.cy // height of bitmap, in pixels
pso->pvBits // pointer to the beginning of the bitmap pixel array, as you correctly guessed
pso->lDelta // the absolute width of one row of pixels, in bytes, the “stride”
pso->iBitmapFormat // the number of bits per pixel (BMF_1BPP, BMF_8BPP, BMF_24BPP, etc.)

If you are intending to roll up your sleeves and physically “dig around” (like a a surgeon) in the bitmap to modify or process it, you will need the above parameters to negotiate your way around the bitmap.

For starters, I would recommend writing your own hand rolled
MyWriteBitmapFunction(SURFOBJ *surfin, WCHAR *filepathout) function.

In your hooked called to DrvSendpage(SURFOBJ *pso) I would place a call like this…

MyWriteBitmapFunction(pso, L"c:\some folder\driver page.bmp")

This would be a good way to master the bitmap structure, and have a physical bitmap which you can open and view in something as simple and common as Paint, etc.

Then, when you create MyProcessBitmapFunction(SURFOBJ *surfin), you could make the following calls from within DrvSendPage,

MyProcessBitmapFunction(pso);
MyWriteBitmapFunction(pso, L"c:\some folder\driver page.bmp");

and you will be able to immediately see the results of your brilliant processing algorithm.

Cary J.

Hi Cary,

Thanks again for your help. Your explanations help me to better understand
what it is I need to be doing.

The printer that we’re working with is “special”. To render text it
processes the ascii characters directly (, the whole bit). After ou
conversation, I modified the driver to manage its own surface to accummulate
all of the text lines sending then it to the spooler at DrvSendPage time.

To process images, the printer needs to process the bit map images. It needs
to transpose each pixel into a special font understood by the printer.

I’ve been doing some experimenting with various types of images (bmp, gif,
tiff, etc) and perhaps you can help me to understand what I’m seeing.

I most cases I see the DrvStretchBlt being called as the first processing
method. To process, the driver is “punting” to the GDI by calling
EngStretchBlt to render the image. Upon entry into DrvStretchBlt, pvBits of
the desrtination surface is NULL and the pvBits of the source surface are
non-NULL.

From within EngStretchBlt, I’m seeing DrvCopyBits being called. When
DrvCopyBits is called, I see that the source surface has been transposed. It
is now (according to sizlBitmap) the size of the entire page and that the
iBitmapFormat is now BMF_1BPP. In looking at the pvBits buffer it looks as
if EngStretchBlt has definitely rendered the image.

Some of the things that I’m not sure of are:
1. After being processed by EngStretchBlt, why is the iBitmapFormat
BMF_1BPP?
2. When EngStretchBlt processes the data what is the final format of the
data? Is it still a bitmap just stretch and with color added or is it a
rasterized image?

Thanks again for your help.
Jim

wrote in message news:xxxxx@ntdev…
> Jimmy,
>
> The SURFOBJ that is passed to DrvSendPage is a bitmap which has had all
> operations, including text calls, rasterized onto it. So there will be no
> text info, just a finished bitmap ready to be sent to a printer, etc.
>
> The SURFOBJ structure has members which give you all the info you will
> need to “read”, “parse” or “modify” or “save” the bitmap. In particular…
>
> pso->sizlBitmap.cx // width of bitmap, in pixels
> pso->sizlBitmap.cy // height of bitmap, in pixels
> pso->pvBits // pointer to the beginning of the bitmap pixel array, as you
> correctly guessed
> pso->lDelta // the absolute width of one row of pixels, in bytes, the
> “stride”
> pso->iBitmapFormat // the number of bits per pixel (BMF_1BPP, BMF_8BPP,
> BMF_24BPP, etc.)
>
> If you are intending to roll up your sleeves and physically “dig around”
> (like a a surgeon) in the bitmap to modify or process it, you will need
> the above parameters to negotiate your way around the bitmap.
>
> For starters, I would recommend writing your own hand rolled
> MyWriteBitmapFunction(SURFOBJ *surfin, WCHAR *filepathout) function.
>
> In your hooked called to DrvSendpage(SURFOBJ *pso) I would place a call
> like this…
>
> MyWriteBitmapFunction(pso, L"c:\some folder\driver page.bmp")
>
> This would be a good way to master the bitmap structure, and have a
> physical bitmap which you can open and view in something as simple and
> common as Paint, etc.
>
> Then, when you create MyProcessBitmapFunction(SURFOBJ *surfin), you could
> make the following calls from within DrvSendPage,
>
> MyProcessBitmapFunction(pso);
> MyWriteBitmapFunction(pso, L"c:\some folder\driver page.bmp");
>
> and you will be able to immediately see the results of your brilliant
> processing algorithm.
>
> Cary J.
>

Jim,

I believe that the reason you are getting a NULL pvBits on the destination surface in your DrvStretchBlt call is because of the way you created your surface. Unless I am mistaken, it seems you called

EngCreateDeviceSurface

and probably should have instead called

EndCreateBitmap

When you call EngCreateDeviceSurface, you are, in effect, telling GDI “Look, take it for granted that I have created a surface bitmap that is X wide by Y high. I will take care of all the drawing operations.”
When told this, the GDI shrugs and says “OK, you’re the boss, but be ready to handle everything I throw at you.”

Then, during the calls to DrvStretchBlt, etc, the GDI will pass in a pointer to a bitmap representing the source bitmap, but the pvBits of the destination will be NULL because you have already, in essence, told GDI that YOU were going to take care of the actual destination bitmap surface.

Getting back to your original goal, if your desire is to merely process the final image before it makes its way to the printer, you should be able to get away with allowing GDI to do everything, up until the last moment.

I would try this…

In your DrvEnableSurface call, eliminate the call to EngCreateDeviceSurface and replace it with a call to EngCreateBitmap. In this call you tell the GDI how large to make the bitmap, and you also tell it the format. If you desire or require a full color RGB bitmap, make sure that you pass the argument BMF_24BPP, etc. So your call would look something like…

SIZEL bitmapsize;

bitmapsize.cx = bitmap width;
bitmapsize.cy = bitmap height;

EngCreateBitmap(bitmapsize, bitmapstride, BMF_24BPP, 0, NULL);

With this call, you will have asked GDI to allocate the memory for the bitmap, and it will be in a format that the GDI can directly do all the drawing on. The GDI will also KNOW about this surface, so in all Drv_xxx calls the destination surface will be this surface, and will no longer be NULL.

Also, there is no need to hook DrvStretchBlt, nor any of the other Drv_xxx drawing calls. If you hook DrvStretchBlt, etc, you will have to punt the call back to EngStretchBlt, etc. But if you do NOT hook the calls, then GDI will see that the calls are not hooked, and it will automatically call EngStretchBlt on your behalf, without you even having to bother with it. Unless you have a specific reason why you need to hook DrvStretchBlt, etc, such as collecting stats for decisions later, there is no reason to hook DrvStretchBlt if the only work it accomplishes is immediately punting the call to EngStretchBlt, etc. You have the option of not hooking the calls, saving the effort, and GDI will automatically rasterize EVERYTHING onto your surface bitmap.

The only call you would need to hook would be DrvSendPage. GDI will call this with a pointer to your surface bitmap, which has by that time been completely drawn and finished.

With the pointer to this surface, you can at that time modify, or pre-process the image by direct manipulation of the bits pointed to by pvBits. As I suggested earlier, you could create a function similar to the following…

MyBitmapPreProcessingFunction(SURFOBJ *surfin)

and within that function do whatever you desire to the complete page image.
Then send the image to EngWritePrinter.

If you cannot send the bitmap directly to the printer, but need to translate it into “…special fonts understood by the printer…” then within the DrvSendPage function you can traverse each scanline using the pointer to pvBits, make a translation of the pixel into the “font character”, and send it to the printer via EngWritePrinter, etc.

Again, you should not need to hook any of the drv_xxx drawing calls unless you are going to do MORE than merely punting them to Eng_xxx equivalents. If you do not hook them, the GDI will call them directly without any effort on your part.

DrvSendPage is your best chance at getting access to the completely finished page in a rasterized format, and doing whatever you need before sending it on its way to the printer.

Cary J.

Hi Cary,
Thanks again. I’m back to working on this project and considering your comments.

Right now I’m having a fundemental problem. I’m trying to create/associate a surface with my device but the call to EngAssociateSurface() is failing. In the DrvEnablePDEV routine I’m calling EngCreateBitmap and EngAssociateSurface. EngAssociateSurface is returning FALSE and GetLastError() is returning 122 (ERROR_INSIFFICIENT_BUFFER). EngCreateBitmap() seems to succeed. The code is below. Do you have any ideas. By the way, I’ve tried various surface sizes and various parms values and always get the same error.

Thanks,
Jim
SIZEL surfSize;

surfSize.cx = 5100;

surfSize.cy = 6600;

ULONG lWidth = surfSize.cx*sizeof(ULONG);

// Create the bitmap surface

HBITMAP hBitMap;

hBitMap = EngCreateBitmap( surfSize,lWidth, BMF_32BPP,BMF_TOPDOWN | BMF_NOZEROINIT,NULL);

if (hBitMap == NULL)

{

ETCDbgPrint(“IETCPlugin::EnablePDEV: Failed to create the device surface. Status: %i.\n”,ERROR_OUTOFMEMORY);

}

else

{

// Associate the surface with the device

success = EngAssociateSurface( (HSURF)hBitMap, (HDEV)pDevObj->hEngine, (HOOK_BITBLT | HOOK_STRETCHBLT |HOOK_COPYBITS));

if (success == FALSE)

{

status = GetLastError();

ETCDbgPrint(“IETCPlugin::EnablePDEV:: Failed to associate the surface with the device. Status: %i.\n”,status);

EngDeleteSurface((HSURF)hBitMap);

}

else

{

pDevExt->pSurf = (PCHAR)hBitMap;

}

}

wrote in message news:xxxxx@ntdev…
> Jim,
>
> I believe that the reason you are getting a NULL pvBits on the destination surface in your DrvStretchBlt call is because of the way you created your surface. Unless I am mistaken, it seems you called
>
> EngCreateDeviceSurface
>
> and probably should have instead called
>
> EndCreateBitmap
>
> When you call EngCreateDeviceSurface, you are, in effect, telling GDI “Look, take it for granted that I have created a surface bitmap that is X wide by Y high. I will take care of all the drawing operations.”
> When told this, the GDI shrugs and says “OK, you’re the boss, but be ready to handle everything I throw at you.”
>
> Then, during the calls to DrvStretchBlt, etc, the GDI will pass in a pointer to a bitmap representing the source bitmap, but the pvBits of the destination will be NULL because you have already, in essence, told GDI that YOU were going to take care of the actual destination bitmap surface.
>
> Getting back to your original goal, if your desire is to merely process the final image before it makes its way to the printer, you should be able to get away with allowing GDI to do everything, up until the last moment.
>
> I would try this…
>
> In your DrvEnableSurface call, eliminate the call to EngCreateDeviceSurface and replace it with a call to EngCreateBitmap. In this call you tell the GDI how large to make the bitmap, and you also tell it the format. If you desire or require a full color RGB bitmap, make sure that you pass the argument BMF_24BPP, etc. So your call would look something like…
>
> SIZEL bitmapsize;
>
> bitmapsize.cx = bitmap width;
> bitmapsize.cy = bitmap height;
>
> EngCreateBitmap(bitmapsize, bitmapstride, BMF_24BPP, 0, NULL);
>
> With this call, you will have asked GDI to allocate the memory for the bitmap, and it will be in a format that the GDI can directly do all the drawing on. The GDI will also KNOW about this surface, so in all Drv_xxx calls the destination surface will be this surface, and will no longer be NULL.
>
> Also, there is no need to hook DrvStretchBlt, nor any of the other Drv_xxx drawing calls. If you hook DrvStretchBlt, etc, you will have to punt the call back to EngStretchBlt, etc. But if you do NOT hook the calls, then GDI will see that the calls are not hooked, and it will automatically call EngStretchBlt on your behalf, without you even having to bother with it. Unless you have a specific reason why you need to hook DrvStretchBlt, etc, such as collecting stats for decisions later, there is no reason to hook DrvStretchBlt if the only work it accomplishes is immediately punting the call to EngStretchBlt, etc. You have the option of not hooking the calls, saving the effort, and GDI will automatically rasterize EVERYTHING onto your surface bitmap.
>
> The only call you would need to hook would be DrvSendPage. GDI will call this with a pointer to your surface bitmap, which has by that time been completely drawn and finished.
>
> With the pointer to this surface, you can at that time modify, or pre-process the image by direct manipulation of the bits pointed to by pvBits. As I suggested earlier, you could create a function similar to the following…
>
> MyBitmapPreProcessingFunction(SURFOBJ *surfin)
>
> and within that function do whatever you desire to the complete page image.
> Then send the image to EngWritePrinter.
>
> If you cannot send the bitmap directly to the printer, but need to translate it into “…special fonts understood by the printer…” then within the DrvSendPage function you can traverse each scanline using the pointer to pvBits, make a translation of the pixel into the “font character”, and send it to the printer via EngWritePrinter, etc.
>
> Again, you should not need to hook any of the drv_xxx drawing calls unless you are going to do MORE than merely punting them to Eng_xxx equivalents. If you do not hook them, the GDI will call them directly without any effort on your part.
>
> DrvSendPage is your best chance at getting access to the completely finished page in a rasterized format, and doing whatever you need before sending it on its way to the printer.
>
> Cary J.
>

Jimmy,

You should not try to create your bitmap or associate the surface in DrvEnablePDEV, but should do these in DrvEnableSurface instead.

Move your calls for EngCreateBitmap and EngAssociateSurface out of DrvEnablePDEV and put them into DrvEnableSurface and then see if your surface assoication works.

Cary J.

Hi Cary,

Oh I see.

Just to be clear: this is a unidrv rendering plugin. I tried hooking out
DrvEnableSurface/DrvDisableSurface but I never saw them get called. If you
think (know) that hooking DrvEnableSurface/DrvDisableSurface works in this
model then obviously I’ve done something wrong and will re-visit it.

TIA,
Jimmy

On Wed, Sep 21, 2011 at 9:01 AM, wrote:

> Jimmy,
>
> You should not try to create your bitmap or associate the surface in
> DrvEnablePDEV, but should do these in DrvEnableSurface instead.
>
> Move your calls for EngCreateBitmap and EngAssociateSurface out of
> DrvEnablePDEV and put them into DrvEnableSurface and then see if your
> surface assoication works.
>
> Cary J.
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>

Jimmy,

Are you implementing a com based rendering plug in, or a non com based rendering plug in…

Cary J.

Hi Cary,

Its COM based plugin.

Since our last emal exchange I’ve done some more testing to verify that
DrvEnable/DisableSurface does not get called - but from the quetion above
you’ve probably already gathered that.

Thanks,
Jimmy

On Wed, Sep 21, 2011 at 2:06 PM, wrote:

> Jimmy,
>
> Are you implementing a com based rendering plug in, or a non com based
> rendering plug in…
>
> Cary J.
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>

Just another question on unrelated topic:

Do you happen to know of a way to specify a feature in a GPD file such that
its options are adjusted via an edit control instead of drop down list box?

In other words: do you know of a way to change the control type that is used
to select the options for a feature?

TIA!
Jimmy

On Wed, Sep 21, 2011 at 3:13 PM, JIm james wrote:

> Hi Cary,
>
> Its COM based plugin.
>
> Since our last emal exchange I’ve done some more testing to verify that
> DrvEnable/DisableSurface does not get called - but from the quetion above
> you’ve probably already gathered that.
>
> Thanks,
> Jimmy
>
>
>
> On Wed, Sep 21, 2011 at 2:06 PM, wrote:
>
>> Jimmy,
>>
>> Are you implementing a com based rendering plug in, or a non com based
>> rendering plug in…
>>
>> Cary J.
>>
>> —
>> NTDEV is sponsored by OSR
>>
>> For our schedule of WDF, WDM, debugging and other seminars visit:
>> http://www.osr.com/seminars
>>
>> To unsubscribe, visit the List Server section of OSR Online at
>> http://www.osronline.com/page.cfm?name=ListServer
>>
>
>

Jimmy,

Had to do a little research since my project is not unidrv, but this is what I found…

You are correct: it does no good to “hook” DrvEnableSurface in unidrv project. Seems that where surface creation is taken care of is in

IPrintOemUni::DriverDMS

If I am reading the documentation correctly, it seems to be saying that if you do not hook any functions within this call, that a GDI managed surface will be created via a call to EngCreateBitmap on your behalf. However, if you hook ANY drawing functions here, then the GDI will create a device managed surface with a call to EngCreateDeviceSurface on your behalf. Also, this implies the following…

You are still left with allocating space for you surface (after all it IS DEVICE MANAGED, meaning YOU)
You must hook ALL drawing functions. (I might be wrong on that, but the documentation seems to say as much).

So I would boil it down to this…

If you know that you are going to let the GDI do all drawing, you do not need to hook any drawing functions within IPrintOemUni::DriverDMS. That means not hooking even HOOK_BITBLT. HOOK_STRETCHBLT or HOOK_COPYBITS. If you leave those hooks out, and leave your hooks blank, then the GDI will create a GDI managed surface for you which the GDI will do all drawing on. Then all you have to do is take care of your call in DrvSendPage for your post processing.

Remember, if in your calls to DrvStretchBlt, DrvBitBt and DrvCopyBits, if ALL you are doing is merely taking the incoming arguments and passing them straight to EngStretchBlt, EngBitBlt and EngCopyBits, then there is no reason to hook those calls. So if you eliminate the hooks for those in IPrintOemUni::DriverDMS then you will not need those functions, they will not be called, and GDI will set up a GDI managed surface. This means that when GDI calls your DrvSendPage the pso->pbVits will not be null, but will contain a completely rastered page which you can parse and translate, etc.

However, if you are doing stuff in your calls to DrvStretchBlt, etc, other than punting to EngStretchBlt, etc, and therefore hook those functions in IPrintOemUni::DriverDMS, then you will be required to implement ALL drawing functions (I think), in which case most of those can still be punted to Eng_xxx.

And if you do so, GDI will create a Device managed surface with its own call to EngCreateDevice Surface (which it is currently doing under your architecture). This means that you will have to create your own surface, which you CANNOT associate with the PDEV. Remember, under Unidrv, the surface creation AND implementation is taken care of for you in IPrintOemUni::DriverDMS.

So I would try eliminating you current hooks in IPrintOemUni::DriverDMS, and if you do so you should notice that when DrvSendPage is called that your pso->pvBits value is now NON NULL.

I will have to look into the GPD file edit control versus drop down list box.

Cary J.

Hi Cary,

Thanks a lot for this. This helps me to verify what I’m seeing in my
testing.

When processing a graphical image, the printer has to be put into a special
mode. Thus I believe requires the driver to hook out all of the graphics
functions and then punting to the GDI to do the actual drawing.

I’m confused about the format of the source data that I’m receiving at the
entry point of DrvStretchBlt and the source data at the entry point of
DrvCopyBits.

When DrvStretchBlt is called, the source data (pso) is the size of the
original image and the BMF is usually 8 or 24 bits. When DrvCopyBits is
called (as a result of punting to GDI), the source data has now been stretch
to the full, on page size, and the BMF is 1.

I am assume that the source data at DrvStretchBlt is the image portion of
the gif or bmp, tiff, etc that has been extracted from the file - is this
correct? But the source data at DrvCopyBits - one bit monochrome data - what
is that? I guess that’s rasterized data but why is it black/white?

Also, after doing a far amount of testing the only hooked functions that get
called are DrvStretchBlt and DrvCopyBits. Do you happen to know of ways to
get the other entry points (DrvStretchBltROP, DrvTransparentBlt, DrvBitBlt,
etc) to be called?

After looking at the Edit Control Issue it seems that the best way would be
to use the Layout Template and add the control through the methods described
in the following section of the DDK. Does that sound reasonable to you?

ms-help://MS.WDK.v10.7600.090618.01/Print_d/hh/Print_d/cpsui_c008ab0a-fafc-44d6-a606-1cc021c67191.xml.htm

Thanks again,
Jimmy

On Thu, Sep 22, 2011 at 12:33 PM, wrote:

> Jimmy,
>
> Had to do a little research since my project is not unidrv, but this is
> what I found…
>
> You are correct: it does no good to “hook” DrvEnableSurface in unidrv
> project. Seems that where surface creation is taken care of is in
>
> IPrintOemUni::DriverDMS
>
> If I am reading the documentation correctly, it seems to be saying that if
> you do not hook any functions within this call, that a GDI managed surface
> will be created via a call to EngCreateBitmap on your behalf. However, if
> you hook ANY drawing functions here, then the GDI will create a device
> managed surface with a call to EngCreateDeviceSurface on your behalf. Also,
> this implies the following…
>
> You are still left with allocating space for you surface (after all it IS
> DEVICE MANAGED, meaning YOU)
> You must hook ALL drawing functions. (I might be wrong on that, but the
> documentation seems to say as much).
>
> So I would boil it down to this…
>
> If you know that you are going to let the GDI do all drawing, you do not
> need to hook any drawing functions within IPrintOemUni::DriverDMS. That
> means not hooking even HOOK_BITBLT. HOOK_STRETCHBLT or HOOK_COPYBITS. If you
> leave those hooks out, and leave your hooks blank, then the GDI will create
> a GDI managed surface for you which the GDI will do all drawing on. Then all
> you have to do is take care of your call in DrvSendPage for your post
> processing.
>
> Remember, if in your calls to DrvStretchBlt, DrvBitBt and DrvCopyBits, if
> ALL you are doing is merely taking the incoming arguments and passing them
> straight to EngStretchBlt, EngBitBlt and EngCopyBits, then there is no
> reason to hook those calls. So if you eliminate the hooks for those in
> IPrintOemUni::DriverDMS then you will not need those functions, they will
> not be called, and GDI will set up a GDI managed surface. This means that
> when GDI calls your DrvSendPage the pso->pbVits will not be null, but will
> contain a completely rastered page which you can parse and translate, etc.
>
> However, if you are doing stuff in your calls to DrvStretchBlt, etc, other
> than punting to EngStretchBlt, etc, and therefore hook those functions in
> IPrintOemUni::DriverDMS, then you will be required to implement ALL drawing
> functions (I think), in which case most of those can still be punted to
> Eng_xxx.
>
> And if you do so, GDI will create a Device managed surface with its own
> call to EngCreateDevice Surface (which it is currently doing under your
> architecture). This means that you will have to create your own surface,
> which you CANNOT associate with the PDEV. Remember, under Unidrv, the
> surface creation AND implementation is taken care of for you in
> IPrintOemUni::DriverDMS.
>
> So I would try eliminating you current hooks in IPrintOemUni::DriverDMS,
> and if you do so you should notice that when DrvSendPage is called that your
> pso->pvBits value is now NON NULL.
>
> I will have to look into the GPD file edit control versus drop down list
> box.
>
> Cary J.
>
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>