Link to home
Start Free TrialLog in
Avatar of SStory
SStoryFlag for United States of America

asked on

vb.net acurate printer output

I'm having trouble printing accurately by inches, to a form.

I'm trying to print text starting at 1/16" left, 1 1/8 inches down
I even printed a rectangle around it to see where the layout rectangle is.
I'm getting 1/4" over and 1 1/4" down.

This makes the form not line up. I can never know what printer this app will run on, but it needs to print correctly on the form each time.  Any thoughts?
Private Function InchesToPrinterUnits(ByVal InchValue As Single) As Single
        'printer units are 1/100 of an inch

        Return InchValue * 100
 End Function

  Private Sub PrintDocument1_PrintPage(ByVal sender As System.Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles MyDoc.PrintPage
        'get printer dpi

        MyDoc.OriginAtMargins = False

        '1/16in,1 1/8in, 2 7/8in 1/16in
        Dim rctfResidence As New RectangleF(InchesToPrinterUnits(0.0625), 
InchesToPrinterUnits(1.125), InchesToPrinterUnits(2.875), InchesToPrinterUnits(0.3125))
        Dim sf As New System.Drawing.StringFormat()
        sf.Alignment = StringAlignment.Near

        With e.Graphics
            .DrawString(txtResidence.Text, fntData, Brushes.Black, rctfResidence, sf)
            .DrawRectangle(Pens.Red, rctfResidence.X, rctfResidence.Y, rctfResidence.Width, rctfResidence.Height)
            '.DrawString("", fntData, Brushes.Black, 0, 0)
        End With


        e.HasMorePages = False
    End Sub

Open in new window

Avatar of Jacques Bourgeois (James Burger)
Jacques Bourgeois (James Burger)
Flag of Canada image

Since you are dealing with different printers, you cannot assume that printer units are 1/100 of an inch. Most modern printers are 1/600 or 1/1200.

The resolution can change from one printer to another, and a printer can have many resolutions. Some have resolutions that are different horizontally and vertically.

Here is the code I use to get the default resolution of my own printer:
Dim settings As New System.Drawing.Printing.PrinterSettings
settings.PrinterName = "HP LaserJet 3015"
Debug.WriteLine(settings.DefaultPageSettings.PrinterResolution.X.ToString, settings.DefaultPageSettings.PrinterResolution.Y.ToString)

Open in new window

The result is 600: 600

If I run it with an older InkJet printer, I get 300:300.
Avatar of SStory

ASKER

Well, I thought that returned DPI, and the docs I read said printing in dotnet was done on a unit that was in 1/100 inch no matter what. So which is true?  I am wondering if my only real problem is the hard margin that the printer may have. I have found an article related to this :
http://www.codeproject.com/KB/printing/dotnetprinterbounds.aspx

I haven't tested it yet, and don't know if this is still an issue since the article was for an old version of Dotnet.  Do you have any experience with this to know?  The article suggests getting the hard margins and offsetting. I don't know why that would be necessary, but my print is only off 1/4" in both directions which could suggest the hard margin issue or minimum margin.  I just assumed that when I set
MyDoc.OriginAtMargins = False

That it would calculate from absolute 0,0 and not 0,0 at the hard margin. Maybe that is not correct.
I have not worked with that stuff in real life for years, I mostly go through Word, Excel and Access when I want to print from my applications nowadays. They take care of all that stuff.

But by reading the documentation in details, I think I might have found the solution. I am not at my development computer right now, so I cannot test.

If you set OriginAtMargins to False, the coordinate system is relative to the "printable page". It thus takes into account the hard margins, that is the portion of the sheet on which the printer won't print to prevent ink or toner overflow in the printer mechanism.

If you set it to True, then the coordinate system is at the page margins. The page margins are not set at 0,0 by default. I just tested on my current printer, and they are set at 100,100. This means 1/6", which is very close to the gap you get between 1/16" and 1/4".

Try setting the margins to what you need, something like the following before setting the OriginAtMargins to False. Adjust the value as needed. With 600 dots per inch, 1/4" would theoretically require a margin of 150:

MyDoc.DefaultPageSettings.Margins.Left = 150
Avatar of SStory

ASKER

Thanks! I will try that.
Yes, well, this is a "simple" app, and I didn't want to involve Word, etc. as the person buying it would have to then buy those.
I like the double quotes around "simple". Those simple applications always end up being more complex than they appear at the start.
Avatar of SStory

ASKER

So if I say print 1/16" over would that be

left margin + 1/16" or 1/16" from the edge? The form I am trying to print two really has no margin.
Avatar of SStory

ASKER

I'm starting to think this isn't going to be possible on a laser printer as the form needs to have no margins.
Maybe on a dot matrix or something where you can offset the form until it is properly aligned or something.
ASKER CERTIFIED SOLUTION
Avatar of Jacques Bourgeois (James Burger)
Jacques Bourgeois (James Burger)
Flag of Canada image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of SStory

ASKER

Well, actually some photo printers, print right to the edge.  I am looking for a printer that will do 1/16" or less and after talking with HP it appears there may be some portable printers capable of this.

I agree it is a pain. I will let you know how it turns out.
You are right, I forgot about that because I almost never print photos for my personal use and never had to do it on photo paper from my applications.

I happen to be able to do that on two HP inkjet color printers, and they are standard inkjet printers, not of the portable type.

Just checked on my DeskJet 6940. If I set it for Bordeless Printing, hard margins are set to 0.0, 0.0 and I can print up to the edges.

But for your information, there are limitations that might not be acceptable for your use. Some of those might be specific to my model of printer however.

First of all, this setting is defined in a special property of the printer drivers that needs to be set manually in the printer's preferences. I see no way of setting it through code, since this is not a feature that is exposed through the PrinterSettings class.

Printing is slower than normal in this mode, even when set for draft printing.

The paper track in those printers is not precise. There might be a slight difference in alignment between 2 sheets. This is usually not visible if you print with a margin or a thick border, but if the border is thin, it is very evident. In some sheets, part of the printout ends up outside of sheet so a thin line could not show on some pages.

When set to to Borderless printing, the only choice of sizes is a series of "Borderless ..." papers, such as "Borderless 8 1/2 x 11". There is photo paper sold in those sizes, but this paper is thicker than standard paper though. I wonder if there could be a problem such as ink buildup on the rollers in the long run with standard thinner paper.

If your need is to have a border around the page, you might consider having the border printed by a printing shop and use that paper when needed. A regular printer could then be used without problem.

Hoping these help you a bit.
Avatar of SStory

ASKER

Well, the form to be printed on is more like card stock paper anyway--thicker than normal paper at least.
Avatar of SStory

ASKER

I've talked to many manufacturers of printers and not found a one that sales a printer that will do this.  It is amazing to me.  For that reason I've not been able to complete the program.
Avatar of SStory

ASKER

I am awarding points because the question asked for "any thoughts," and the answer is apparently that it is not doable.