?
Solved

Printing from a PictureBox

Posted on 1999-07-08
7
Medium Priority
?
451 Views
Last Modified: 2013-12-25
I am attempting to print the contents of a PictureBox to a printer. I am running into many different problems.

First of all, in my PictureBox, I have different components, including a frame, lines, and circles (from using the Circle command). As you probably know, PrintForm does not work, and really messes with the appearance if you're printing to a black & white printer.

What I need is for everything to show up exactly as it appears on the print and, ideally, I'd like to see the form scaled to the dimensions of the paper. That way, the entire sheet of paper is filled, as opposed to PrintForm, which only uses about 50% of the paper.

I've been playing around with API functions like BitBlt and StretchBlt all day, but I've been unable to come up with an answer. Has anyone come up with code to do this?

Thanks in advance...

0
Comment
Question by:haz1
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
7 Comments
 
LVL 13

Expert Comment

by:Mirkwood
ID: 1495150
Printer.PaintPicture(picture1.picture,0,0,picture1.width,
picture1.height.....

Printer.EndDoc
0
 

Author Comment

by:haz1
ID: 1495151
The Printer.PaintPicture command didn't seem to work. I got an error: Run-time error '481': Invalid picture. It seems that the program is looking for a picture, image, or icon in the PictureBox. But I also have lines, frames, and circles in there, as well. Hence, I get that error.
0
 

Author Comment

by:haz1
ID: 1495152
The Printer.PaintPicture command didn't seem to work. I got an error: Run-time error '481': Invalid picture. It seems that the program is looking for a picture, image, or icon in the PictureBox. But I also have lines, frames, and circles in there, as well. Hence, I get that error.
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 2

Expert Comment

by:tylerd
ID: 1495153
It can't be done.
0
 
LVL 3

Expert Comment

by:rmichels
ID: 1495154
why don't you bitblt the picture box bitmap to the printer's hdc?

0
 
LVL 13

Accepted Solution

by:
Mirkwood earned 200 total points
ID: 1495155

How to Print Entire VB Form and Control the Printed Size
Last reviewed: June 21, 1996
Article ID: Q84066  
The information in this article applies to:
- Standard and Professional Editions of Microsoft Visual Basic for

  Windows, versions 2.0 and 3.0
- Microsoft Visual Basic programming system for Windows, version 1.0


SUMMARY
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).



MORE INFORMATION
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

This method works on maximized forms as well as any smaller forms. The use of GetSystemMetrics allows a general procedure to handle different window border styles passed to it by querying the video driver for the size of windows standard borders in pixels.
The example below requires a single form with an invisible picture control.



Example

Add the following code to the general Declarations level of the form in a new project:
NOTE: All Declare statements below must be on one line each.


DefInt A-Z
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


Set the following properties at design time:

   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.

Add the following code to the Form_Load procedure of Form1:

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


Add the following code to the general procedure level of the form:

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


Add the following code to the Double_Click event:

Sub Form_DblClick ()
   FormPrint Form1
End Sub


After saving the project, run the example.

Double-click the form to invoke the FormPrint procedure. Any form passed as a parameter to FormPrint will be printed. BitBlt will transfer the image to the Picture control, then StretchBlt transfers it to the printer DC, which will print the image that was transferred by BitBlt.
Optionally, you could place text or graphics in the picture (Form1.Picture2) before printing with StretchBlt or print directly to the page using Printer.Print or Printer.Line. If you choose the latter method, by adjusting the second and third parameters of StretchBlt, you can make the already printed content be followed by the image of the form on the same page.



REFERENCES
"Microsoft Windows Programmer's Reference Book and Online Resource" (Add-on kit number 1-55615-413-5)

 


--------------------------------------------------------------------------------

Additional reference words: 1.00 2.00 3.00
KBCategory: kbprint kbprg kbcode
KBSubcategory: APrgPrint


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: June 21, 1996
) 1998 Microsoft Corporation. All rights reserved. Terms of Use.
 

0
 

Author Comment

by:haz1
ID: 1495156
Turns out that that solution didn't work either. I did manage to find a solution from Microsoft's support site. Check Q161299 there for the necessary code. Thanks anyways!
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Enums (shorthand for ‘enumerations’) are not often used by programmers but they can be quite valuable when they are.  What are they? An Enum is just a type of variable like a string or an Integer, but in this case one that you create that contains…
If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…
Suggested Courses

719 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question