目标:使用指定的Win API函数从字符串或富文本框打印到任何所需的打印机。
问题:在VBA Access中调用StartDocPrinter始终返回0.
信息:以下代码贯穿始终,不会中断。 OpenPrinter
似乎得到了很好的处理。调用StartDocPrinter
时,它返回0.
使用以下代码我尝试过,
dDocInfo
和@David_Heffernan建议,将DOCINFO属性声明为Long并将值设置为0。
.pDatatype = vbNullstring
,GetLastError
返回时,
StartDocPrinter parameter Level
= 1
StarDocPrinter parameter Level
= ByVal 1
时出现错误6(无效句柄),但hPrinter中显示的是明显有效句柄.pDatatype = "RAW"
时,GetLastError
无论如何都会返回0。.pDatatype = 'vbNullString
和DOCINFO属性设置为字符串时,GetLastError
无论如何返回0. ByRef DOCINFO
)OpenPrinter
参数设置为0应该将对打印机的请求访问权限设置为PRINTER_ACCESS_USE
。是否有可能GetLastError没有返回访问拒绝错误?StartDocPrinter(printer, 1, (LPBYTE) &docInfo);
吗?代码:
声明:
Type DOCINFO
pDocName As String
pOutputFile As String
pDatatype As String
End Type
Public Declare Function OpenPrinter Lib "winspool.drv" Alias "OpenPrinterA" (ByVal pPrinterName As String, hPrinter As Long, ByVal pDefault As Long) As Long
Public Declare Function StartDocPrinter Lib "winspool.drv" Alias "StartDocPrinterA" (hPrinter As Long, Level As Long, dDocInfo As DOCINFO) As Long
功能:
Public Function printRawData(sPrinterName As String, lData As String) As Boolean
Dim bStatus As Boolean, hPrinter As Long, dDocInfo As DOCINFO, lJob As Long, nWritten As Integer
' Open a handle to the printer.
bStatus = OpenPrinter(sPrinterName, hPrinter, 0)
If bStatus Then
' Fill in the structure with info about this "document."
dDocInfo.pDocName = vbNullString
dDocInfo.pOutputFile = vbNullString
dDocInfo.pDatatype = "RAW"
' Inform the spooler the document is beginning.
lJob = StartDocPrinter(hPrinter, 1, dDocInfo) 'Returns 0 :(
Debug.Print hPrinter, sPrinterName, lJob, GetLastError()
If lJob > 0 Then
' Start a page.
bStatus = StartPagePrinter(hPrinter)
If bStatus Then
' Send the data to the printer.
bStatus = WritePrinter(hPrinter, lData, Len(lData), nWritten)
EndPagePrinter (hPrinter)
End If
' Inform the spooler that the document is ending.
EndDocPrinter (hPrinter)
End If
' Close the printer handle.
ClosePrinter (hPrinter)
End If
' Check to see if correct number of bytes were written.
If Not bStatus Or (nWritten <> Len(lData)) Then
printRawData = False
Else
printRawData = True
End If
End Function
参考资料/相关问题:
- http://support.microsoft.com/kb/154078此代码的基础文档。 编辑:找到ByVal
在这里的一些声明中遗漏的地方。
- Send Raw Data to ZPL Printer using Visual Basic (MS Access 2000)这个人似乎有效地使用了几乎相同的代码,为什么我不能呢?这个问题的答案是用C ++编写的
- http://www.cplusplus.com/forum/general/26184/此处的代码也是用C ++编写的,我不确定如何转换
- http://codingdomain.com/visualbasic/win32api/datatypes/我正在使用转换数据类型和指针的指南,我并不完全理解
- StartDocPrinter(hPrinter, 1, di) returns false此处提供了一些代码,但没有答案。这是我有意提供错误的地方。
- excel bva code to send command to usb printer我尝试过此操作但没有所需的访问权限。我仍然想知道如何正确使用上面的代码,即使这是我最终会做的。
答案 0 :(得分:0)
使用@ HansPassant链接到MS KB,我在代码中发现了错误。对于ByVal
和hPrinter
参数,StartDocPrinter函数的声明缺少Level
。
Public Declare Function StartDocPrinter Lib "winspool.drv" Alias "StartDocPrinterA" (ByVal hPrinter As Long, ByVal Level As Long, dDocInfo As DOCINFO) As Long
答案 1 :(得分:-1)
您对DOCINFO结构的声明看起来不正确。它应该声明为:
Type DOCINFO
cbSize As Integer
lpszDocName As String
lpszOutput As String
lpszDatatype As String
fwType As Integer
End Type
应该将cbSize初始化为结构的大小(以字节为单位),并将fwType设置为0.