Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations John Tel on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Printing a picture box. 3

Status
Not open for further replies.

peekay

Programmer
Oct 11, 1999
324
ZA
How do I print the contents of a picture box to the printer. It seems that the PrintForm method only prints a form to a printer and not a picture box. PK Odendaal
and pko@942.co.za
 
well i am not quite sure, but there is round about way,

do u know html?
if yes then using vb file commands create a html code like this
<html>
<body>
<img src=&quot;ImgPath&quot;></img>
</body>
</html>

name the file as first.html

call it in the WebBrowser control of VB

from there u can print it (like any IE page).
 
you will need to get all the api's declared and the various types used but the following code should do what you want!!!

Code:
' Printing using the VB printer object
'
Private Sub CmdPrint_Click()
    Dim oldcursor&
    oldcursor = Screen.MousePointer
    Screen.MousePointer = 11
    Printer.Print &quot; &quot;   ' Convince VB that something should be printed
    PrintBitmap Printer.hdc
    Printer.NewPage
    Printer.EndDoc
    Screen.MousePointer = oldcursor
End Sub

'   Prints the bitmap in the picture1 control to the
'   printer context specified.
'
Private Sub PrintBitmap(hdc&)
    Dim bi As BITMAPINFO
    Dim dctemp&, dctemp2&
    Dim msg$
    Dim bufsize&
    Dim bm As BITMAP
    Dim ghnd&
    Dim gptr&
    Dim xpix&, ypix&
    Dim doscale&
    Dim uy&, ux&
    Dim di&

    ' Create a temporary memory DC and select into it
    ' the background picture of the picture1 control.
    dctemp& = CreateCompatibleDC(Picture1.hdc)
    
    ' Get the size of the picture bitmap
    di = GetObjectAPI(Picture1.Picture, Len(bm), bm)

    ' Can this printer handle the DIB?
    If (GetDeviceCaps(hdc, RASTERCAPS)) And RC_DIBTODEV = 0 Then
        msg$ = &quot;This device does not support DIB's&quot; + vbCrLf + &quot;See source code for further info&quot;
        MsgBox msg$, 0, &quot;No DIB support&quot;
    End If

    ' Fill the BITMAPINFO for the desired DIB
    bi.bmiHeader.biSize = Len(bi.bmiHeader)
    bi.bmiHeader.biWidth = bm.bmWidth
    bi.bmiHeader.biHeight = bm.bmHeight
    bi.bmiHeader.biPlanes = 1
    ' Set to 24 here to create a 24 bit DIB
    ' Set to 8 here to create an 8 bit DIB
    bi.bmiHeader.biBitCount = 4
    bi.bmiHeader.biCompression = BI_RGB
    ' Now calculate the data buffer size needed
    bufsize& = bi.bmiHeader.biWidth

    ' Figure out the number of bytes based on the
    ' number of pixels in each byte. In this case we
    ' really don't need all this code because this example
    ' always uses a 16 color DIB, but the code is shown
    ' here for your future reference
    Select Case bi.bmiHeader.biBitCount
        Case 1
            bufsize& = Int((bufsize& + 7) / 8)
        Case 4
            bufsize& = Int((bufsize& + 1) / 2)
        Case 24
            bufsize& = bufsize& * 3
    End Select
    ' And make sure it aligns on a long boundary
    bufsize& = (Int((bufsize& + 3) / 4)) * 4
    ' And multiply by the # of scan lines
    bufsize& = bufsize& * bi.bmiHeader.biHeight

    ' Now allocate a buffer to hold the data
    ' We use the global memory pool because this buffer
    ' could easily be above 64k bytes.
    ghnd = GlobalAlloc(GMEM_MOVEABLE, bufsize&)
    gptr& = GlobalLock&(ghnd)

    di = GetDIBits(dctemp, Picture1.Picture, 0, bm.bmHeight, ByVal gptr&, bi, DIB_RGB_COLORS)
    di = SetDIBitsToDevice(hdc, 0, 0, bm.bmWidth, bm.bmHeight, 0, 0, 0, bm.bmHeight, ByVal gptr&, bi, DIB_RGB_COLORS)

    ' Now see if we can also print a scaled version
    xpix = GetDeviceCaps(hdc, HORZRES)
    ' We subtract off the size of the bitmap already
    ' printed, plus some extra space
    ypix = GetDeviceCaps(hdc, VERTRES) - (bm.bmHeight + 50)

    ' Find out the largest multiplier we can use and still
    ' fit on the page
    doscale = xpix / bm.bmWidth
    If (ypix / bm.bmHeight < doscale) Then doscale = ypix / bm.bmHeight
    If doscale > 1 Then
        doscale = doscale
        ux = bm.bmWidth * doscale
        uy = bm.bmHeight * doscale
        ' Now how this is offset a bit so that we don't
        ' print over the 1:1 scaled bitmap
        di = StretchDIBits(hdc, 0, bm.bmHeight + 50, ux, uy, 0, 0, bm.bmWidth, bm.bmHeight, ByVal gptr&, bi, DIB_RGB_COLORS, SRCCOPY)
    End If
    ' Dump the global memory block
    di = GlobalUnlock(ghnd)
    di = GlobalFree(ghnd)
    di = DeleteDC(dctemp)

End Sub

good luck! If somethings hard to do, its not worth doing - Homer Simpson
 
ok i dug out the apis etc:

Private Declare Function CreateCompatibleDC Lib &quot;gdi32&quot; (ByVal hdc As Long) As Long
Private Declare Function GetObjectAPI Lib &quot;gdi32&quot; Alias &quot;GetObjectA&quot; (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long
Private Declare Function GetDeviceCaps Lib &quot;gdi32&quot; (ByVal hdc As Long, ByVal nIndex As Long) As Long
Private Declare Function GlobalAlloc Lib &quot;kernel32&quot; (ByVal wFlags As Long, ByVal dwBytes As Long) As Long
Private Declare Function GlobalFree Lib &quot;kernel32&quot; (ByVal hMem As Long) As Long
Private Declare Function GlobalLock Lib &quot;kernel32&quot; (ByVal hMem As Long) As Long
Private Declare Function GetDIBits Lib &quot;gdi32&quot; (ByVal aHDC As Long, ByVal hBitmap As Long, ByVal nStartScan As Long, ByVal nNumScans As Long, lpBits As Any, lpBI As BITMAPINFO, ByVal wUsage As Long) As Long
Private Declare Function SetDIBitsToDevice Lib &quot;gdi32&quot; (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal dx As Long, ByVal dy As Long, ByVal SrcX As Long, ByVal SrcY As Long, ByVal Scan As Long, ByVal NumScans As Long, Bits As Any, BitsInfo As BITMAPINFO, ByVal wUsage As Long) As Long
Private Declare Function StretchDIBits Lib &quot;gdi32&quot; (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal dx As Long, ByVal dy As Long, ByVal SrcX As Long, ByVal SrcY As Long, ByVal wSrcWidth As Long, ByVal wSrcHeight As Long, lpBits As Any, lpBitsInfo As BITMAPINFO, ByVal wUsage As Long, ByVal dwRop As Long) As Long
Private Declare Function GlobalUnlock Lib &quot;kernel32&quot; (ByVal hMem As Long) As Long
Private Declare Function DeleteDC Lib &quot;gdi32&quot; (ByVal hdc As Long) As Long

Const RASTERCAPS = 38
Const RC_DIBTODEV = &H200
Const GMEM_MOVEABLE = &H2
Const DIB_RGB_COLORS = 0
Const HORZRES = 8
Const VERTRES = 10
Const SRCCOPY = &HCC0020
Const BI_RGB = 0&

Private Type BITMAPINFOHEADER '40 bytes
biSize As Long
biWidth As Long
biHeight As Long
biPlanes As Integer
biBitCount As Integer
biCompression As Long
biSizeImage As Long
biXPelsPerMeter As Long
biYPelsPerMeter As Long
biClrUsed As Long
biClrImportant As Long
End Type

Private Type RGBQUAD
rgbBlue As Byte
rgbGreen As Byte
rgbRed As Byte
rgbReserved As Byte
End Type

' BITMAPINFO for 16 color bitmap
Private Type BITMAPINFO
bmiHeader As BITMAPINFOHEADER
bmiColors(256) As RGBQUAD
End Type

Private Type BITMAP
bmType As Long
bmWidth As Long
bmHeight As Long
bmWidthBytes As Long
bmPlanes As Integer
bmBitsPixel As Integer
bmBits As Long
End Type

If somethings hard to do, its not worth doing - Homer Simpson
 
Or, of course, the dramatically shorter and easier:
[tt]
Printer.PaintPicture Picture1, 0, 0
Printer.EndDoc
 
[rofl2]

15 All strongm
________________________________________________________________
If you want to get the best response to a question, please check out FAQ222-2244 first

'People who live in windowed environments shouldn't cast pointers.'
 
ADoozer, Thank you for the trouble you have gone to and i will try it out.I appreciate it.

Strongm. I have tried out that solution but could not yet get it to work.

For all. I have tried another simple solution that has worked well so far. The solution is to add another form - something like a preview form - and to print the picture image to that and then to use printform to print to the printer.

PK Odendaal
and pko@942.co.za
 
Ok, well I clearly didn't undestand your problem then. Sorry it wasn't of use (although I should point out that it is the uncomplicated version of Adoozer's solution, so that probably won't work for you either)
 
whys that strongm?? i thought the code i posted printed any picture from a picturebox (at least thats how ive been using it)..... i have a way using all api but thats mucho complicated!!!!

input appreciated!! If somethings hard to do, its not worth doing - Homer Simpson
 

This is just off the wall but strongm's code works for me but then it may not work for you because of different OS version, different version of picture box etc. Well to get to the point it may be the reference
[tt]
Printer.PaintPicture Picture1.Image, 0, 0
Printer.EndDoc
[/tt]
that you may need to get it to work.

Then there is always the PSet and Point loop.

Good Luck

 
Erm...because the two line code I posted does exactly the same as your code - prints any picture from a picturebox. Only shorter. And with less API calls. And therefore if my code doesn't help peekay, then neither will yours.
 
oops... sorry... i wasnt questioning your reasoning i was just wondering why??... i have tried this code on a win98se machine connected to a epson stylus color 600 and through a 2000 pro connected to my 98se over a network?!? If somethings hard to do, its not worth doing - Homer Simpson
 
Oh - I have no idea why either your code or my slightly shorter version don't work in peekay's particular case. All I'm saying is that, since they are exactly the same (to all intents and purposes: your code happens to include a scaling feature, which, as presented, my code does not - but the PainPicture method can take additional parameters which implement scaling amongst a host of other functionality) then if one doesn't work, then neither will the other.
 
ok... i know little to nothing about printing, i appreciate the input, all my printing code is straight out of books or of the net!!!

however, should i come across a problem in the future i will bear this thread in mind!!!

thanks again for pointing the simpler version out :) If somethings hard to do, its not worth doing - Homer Simpson
 

Like I said it was off the wall, and that if peekay is recieving an error or the picture does not print at the printer it may be the reference (.Image) that could be causing the problem. A shot in the dark [cannon]

But also let it be known that if peekay is creating an image via code with a picturebox or drawing lines, circles etc. over an existing image strongm's code will either print nothing, error or just the origional image since the default property of the picture box is picture and the image property holds the current displayed image. Meaning the origional background/picture and all lines,circles,bitblts etc. (also based upon autoredraw).

So to test this place a picture box on a form and a command button and the following code...
[tt]
Option Explicit

Private Sub Command1_Click()
Picture1.AutoRedraw = True
Picture1.AutoSize = True
Picture1.Line (100, 100)-(1000, 1000), RGB(255, 0, 0)
Printer.PaintPicture Picture1, 0, 0
Printer.EndDoc
Printer.PaintPicture Picture1.Image, 0, 0
Printer.EndDoc

End Sub
[/tt]

Please note: if you do not load a picture in the design env or at runtime you will get an error (481) on the...
[tt]
Printer.PaintPicture Picture1, 0, 0
[/tt]

my .02

Good Luck

 
Erm...yes. I guess there is an implicit assumption that the Picturebox's Picture property actually contains the image we want to print, however that is achieved.
 

Ah, but what I am getting at (with a lack of information from peekay) is that if peekay is altering the origional image then the picture property will print the origional unaltered version where the image property will print the altered version.

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top