用EnumJobs 函数,如果没有作业,则打印结束: 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 EnumJobs Lib "winspool.drv" Alias "EnumJobsA" (ByVal hPrinter As Long, ByVal FirstJob As Long, ByVal NoJobs As Long, ByVal Level As Long, pJob As Any, ByVal cdBuf As Long, pcbNeeded As Long, pcReturned As Long) As Long Private Sub Form_Load() Dim hPrinter As Long, lNeeded As Long, lReturned As Long Dim lJobCount As Long OpenPrinter Printer.DeviceName, hPrinter, ByVal 0& EnumJobs hPrinter, 0, 99, 1, ByVal 0&, 0, lNeeded, lReturned If lNeeded > 0 Then ReDim byteJobsBuffer(lNeeded - 1) As Byte EnumJobs hPrinter, 0, 99, 1, byteJobsBuffer(0), lNeeded, lNeeded, lReturned If lReturned > 0 Then lJobCount = lReturned Else lJobCount = 0 End If Else lJobCount = 0 End If ClosePrinter hPrinter MsgBox "Jobs in printer queue: " + CStr(lJobCount), vbInformation End Sub
参考:http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/prntspol_99nm.aspVB声明 Declare Function AddJob Lib "winspool.drv" Alias "AddJobA" (ByVal hPrinter As Long, ByVal Level As Long, pData As Byte, ByVal cdBuf As Long, pcbNeeded As Long) As Long 说明 用于获取一个有效的路径名,以便用它为作业创建一个后台打印文件。它也会为作业分配一个作业编号 返回值 Long,非零表示成功,零表示失败。会设置GetLastError 参数表 参数 类型及说明 hPrinter Long,一个已打开的打印机对象的句柄(用OpenPrinter获得) Level Long,设为1 pData Byte,缓冲区会引用一个ADDJOB_INFO_1结构 cdBuf Long,pData缓冲区中的字符数量 pcbNeeded Long,指向一个Long型变量的指针,该变量用于保存请求的缓冲区长度,或者实际读入的字节数量 注解 调用这个函数以后,可创建指定的文件,向其中写入数据,然后用API函数ScheduleJob令其将数据发给打印机
如何在不开启文件的情况下打印各类文件? 您还记得或怀念以前 DOS 时代,在 DOS 的命令列就可以直接下指令打印文件吗? 其实这个题目的标题,就如同当今的报纸标题一般,有点夸张,因为要打印文件,势必要先开启文件! 但是您也不用失望,既然标题会这样订,表示我也有好方法 (其实应该说 Microsoft 有提供好方法)!您只要使用 ShellExecuteAny 这个 API,对于各种不同格式不同类型的文件,您都不用自己先去启动开启该类文件的应用程序,再开启文件,再打印文件! 看到上面的说明,是否让您回想起之前我们提到过的二个主题: 如何用 VB 启动其他程序或开启各类文件? 完全模拟【开始】中的【运行...】功能在这二个主题中,我们都有提到,不必管文件的扩展名是什么?格式是什么?您都可以使用如下面Shell("Start C:\Test.txt") Call Shell("rundll32.exe url.dll,FileProtocolHandler " & Text1, 1)的方式来启动程序或开启文件。今天,我们要提到的 API 也可以开启或执行各种不同类型的文件,但是那不是我们今天的重点 (如果各位有兴趣的话,请自行研究!),今天的重点是 ShellExecuteAny 这个 API 它可以:1、自动依文件型态帮我们在 Background 启动应用程序。 2、自动打印文件。 3、自动再关闭文件。应用在我们的 VB 程序中的话,使用者只要输入或选择文件,不管什么文件 (当然是指在注册表中曾经注册过的文件类型),都可以打印!'以下是完成的模组:Private Declare Function ShellExecuteAny Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As Any, ByVal lpDirectory As Any, ByVal nShowCmd As Long) As LongConst SW_SHOWMINNOACTIVE = 7Sub PrintAnyFile(FileToPrint As String) Dim Ret As Long Ret = ShellExecuteAny(Me.hwnd, "print", FileToPrint, ByVal 0&, ByVal 0&, SW_SHOWMINNOACTIVE) End Sub'实际使用案例如下:Private Sub Command1_Click() PrintAnyFile Text1.Text End Sub其实上面这种打印文件的方式,它的作用方式,和我们直接将文件文件拖拉到打印机的图示上去打印文件是一样的道理! (如果您之前尚不知道这个功能的话,您现在可以试试看将一份文件直接拖拉放到打印机的图示上,看看结果如何!)
我知道,要想知道打印任务的状态,可以通过EnumJobs或GetJob,但我想用GetJob,不想用EnumJobs,因为我只关心我自己的打印任务。也因为如此,所以我需要知道我的任务的jobid,故此我不能直接用Word进行打印,也不能用ShellExecute,因为这两种方法我都得不到jobid,当然我值得也可以用StartDoc(byval hdc as long, byval doc as DOCINFO),但是我调用StartDoc的结果都只是的到一个0字节的输出文件。 (注:我需要打印到文件) 所以还请各位打下帮忙。
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 EnumJobs Lib "winspool.drv" Alias "EnumJobsA" (ByVal hPrinter As Long, ByVal FirstJob As Long, ByVal NoJobs As Long, ByVal Level As Long, pJob As Any, ByVal cdBuf As Long, pcbNeeded As Long, pcReturned As Long) As Long
Private Sub Form_Load() Dim hPrinter As Long, lNeeded As Long, lReturned As Long
Dim lJobCount As Long
OpenPrinter Printer.DeviceName, hPrinter, ByVal 0&
EnumJobs hPrinter, 0, 99, 1, ByVal 0&, 0, lNeeded, lReturned
If lNeeded > 0 Then
ReDim byteJobsBuffer(lNeeded - 1) As Byte
EnumJobs hPrinter, 0, 99, 1, byteJobsBuffer(0), lNeeded, lNeeded, lReturned
If lReturned > 0 Then
lJobCount = lReturned
Else
lJobCount = 0
End If
Else
lJobCount = 0
End If
ClosePrinter hPrinter
MsgBox "Jobs in printer queue: " + CStr(lJobCount), vbInformation
End Sub
参考:http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/prntspol_99nm.aspVB声明
Declare Function AddJob Lib "winspool.drv" Alias "AddJobA" (ByVal hPrinter As Long, ByVal Level As Long, pData As Byte, ByVal cdBuf As Long, pcbNeeded As Long) As Long
说明
用于获取一个有效的路径名,以便用它为作业创建一个后台打印文件。它也会为作业分配一个作业编号
返回值
Long,非零表示成功,零表示失败。会设置GetLastError
参数表
参数 类型及说明
hPrinter Long,一个已打开的打印机对象的句柄(用OpenPrinter获得)
Level Long,设为1
pData Byte,缓冲区会引用一个ADDJOB_INFO_1结构
cdBuf Long,pData缓冲区中的字符数量
pcbNeeded Long,指向一个Long型变量的指针,该变量用于保存请求的缓冲区长度,或者实际读入的字节数量
注解
调用这个函数以后,可创建指定的文件,向其中写入数据,然后用API函数ScheduleJob令其将数据发给打印机
您还记得或怀念以前 DOS 时代,在 DOS 的命令列就可以直接下指令打印文件吗?
其实这个题目的标题,就如同当今的报纸标题一般,有点夸张,因为要打印文件,势必要先开启文件!
但是您也不用失望,既然标题会这样订,表示我也有好方法 (其实应该说 Microsoft 有提供好方法)!您只要使用 ShellExecuteAny 这个 API,对于各种不同格式不同类型的文件,您都不用自己先去启动开启该类文件的应用程序,再开启文件,再打印文件!
看到上面的说明,是否让您回想起之前我们提到过的二个主题:
如何用 VB 启动其他程序或开启各类文件?
完全模拟【开始】中的【运行...】功能在这二个主题中,我们都有提到,不必管文件的扩展名是什么?格式是什么?您都可以使用如下面Shell("Start C:\Test.txt")
Call Shell("rundll32.exe url.dll,FileProtocolHandler " & Text1, 1)的方式来启动程序或开启文件。今天,我们要提到的 API 也可以开启或执行各种不同类型的文件,但是那不是我们今天的重点 (如果各位有兴趣的话,请自行研究!),今天的重点是 ShellExecuteAny 这个 API 它可以:1、自动依文件型态帮我们在 Background 启动应用程序。
2、自动打印文件。
3、自动再关闭文件。应用在我们的 VB 程序中的话,使用者只要输入或选择文件,不管什么文件 (当然是指在注册表中曾经注册过的文件类型),都可以打印!'以下是完成的模组:Private Declare Function ShellExecuteAny Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As Any, ByVal lpDirectory As Any, ByVal nShowCmd As Long) As LongConst SW_SHOWMINNOACTIVE = 7Sub PrintAnyFile(FileToPrint As String)
Dim Ret As Long
Ret = ShellExecuteAny(Me.hwnd, "print", FileToPrint, ByVal 0&, ByVal 0&, SW_SHOWMINNOACTIVE)
End Sub'实际使用案例如下:Private Sub Command1_Click()
PrintAnyFile Text1.Text
End Sub其实上面这种打印文件的方式,它的作用方式,和我们直接将文件文件拖拉到打印机的图示上去打印文件是一样的道理! (如果您之前尚不知道这个功能的话,您现在可以试试看将一份文件直接拖拉放到打印机的图示上,看看结果如何!)
我可以给你个完整的例子。
(注:我需要打印到文件)
所以还请各位打下帮忙。