我的VB程序中用data report打印报表,现有两报表A、B, A报表是A4大小,B报表是自定义纸型,比A4大些。运行时,若此时打印机的默认纸型是A4,则B报表会出错,提示纸张超出,若此时打印机的默认纸型是我的自定义的那种纸型,则A报表也按自定义的纸张大小显示而不是A4版面了。一般情况下默认纸型都是A4,我如何才能在调用B报表前,用代码改变打印机的默认纸型成为自定义的,在报表打印完成后用又代码还原成A4的?
或者有其他方法能解决我的问题也行,比如用代码来设定纸张大小。谢谢!
或者有其他方法能解决我的问题也行,比如用代码来设定纸张大小。谢谢!
Private Const CCHDEVICENAME = 32
Private Const CCHFORMNAME = 32
'*Constants for NT security
Private Const STANDARD_RIGHTS_REQUIRED = &HF0000
Private Const PRINTER_ACCESS_ADMINISTER = &H4
Private Const PRINTER_ACCESS_USE = &H8
Private Const PRINTER_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED Or PRINTER_ACCESS_ADMINISTER Or PRINTER_ACCESS_USE)
'*Constants used to make changes to the values contained in the DevMode
Private Const DM_MODIFY = 8
Private Const DM_COPY = 2
Private Const DM_DUPLEX = &H1000&
Private Const DMDUP_SIMPLEX = 1
Private Const DMDUP_VERTICAL = 2
Private Const DMDUP_HORIZONTAL = 3
Private Const DM_IN_BUFFER As Long = 8
Private Const DM_OUT_BUFFER As Long = 2
Private Const DM_ORIENTATION As Long = &H1
Private Const DM_PAPERSIZE = &H2&
Private Const DM_PAPERWIDTH = &H8&
Private Const DM_PAPERLENGTH = &H4&
Private Type DEVMODE
dmDeviceName As String * 32
dmSpecVersion As Integer
dmDriverVersion As Integer
dmSize As Integer
dmDriverExtra As Integer
dmFields As Long
dmOrientation As Integer
dmPaperSize As Integer
dmPaperLength As Integer
dmPaperWidth As Integer
dmScale As Integer
dmCopies As Integer
dmDefaultSource As Integer
dmPrintQuality As Integer
dmColor As Integer
dmDuplex As Integer
dmYResolution As Integer
dmTTOption As Integer
dmCollate As Integer
dmFormName As String * 32
dmUnusedPadding As Integer
dmBitsPerPel As Integer
dmPelsWidth As Long
dmPelsHeight As Long
dmDisplayFlags As Long
dmDisplayFrequency As Long
End Type
Private Type PRINTER_DEFAULTS
pDataType As String
pDevMode As Long
DesiredAccess As Long
End Type
Private Type PRINTER_INFO_2
pServerName As Long
pPrinterName As Long
pShareName As Long
pPortName As Long
pDriverName As Long
pComment As Long
pLocation As Long
pDevMode As Long
pSepFile As Long
pPrintProcessor As Long
pDataType As Long
pParameters As Long
pSecurityDescriptor As Long
Attributes As Long
Priority As Long
DefaultPriority As Long
StartTime As Long
UntilTime As Long
status As Long
cJobs As Long
AveragePPM As Long
End Type
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
(hpvDest As Any, hpvSource As Any, _
ByVal cbCopy As Long)
Private Declare Function OpenPrinter Lib "winspool.drv" Alias "OpenPrinterA" _
(ByVal pPrinterName As String, _
phPrinter As Long, pDefault As Any) As Long
Private Declare Function ClosePrinter Lib "winspool.drv" _
(ByVal hPrinter As Long) As Long
Private Declare Function DocumentProperties Lib "winspool.drv" Alias "DocumentPropertiesA" _
(ByVal hWnd As Long, ByVal hPrinter As Long, _
ByVal pDeviceName As String, pDevModeOutput As Any, _
pDevModeInput As Any, ByVal fMode As Long) As Long
Private Declare Function GetPrinter Lib "winspool.drv" Alias "GetPrinterA" _
(ByVal hPrinter As Long, ByVal level As Long, _
pPrinter As Any, ByVal cbBuf As Long, pcbNeeded As Long) As Long
Private Declare Function SetPrinter Lib "winspool.drv" Alias "SetPrinterA" _
(ByVal hPrinter As Long, ByVal level As Long, _
pPrinter As Any, ByVal Command As Long) As Long
Private Sub Command1_Click()
Dim uu As Boolean
If Printer.PaperSize <> 9 Then
uu = mySetPrinter(Printer.DeviceName, 1, 9, 0, 0)
Printer.EndDoc
End If
End Sub
Public Function mySetPrinter(prnName As String, Optional eOrientation As Integer, Optional iDmpaper As Integer, Optional iDmpaperLength As Single, Optional iDmpaperWidth As Single) As Boolean
Dim bDevMode() As Byte
Dim bPrinterInfo2() As Byte
Dim hPrinter As Long
Dim lResult As Long
Dim nSize As Long
Dim sPrnName As String
Dim dm As DEVMODE
Dim olddm As DEVMODE
Dim pd As PRINTER_DEFAULTS
Dim pi2 As PRINTER_INFO_2
On Error GoTo err_proc
sPrnName = prnName
pd.DesiredAccess = PRINTER_ALL_ACCESS
If OpenPrinter(sPrnName, hPrinter, pd) Then
Call GetPrinter(hPrinter, 2&, 0&, 0&, nSize)
ReDim bPrinterInfo2(1 To nSize) As Byte
lResult = GetPrinter(hPrinter, 2, bPrinterInfo2(1), nSize, nSize)
Call CopyMemory(pi2, bPrinterInfo2(1), Len(pi2))
nSize = DocumentProperties(0&, hPrinter, sPrnName, 0&, 0&, 0)
ReDim bDevMode(1 To nSize)
If pi2.pDevMode Then
Call CopyMemory(bDevMode(1), ByVal pi2.pDevMode, Len(dm))
Else
Call DocumentProperties(0&, hPrinter, sPrnName, bDevMode(1), 0&, DM_OUT_BUFFER)
End If
Call CopyMemory(dm, bDevMode(1), Len(dm))
Call CopyMemory(olddm, bDevMode(1), Len(olddm))
With dm
If eOrientation <> 0 Then
.dmOrientation = eOrientation
.dmFields = DM_ORIENTATION
End If
If iDmpaper <> 0 And iDmpaper <> vbPRPSUser Then
.dmPaperSize = iDmpaper
.dmFields = DM_PAPERSIZE
End If
If iDmpaper = vbPRPSUser Then
.dmFields = DM_PAPERLENGTH Or DM_PAPERWIDTH
.dmPaperLength = iDmpaperLength
.dmPaperWidth = iDmpaperWidth
End If
End With
Call CopyMemory(bDevMode(1), dm, Len(dm))
Call DocumentProperties(0&, hPrinter, sPrnName, _
bDevMode(1), bDevMode(1), DM_IN_BUFFER Or _
DM_OUT_BUFFER)
pi2.pDevMode = VarPtr(bDevMode(1))
lResult = SetPrinter(hPrinter, 2, pi2, 0&)
Call ClosePrinter(hPrinter)
mySetPrinter = True
Else
mySetPrinter = False
End If
Exit Function
err_proc:
mySetPrinter = False
End Function
在2000下我也遇到过,不过是常规纸张的设置,至于自定义你可以试试,eOrientation是方向,iDmpaper = vbPRPSUser为自定义, iDmpaperLength和iDmpaperWidth 是长和宽以上程序是网上zt的
如果您使用Win98/me系统,您可以设置VB的 printer object的Width和Height属性或Papersize属性调整打印的纸张大小。 相关信息请参考: PaperSize Property http://msdn.microsoft.com/library/en-us/vb98/html/vbproPaperSize.asp Height, Width Properties http://msdn.microsoft.com/library/en-us/vb98/html/vbproheight.asp 如果您使用Win2000/NT系统,纸张的大小由DevMode结构的四个属性决定: dmPaperSize As Integer dmPaperLength As Integer dmPaperWidth As Integer dmFormName As String * CCHFORMNAME 其中dmFormName用于NT系统中指定打印纸张大小为预定义的某个纸张(Form),但是VB的 printer object不支持FormName属性,您可以通过API函数DocumentProperties修改DevMode结构的dmFormName属性实现自定义打印。 分两步做: 1. 先在打印机目录下,从File菜单下进入Server Properties对话框,在这里您可以手工添加自定义纸张,您也可以用API函数AddForm在程序中添加自定义纸张。 2. 在您的程序中,用API函数DocumentProperties获得当前打印机的设置并修改dmFormName为前面添加的自定义纸张。 关于DevMode结构和DocumentProperties的使用可参考下面的例子。 Q282474 HOWTO: Print Using Custom Page Sizes on Windows NT/2000
http://support.microsoft.com/support/kb/articles/q282/4/74.asp Q180645 FIX: Cannot Change Page Settings During Print Job
http://support.microsoft.com/support/kb/articles/q180/6/45.asp
API函数的相关信息请参考: AddForm http://msdn.microsoft.com/library/en-us/gdi/prntspol_0prh.aspAddForm
The AddForm function adds a form to the list of available forms that can be selected for the specified printer. BOOL AddForm(
HANDLE hPrinter, // handle to printer object
DWORD Level, // data-structure level
LPBYTE pForm // form information buffer
);
Parameters
hPrinter
[in] Handle to the printer that supports printing with the specified form. Use the OpenPrinter or AddPrinter function to retrieve a printer handle.
Level
[in] Specifies the level of the structure to which pForm points. This value must be 1.
pForm
[in] Pointer to a FORM_INFO_1 structure.
Return Values
If the function succeeds, the return value is a nonzero value.If the function fails, the return value is zero. To get extended error information, call GetLastError. Res
An application can determine which forms are available for a printer by calling the EnumForms function. Requirements
Windows NT/2000/XP: Included in Windows NT 3.51 and later.
Windows 95/98/Me: Unsupported.
Header: Declared in Winspool.h; include Windows.h.
Library: Use Winspool.lib.
Unicode: Implemented as Unicode and ANSI versions.
DocumentProperties http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/prntspol_7k1f.asp
DataReport1.LeftMargin = 700
DataReport1.RightMargin = 700
DataReport1.TopMargin = 2.8 * 567
DataReport1.BottomMargin = 2 * 567
End Sub