*URGENT* Printed output different on different printers?

Dear Experts,

I have a visual basic .net application printing on considerably
complex pre-printed forms using precise X and Y co-ordinates,
which all works well when printing from my own printer.

The problem is that different printers seem to have different
printable areas / hard margins and I every different printer I
try and print the forms on, the layout jumps and everything
prints incorrectly!

Does anyone have any suggestions to solve this problem?

Any suggestions appreciated...thanks!

Who is Participating?
softplusConnect With a Mentor Commented:
Which scaling are you using? I hope not Pixels :)

I use 4 settings, marginx, marginy, scalex, scaley;

To calibrate, print 4 "+"'s on a sheet of paper, so that they are clearly visible on all printers (i.e. 1/3 into the page). Have the user measure the distance from one border to the first one and the distance between two -> from left to right and top to bottom -> this will give you a margin + scale for x/y. Save these settings somewhere :))

For your scaling, I would do it differently, to make sure you don't make any simple typos in your code:

function ScaleAbsolutePrint(Xin, Yin, Byref Xout, Byref Yout)
.... returns the data in Xout and Yout

function ScaleRelativePrint(Xin, Yin, Byref Xout, Byref Yout)
.... also returns the data in Xout and Yout

Do all scaling in these functions. This way it doesn't matter if you have the wrong number here or there + you likely won't make a mistake with X/Y :).
It won't work. Different printer drivers use different settings - different printer models use different settings, different paper trays use different origins, etc.

The only reliable thing you can do is offer a calibration function with the app, i.e. print little "+"'s in the corners and have the user measure the distances from the paper border; use this to calculate the origin offset + size difference.

And yes, if you use something like Crystal Reports, it's going to be a pain!

For my "must be right" forms, I code the printing directly, that way I can use all the possible user settings and can reasonably hope that they are printed correctly. (yes, in a network, you will have to save the settings per Workstation+Printer -- the driver for Win2k might have a slightly different origin / border than the driver for XP ... ).

Who said printing was easy? :)
karim_ladhuAuthor Commented:
*shocked* Oh my goodness! Sounds a lot like my greatest fear there...
but thanks for the reply... i'm worried that you're probably right...

I was investigating the following... was just wondering if anyone could
give me some pointers on how to apply it or if it is doable for the issue
I'm describing...


Thanks again...

Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

what you do is setup offsets and scalars that can be configured by the user (very easy to add to your math  for printing)
karim_ladhuAuthor Commented:
Thanks for the pointers... having something user-configured does
appear to be the route here - if anyone has any code already written
for a calibration process or something of the sort and would not
mind sharing it here it would be appreciated a lot... :o)
the thing is that you need to use the values in YOUR code that prints (i.e. add offsets and multiply by scalars to calculate your x/y)
karim_ladhuAuthor Commented:
Of course, you're right - I was just hoping for an example to
look at because I'm a little unsure on how what you say can
be implemented... I looked on the web for some kind of an
article describing it too but without success...

If you could elaborate at all then that would be very helpful.

Here is how my printing code works... I have a function that
returns a the pixel equivelant of a measurement which is
taken in millimeters and passed into it. All X and Y co-ords
within Print Documents pass through that one routine, so it
looks like this...

    Private Function mm(ByVal n As Double, ByVal d As Integer) As Double

        Dim xmargin As Single
        Dim ymargin As Single

        'the -4 (mm) and -2 (mm) values seem to work for aligning the document on the printer I'm using now...
        ymargin = -4 * (827 / 210) '827 pixels = A4 Measure, 210mm (should be ~ same as below)
        xmargin = -2 * (1169 / 297) '1169 pixels = A4 Measure, 297mm

        If d = 1 Then 'absolute x
            Return (n * (1169 / 297)) + xmargin
            If d = 2 Then 'absolute y
                Return (n * (827 / 210)) + ymargin
                If d = 3 Then 'relative x - no need to take margin into account
                    Return (n * (1169 / 297))
                Else 'relative y - no need to take margin into account
                    Return (n * (827 / 210))
                End If
            End If
        End If

    End Function


In a printdocument, it would work like this...

   'absolute reference
   X = mm(15, 1)
   Y = mm(15, 2)
   e.Graphics.DrawString("Sample String", MyFont, Brushes.Black, X, Y)

   'relative reference - ie. between code to loop lines in a repeating list
   Y = Y + mm(20,4)


Any further assistance much appreciated... thank you,

karim_ladhuAuthor Commented:
Thanks softplus...

From what I gather, it would be something like this...

Print an X at (50mm,50mm)
and another (50mm,120mm)
and another (120mm,50mm)
and another (120mm,120mm)

So that on the page it looks something like this:

                 X                     X

                 X                     X

Measure distance between top and left edges to first X to get printer margin...
Measure distance between vertical and horizontal X marks to get scale...

let's say that Xdist and Ydist is the distance from right and top edges to X...
and Hdist and Vdist the distance between horizontal and vertical X marks...

Knowing that there is a gap of 70mm between each X mark, and 50mm from
each of the borders to the virtual page, would these calculations be right?
(assuming we're converting the margins from milimeters into pixels)

marginX = (Xdist - 50) * (1169 / 297)
marginY = (Ydist - 50) * (827 / 210)
scaleX = (Hdist/70)
sclaeY = (Vdist/70)

...and then within the return block of the function...

        If d = 1 Then 'absolute x
            Return ((n * scaleX )*(1169 / 297)) - marginX
            If d = 2 Then 'absolute y
                Return ((n * scaleY)*(827 / 210)) - marginY
                If d = 3 Then 'relative x - no need to take margin into account
                    Return ((n * scaleX) * (1169 / 297))
                Else 'relative y - no need to take margin into account
                    Return ((n * scaleY) * (827 / 210))
                End If
            End If
        End If

Does that look alright to you? - I'm not able to try it out until later on today
but I thought I would perfect the conceptual model in the meanwhile :o)

Thank you for all your time and help... I hope I haven't misunderstood the
whole thing but hey, I wouldn't be suprised either! ;-)

Karim, that looks about right -- play around with it a bit, you'll see there's no magic involved :))
karim_ladhuAuthor Commented:
Thanks for your help - worked great, though thus far,
the scaling ratio on all printers checked (ten models,
three manufacturers) has been 1:1 so I am not very
sure it will ever be used - nonetheless, all is well
that ends well I suppose!

Thanks again,

All Courses

From novice to tech pro — start learning today.