Print -> Mike Williams

Print -> Mike Williams

Post by Jim » Wed, 29 Oct 2003 01:08:35


Mike,
I tried several ways, but was not able to determine how to modify your code to position the printed picture in a
specific place on the paper. I have WNT 4 and it did print at 0, 0 on the paper. I just could not determine how to
reposition it to say .75, .75. Can you show me?

Thanks,
Jim Y






 
 
 

Print -> Mike Williams

Post by Mike Willi » Wed, 29 Oct 2003 02:30:37

Jim Y" < XXXX@XXXXX.COM > wrote in message
news:7qbnb.16530$ XXXX@XXXXX.COM ...


All you need to remember, Jim, is that all of the coordinates in the
StretchBlt API function are (by default) in printer pixels. So, to print a
picture at position (0.75, 0.75) and at a size of 4 by 3 inches you would
use:

iret = StretchBlt(MyPrinter.Handle, _
0.75 * MyPrinter.PixPerInchX, _
0.75 * MyPrinter.PixPerInchY, _
4 * MyPrinter.PixPerInchX, _
4 * MyPrinter.PixPerInchY, _
hMemoryDC, _
0, 0, _
Picture1.Width, Picture1.Height, _
vbSrcCopy)

In the above code the coordinates (0.75, 0.75 in the example) are relative
to the top left corner of the printable area of the page. With most printers
this area is slightly smaller than the physical page and is positioned a
little bit down and to the right of the physical top left corner. These
"inaccuracies in position" have different values on different printers, and
so to ensure that the positioning is accurate regardless of the printer in
use you need to take account of them. The following is the code I originally
posted that I have now modified to take account of this and to position the
stuff accurately:

Option Explicit
Private Declare Function StartDoc Lib "gdi32" Alias _
"StartDocA" (ByVal hDC As Long, lpdi As DOCINFO) As Long
Private Declare Function EndDoc Lib "gdi32" _
(ByVal hDC As Long) As Long
Private Declare Function StartPage Lib "gdi32" _
(ByVal hDC As Long) As Long
Private Declare Function EndPage Lib "gdi32" _
(ByVal hDC As Long) As Long
Private Declare Function GetDeviceCaps Lib "gdi32" _
(ByVal hDC As Long, ByVal nindex As Long) As Long
Private Declare Function DeleteDC Lib "gdi32" _
(ByVal hDC As Long) As Long
Private Declare Function StretchBlt Lib "gdi32" _
(ByVal hDC As Long, ByVal x As Long, ByVal y As Long, _
ByVal nWidth As Long, ByVal nHeight As Long, _
ByVal hSrcDC As Long, ByVal xSrc As Long, _
ByVal ySrc As Long, ByVal nSrcWidth As Long, _
ByVal nSrcHeight As Long, ByVal dwRop As Long) As Long
Private Declare Function CreateCompatibleDC Lib "gdi32" _
(ByVal hDC As Long) As Long
Private Declare Function SelectObject Lib "gdi32" _
(ByVal hDC As Long, ByVal hObject As Long) As Long
Private Declare Function DeleteObject Lib "gdi32" _
(ByVal hObject As Long) As Long
Private Const LOGPIXELSX = 88
Private Const LOGPIXELSY = 90
Private Const PHYSICALOFFSETX = 112
Private Const PHYSICALOFFSETY = 113
Private Type DOCINFO
cbSize As Long
lpszDocName As String
lpszOutput As String
lpszDatatype As String
fwType As Long
End Type
Private Type PrinterInfo
Handle As Long
PixPerInchX As Long
PixPerInchY As Long
PixOffsetX As Long
PixOffsetY As Long
End Type
Private MyPrinter As PrinterInfo

Private Sub Form_Load()
Me.ScaleMode = vbPixels
Picture1.BorderStyle = vbBSNone
Picture1.AutoRedraw = True
Picture1.AutoSize = True
Picture1.Visible = False
End Sub

Private Sub GetMyPrinter()
CommonDialog1.PrinterDefault = False
CommonDialog1.Flags = cdlPDReturnDC
CommonDialog1.ShowPrinter
MyPrinter.Handle = CommonDialog1.hDC
MyPrinter.PixPerInchX = GetDeviceCaps _
(MyPrinter.Handle, LOGPIXELSX)
MyPrinter.PixPerInchY = GetDeviceCaps _
(MyPrinter.Handle, LOGPIXELSY)
MyPrinter.PixOffsetX = GetDeviceCaps _
(MyPrinter.Handle, PHYSICALOFFSETX)
MyPrinter.PixOffsetY = GetDeviceCaps _
(MyPrinter.Handle, PHYSICALOFFSETY)
End Sub

Private Sub Comma
 
 
 

Print -> Mike Williams

Post by Mike Willi » Wed, 29 Oct 2003 02:38:02


Oops! Slip of the tongue! For I picture of 4 x 3 inches I of course meant
you to use:

iret = StretchBlt(MyPrinter.Handle, _
0.75 * MyPrinter.PixPerInchX, _
0.75 * MyPrinter.PixPerInchY, _
4 * MyPrinter.PixPerInchX, _
3 * MyPrinter.PixPerInchY, _
hMemoryDC, _
0, 0, _
Picture1.Width, Picture1.Height, _
vbSrcCopy)

But of course you will almost certainly want to use my modified "accurate
positioning" code instead, which is correct as it stands in my previous
post.

Mike
 
 
 

Print -> Mike Williams

Post by Jim » Wed, 29 Oct 2003 03:03:19

Thanks again. I did not expect an answer this quick. I have a few things to do before trying this, but will let you
know how it works on WNT 4.
Thank you,
Jim Y
 
 
 

Print -> Mike Williams

Post by Jim » Wed, 29 Oct 2003 04:49:19


iret = StretchBlt(MyPrinter.Handle, 0.75 * MyPrinter.PixPerInchX, _
0.75 * MyPrinter.PixPerInchY, 3.46 * MyPrinter.PixPerInchX, _
3 * MyPrinter.PixPerInchY, hMemoryDC, 0, 0, Picture1.Width, _
Picture1.Height, vbSrcCopy)

That re-postioned the picture, but not at the .75, .75 in the code. (My picture is 3.46" wide x 3.00" high.)
On the HP Deskjet: Left Border = 1.00", Top Border = 0.94"
On the Epson FX-80: Left Border = 0.97", Top Border = 0.78" (this is a tractor feed, so the top margin depends on where
I have the seam set.)
There is nothing wrong with the above results, I just wanted to show you the variation for your information.

Initially, I had tried this and it did not work:
iret = StretchBlt(MyPrinter.Handle, 0.75 * MyPrinter.PixPerInchX, _
0.75 * MyPrinter.PixPerInchY, 3.46 * MyPrinter.PixPerInchX, _
3 * MyPrinter.PixPerInchY, hMemoryDC, 0.75 * MyPrinter.PixPerInchX, _
0.75 * MyPrinter.PixPerInchY, Picture1.Width, _
Picture1.Height, vbSrcCopy)


Thank you,
Jim Y
 
 
 

Print -> Mike Williams

Post by Mike Willi » Wed, 29 Oct 2003 05:56:50

Jim Y" < XXXX@XXXXX.COM > wrote in message
news:3Fenb.196155$ XXXX@XXXXX.COM ...


You need to use the second lot of code that I posted, Jim (the code that
inlcudes two extra calls to GetDeviceCaps with the parameters
PHYSICALOFFSETX and PHYSICALOFFSETY. The purpose of them is to examine the
selected printer so that we can allow for its "forced margins" and thereby
print the picture at the same position on all printers. Here is an extract
from that code that positions the picture using two extra parameters:

iret = StretchBlt(MyPrinter.Handle, _
(0.75 * MyPrinter.PixPerInchX) - MyPrinter.PixOffsetX, _
(0.75 * MyPrinter.PixPerInchY) - MyPrinter.PixOffsetY, _
4 * MyPrinter.PixPerInchX, _
3 * MyPrinter.PixPerInchY, _
hMemoryDC, _
0, 0, _
Picture1.Width, Picture1.Height, _
vbSrcCopy)

Just to make sure you are using the correct code, here it is again complete
(below):

Mike

Option Explicit
Private Declare Function StartDoc Lib "gdi32" Alias _
"StartDocA" (ByVal hDC As Long, lpdi As DOCINFO) As Long
Private Declare Function EndDoc Lib "gdi32" _
(ByVal hDC As Long) As Long
Private Declare Function StartPage Lib "gdi32" _
(ByVal hDC As Long) As Long
Private Declare Function EndPage Lib "gdi32" _
(ByVal hDC As Long) As Long
Private Declare Function GetDeviceCaps Lib "gdi32" _
(ByVal hDC As Long, ByVal nindex As Long) As Long
Private Declare Function DeleteDC Lib "gdi32" _
(ByVal hDC As Long) As Long
Private Declare Function StretchBlt Lib "gdi32" _
(ByVal hDC As Long, ByVal x As Long, ByVal y As Long, _
ByVal nWidth As Long, ByVal nHeight As Long, _
ByVal hSrcDC As Long, ByVal xSrc As Long, _
ByVal ySrc As Long, ByVal nSrcWidth As Long, _
ByVal nSrcHeight As Long, ByVal dwRop As Long) As Long
Private Declare Function CreateCompatibleDC Lib "gdi32" _
(ByVal hDC As Long) As Long
Private Declare Function SelectObject Lib "gdi32" _
(ByVal hDC As Long, ByVal hObject As Long) As Long
Private Declare Function DeleteObject Lib "gdi32" _
(ByVal hObject As Long) As Long
Private Const LOGPIXELSX = 88
Private Const LOGPIXELSY = 90
Private Const PHYSICALOFFSETX = 112
Private Const PHYSICALOFFSETY = 113
Private Type DOCINFO
cbSize As Long
lpszDocName As String
lpszOutput As String
lpszDatatype As String
fwType As Long
End Type
Private Type PrinterInfo
Handle As Long
PixPerInchX As Long
PixPerInchY As Long
PixOffsetX As Long
PixOffsetY As Long
End Type
Private MyPrinter As PrinterInfo

Private Sub Form_Load()
Me.ScaleMode = vbPixels
Picture1.BorderStyle = vbBSNone
Picture1.AutoRedraw = True
Picture1.AutoSize = True
Picture1.Visible = False
End Sub

Private Sub GetMyPrinter()
CommonDialog1.PrinterDefault = False
CommonDialog1.Flags = cdlPDReturnDC
CommonDialog1.ShowPrinter
MyPrinter.Handle = CommonDialog1.hDC
MyPrinter.PixPerInchX = GetDeviceCaps _
(MyPrinter.Handle, LOGPIXELSX)
MyPrinter.PixPerInchY = GetDeviceCaps _
(MyPrinter.Handle, LOGPIXELSY)
MyPrinter.PixOffsetX = GetDeviceCaps _
(MyPrinter.Handle, PHYSICALOFFSETX)
MyPrinter.PixOffsetY = GetDeviceCaps _
(MyPrinter.Handle, PHYSICALOFFSETY)
End Sub

Private Sub Command1_Click()
Dim hMemoryDC As Long, hOldBitmap As Long, iret As Long
Dim docinf As DOCINFO
GetMyPrinter
docinf.cbSize = Len(docinf) ' Size of DOCINFO structure
iret = StartDoc(MyPrinter.Handle, docinf) 'Start new document
iret = StartPage(MyPrinter.Handle) 'Start a
 
 
 

Print -> Mike Williams

Post by Jim » Wed, 29 Oct 2003 14:13:15

had some time to experiment and now have it working with the correct size borders. You gave what I needed to get it
going and I added the necessary lines to get the final results. I owe you a case of Bud for the times you have helped
me.
Thank you once again,
Jim Y

Mike Williams < XXXX@XXXXX.COM > wrote in message news:bnk128$732$ XXXX@XXXXX.COM ...


 
 
 

Print -> Mike Williams

Post by Mike Willi » Wed, 29 Oct 2003 19:04:34


I'll drink to that ;-)

Mike