Printing Graphics.PageBounds not accurate

G

Gregg Walker

Hi,

I'm writing a check printing program that needs to put a MICR line 6/16" from the bottom of the page. Since the checks will be
printed on a laser printer using letter sized paper the printable area is not actually 8 1/2" x 11". I'm using an HP LaserJet 4000
and it cannot print all the way to the physical page boundaries. It has the following limitations:

Top Margin = 0.18"
Left Margin = 0.25"
Right Margin = 0.25"
Bottom Margin = 0.28"

The problem I'm having is the the graphics object being passed with PrintPageEventArgs is reporting its PageBounds property as the
full physical page size (850, 1100) instead of (804, 1050). The other properties are as follows:

Top = 0
Left = 0
Right = 850
Bottom = 1100
Width = 1100
Height = 950

I would have thought the PageBounds would be as follows:

Top = 18
Left = 25
Right = 1075
Bottom = 822
Width = 1050
Height = 804

It appears the drawing methods in the graphics are scaling the e.Graphics.PageBounds to fit within the physical page bounds which
makes it difficult to position gdi objects at exact physical locations on the printed page. In other words I can draw anywhere
within the e.Graphics.PageBounds and the results are visible on the printed page.

Is this a known bug in the .net printing or is it possibly a problem with my printer driver? Microsoft word does not have a problem
determing what the physical bounds of the printed page are.

Is there some other way to get the physical page bounds so that I can rescale the drawing points and rectangles?

Thanks for your help,
Gregg Walker
 
H

Herfried K. Wagner [MVP]

* "Gregg Walker said:
Is there some other way to get the physical page bounds so that I can rescale the drawing points and rectangles?

From my FAQ (<URL:http://dotnet.mvps.org/dotnet/faqs/>):

Sample is based on a C# sample written by Ron Allen.

The method 'GetHardMargins' expects a hDC to the printer's 'Graphics'
object during the print call. The printer may have a margin that is
different from the PrintPreViewDialog's margin. Values are returned in
the procedure's parameters:

\\\
Public Declare Function GetDeviceCaps Lib "gdi32.dll" ( _
ByVal hdc As IntPtr, _
ByVal nIndex As Int32 _
) As Int32

Private Const PHYSICALOFFSETX As Int32 = 112
Private Const PHYSICALOFFSETY As Int32 = 113
Private Const HORZRES As Int32 = 8
Private Const VERTRES As Int32 = 10
Private Const HORZSIZE As Int32 = 4
Private Const VERTSIZE As Int32 = 6

Public Sub GetHardMargins( _
ByVal hDC As IntPtr, _
ByRef Left As Single, _
ByRef Top As Single, _
ByRef Right As Single, _
ByRef Bottom As Single _
)
Dim offx As Single = _
Convert.ToSingle(GetDeviceCaps(hDC, PHYSICALOFFSETX))
Dim offy As Single = _
Convert.ToSingle(GetDeviceCaps(hDC, PHYSICALOFFSETY))
Dim resx As Single = _
Convert.ToSingle(GetDeviceCaps(hDC, HORZRES))
Dim resy As Single = _
Convert.ToSingle(GetDeviceCaps(hDC, VERTRES))
Dim hsz As Single = _
Convert.ToSingle(GetDeviceCaps(hDC, HORZSIZE)) / _
25.4F ' Screen width in inches.
Dim vsz As Single = _
Convert.ToSingle(GetDeviceCaps(hDC, VERTSIZE)) / _
25.4F ' Screen height in inches.
Dim ppix As Single = resx / hsz
Dim ppiy As Single = resy / vsz
Left = (offx / ppix) * 100.0F
Top = (offy / ppix) * 100.0F
Bottom = Top + (vsz * 100.0F)
Right = Left + (hsz * 100.0F)
End Sub
///
 
G

Gregg Walker

Thank you for the quick reply Herfried. I will definitely use this for my application.

Can I assume from your response that the problem as I described it is a bug that will be or has been fixed in .Net Framework 2.0?
Or is your sample just the expected way to deal with this issue?

Thanks again.

Sincerely,
Gregg Walker
 
J

Jeffrey Tan[MSFT]

Hi Gregg,

Yes, this is a known issue. PrintPageEventArgs.PageBounds will not start
from the actual page left-top corner related to the Graphic object, it will
start from the Graphic object left-top corner. That is: the physical
non-printing margins of the printer are not taken into account when
calculating the margins for the whole page.

If you are looking for the exact physical non-printing margins, you'll have
to P/Invoke the GetDeviceCaps API with the arguments PHYSICALOFFSETX and
PHYSICALOFFSETY.

For more information, please refer to:
http://groups.google.com/groups?hl=zh-CN&lr=&ie=UTF-8&frame=right&th=8f0838d
a6b8fb8b5&seekm=evwE91EACHA.1316%40tkmsftngp05

Thank you for your patience and cooperation. If you have any questions or
concerns, please feel free to post it in the group. I am standing by to be
of assistance.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.
 
R

Ron Allen

Gregg,
This is just the way it works for FW1.0/1.1.
For FW2.0(beta) they have added some new properties to the Graphics
object for OnPrintPage that return the hard margins for the printer. There
is also some code that supposedly shows that you are calling PrintPreview
vs. printing to a printer but it appears to not be working right in this
beta. I've filed a bug with code to reproduce that error.
This means that when FW2.0 is released if all works correctly there will
be no need to PInvoke GetDeviceCaps for most things.

Ron Allen

Gregg Walker said:
Thank you for the quick reply Herfried. I will definitely use this for my
application.

Can I assume from your response that the problem as I described it is a
bug that will be or has been fixed in .Net Framework 2.0? Or is your
sample just the expected way to deal with this issue?

Thanks again.

Sincerely,
Gregg Walker
 
R

Ron Allen

Gregg,
Make sure that when you get the hDC from the printer before calling this
that you release it again right away or there could be some problems.
Ron Allen
Gregg Walker said:
Thank you for the quick reply Herfried. I will definitely use this for my
application.

Can I assume from your response that the problem as I described it is a
bug that will be or has been fixed in .Net Framework 2.0? Or is your
sample just the expected way to deal with this issue?

Thanks again.

Sincerely,
Gregg Walker
 
G

Gregg Walker

Thanks for all the information and help everyone!!
Sincerely,
Gregg Walker

Ron Allen said:
Gregg,
Make sure that when you get the hDC from the printer before calling this that you release it again right away or there could be
some problems.
Ron Allen
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top