How to Print Entire VB Form and Control the Printed SizeID: Q84066
|
The Visual Basic for Windows PrintForm method provides a way to print
the client area of a form. However, PrintForm does not allow you to
control the size or proportion of the printed output, or to print the
non-client area (the caption and border) of the form.
The following code example uses Windows API functions to print the
entire form, and provides a method to control the size of the output.
This method can also be used to print only the client area to a
specific size and to control the position of the printed form to allow
text or other graphics to be printed on the same page as the image of
the form. The method is also applicable to printing all the forms in a
project.
NOTE: This example will not work correctly on PostScript printers.
For the example to work correctly, the printer must use a standard
non-PostScript laser printer configuration (such as PCL/HP).
Combining the Windows API functions BitBlt, StretchBlt,
CreateCompatibleDC, DeleteDC, SelectObject, and Escape allows greater
control over the placement and size of the printed form than the
PrintForm method. In a two-part process, the image of the entire form
is captured by using BitBlt to make an invisible picture, and is
turned into a persistent bitmap using the AutoRedraw property. Then
the picture is printed using the method of printing a picture control
(outlined in a separate article, found by querying for the following
word in the Microsoft Knowledge Base):
CreateCompatibleDC
Declare Function BitBlt Lib "gdi" (ByVal hDestDC, ByVal X, ByVal Y,
ByVal nWidth, ByVal nHeight, ByVal hSrcDC, ByVal XSrc,
ByVal YSrc, ByVal dwRop&)
Declare Function CreateCompatibleDC Lib "GDI" (ByVal hDC)
Declare Function SelectObject Lib "GDI" (ByVal hDC, ByVal hObject)
Declare Function StretchBlt Lib "GDI" (ByVal hDC, ByVal X, ByVal Y,
ByVal nWidth, ByVal nHeight, ByVal hSrcDC, ByVal XSrc,
ByVal YSrc, ByVal nSrcWidth, ByVal nSrcHeight, ByVal dwRop&)
Declare Function DeleteDC Lib "GDI" (ByVal hDC)
Declare Function Escape Lib "GDI" (ByVal hDC, ByVal nEscape,
ByVal nCount, lplnData As Any, lpOutData As Any)
Declare Function GetSystemMetrics Lib "User" (ByVal nIndex)
Const SM_CYCAPTION = 4
Const SM_CXBORDER = 5
Const SM_CYBORDER = 6
Const SM_CXDLGFRAME = 7
Const SM_CYDLGFRAME = 8
Const SM_CXFRAME = 32
Const SM_CYFRAME = 33
Const TWIPS = 1
Const PIXEL = 3
Const NILL = 0&
Const SRCCOPY = &HCC0020
Const NEWFRAME = 1
Dim ModeRatio, XOffset, YOffset As Integer
Control Property Setting
------- -------- -------
Form1 Name Form1 (default)
Form1.Picture1 Name Picture1 (default)
Form1.Picture2 Name Picture2 (default)
Form1.File1 Name File1 (default)
(In Visual Basic version 1.0 for Windows, set the CtlName/FormName
Property for the above objects instead of the Name property.)
You can add any other control(s) to the form to print. If a picture
control is drawn at run time, be sure to set its AutoRedraw property
to True so that the graphics will be transferred by the Windows API
call BitBlt and eventually printed by StretchBlt.
Sub Form_Load ()
' Size the form explicitly to match parameters of StretchBlt.
' Or use design time size to set coordinates.
Form1.Move 1095, 1200, 8070, 5280
' Size two example controls.
File1.Move 4080, 120, 2775, 2535
Picture1.Move 240, 120, 2775, 2535
' Put up a caption to indicate how to print the form.
Form1.Caption = "Double Click to Print Form And Text"
' The following *optional* code illustrates creating a persistent
' bitmap that will successfully StretchBlt to the printer.
Picture1.AutoRedraw = -1 ' Create persistent bitmap of picture
' contents.
Picture1.Line (0, 0)-(Picture1.ScaleWidth / 2,
Picture1.ScaleHeight / 2), , BF
Picture1.AutoRedraw = 0 ' Toggle off.
' Make sure the temporary workspace picture is invisible.
Picture2.visible = 0
End Sub
Sub FormPrint (localname As Form)
' Display cross.
screen.MousePointer = 2
' Calculate ratio between ScaleMode twips and ScaleMode pixel.
localname.ScaleMode = PIXEL
ModeRatio = localname.height \ localname.ScaleHeight
localname.ScaleMode = TWIPS
XOffset = (localname.width - localname.ScaleWidth) \ ModeRatio
YOffset = (localname.height - localname.ScaleHeight) \ ModeRatio
CapSize% = GetSystemMetrics(SM_CYCAPTION) ' The height of the caption.
' The size of the fixed single border:
FudgeFactor% = GetSystemMetrics(SM_CYBORDER)
' The fudgefactor is due to inevitable mapping errors when converting
' logical pixels to screen pixels. This example is coded for 640X480
' screen resolution. For 800X600, remove the fudgefactor.
' For other resolutions, tweak for perfection!
Select Case localname.BorderStyle
Case 0 ' None.
XOffset = 0
YOffset = 0
Case 1 ' Fixed Single.
XOffset = GetSystemMetrics(SM_CXBORDER)
YOffset = GetSystemMetrics(SM_CYBORDER) + CapSize% - FudgeFactor%
Case 2 ' Sizeable.
XOffset = GetSystemMetrics(SM_CXFRAME)
YOffset = GetSystemMetrics(SM_CYFRAME) + CapSize% - FudgeFactor%
Case 3 ' Fixed Double.
XOffset = GetSystemMetrics(SM_CXDLGFRAME) + FudgeFactor%
YOffset = GetSystemMetrics(SM_CYDLGFRAME) + CapSize%
End Select
' Size the picture to the size of the form's non-client (complete)
' area.
Picture2.Move 0, 0, localname.Width, localname.Height
' NOTE: Bitblt requires coordinates in pixels.
Picture2.ScaleMode = PIXEL
' Clear Picture property of any previous BitBlt image.
Picture2.Picture = LoadPicture("")
' -1 equals true: Must Have This!!!
Picture2.AutoRedraw = -1
' Assign information of the destination bitmap.
hDestDC% = Picture2.hDC
X% = 0: Y% = 0
nWidth% = Picture2.ScaleWidth
nHeight% = Picture2.ScaleHeight
' Assign information of the source bitmap.
' Source is entire client area of form (plus non-client area)
' XOffset and YOffset settings depend on the BorderStyle chosen for
' the form.
hSrcDC% = localname.hDC
XSrc% = -XOffset: YSrc% = -YOffset
' Show transition to BitBlt by changing MousePointer.
Screen.MousePointer = 4
' Assign the SRCCOPY constant to the Raster operation.
dwRop& = SRCCOPY
' The following statement must appear on one line.
Suc% = BitBlt(hDestDC%, X%, Y%, nWidth%, nHeight%, hSrcDC%, XSrc%,
YSrc%, dwRop&)
' Start the StretchBlt process now.
' Assign persistent bitmap to Picture property:
Picture2.Picture = Picture2.Image
' StretchBlt requires pixel coordinates.
Picture2.ScaleMode = PIXEL
Printer.ScaleMode = PIXEL
' * The following is an example of mixing text with StretchBlt.
Printer.Print "This is a test of adding text and bitmaps "
Printer.Print "This is a test of adding text and bitmaps "
Printer.Print "This is a test of adding text and bitmaps "
' * If no text is printed in this procedure,
' * then you must add minimum: Printer.Print " "
' * to initialize Printer.hDC.
' Now display hour glass for the StretchBlt to printer.
screen.MousePointer = 11
hMemoryDC% = CreateCompatibleDC(Picture2.hDC)
hOldBitMap% = SelectObject(hMemoryDC%, Picture2.Picture)
' You adjust the vertical stretch factor of the form in the
' argument "Printer.ScaleHeight - 1000":
ApiError% = StretchBlt(Printer.hDC, 0, 192,
Printer.ScaleWidth - 300, Printer.ScaleHeight - 1000,
hMemoryDC%, 0, 0, Picture2.ScaleWidth,
Picture2.ScaleHeight, SRCCOPY) ' concatenate above
' The second parameter above allows for text already printed: modify
' accordingly.
hOldBitMap% = SelectObject(hMemoryDC%, hOldBitMap%)
ApiError% = DeleteDC(hMemoryDC%)
' * The following is an example of mixing text with StretchBlt.
' Set the printer currentY to allow for the size of the StretchBlt
' image. (This is relative to size of form and stretch factors chosen)
Printer.currentY = 2392 ' In Twips.
Printer.Print "This is for text after the StretchBlt"
Printer.Print "This is for text after the StretchBlt"
Printer.Print "This is for text after the StretchBlt"
Printer.EndDoc
ApiError% = Escape(Printer.hDC, NEWFRAME, 0, NILL, NILL)
' Reset MousePointer to default.
Screen.MousePointer = 1
End Sub
Sub Form_DblClick ()
FormPrint Form1
End Sub
"Microsoft Windows Programmer's Reference Book and Online Resource" (Add-on kit number 1-55615-413-5)
Additional query words: 2.00 3.00
Keywords : kbcode kbPrinting
Version : WINDOWS:1.0,2.0,3.0
Platform : WINDOWS
Issue type :
Last Reviewed: May 14, 1999