tags:

views:

126

answers:

2

I'm trying to find out max available area on my printer. I've printed a simple rectangle trying out different boundary variables. My question is, why doesn't first two work correctly? They don't print a full rectangle on the paper, only the left and top sides are drawn. Why does only the third one prints a full rectangle? I was under the impression of that all three should be working correctly. What am I missing?

Here's my code:

this.printDocument1.DefaultPageSettings.Margins = new Margins(0, 0, 0, 0);

...
private void PrintPage(object sender, PrintPageEventArgs e)
{
    //Method 1, no right and bottom sides are printed
    e.Graphics.DrawRectangle(new Pen(Color.Black, 1), e.PageBounds);

    //Method 2, same as Method 1
    e.Graphics.DrawRectangle(new Pen(Color.Black, 1), e.MarginBounds);

    //Method 3, works correctly
    e.Graphics.DrawRectangle(new Pen(Color.Black, 1), new Rectangle((int)e.Graphics.VisibleClipBounds.X, (int)e.Graphics.VisibleClipBounds.Y, (int)e.Graphics.VisibleClipBounds.Width, (int)e.Graphics.VisibleClipBounds.Height));
}
+1  A: 

My first guess is that 2 is working with the margins you set previously (0,0,0,0) and that your printer doesn't actually support no-margin printing (most don't). Because of the fact that most printers require at least some margins, #1 will pretty much never work.

Method 3 appears to actually be querying the driver for the printable area of the page and then using that, so, it works.

As for why you get the top and left instead of nothing with #1 and #2, this is because you're just saying "print me a rectangle of these dimensions starting at the upper left hand corner of the printable area" not "print me a rectangle with these dimensions and start in the far upper left hand corner of the page where you can't actually print" so it's trying to, but it goes off the edge of the page since it's bigger than the printable area of the page.

Donnie
+1  A: 

First one doesn't work because you are trying to print out of margins. Second one fails because you are trying to print over the margin, so the right and bottom lines fall 1 pixel off the bounds. Now 3rd one works IMO because, printing rectangle coordinates are floating point, and you are casting them to integers, thus rounding them down, so the rectangle falls inside the print area.

EDIT Some additional info I found regarding your comment: "If the Graphics object is using a nondefault PageUnit,[2] then VisibleClipBounds will be in different units than PageBounds (which is always in units of 100 dpi). To handle these variables, it's useful to have a helper method to return the "real" page bounds in a consistent unit of measure"

Check out this article , I believe it covers everything.

m0s
Regarding to method 2, I traced two areas. e.MarginBounds: {X=0,Y=0,Width=827,Height=1169} and e.Graphics.VisibleClipBounds: {X=0,Y=0,Width=799,9999,Height=1137,667}. Why is MarginBounds is this much different then VisibleClipBounds? If it is any important, e.PageSettings.HardMarginX: 13 and e.PageSettings.HardMarginY: 11.
Armagan