home *** CD-ROM | disk | FTP | other *** search
/ Dan Appleman's Visual Bas…s Guide to the Win32 API / Dan.Applmans.Visual.Basic.5.0.Programmers.Guide.To.The.Win32.API.1997.Ziff-Davis.Press.CD / VB5PG32.mdf / vbpg32 / samples5 / ch12 / picprint.frm (.txt) < prev    next >
Encoding:
Visual Basic Form  |  1997-02-16  |  14.8 KB  |  394 lines

  1. VERSION 5.00
  2. Begin VB.Form Picprint 
  3.    Caption         =   "Picture Print Demo"
  4.    ClientHeight    =   4005
  5.    ClientLeft      =   1380
  6.    ClientTop       =   2055
  7.    ClientWidth     =   7365
  8.    BeginProperty Font 
  9.       Name            =   "MS Sans Serif"
  10.       Size            =   8.25
  11.       Charset         =   0
  12.       Weight          =   700
  13.       Underline       =   0   'False
  14.       Italic          =   0   'False
  15.       Strikethrough   =   0   'False
  16.    EndProperty
  17.    ForeColor       =   &H80000008&
  18.    LinkMode        =   1  'Source
  19.    LinkTopic       =   "Form1"
  20.    PaletteMode     =   1  'UseZOrder
  21.    ScaleHeight     =   4005
  22.    ScaleWidth      =   7365
  23.    Begin VB.CommandButton CmdPrintAPI 
  24.       Appearance      =   0  'Flat
  25.       BackColor       =   &H80000005&
  26.       Caption         =   "Print: Use API"
  27.       Height          =   495
  28.       Left            =   5160
  29.       TabIndex        =   2
  30.       Top             =   840
  31.       Width           =   2055
  32.    End
  33.    Begin VB.CommandButton CmdPrint 
  34.       Appearance      =   0  'Flat
  35.       BackColor       =   &H80000005&
  36.       Caption         =   "Print: Use VB Printer"
  37.       Height          =   495
  38.       Left            =   5160
  39.       TabIndex        =   1
  40.       Top             =   240
  41.       Width           =   2055
  42.    End
  43.    Begin VB.PictureBox Picture1 
  44.       Appearance      =   0  'Flat
  45.       AutoRedraw      =   -1  'True
  46.       BackColor       =   &H80000005&
  47.       ForeColor       =   &H80000008&
  48.       Height          =   3615
  49.       Left            =   120
  50.       Picture         =   "PICPRINT.frx":0000
  51.       ScaleHeight     =   3585
  52.       ScaleWidth      =   4785
  53.       TabIndex        =   0
  54.       Top             =   120
  55.       Width           =   4815
  56.    End
  57.    Begin VB.Menu MenuConfigPrinter 
  58.       Caption         =   "ConfigPrinter"
  59.       Begin VB.Menu mnuPrinterProperties 
  60.          Caption         =   "PrinterProperties"
  61.       End
  62.       Begin VB.Menu mnuConfigurePort 
  63.          Caption         =   "Configure LPT1"
  64.       End
  65.       Begin VB.Menu mnuConnectToPrinter 
  66.          Caption         =   "ConnectToPrinter"
  67.       End
  68.       Begin VB.Menu mnuDocProperties 
  69.          Caption         =   "DocumentProperties"
  70.       End
  71.       Begin VB.Menu MenuPaperSizes 
  72.          Caption         =   "PaperSizes"
  73.       End
  74.    End
  75. Attribute VB_Name = "Picprint"
  76. Attribute VB_GlobalNameSpace = False
  77. Attribute VB_Creatable = False
  78. Attribute VB_PredeclaredId = True
  79. Attribute VB_Exposed = False
  80. Option Explicit
  81. ' Copyright 
  82.  1997 by Desaware Inc. All Rights Reserved.
  83. ' This function is called during the EndPage API function
  84. ' to allow the user to abort printing
  85. ' Printing using the VB printer object
  86. Private Sub CmdPrint_Click()
  87.     Dim oldcursor&
  88.     oldcursor = Screen.MousePointer
  89.     Screen.MousePointer = 11
  90.     Printer.Print " "   ' Convince VB that something should be printed
  91.     PrintBitmap Printer.hdc
  92.     Printer.NewPage
  93.     Printer.EndDoc
  94.     Screen.MousePointer = oldcursor
  95. End Sub
  96. ' This function shows how you can use the API to obtain
  97. '   a printer device context for printing.
  98. '   Note how this function also switches to print in
  99. '   landscape mode without changing the default printer
  100. '   configuration.
  101. Private Sub CmdPrintAPI_Click()
  102.     Dim DeviceName$
  103.     Dim dm As DEVMODE, dmout As DEVMODE
  104.     Dim bufsize&
  105.     Dim dmInBuf() As Byte
  106.     Dim dmOutBuf() As Byte
  107.     Dim prhdc&
  108.     Dim dinfo As DOCINFO
  109.     Dim docname$
  110.     Dim oldcursor&
  111.     Dim hPrinter&
  112.     Dim res&, di&
  113.     hPrinter = OpenDefaultPrinter(DeviceName$)
  114.         
  115.     ' Get a copy of the DEVMODE structure for this printer
  116.     ' First find out how big the DEVMODE structure is
  117.     bufsize& = DocumentProperties(hwnd, hPrinter, DeviceName$, 0, 0, 0)
  118.     ' Allocate buffers of that size
  119.     ReDim dmInBuf(bufsize&)
  120.     ReDim dmOutBuf(bufsize&)
  121.     ' Get the output DEVMODE structure
  122.     res = DocumentProperties(hwnd, hPrinter, DeviceName$, agGetAddressForObject(dmOutBuf(0)), agGetAddressForObject(dmInBuf(0)), DM_OUT_BUFFER)
  123.     ' Copy the data buffer into the DEVMODE structure
  124.      agCopyData dmOutBuf(0), dmout, Len(dmout)
  125.     ' Set the orientation, and set the dmField flag so that
  126.     ' the function will know that it is valid.
  127.     dmout.dmOrientation = DMORIENT_LANDSCAPE
  128.     dmout.dmFields = dm.dmFields Or DM_ORIENTATION
  129.     ' Now copy the data back to the buffer
  130.     agCopyData dmout, dmOutBuf(0), Len(dmout)
  131.     ' We now have need DC to the default printer
  132.     ' This DC is also initialized to landscape mode
  133.     prhdc = CreateDCBynum("WINSPOOL", DeviceName$, vbNullString, agGetAddressForObject&(dmOutBuf(0)))
  134.     If prhdc = 0 Then GoTo cleanup2
  135.     ' The DOCINFO structure is the information that the
  136.     ' print manager will show. This also gives you the
  137.     ' opportunity of dumping output to a file.
  138.     docname$ = "Sample Document"
  139.     dinfo.cbSize = Len(dinfo)
  140.     dinfo.lpszDocName = docname$
  141.     dinfo.lpszOutput = vbNullString
  142.     ' We set up the abort procdure here
  143.     AbortPrinting% = 0
  144.     di = SetAbortProc(prhdc, AddressOf Callback1_AbortProc)
  145.     ' And show the abort form which will be system modal
  146.     AbortForm.Show
  147.     Call BringWindowToTop(AbortForm.hwnd)
  148.     AbortForm.Refresh
  149.     Enabled = False ' Disable the main form
  150.     ' The usual print sequence here
  151.     di = StartDoc(prhdc, dinfo)
  152.     di = StartPage(prhdc)
  153.     PrintBitmap prhdc
  154.     ' The system will spend a long time in the EndPage
  155.     ' function, but it will periodically call the Abort
  156.     ' procedure which in turn triggers the Callback1
  157.     ' AbortProc event.
  158.     di = EndPage(prhdc)
  159.     If di >= 0 Then di = EndDocAPI(prhdc)
  160.     Unload AbortForm
  161.     Enabled = True
  162. cleanup2:
  163.     If prhdc <> 0 Then di = DeleteDC(prhdc)
  164.     If hPrinter <> 0 Then Call ClosePrinter(hPrinter)
  165. End Sub
  166. '   This function retrieves the definition of the default
  167. '   printer on this system
  168. Private Function GetDefPrinter$()
  169.     Dim def$
  170.     Dim di&
  171.     def$ = String$(128, 0)
  172.     di = GetProfileString("WINDOWS", "DEVICE", "", def$, 127)
  173.     def$ = agGetStringFromLPSTR$(def$)
  174.     GetDefPrinter$ = def$
  175. End Function
  176. '   This function returns the driver module name
  177. Private Function GetDeviceDriver$(dev$)
  178.     Dim firstpos%, nextpos%
  179.     firstpos% = InStr(dev$, ",")
  180.     nextpos% = InStr(firstpos% + 1, dev$, ",")
  181.     GetDeviceDriver$ = Mid$(dev$, firstpos% + 1, nextpos% - firstpos% - 1)
  182. End Function
  183. '   Retrieves the name portion of a device string
  184. Private Function GetDeviceName$(dev$)
  185.     Dim npos%
  186.     npos% = InStr(dev$, ",")
  187.     GetDeviceName$ = Left$(dev$, npos% - 1)
  188. End Function
  189. '   Returns the output destination for the specified device
  190. Private Function GetDeviceOutput$(dev$)
  191.     Dim firstpos%, nextpos%
  192.     firstpos% = InStr(dev$, ",")
  193.     nextpos% = InStr(firstpos% + 1, dev$, ",")
  194.     GetDeviceOutput$ = Mid$(dev$, nextpos% + 1)
  195. End Function
  196. '   Demonstration of the DocumentProperties function
  197. Private Sub mnuDocProperties_Click()
  198.     Dim dm As DEVMODE, dmout As DEVMODE
  199.     Dim bufsize&, res&
  200.     Dim dmInBuf() As Byte
  201.     Dim dmOutBuf() As Byte
  202.     Dim hPrinter&
  203.     Dim DeviceName$
  204.         
  205.     hPrinter = OpenDefaultPrinter(DeviceName$)
  206.     If hPrinter = 0 Then
  207.         MsgBox "Unable to open default printer"
  208.         Exit Sub
  209.     End If
  210.     ' The output DEVMODE structure will reflect any changes
  211.     ' made by the printer setup dialog box.
  212.     ' Note that no changes will be made to the default
  213.     ' printer settings!
  214.     bufsize = DocumentProperties(hwnd, hPrinter, DeviceName$, 0, 0, 0)
  215.     ReDim dmInBuf(bufsize)
  216.     ReDim dmOutBuf(bufsize)
  217.     res = DocumentProperties(hwnd, hPrinter, DeviceName$, agGetAddressForObject(dmOutBuf(0)), agGetAddressForObject(dmInBuf(0)), DM_IN_PROMPT Or DM_OUT_BUFFER)
  218.         
  219.     ' Copy the data buffer into the DEVMODE structure
  220.     agCopyData dmOutBuf(0), dmout, Len(dmout)
  221.     ShowDevMode dmout
  222.     ClosePrinter hPrinter
  223. End Sub
  224. '   This function shows how to use the DeviceCapabilities
  225. '   function to find out how many paper names the device
  226. '   supports. This technique can be used for any
  227. '   device capability
  228. Private Sub MenuPaperSizes_Click()
  229.     Dim dev$, devname$, devoutput$
  230.     Dim papercount&
  231.     Dim papername$
  232.     Dim a$, tname$
  233.     Dim x&, di&
  234.     dev$ = GetDefPrinter$() ' Get default printer info
  235.     If dev$ = "" Then Exit Sub
  236.     devname$ = GetDeviceName$(dev$)
  237.     devoutput$ = GetDeviceOutput$(dev$)
  238.     ' Find out how many paper names there are
  239.     papercount = DeviceCapabilities(devname$, devoutput$, DC_PAPERNAMES, vbNullString, 0)
  240.     If papercount = 0 Then
  241.         MsgBox "No paper names available", 0, "Paper name capability"
  242.         Exit Sub
  243.     End If
  244.     ' Now dimension the string large enough to hold them all
  245.     papername$ = String$(64 * papercount, 0)
  246.     di = DeviceCapabilities(devname$, devoutput$, DC_PAPERNAMES, papername$, 0)
  247.     ' Now display the results
  248.     For x = 1 To papercount
  249.         tname$ = Mid$(papername$, (x - 1) * 64 + 1)
  250.         a$ = a$ + agGetStringFromLPSTR$(tname$) & vbCrLf
  251.     Next x
  252.     MsgBox a$, 0, "Paper Names for Default Printer"
  253. End Sub
  254. '   Prints the bitmap in the picture1 control to the
  255. '   printer context specified.
  256. Private Sub PrintBitmap(hdc&)
  257.     Dim bi As BITMAPINFO
  258.     Dim dctemp&, dctemp2&
  259.     Dim msg$
  260.     Dim bufsize&
  261.     Dim bm As BITMAP
  262.     Dim ghnd&
  263.     Dim gptr&
  264.     Dim xpix&, ypix&
  265.     Dim doscale&
  266.     Dim uy&, ux&
  267.     Dim di&
  268.     ' Create a temporary memory DC and select into it
  269.     ' the background picture of the picture1 control.
  270.     dctemp& = CreateCompatibleDC(Picture1.hdc)
  271.     ' Get the size of the picture bitmap
  272.     di = GetObjectAPI(Picture1.Picture, Len(bm), bm)
  273.     ' Can this printer handle the DIB?
  274.     If (GetDeviceCaps(dctemp, RASTERCAPS)) And RC_DIBTODEV = 0 Then
  275.         msg$ = "This device does not support DIB's" + vbCrLf + "See source code for further info"
  276.         MsgBox msg$, 0, "No DIB support"
  277.     End If
  278.     ' Fill the BITMAPINFO for the desired DIB
  279.     bi.bmiHeader.biSize = Len(bi.bmiHeader)
  280.     bi.bmiHeader.biWidth = bm.bmWidth
  281.     bi.bmiHeader.biHeight = bm.bmHeight
  282.     bi.bmiHeader.biPlanes = 1
  283.     ' Set to 24 here to create a 24 bit DIB
  284.     ' Set to 8 here to create an 8 bit DIB
  285.     bi.bmiHeader.biBitCount = 4
  286.     bi.bmiHeader.biCompression = BI_RGB
  287.     ' Now calculate the data buffer size needed
  288.     bufsize& = bi.bmiHeader.biWidth
  289.     ' Figure out the number of bytes based on the
  290.     ' number of pixels in each byte. In this case we
  291.     ' really don't need all this code because this example
  292.     ' always uses a 16 color DIB, but the code is shown
  293.     ' here for your future reference
  294.     Select Case bi.bmiHeader.biBitCount
  295.         Case 1
  296.             bufsize& = (bufsize& + 7) / 8
  297.         Case 4
  298.             bufsize& = (bufsize& + 1) / 2
  299.         Case 24
  300.             bufsize& = bufsize& * 3
  301.     End Select
  302.     ' And make sure it aligns on a long boundary
  303.     bufsize& = ((bufsize& + 3) / 4) * 4
  304.     ' And multiply by the # of scan lines
  305.     bufsize& = bufsize& * bi.bmiHeader.biHeight
  306.     ' Now allocate a buffer to hold the data
  307.     ' We use the global memory pool because this buffer
  308.     ' could easily be above 64k bytes.
  309.     ghnd = GlobalAlloc(GMEM_MOVEABLE, bufsize&)
  310.     gptr& = GlobalLock&(ghnd)
  311.     di = GetDIBits(dctemp, Picture1.Picture, 0, bm.bmHeight, ByVal gptr&, bi, DIB_RGB_COLORS)
  312.     di = SetDIBitsToDevice(hdc, 0, 0, bm.bmWidth, bm.bmHeight, 0, 0, 0, bm.bmHeight, ByVal gptr&, bi, DIB_RGB_COLORS)
  313.     ' Now see if we can also print a scaled version
  314.     xpix = GetDeviceCaps(hdc, HORZRES)
  315.     ' We subtract off the size of the bitmap already
  316.     ' printed, plus some extra space
  317.     ypix = GetDeviceCaps(hdc, VERTRES) - (bm.bmHeight + 50)
  318.     ' Find out the largest multiplier we can use and still
  319.     ' fit on the page
  320.     doscale = xpix / bm.bmWidth
  321.     If (ypix / bm.bmHeight < doscale) Then doscale = ypix / bm.bmHeight
  322.     If doscale > 1 Then
  323.         doscale = doscale
  324.         ux = bm.bmWidth * doscale
  325.         uy = bm.bmHeight * doscale
  326.         ' Now how this is offset a bit so that we don't
  327.         ' print over the 1:1 scaled bitmap
  328.         di = StretchDIBits(hdc, 0, bm.bmHeight + 50, ux, uy, 0, 0, bm.bmWidth, bm.bmHeight, ByVal gptr&, bi, DIB_RGB_COLORS, SRCCOPY)
  329.     End If
  330.     ' Dump the global memory block
  331.     di = GlobalUnlock(ghnd)
  332.     di = GlobalFree(ghnd)
  333.     di = DeleteDC(dctemp)
  334. End Sub
  335. ' Shows information about the current device mode
  336. Private Sub ShowDevMode(dm As DEVMODE)
  337.     Dim crlf$
  338.     Dim a$
  339.     crlf$ = Chr$(13) + Chr$(10)
  340.     a$ = "Device name = " + agGetStringFromLPSTR$(dm.dmDeviceName) + crlf$
  341.     a$ = a$ + "Devmode Version: " + Hex$(dm.dmSpecVersion) + ", Driver version: " + Hex$(dm.dmDriverVersion) + crlf$
  342.     a$ = a$ + "Orientation: "
  343.     If dm.dmOrientation = DMORIENT_PORTRAIT Then a$ = a$ + "Portrait" Else a$ = a$ + "Landscape"
  344.     a$ = a$ + crlf$
  345.     a$ = a$ + "Field mask = " + Hex$(dm.dmFields) + crlf$
  346.     a$ = a$ + "Copies = " + Str$(dm.dmCopies) + crlf$
  347.     If dm.dmFields And DM_YRESOLUTION <> 0 Then
  348.         a$ = a$ + "X,Y resolution = " + Str$(dm.dmPrintQuality) + "," + Str$(dm.dmYResolution) + crlf$
  349.     End If
  350.     MsgBox a$, 0, "Devmode structure"
  351. End Sub
  352. Private Sub mnuConfigurePort_Click()
  353.     Dim dev$, devname$, devoutput$
  354.     Dim hPrinter&, res&
  355.     dev$ = GetDefPrinter$() ' Get default printer info
  356.     If dev$ = "" Then Exit Sub
  357.     devname$ = GetDeviceName$(dev$)
  358.     devoutput$ = GetDeviceOutput$(dev$)
  359.     Call ConfigurePort(vbNullString, hwnd, "LPT1:")
  360. End Sub
  361. Private Sub mnuConnectToPrinter_Click()
  362.     Call ConnectToPrinterDlg(hwnd, 0)
  363. End Sub
  364. Private Sub mnuPrinterProperties_Click()
  365.     Dim hPrinter&
  366.     hPrinter& = OpenDefaultPrinter()
  367.     If hPrinter = 0 Then
  368.         MsgBox "Can't open default printer"
  369.         Exit Sub
  370.     End If
  371.     Call PrinterProperties(hwnd, hPrinter)
  372.     Call ClosePrinter(hPrinter)
  373. End Sub
  374. Public Function OpenDefaultPrinter(Optional DeviceName) As Long
  375.     Dim dev$, devname$, devoutput$
  376.     Dim hPrinter&, res&
  377.     Dim pdefs As PRINTER_DEFAULTS
  378.     pdefs.pDatatype = vbNullString
  379.     pdefs.pDevMode = 0
  380.     pdefs.DesiredAccess = PRINTER_ACCESS_ADMINISTER Or PRINTER_ACCESS_USE
  381.     dev$ = GetDefPrinter$() ' Get default printer info
  382.     If dev$ = "" Then Exit Function
  383.     devname$ = GetDeviceName$(dev$)
  384.     devoutput$ = GetDeviceOutput$(dev$)
  385.     If Not IsMissing(DeviceName) Then
  386.         DeviceName = devname$
  387.     End If
  388.     ' You can use OpenPrinterBynum to pass a zero as the
  389.     ' third parameter, but you won't have full access to
  390.     ' edit the printer properties
  391.     res& = OpenPrinter(devname$, hPrinter, pdefs)
  392.     If res <> 0 Then OpenDefaultPrinter = hPrinter
  393. End Function
  394.