Accurate positioning of polygon for printer 
Author Message
 Accurate positioning of polygon for printer

Page to send to printer (PDF/inkjet/whatever).
ScaleMode set to millimetres - accuracy of layout is fine.
Have had to introduce some coloured, block arrows on 2 charts with vertical
positioning set by their values.
Using Polygon and CreatePolygonRgn for drawing the block arrows.
To translate from pixels to millimetres, I have been trying with:
GetDeviceCaps(Printer.hdc, LOGPIXELSX) and GetDeviceCaps(Printer.hdc,
LOGPIXELSY)
to produce a correction factor for pixels to millimetres - with not much
success.
The PDF printer is good on horizontal positining but illogically erratic on
the vertical
An HP inkjet is much more out of position.
Any help would be appreciated

Michael



Thu, 28 Oct 2010 00:24:06 GMT  
 Accurate positioning of polygon for printer

Quote:
> Page to send to printer (PDF/inkjet/whatever).
> ScaleMode set to millimetres - accuracy of layout is fine.
> Have had to introduce some coloured, block arrows on 2 charts with
> vertical
> positioning set by their values.
> Using Polygon and CreatePolygonRgn for drawing the block arrows.
> To translate from pixels to millimetres, I have been trying with:
> GetDeviceCaps(Printer.hdc, LOGPIXELSX) and GetDeviceCaps(Printer.hdc,
> LOGPIXELSY)
> to produce a correction factor for pixels to millimetres - with not much
> success.
> The PDF printer is good on horizontal positining but illogically erratic
> on
> the vertical
> An HP inkjet is much more out of position.
> Any help would be appreciated

> Michael

Dot{*filter*}illmeter = DPI / 25.4

If you are already doing this, post some code, including what
Printer.ScaleMode is set to, and the values from GetDeviceCaps().



Thu, 28 Oct 2010 02:28:55 GMT  
 Accurate positioning of polygon for printer


Quote:


> > Page to send to printer (PDF/inkjet/whatever).
> > ScaleMode set to millimetres - accuracy of layout is fine.
> > Have had to introduce some coloured, block arrows on 2 charts with
> > vertical
> > positioning set by their values.
> > Using Polygon and CreatePolygonRgn for drawing the block arrows.
> > To translate from pixels to millimetres, I have been trying with:
> > GetDeviceCaps(Printer.hdc, LOGPIXELSX) and GetDeviceCaps(Printer.hdc,
> > LOGPIXELSY)
> > to produce a correction factor for pixels to millimetres - with not much
> > success.
> > The PDF printer is good on horizontal positining but illogically erratic
> > on
> > the vertical
> > An HP inkjet is much more out of position.
> > Any help would be appreciated

> > Michael

> Dot{*filter*}illmeter = DPI / 25.4

> If you are already doing this, post some code, including what
> Printer.ScaleMode is set to, and the values from GetDeviceCaps().

Thanks for reply
Yes, tried the DPI/25.4
Have cut the code down as much as I can - still seems a lot to post
Everything positioned with Printer ScaleMode as vbMillimeters positions
accurately
but not with the pixels to millimetres conversion

Form1:

Option Explicit

Private Sub Command1_Click()
Dim PD As New cPrnDlg

    If PD.ShowPrinterDialog Then
        Printer.PaperSize = 9       'A4
        PrintCoverSheet
        Printer.EndDoc
    End If

    Set PD = Nothing

End Sub
*****************************************************
Bas Module:

Option Explicit

Private Type POINTAPI
    X As Long
    Y As Long
End Type

Private Declare Function GetDeviceCaps Lib "gdi32" _
    (ByVal hdc As Long, ByVal nIndex As Long) As Long

Private Declare Function SetBkMode Lib "gdi32" _
    (ByVal hdc As Long, ByVal nBkMode As Long) As Long

Private Declare Function CreatePolygonRgn Lib _
    "gdi32" (lpPoint As Any, ByVal nCount As Long, _
    ByVal nPolyFillMode As Long) As Long

Private Declare Function Polygon Lib "gdi32" _
    (ByVal hdc As Long, lpPoint As Any, ByVal nCount As Long) As Long

Private Declare Function FillRgn Lib "gdi32" _
    (ByVal hdc As Long, ByVal hRgn As Long, ByVal hBrush As Long) As Long

Private Declare Function DeleteObject Lib "gdi32" _
    (ByVal hObject As Long) As Long

Private Declare Function CreateSolidBrush Lib "gdi32" _
    (ByVal crColor As Long) As Long

Private Const LOGPIXELSX = 88
Private Const LOGPIXELSY = 90

Private Const ALTERNATE = 1 'constant for FillMode

Private Const PHYSICALOFFSETX As Long = 112
Private Const PHYSICALOFFSETY As Long = 113

Private Const TRANSPARENT As Long = 1
Private Const OPAQUE As Long = 2

Private Sub SetPrinterOrigin(X As Single, Y As Single)

    With Printer
        .ScaleLeft = .ScaleX(GetDeviceCaps(.hdc, PHYSICALOFFSETX), vbPixels,
.ScaleMode) - X
        .ScaleTop = .ScaleY(GetDeviceCaps(.hdc, PHYSICALOFFSETY), vbPixels,
.ScaleMode) - Y
        .CurrentX = 0
        .CurrentY = 0
    End With

End Sub

Private Sub DoPrint(sX As Single, sY As Single, Optional lFColor As Long =
vbBlack, _
                    Optional bBold As Boolean = False, Optional bItalic As
Boolean = False, _
                    Optional lFSize As Long = 9, Optional sFont As String =
"Times New Roman", _
                    Optional bText As Boolean = True, Optional sText As
String = "", _
                    Optional sLongBox As Single = 0, Optional sBoxLength As
Single = 17, _
                    Optional sLineLength As Single = 0, Optional bLineHoriz
As Boolean = True, _
                    Optional lLongBoxColour As Long = &HE0E0E0, Optional
sLongBoxHeight As Single = 4.5)

                    'X co-ord, Y co-ord, text colour, bold or not, italic or
not,
                    'font size in points, font
                    'false if data text needs standard box drawing , text to
print
                    'if box is longbox for headings with fill, otherwise box
length
                    'if line then length, line horizontal or vertical
                    'options for long box

    On Error GoTo EH

    With Printer
        .ScaleMode = vbMillimeters
        .FontName = sFont
        .FontSize = lFSize
        .FontBold = bBold
        .FontItalic = bItalic
        .ForeColor = lFColor
    End With

    If sLongBox > 0 Then
        Printer.FillColor = lLongBoxColour
        Printer.FillStyle = 0   'solid
        Call SetBkMode(Printer.hdc, OPAQUE)
        SetPrinterOrigin sX, sY - 0.25
        Printer.Line -(sLongBox, sLongBoxHeight), lLongBoxColour, B
        Call SetBkMode(Printer.hdc, TRANSPARENT)
        SetPrinterOrigin sX + 1, sY
        Printer.Print sText
        Exit Sub
    End If

    If sLineLength > 0 Then
        SetPrinterOrigin sX, sY
        Printer.DrawWidth = 1
        If bLineHoriz Then
            Printer.Line -(sLineLength, 0), vbGrayText
        Else
            Printer.Line -(0, sLineLength), vbGrayText
        End If
        Exit Sub
    End If

    If bText Then
        SetPrinterOrigin sX, sY
        Printer.Print sText 'print text
    Else
        SetPrinterOrigin sX, sY - 0.5
        Printer.FillColor = vbWhite
        Call SetBkMode(Printer.hdc, TRANSPARENT)
        Printer.DrawWidth = 1
        Printer.Line -(sBoxLength, 4.2), , B
        If Len(sText) > 0 Then
            Dim sngText As Single
            sngText = Printer.TextWidth(sText)
            SetPrinterOrigin sX + sBoxLength - 1 - sngText, sY
            Printer.Print sText
        End If
    End If

    Exit Sub

EH:
    MsgBox Err.Number & vbCrLf & Err.Description

End Sub

Public Sub PrintCoverSheet()
'Dim sPath As String
'Dim picLogo As StdPicture
Dim ptStart As POINTAPI
Dim sSAP As String, sEIR As String
Dim lSAPColour As Long, lEIRColour As Long, lEIR As Long

    On Error GoTo EH

'    sPath = "E:\VbMyFiles\SAP_wsheet_2005_TER_9.81\Cover_sheets\logo.jpg"
'    Set picLogo = LoadPicture(sPath)
'    SetPrinterOrigin 145, 14
'    Printer.PaintPicture picLogo, 0, 0, 32, 28
'    Set picLogo = Nothing

    DoPrint 30, 15, , , , 24, , , Trim$("Architect Name") & " " &
Trim$("MCIAT")
    DoPrint 30, 25, , , , 12, , , Trim$("Address bla bla bla")
    DoPrint 30, 31, , , , 10, , , Trim$("Telephone / email")
    DoPrint 15, 50, , , , 18, , , "SAP2005 WORKSHEET / DOCUMENT L1A (2006)"

    DoPrint 15, 68, , , , 12, , , CStr(Date)

    DoPrint 15, 78, , , , 12, , , "Project Ref: 9999"
    DoPrint 15, 88, , , , 12, , , "Project Address:"
    DoPrint 20, 99, , , , 12, , , "Client Name"
    DoPrint 20, 105, , , , 12, , , "Address1"
    DoPrint 20, 111, , , , 12, , , "Address2"
    DoPrint 20, 117, , , , 12, , , "Address3"
    DoPrint 20, 123, , , , 12, , , "Address4"

    DoPrint 15, 135, , , , 12, , , "Copy to: Office"

    'insert charts

    'draw the lines
    DoPrint 10, 168, , , , , , False, , , 0, 70.5, False
    DoPrint 72, 168, , , , , , False, , , 0, 62.5, False
    DoPrint 86, 168, , , , , , False, , , 0, 62.5, False
    DoPrint 100, 168, , , , , , False, , , 0, 70.5, False
    DoPrint 10, 168, , , , , , False, , , 0, 90, True
    DoPrint 10, 172.5, , , , , , False, , , 0, 90, True
    DoPrint 10, 230.5, , , , , , False, , , 0, 90, True
    DoPrint 10, 238.5, , , , , , False, , , 0, 90, True

    DoPrint 10, 160.5, vbWhite, True, , 12, "Arial", , "  Energy Efficiency
Rating", 90, , , , RGB(11, 103, 171), 5.5
    DoPrint 75, 169, , , , 7, "Arial", , "Current"
    DoPrint 88, 169, , , , 7, "Arial", , "Potential"
    DoPrint 11.5, 174, , , True, 7, "Arial", , " Very energy efficient -
lower running costs"
    DoPrint 11, 178, vbWhite, True, False, 7, "Arial", False, "(92-100)",
14, , , , RGB(0, 127, 83), 5
    DoPrint 24, 178, vbWhite, True, False, 11, "Arial", False, "A", 6, , , ,
RGB(0, 127, 83), 5

    DoPrint 11, 185, vbWhite, True, False, 7, "Arial", False, "(81-91)", 21,
, , , RGB(40, 164, 85), 5
    DoPrint 30, 185, vbWhite, True, False, 11, "Arial", False, "B", 6, , , ,
RGB(40, 164, 85), 5

    DoPrint 11, 192, vbWhite, True, False, 7, "Arial", False, "(69-80)", 28,
, , , RGB(134, 187, 67), 5
    DoPrint 36, 192, vbWhite, True, False, 11, "Arial", False, "C", 6, , , ,
RGB(134, 187, 67), 5

    DoPrint 11, 199, vbWhite, True, False, 7, "Arial", False, "(55-68)", 35,
, , , RGB(255, 203, 35), 5
    DoPrint 42, 199, vbWhite, True, False, 11, "Arial", False, "D", 6, , , ,
RGB(255, 203, 35), 5

    DoPrint 11, 206, vbWhite, True, False, 7, "Arial", False, "(39-54)", 42,
, , , RGB(247, 166, 98), 5
    DoPrint 48, 206, vbWhite, True, False, 11, "Arial", False, "E", 6, , , ,
RGB(247, 166, 98), 5

    DoPrint 11, 213, vbWhite, True, False, 7, "Arial", False, "(21-38)", 49,
, , , RGB(240, 120, 43), 5
    DoPrint 54, 213, vbWhite, True, False, 11, "Arial", False, "F", 6, , , ,
RGB(240, 120, 43), 5

    DoPrint 11, 220, vbWhite, True, False, 7, "Arial", False, "(1-20)", 56,
, , , RGB(288, 19, 56), 5
    DoPrint 60, 220, vbWhite, True, False, 11, "Arial", False, "G", 6, , , ,
RGB(288, 19, 56), 5

    DoPrint 11.5, 226, , , True, 7, "Arial", , " Not energy efficient -
higher running costs"
    DoPrint 12, 232.5, , , , 12, "Arial", , "England & Wales"
    DoPrint 70, 231.5, , , , 8, "Arial", , "EU Directive"
    DoPrint 70, 235, , , , 8, "Arial", , "2002/91/EC"

    Dim lTemp As Long
    'test to try different values for lTemp & lEIR
    lTemp = 80
    lEIR = 70

    sSAP = CStr(lTemp)

    Select Case lTemp
        Case Is < 21: lSAPColour = RGB(288, 19, 56)
        Case Is < 39: lSAPColour = RGB(240, 120, 43)
        Case Is < 55: lSAPColour = RGB(247, 166, 98)
        Case Is < 69: lSAPColour = RGB(255, 203, 35)
        Case Is < 81: lSAPColour = RGB(134, 187, 67)
        Case Is < 92: lSAPColour = RGB(40, 164, 85)
        Case Is >= 92: lSAPColour = RGB(0, 127, 83)
    End Select

    'range for pointer between 0 and 100 covers 49mm
    ptStart.X = 73: ptStart.Y = 177 + (49 - CLng(lTemp * 0.49))
    Call
...

read more »



Thu, 28 Oct 2010 06:31:03 GMT  
 Accurate positioning of polygon for printer
Until someone else more knowledgeable in this area hops in, you may want to
check LPtoDP/DPtoLP in MSDN.


Thu, 28 Oct 2010 12:13:07 GMT  
 Accurate positioning of polygon for printer

Quote:
> Yes, tried the DPI/25.4. Have cut the code down as much
> as I can - still seems a lot to post Everything positioned with
> Printer ScaleMode as vbMillimeters positions accurately
> but not with the pixels to millimetres conversion

I was about to post an answer to your original question when I noticed that
you had posted an update to it containing a fairly large amount of your
code. I haven't got time at the moment to look through that code in any
detail (although I promise I will do that if this answer does not provide a
solution for you) so for the time being I will post what I was about to post
before I read your second message . . .

. . . I was initially going to suggest that you were possibly failing to
correctly perform the conversion from the current ScaleMode to Pixels, but I
notice that you are using LogPixelsX and LogPixelsY, which is fine for
printing to screen devices and to printers (although it is not correct if
you are printing to metafiles, when you need to perform the conversion in a
different manner). Presumably you are printing only to Screen devices and to
Printers and to PDF Drivers, so LogPixelsX etc should be fine (although you
can more easily do it using the VB ScaleX and ScaleY functions if you wish).

Then I was going to suggest that you were probably not taking account of
either the size or position of the printer's "unprintable margins", but I
notice from a cursory glance at the example you've posted that you are in
fact doing so, because you are using the SetPrinterOrigin routine that I
wrote myself some time ago and which I posted on this newsgroup, and on the
clbvm newsgroup.

However, perhaps you have not realised that SetPrinterOrigin shifts the
origin only for functions which "know about" the VB ScaleLeft and ScaleTop
properties, in other words only for native VB drawing methods such as Line
and Circle and PaintPicture and Print and various other things. When you are
printing stuff using the API routines (such as the Polygon method you are
using to draw your arrows) you need to provide those offsets yourself in
code, because the API routines know nothing whatsoever about the VB
ScaleLeft and ScaleTop properties on the device.

Have a look at the following example. It uses the Polygon API to draw a
triangle on the page. The top left corner of the triangle should be
positioned at (50, 50) millimetres and its width should be 60 millimetres
and its height should be 80 millimetres. The reason it appears at the
correct position on the page is simply because I have added the required
"unprintable margin" offsets to the coordinates, which is required because
the Polygon API (unlike the native VB drawing methods) knows nothing about
the Printer's ScaleLeft or ScaleTop properties and is therefore unaffected
by the SetPrinterOrigin routine.

Does this help you at all? If not then post again and I'll have a look at
your example code in more detail.

Mike

Option Explicit
Private Declare Function GetDeviceCaps Lib "gdi32" _
(ByVal hdc As Long, ByVal nindex As Long) As Long
Private Declare Function Polygon Lib "gdi32" _
  (ByVal hdc As Long, lpPoint As Any, _
  ByVal nCount As Long) As Long
Private Type POINTAPI
  x As Long
  y As Long
End Type
Private Const PHYSICALOFFSETX As Long = 112
Private Const PHYSICALOFFSETY As Long = 113

Private Sub Command1_Click()
Dim p(1 To 3) As POINTAPI
Dim x1 As Long, y1 As Long
Dim wide As Long, high As Long
Dim xOffset As Long, yOffset As Long
Printer.ScaleMode = vbMillimeters
Printer.Print
xOffset = GetDeviceCaps(Printer.hdc, PHYSICALOFFSETX)
yOffset = GetDeviceCaps(Printer.hdc, PHYSICALOFFSETY)
x1 = Printer.ScaleX(50, vbMillimeters, vbPixels) - xOffset
y1 = Printer.ScaleY(50, vbMillimeters, vbPixels) - yOffset
wide = Printer.ScaleX(60, vbMillimeters, vbPixels)
high = Printer.ScaleY(80, vbMillimeters, vbPixels)
p(1).x = x1
p(1).y = y1
p(2).x = x1 + wide
p(2).y = y1
p(3).x = x1 + (p(2).x - p(1).x) \ 2
p(3).y = y1 + high
Polygon Printer.hdc, p(1), 3
Printer.EndDoc
End Sub



Fri, 29 Oct 2010 03:26:54 GMT  
 Accurate positioning of polygon for printer

Quote:
> Until someone else more knowledgeable in this area hops in, you may want
> to check LPtoDP/DPtoLP in MSDN.

It seems that VB6 uses MM_TEXT mapping mode regardless of what you set
ScaleMode to(Just checked with GetMapMode), so using LPtoDP/DPtoLP has no
effect because it's a 1:1 mapping mode, meaning that the expected units are
in pixels.


Fri, 29 Oct 2010 04:09:02 GMT  
 Accurate positioning of polygon for printer

Quote:
> It seems that VB6 uses MM_TEXT mapping mode regardless
> of what you set ScaleMode to(Just checked with GetMapMode)

Yes it does, and it performs the conversion from supplied units to device
pixels "on the fly", which is what enables VB to use floating point values
for your coordinates and sizes (something which the API standard drawing
functions cannot do even if you change the mapping mode, and even if you
change it to MM_ANISOTROPIC) and which is why you should normally use pixels
when using API drawing functions.

Quote:
> so using LPtoDP/DPtoLP has no effect because it's a
> 1:1 mapping mode, meaning that the expected units are in pixels.

But the OP (Michael) has said that he is using GetDeviceCaps(Printer.hdc,
LOGPIXELSX) to perform the conversion from millimetres to pixels, so he
should be okay in that respect (although I haven't yet had time to read
through his example code in detail). Personally I suspect that he is
actually performing the conversion from millimetres to device pixels
correctly but that he is failing to properly take account of the non
printable margins.

Mike



Fri, 29 Oct 2010 04:49:55 GMT  
 Accurate positioning of polygon for printer


Quote:


> > Yes, tried the DPI/25.4. Have cut the code down as much
> > as I can - still seems a lot to post Everything positioned with
> > Printer ScaleMode as vbMillimeters positions accurately
> > but not with the pixels to millimetres conversion

> I was about to post an answer to your original question when I noticed
that
> you had posted an update to it containing a fairly large amount of your
> code. I haven't got time at the moment to look through that code in any
> detail (although I promise I will do that if this answer does not provide
a
> solution for you) so for the time being I will post what I was about to
post
> before I read your second message . . .

> . . . I was initially going to suggest that you were possibly failing to
> correctly perform the conversion from the current ScaleMode to Pixels, but
I
> notice that you are using LogPixelsX and LogPixelsY, which is fine for
> printing to screen devices and to printers (although it is not correct if
> you are printing to metafiles, when you need to perform the conversion in
a
> different manner). Presumably you are printing only to Screen devices and
to
> Printers and to PDF Drivers, so LogPixelsX etc should be fine (although
you
> can more easily do it using the VB ScaleX and ScaleY functions if you
wish).

> Then I was going to suggest that you were probably not taking account of
> either the size or position of the printer's "unprintable margins", but I
> notice from a cursory glance at the example you've posted that you are in
> fact doing so, because you are using the SetPrinterOrigin routine that I
> wrote myself some time ago and which I posted on this newsgroup, and on
the
> clbvm newsgroup.

> However, perhaps you have not realised that SetPrinterOrigin shifts the
> origin only for functions which "know about" the VB ScaleLeft and ScaleTop
> properties, in other words only for native VB drawing methods such as Line
> and Circle and PaintPicture and Print and various other things. When you
are
> printing stuff using the API routines (such as the Polygon method you are
> using to draw your arrows) you need to provide those offsets yourself in
> code, because the API routines know nothing whatsoever about the VB
> ScaleLeft and ScaleTop properties on the device.

> Have a look at the following example. It uses the Polygon API to draw a
> triangle on the page. The top left corner of the triangle should be
> positioned at (50, 50) millimetres and its width should be 60 millimetres
> and its height should be 80 millimetres. The reason it appears at the
> correct position on the page is simply because I have added the required
> "unprintable margin" offsets to the coordinates, which is required because
> the Polygon API (unlike the native VB drawing methods) knows nothing about
> the Printer's ScaleLeft or ScaleTop properties and is therefore unaffected
> by the SetPrinterOrigin routine.

> Does this help you at all? If not then post again and I'll have a look at
> your example code in more detail.

> Mike

> Option Explicit
> Private Declare Function GetDeviceCaps Lib "gdi32" _
> (ByVal hdc As Long, ByVal nindex As Long) As Long
> Private Declare Function Polygon Lib "gdi32" _
>   (ByVal hdc As Long, lpPoint As Any, _
>   ByVal nCount As Long) As Long
> Private Type POINTAPI
>   x As Long
>   y As Long
> End Type
> Private Const PHYSICALOFFSETX As Long = 112
> Private Const PHYSICALOFFSETY As Long = 113

> Private Sub Command1_Click()
> Dim p(1 To 3) As POINTAPI
> Dim x1 As Long, y1 As Long
> Dim wide As Long, high As Long
> Dim xOffset As Long, yOffset As Long
> Printer.ScaleMode = vbMillimeters
> Printer.Print
> xOffset = GetDeviceCaps(Printer.hdc, PHYSICALOFFSETX)
> yOffset = GetDeviceCaps(Printer.hdc, PHYSICALOFFSETY)
> x1 = Printer.ScaleX(50, vbMillimeters, vbPixels) - xOffset
> y1 = Printer.ScaleY(50, vbMillimeters, vbPixels) - yOffset
> wide = Printer.ScaleX(60, vbMillimeters, vbPixels)
> high = Printer.ScaleY(80, vbMillimeters, vbPixels)
> p(1).x = x1
> p(1).y = y1
> p(2).x = x1 + wide
> p(2).y = y1
> p(3).x = x1 + (p(2).x - p(1).x) \ 2
> p(3).y = y1 + high
> Polygon Printer.hdc, p(1), 3
> Printer.EndDoc
> End Sub

Thank you for your (as always) comprehensive and generous reply.
I missed (what should have been obvious) that the 7 different bands of
values were not equal and so the vertical axis translations were not
inaccurate at all! So please don't bother wading through the mass of code I
posted.
Just leaves the slightly surprising fact that whereas the PDF printer seems
spot-on accurate, the HP inkjet needs a correction factor to align correctly
both vertically & horizontally.

On a different note, from someone who has learnt so much from the generous
help of the many experts on this newsgroup, it has been disheartening
recently to see the destructive nature of certain Australian 'contributors'
whose contribution to the problem solving of posters hase been NOTHING
compared to the genuine helpers here.

Thank you Mike - and 'expvb'



Fri, 29 Oct 2010 05:18:52 GMT  
 Accurate positioning of polygon for printer

Quote:
> Thank you for your (as always) comprehensive and generous
> reply. I missed (what should have been obvious) that the 7
> different bands of values were not equal and so the vertical
> axis translations were not inaccurate at all! So please don't
> bother wading through the mass of code I posted. Just leaves
> the slightly surprising fact that whereas the PDF printer seems
> spot-on accurate, the HP inkjet needs a correction factor to
> align correctly both vertically & horizontally.

I'm not sure what you mean by a "correction factor"? Do you mean that you
are applying a correction factor other than the factor I have obtained using
the GetDeviceCaps Lib "gdi32" with the constants PHYSICALOFFSETX and
PHYSICALOFFSETY? Or do you just mean those correction factors?

The GetDeviceCaps function (used twice with those two constants) effectively
returns the position of the top left corner of the page's printable area.
The Windows system "sees" location (0, 0) as being the top left corner of
the printable area, NOT the top left corner of the physical page, which is
why we need to make the adjustments. Also, both the size and position of the
printable area can be different on different printers, which is why we need
to use GetDeviceCaps to get those values again if we print to a different
printer, or even to the same printer at different user settings.

The only time we do not need to make such adjustments is if the top left
corner of the printable area on a specific printer exactly matches the top
left corner of the physical page, but we don't know that without using
GetDeviceCaps to test for it (and it will return zero for both calls if that
is the case) so we might as well just call the function and use the returned
offsets in all cases.

Some printers DO have a printable area that exactly matches the printable
page in both size and position, and some printers that do not have such a
"match" under their default settings DO have such a match under different
user settings. In the case of a normal PDF printer driver it DOES have such
a match, and the size of the left and top unprintable margin returned by
GetDeviceCaps will be zero. So that is why on a PDF driver (and on some real
printers at certain settings) it appears to make no difference whether you
make the offsets or not, simply because in such cases both offsets are zero.

But if you mean that you are finding yourself having to make other
adjustments *as well as* the GetDeviceCaps adjustments then post again and
we'll look at it. There are some printers, and some HP printers that I know
of personally, which misreport their unprintable margins, and some which
only misreport it under certain specific settings, because HP have not got
the driver programmed properly. The particular HP printer I am thinking of
misreports its unprintable margins if you are using the printer's "minimize
margins" mode. In such cases nothing on your machine will position things on
the page entirely accurately on that specific printer, not your VB programs
or Microsoft Word or Corel Draw or anything else. The difference is usually
small, but it is noticeable. Do you happen to have such a printer?

Quote:
> On a different note, from someone who has learnt so much from
> the generous help of the many experts on this newsgroup, it has
> been disheartening recently to see the destructive nature of certain
> Australian 'contributors' whose contribution to the problem solving
> of posters has been NOTHING compared to the genuine helpers
> here.

Yes. I know who you mean. They simply refuse to accept any criticism of
Microsoft or of any of their products. I must admit that I do tend to get
drawn into long threads with these people, and I keep telling myself that I
should stop doing it, but sometimes their blind refusal to accept facts
really does wind me up. I've got one going with this McCarthy fellow in
another group at this very moment, about the fact that a graphics card's
gdi32 acceleration (standard BitBlt and StretchBlt and VB PaintPicture and
the like) does not work in Vista. The functions work of course, but they are
not accelerated. On my own specific machine standard BitBlts run five times
slower under Vista than they did under XP. But he is totally refusing to
accept that fact. I will ditch the thread soon, probably right away, because
he simply refuses to accept the truth.

Quote:
> Thank you Mike - and 'expvb'

You are very welcome.

Mike



Fri, 29 Oct 2010 17:44:46 GMT  
 Accurate positioning of polygon for printer


Quote:


> I'm not sure what you mean by a "correction factor"? Do you mean that you
> are applying a correction factor other than the factor I have obtained
using
> the GetDeviceCaps Lib "gdi32" with the constants PHYSICALOFFSETX and
> PHYSICALOFFSETY? Or do you just mean those correction factors?

> The GetDeviceCaps function (used twice with those two constants)
effectively
> returns the position of the top left corner of the page's printable area.
> The Windows system "sees" location (0, 0) as being the top left corner of
> the printable area, NOT the top left corner of the physical page, which is
> why we need to make the adjustments. Also, both the size and position of
the
> printable area can be different on different printers, which is why we
need
> to use GetDeviceCaps to get those values again if we print to a different
> printer, or even to the same printer at different user settings.

> The only time we do not need to make such adjustments is if the top left
> corner of the printable area on a specific printer exactly matches the top
> left corner of the physical page, but we don't know that without using
> GetDeviceCaps to test for it (and it will return zero for both calls if
that
> is the case) so we might as well just call the function and use the
returned
> offsets in all cases.

> Some printers DO have a printable area that exactly matches the printable
> page in both size and position, and some printers that do not have such a
> "match" under their default settings DO have such a match under different
> user settings. In the case of a normal PDF printer driver it DOES have
such
> a match, and the size of the left and top unprintable margin returned by
> GetDeviceCaps will be zero. So that is why on a PDF driver (and on some
real
> printers at certain settings) it appears to make no difference whether you
> make the offsets or not, simply because in such cases both offsets are

zero.

Yes, spot on - the PDF printer has offsets of 0, the HP inkjet of 40X & 34Y
So with that incorporated, precision is there

Thank you so much

Michael



Sat, 30 Oct 2010 01:45:36 GMT  
 
 [ 10 post ] 

 Relevant Pages 

1. Accurate print position---help needed

2. Using API Polygon rtn on my printer...

3. polygon - polygon intersection

4. Text positioning problems with VB5 printer object

5. Get current printer position

6. Strange shift position of Printer.Print

7. Adding Up Single defined fields - Not accurate !!!!

8. Newbie to Word 97 VBA: Getting accurate word count programmatically

9. Word 97 SR2: Productivity tracking study accurate word counting

10. Percent scrolled not accurate

11. Getting an accurate mouse point location?

12. About accurate print

 

 
Powered by phpBB® Forum Software