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 / samples4 / ch12 / picprint.frm (.txt) < prev    next >
Encoding:
Visual Basic Form  |  1996-02-16  |  15.3 KB  |  412 lines

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