如何获得打印份数?急求,红包感谢啊

hongzm 2017-11-15 09:29:30
Private Type PRINTER_DEFAULTS
pDatatype As String
pDevMode As Long
DesiredAccess As Long
End Type

Private Declare Function OpenPrinter Lib "winspool.drv" Alias "OpenPrinterA" (ByVal pPrinterName As String, phPrinter As Long, pDefault As PRINTER_DEFAULTS) 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 Byte, ByVal cdBuf As Long, pcbNeeded As Long, pcReturned As Long) As Long

Private Type SYSTEMTIME
wYear As Integer
wMonth As Integer
wDayOfWeek As Integer
wDay As Integer
wHour As Integer
wMinute As Integer
wSecond As Integer
wMilliseconds As Integer
End Type

Private Type JOB_INFO_1
JobId As Long
pPrinterName As Long
pMachineName As Long
pUserName As Long
pDocument As Long
pDatatype As Long
pStatus As Long
Status As Long
Priority As Long
Position As Long
TotalPages As Long
PagesPrinted As Long
Submitted As SYSTEMTIME
dmCopies As Long
End Type

Private Const PRINTER_ACCESS_ADMINISTER = &H4

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)


Private Declare Function FormatMessage Lib "kernel32" Alias "FormatMessageA" (ByVal dwFlags As Long, lpSource As Any, ByVal dwMessageId As Long, ByVal dwLanguageId As Long, ByVal lpBuffer As String, ByVal nSize As Long, Arguments As Long) As Long

Private Const FORMAT_MESSAGE_FROM_SYSTEM = &H1000

Private Const FORMAT_MESSAGE_IGNORE_INSERTS = &H200

Private Sub Command1_Click()
Dim hPrinter As Long
Dim RetVal As Long
Dim pd As PRINTER_DEFAULTS
Dim lngCount As Long

Dim JI1() As JOB_INFO_1
Dim aJi1() As Byte

Dim dwBytesNeed As Long
Dim dwBytesRet As Long

Dim lngSize As Long
Dim JI_1 As JOB_INFO_1

lngSize = Len(JI_1)
pd.DesiredAccess = PRINTER_ACCESS_ADMINISTER
RetVal = OpenPrinter(Printer.DeviceName, hPrinter, pd)
ReDim aJi1(lngSize - 1)
RetVal = EnumJobs(hPrinter, 0, 3, 1, aJi1(0), lngSize, dwBytesNeed, dwBytesRet)

If RetVal = 0 And dwBytesNeed = 0 Then
GetAPIError Err.LastDllError
Exit Sub
End If

If dwBytesNeed = 0 Then
MsgBox "没有打印任务!", vbInformation
Exit Sub
End If

If dwBytesNeed > lngSize Then
ReDim aJi1(dwBytesNeed - 1)
RetVal = EnumJobs(hPrinter, 0, 3, 1, aJi1(0), dwBytesNeed, dwBytesNeed, dwBytesRet)
End If

ReDim JI1(1 To dwBytesRet)
List1.Clear
For lngCount = 1 To dwBytesRet
Call CopyMemory(JI1(lngCount), aJi1((lngCount - 1) * lngSize), lngSize)
List1.AddItem "打印任务" & lngCount
List1.AddItem "JobID:" & JI1(lngCount).JobId
List1.AddItem "pPrinterName:" & GetStringFromMem(JI1(lngCount).pPrinterName)
List1.AddItem "pMachineName:" & GetStringFromMem(JI1(lngCount).pMachineName)
List1.AddItem "pUserName:" & GetStringFromMem(JI1(lngCount).pUserName)
List1.AddItem "pDocument:" & GetStringFromMem(JI1(lngCount).pDocument)
List1.AddItem "pStatus:" & JI1(lngCount).pStatus
List1.AddItem "Status:" & JI1(lngCount).Status
List1.AddItem "Priority:" & JI1(lngCount).Priority
List1.AddItem "Position:" & JI1(lngCount).Position
List1.AddItem "TotalPages:" & JI1(lngCount).TotalPages
List1.AddItem "PagesPrinted:" & JI1(lngCount).PagesPrinted
List1.AddItem "Year:" & JI1(lngCount).Submitted.wYear
List1.AddItem "Month:" & JI1(lngCount).Submitted.wMonth
List1.AddItem "Day:" & JI1(lngCount).Submitted.wDay
List1.AddItem "DayOfWeek:" & JI1(lngCount).Submitted.wDayOfWeek
List1.AddItem "Hour:" & JI1(lngCount).Submitted.wHour
List1.AddItem "Minute:" & JI1(lngCount).Submitted.wMinute
List1.AddItem "Second:" & JI1(lngCount).Submitted.wSecond
List1.AddItem "wMilliseconds:" & JI1(lngCount).Submitted.wMilliseconds
List1.AddItem "copyies:" & Printer.Copies
Next
ClosePrinter (hPrinter)
End Sub

Public Function GetAPIError(ByVal API_ERROR As Long)
Dim Lret As Long
Dim M_Msg As String
M_Msg = String(256, " ")
Lret = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM Or FORMAT_MESSAGE_IGNORE_INSERTS, 0&, API_ERROR, 0&, M_Msg, Len(M_Msg), 0&)
If Lret <> 0 Then
M_Msg = Trim(M_Msg)
MsgBox M_Msg, , "API错误信息"
End If
End Function

'从给定的内存地址中获得字符串
Private Function GetStringFromMem(ByVal Addr As Long) As String
Dim lngSize As Long
Dim bytStr() As Byte
Dim lngX As Long

'获得字符串的长度
Call CopyMemory(lngSize, ByVal Addr - 4, 4)
ReDim bytStr(lngSize / 2)
Call CopyMemory(bytStr(0), ByVal Addr, lngSize / 2 + 1)
GetStringFromMem = StrConv(bytStr, vbUnicode)
End Function


...全文
903 29 打赏 收藏 转发到动态 举报
写回复
用AI写文章
29 条回复
切换为时间正序
请发表友善的回复…
发表回复
PctGL 2017-11-22
  • 打赏
  • 举报
回复
你算如来佛? 百度搜了点东西, 就敢直接拿上来给别人用
舉杯邀明月 2017-11-22
  • 打赏
  • 举报
回复
我再来围观一下。
赵4老师 2017-11-22
  • 打赏
  • 举报
回复
引用 24 楼 PctGL 的回复:
你算如来佛? 百度搜了点东西, 就敢直接拿上来给别人用
现代中国人的能力差别很大程度上体现在会不会合理高效地使用百度上。
赵4老师 2017-11-22
  • 打赏
  • 举报
回复
hongzm 2017-11-22
  • 打赏
  • 举报
回复
救命啊,再加点分。我太菜了,我怎么改都不行。谁能帮忙修改下我的代码啊。救命,再加点分。搞定了不嫌弃的话。红包一定的。救命啊
小噤 2017-11-22
  • 打赏
  • 举报
回复
引用 16 楼 zhao4zhong1 的回复:
[quote=引用 14 楼 qq574221329 的回复:] [quote=引用 7 楼 zhao4zhong1 的回复:] QQ:511606848 等待发红包中……
应该是有效果的.我测试了一下. 但不知道是数量太多还是什么的.会报错.没深入研究了[/quote] 你原来的代码报错的原因至少有两个: ①MSDN中JOB_INFO_1结构后面没有dmCopies,你无端添加一个,导致计算整个结构的大小 Dim JI_1 As JOB_INFO_1 lngSize = Len(JI_1) 不对。 ②For lngCount = 1 To dwBytesRet Call CopyMemory(JI1(lngCount), aJi1((lngCount - 1) * lngSize), lngSize) 这个循环根本达不到每次取一个JOB_INFO_1结构的目的。 参考我最后给出的代码是怎么做的。[/quote] 我只是一个路过的.....我目前用不到这个.........赵老师回复错楼层了吧....
赵4老师 2017-11-21
  • 打赏
  • 举报
回复
好象22楼代码没用18#回复中红色文字标注的内容相关技术似的。 好象孙猴子翻出如来的手掌心似的。
PctGL 2017-11-21
  • 打赏
  • 举报
回复
typedef struct _JOB_INFO_2 { // ji2 DWORD JobId; LPTSTR pPrinterName; LPTSTR pMachineName; LPTSTR pUserName; LPTSTR pDocument; LPTSTR pNotifyName; LPTSTR pDatatype; LPTSTR pPrintProcessor; LPTSTR pParameters; LPTSTR pDriverName; LPDEVMODE pDevMode; LPTSTR pStatus; PSECURITY_DESCRIPTOR pSecurityDescriptor; DWORD Status; DWORD Priority; DWORD Position; DWORD StartTime; DWORD UntilTime; DWORD TotalPages; DWORD Size; SYSTEMTIME Submitted; DWORD Time; DWORD PagesPrinted ; } JOB_INFO_2; 应该是取得这个结构, 某层专家那就是扯 他不知道哪取 dmcopies, 然后楞扯到 printer 去, lz要的应该是打印任务的属性, 是事中或事后状态, 他扯的是事前状态,所以无限 1... 这句是对的: List1.AddItem "dmCopies:" & pd.pDevMode.dmCopies 但这个devmode 应该先 addrdev = globallock (pd.pdevmode) copymemory mydevmode, byval addrdev,len(mydevmode) 然后取 mydevmode.dmcopies 再 globalunlock pd.pdevmode globalfree pd.pdevmode 关于 devmode 内容怎么读可以参照下面代码, enumjob 那一步你自己百度吧

Sub GetSystemDefaultPrinter()
    
    Dim pd                  As PrinterDlg
    Dim pps                 As PrinterPageSetupDlg
    
    pd.lStructSize = Len(pd)
    pd.flags = PD_RETURNDC Or PD_RETURNDEFAULT
    
    If PrintDlg(pd) Then
        PG.HDC_Printer = pd.hdc
        
        Dim hGlobalData         As Long
    
        '// 锁定临时空间, 获取驱动配置信息
        hGlobalData = GlobalLock(ByVal pd.hDevMode)
        CopyMemory PG.dev_dlgMode, ByVal hGlobalData, Len(PG.dev_dlgMode)
        GlobalUnlock (hGlobalData)
        GlobalFree (pd.hDevMode)
        
        '// 锁定临时空间, 获取驱动,设备信息
        hGlobalData = GlobalLock(ByVal pd.hDevNames)
        CopyMemory PG.dev_dlgName, ByVal hGlobalData, Len(PG.dev_dlgName)
        GlobalUnlock (hGlobalData)
        GlobalFree (pd.hDevNames)
        
        Dim mulbits()       As Byte
        Dim i               As Long
        ReDim mulbits(PG.dev_dlgName.wDriverOffset - 1)
        CopyMemory mulbits(0), PG.dev_dlgName.extra(0), PG.dev_dlgName.wDriverOffset
        PG.dev_DriveName = StrConv(mulbits, vbUnicode)
        
        i = lstrlenByte(PG.dev_dlgName.extra(PG.dev_dlgName.wDriverOffset + 2))
        ReDim mulbits(i - 1)
        CopyMemory mulbits(0), PG.dev_dlgName.extra(PG.dev_dlgName.wDriverOffset + 2), i
        PG.dev_PrinterName = StrConv(mulbits, vbUnicode)
        
        '// 获取默认打印机的打印配置
        pps.lStructSize = Len(pds)
        pps.flags = PSD_INHUNDREDTHSOFMILLIMETERS Or PSD_RETURNDEFAULT
        
        If PageSetupDlgX(pps) Then
            
            '// 锁定临时空间, 获取驱动配置信息
            hGlobalData = GlobalLock(ByVal pps.hDevMode)
            CopyMemory PG.dev_dlgMode, ByVal hGlobalData, Len(PG.dev_dlgMode)
            
            ResetDC PG.HDC_Printer, hGlobalData
            
            GlobalUnlock (hGlobalData)
            GlobalFree (pps.hDevMode)
            
            '// 获取打印机分辨率, 每英寸内像素量
            PG.PrinterResolveX = GetDeviceCaps(PG.HDC_Printer, LOGPIXELSX)
            PG.PrinterResolveY = GetDeviceCaps(PG.HDC_Printer, LOGPIXELSY)
            
            '// 转换打印机默认边距度量单位为屏幕逻辑像素
            PG.dev_RectMargin = pds.rtMargin
            PG.dev_RectMargin.Left = mmeterPerPixelX(PG.dev_RectMargin.Left \ 100)
            PG.dev_RectMargin.Right = mmeterPerPixelX(PG.dev_RectMargin.Right \ 100)
            PG.dev_RectMargin.Top = mmeterPerPixelX(PG.dev_RectMargin.Top \ 100)
            PG.dev_RectMargin.bottom = mmeterPerPixelX(PG.dev_RectMargin.bottom \ 100)
            
            '// 设置打印机视图范围度量单位为像素
            SetMapMode PG.HDC_Printer, MM_ANISOTROPIC
            
            '// 设置打印机设备窗口范围, 窗口设置屏幕分辨率
            SetWindowExtEx PG.HDC_Printer, PG.ScreenResolveX, PG.ScreenResolveY, ByVal 0&
            SetWindowOrgEx PG.HDC_Printer, 0, 0, ByVal 0&
    
            '// 设置打印机设备视图范围, 设置为缩放分辨率,系统自动计算为比例
            SetViewportExtEx PG.HDC_Printer, PG.PrinterResolveX, PG.PrinterResolveY, ByVal 0&
            SetViewportOrgEx PG.HDC_Printer, 0, 0, ByVal 0&
            '// 以上api: SetWindowExtEx ,SetViewportExtEx , 也就是说以 WindowExt 设置的视图范围, 显示以 ViewPort 设置的视图范围
            
            '// 获取设备物理尺寸, 以像素为单位
            PG.dev_PaperSize.x = GetDeviceCaps(PG.HDC_Printer, HORZRES)
            PG.dev_PaperSize.y = GetDeviceCaps(PG.HDC_Printer, VERTRES)
            
            '// 物理尺寸解析为逻辑尺寸
            DPtoLP PG.HDC_Printer, PG.dev_PaperSize, 1
            
            
            
        End If
    End If
    
End Sub
赵4老师 2017-11-20
  • 打赏
  • 举报
回复
Using a Print Dialog Box and Retrieving a Printer Device Context The first step in printing involves setting up the printer and obtaining a printer DC. In the sample application, the File menu contains two options, Print and Print Setup. By selecting either option, the user can configure the printer. When the user selects the Print Setup option, the Print Setup dialog box is displayed and the user can select a printer, a page orientation, a paper size, and so on. When the user selects the Print option, the Print dialog box is displayed and the user can select a range of pages, a print quality, a number of copies, and so on. The user can also display the Print Setup dialog box by clicking the Setup push button. The Print and Print Setup dialog boxes are both displayed by initializing the members of aPRINTDLG structure and calling thePrintDlg function. (For more information about displaying the Print Setup dialog box, seeCommon Dialog Box Library). In addition to retrieving user-specified data, PrintDlg can be used to obtain a printer DC by specifying the PD_RETURNDC value in the Flags member of the PRINTDLG structure. The following code sample shows how to intialize the members of the structure and to display the Print dialog box. // Initialize the PRINTDLG members. pd.lStructSize = sizeof(PRINTDLG); pd.hDevMode = (HANDLE) NULL; pd.hDevNames = (HANDLE) NULL; pd.Flags = PD_RETURNDC; pd.hwndOwner = hwnd; pd.hDC = (HDC) NULL; pd.nFromPage = 1; pd.nToPage = 1; pd.nMinPage = 0; pd.nMaxPage = 0; pd.nCopies = 1; pd.hInstance = (HANDLE) NULL; pd.lCustData = 0L; pd.lpfnPrintHook = (LPPRINTHOOKPROC) NULL; pd.lpfnSetupHook = (LPSETUPHOOKPROC) NULL; pd.lpPrintTemplateName = (LPSTR) NULL; pd.lpSetupTemplateName = (LPSTR) NULL; pd.hPrintTemplate = (HANDLE) NULL; pd.hSetupTemplate = (HANDLE) NULL; // Display the PRINT dialog box. PrintDlg(&pd);
赵4老师 2017-11-20
  • 打赏
  • 举报
回复
我不是想得太天真,我是只会复制粘贴MSDN中的内容。 不象Chen8013经常目光焦距失准,连我复制粘贴MSDN中的内容都无视。
舉杯邀明月 2017-11-20
  • 打赏
  • 举报
回复
引用 7 楼 zhao4zhong1 的回复:
QQ:511606848 等待发红包中……
你想得太天真了…… 你用Printer.Copies肯定不对! (我没有打印机,只能“猜测分析”,也可能我的想法也不对) 这个“值”要么是“所有打印作业”的总份数,要么是在代码中通过Printer对象操作的“当前作业”的打印份数。 肯定会不是打印队列中某个特定作业的份数。
赵4老师 2017-11-20
  • 打赏
  • 举报
回复
QQ:511606848 等待发红包中……
赵4老师 2017-11-20
  • 打赏
  • 举报
回复
不一定对,仅供参考:
Private Type PRINTER_DEFAULTS
        pDatatype As String
        pDevMode As Long
        DesiredAccess As Long
End Type

Private Declare Function OpenPrinter Lib "winspool.drv" Alias "OpenPrinterA" (ByVal pPrinterName As String, phPrinter As Long, pDefault As PRINTER_DEFAULTS) 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 Byte, ByVal cdBuf As Long, pcbNeeded As Long, pcReturned As Long) As Long

Private Type SYSTEMTIME
        wYear As Integer
        wMonth As Integer
        wDayOfWeek As Integer
        wDay As Integer
        wHour As Integer
        wMinute As Integer
        wSecond As Integer
        wMilliseconds As Integer
End Type

Private Type JOB_INFO_1
        JobId As Long
        pPrinterName As Long
        pMachineName As Long
        pUserName As Long
        pDocument As Long
        pDatatype As Long
        pStatus As Long
        Status As Long
        Priority As Long
        Position As Long
        TotalPages As Long
        PagesPrinted As Long
        Submitted As SYSTEMTIME
        'dmCopies As Long
End Type

Private Const PRINTER_ACCESS_ADMINISTER = &H4

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)


Private Declare Function FormatMessage Lib "kernel32" Alias "FormatMessageA" (ByVal dwFlags As Long, lpSource As Any, ByVal dwMessageId As Long, ByVal dwLanguageId As Long, ByVal lpBuffer As String, ByVal nSize As Long, Arguments As Long) As Long

Private Const FORMAT_MESSAGE_FROM_SYSTEM = &H1000

Private Const FORMAT_MESSAGE_IGNORE_INSERTS = &H200

Private Sub Command1_Click()
    Dim hPrinter        As Long
    Dim RetVal          As Long
    Dim pd              As PRINTER_DEFAULTS
    Dim lngCount        As Long
    Dim n               As Long

    Dim JI1()           As JOB_INFO_1
    Dim aJi1()          As Byte

    Dim dwBytesNeed     As Long
    Dim dwBytesRet      As Long

    Dim lngSize         As Long
    Dim JI_1             As JOB_INFO_1

    lngSize = Len(JI_1)
    pd.DesiredAccess = PRINTER_ACCESS_ADMINISTER
    RetVal = OpenPrinter(Printer.DeviceName, hPrinter, pd)
    ReDim aJi1(lngSize - 1)
    RetVal = EnumJobs(hPrinter, 0, 3, 1, aJi1(0), lngSize, dwBytesNeed, dwBytesRet)

    If RetVal = 0 And dwBytesNeed = 0 Then
        GetAPIError Err.LastDllError
        Exit Sub
    End If

    If dwBytesNeed = 0 Then
        MsgBox "没有打印任务!", vbInformation
        Exit Sub
    End If

    If dwBytesNeed > lngSize Then
        ReDim aJi1(dwBytesNeed - 1)
        RetVal = EnumJobs(hPrinter, 0, 3, 1, aJi1(0), dwBytesNeed, dwBytesNeed, dwBytesRet)
    End If

    ReDim JI1(1 To dwBytesRet)
    List1.Clear
    'For lngCount = 1 To dwBytesRet
    n=0
    lngCount=1
    Do
        if lngSize * n > dwBytesRet then exit do
        Call CopyMemory(JI1(lngCount), aJi1(lngSize * n), lngSize)
        List1.AddItem "打印任务" & lngCount
        List1.AddItem "JobID:" & JI1(lngCount).JobId
        List1.AddItem "pPrinterName:" & GetStringFromMem(JI1(lngCount).pPrinterName)
        List1.AddItem "pMachineName:" & GetStringFromMem(JI1(lngCount).pMachineName)
        List1.AddItem "pUserName:" & GetStringFromMem(JI1(lngCount).pUserName)
        List1.AddItem "pDocument:" & GetStringFromMem(JI1(lngCount).pDocument)
        List1.AddItem "pStatus:" & JI1(lngCount).pStatus
        List1.AddItem "Status:" & JI1(lngCount).Status
        List1.AddItem "Priority:" & JI1(lngCount).Priority
        List1.AddItem "Position:" & JI1(lngCount).Position
        List1.AddItem "TotalPages:" & JI1(lngCount).TotalPages
        List1.AddItem "PagesPrinted:" & JI1(lngCount).PagesPrinted
        List1.AddItem "Year:" & JI1(lngCount).Submitted.wYear
        List1.AddItem "Month:" & JI1(lngCount).Submitted.wMonth
        List1.AddItem "Day:" & JI1(lngCount).Submitted.wDay
        List1.AddItem "DayOfWeek:" & JI1(lngCount).Submitted.wDayOfWeek
        List1.AddItem "Hour:" & JI1(lngCount).Submitted.wHour
        List1.AddItem "Minute:" & JI1(lngCount).Submitted.wMinute
        List1.AddItem "Second:" & JI1(lngCount).Submitted.wSecond
        List1.AddItem "wMilliseconds:" & JI1(lngCount).Submitted.wMilliseconds
        List1.AddItem "copyies:" & Printer.Copies
    'Next
    Loop
    ClosePrinter (hPrinter)
End Sub

Public Function GetAPIError(ByVal API_ERROR As Long)
    Dim Lret As Long
    Dim M_Msg As String
    M_Msg = String(256, " ")
    Lret = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM Or FORMAT_MESSAGE_IGNORE_INSERTS, 0&, API_ERROR, 0&, M_Msg, Len(M_Msg), 0&)
    If Lret <> 0 Then
       M_Msg = Trim(M_Msg)
       MsgBox M_Msg, , "API错误信息"
    End If
End Function

'从给定的内存地址中获得字符串
Private Function GetStringFromMem(ByVal Addr As Long) As String
    Dim lngSize         As Long
    Dim bytStr()        As Byte
    Dim lngX            As Long

    '获得字符串的长度
    Call CopyMemory(lngSize, ByVal Addr - 4, 4)
    ReDim bytStr(lngSize / 2)
    Call CopyMemory(bytStr(0), ByVal Addr, lngSize / 2 + 1)
    GetStringFromMem = StrConv(bytStr, vbUnicode)
End Function
Copies 属性 返回或设置需要打印的份数。对于 Printer 对象,在设计时不可用。 语法 object.Copies [= number] Copies 属性语法包含下面部分: 部分 描述 Object 对象表达式,其值是“应用于”列表中的一个对象。 Number 数值表达式,指定需要打印的份数。该值必须是整型值。 说明 对于“打印”对话框,该属性返回在“份数”框中用户输入的份数。如果设置 CommonDialog 控件的 cdlPDUseDevModeCopies 标志,则该属性始终返回 1。 对于 Printer 对象,对多份打印可能进行、也可能不进行核对,这取决于打印机驱动程序。可以将整个文档或将每一页打印多份。对于不支持核对的打印机,设置 Copies = 1,然后在程序中使用循环,就可以将整个文档打印多份。 注意 Printer 对象属性的效果取决于打印机生产商提供的驱动程序。一些属性设置可能不起作用,或几个不同的属性设置具有相同的结果。如果设置值超出可接受范围,就会产生错误。更多的信息,参阅有关驱动程序的生产商文档。
hongzm 2017-11-20
  • 打赏
  • 举报
回复
修改后的代码。加一个form1,list1,command1就能运行 'Types Definition Private Const CCHDEVICENAME = 32 Private Const CCHFORMNAME = 32 Private Const PRINTER_ACCESS_ADMINISTER = &H4 Private Const PRINTER_ACCESS_USE = &H8 Private Type DEVMODE dmDeviceName As String * CCHDEVICENAME 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 * CCHFORMNAME dmUnusedPadding As Integer dmBitsPerPel As Long dmPelsWidth As Long dmPelsHeight As Long dmDisplayFlags As Long dmDisplayFrequency As Long End Type Private Type PRINTER_DEFAULTS pDatatype As String pDevMode As DEVMODE DesiredAccess As Long End Type Private Declare Function OpenPrinter Lib "winspool.drv" Alias "OpenPrinterA" (ByVal pPrinterName As String, phPrinter As Long, pDefault As PRINTER_DEFAULTS) 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 Byte, ByVal cdBuf As Long, pcbNeeded As Long, pcReturned As Long) As Long Private Type SYSTEMTIME wYear As Integer wMonth As Integer wDayOfWeek As Integer wDay As Integer wHour As Integer wMinute As Integer wSecond As Integer wMilliseconds As Integer End Type Private Type JOB_INFO_1 JobId As Long pPrinterName As Long pMachineName As Long pUserName As Long pDocument As Long pDatatype As Long pStatus As Long Status As Long Priority As Long Position As Long TotalPages As Long PagesPrinted As Long Submitted As SYSTEMTIME End Type Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long) Private Declare Function FormatMessage Lib "kernel32" Alias "FormatMessageA" (ByVal dwFlags As Long, lpSource As Any, ByVal dwMessageId As Long, ByVal dwLanguageId As Long, ByVal lpBuffer As String, ByVal nSize As Long, Arguments As Long) As Long Private Const FORMAT_MESSAGE_FROM_SYSTEM = &H1000 Private Const FORMAT_MESSAGE_IGNORE_INSERTS = &H200 Private Sub Command1_Click() Dim hPrinter As Long Dim RetVal As Long Dim pd As PRINTER_DEFAULTS Dim lngCount As Long Dim JI1() As JOB_INFO_1 Dim aJi1() As Byte Dim dwBytesNeed As Long Dim dwBytesRet As Long Dim lngSize As Long Dim JI_1 As JOB_INFO_1 lngSize = Len(JI_1) pd.DesiredAccess = PRINTER_ACCESS_ADMINISTER RetVal = OpenPrinter(Printer.DeviceName, hPrinter, pd) ReDim aJi1(lngSize - 1) RetVal = EnumJobs(hPrinter, 0, 3, 1, aJi1(0), lngSize, dwBytesNeed, dwBytesRet) If RetVal = 0 And dwBytesNeed = 0 Then GetAPIError Err.LastDllError Exit Sub End If If dwBytesNeed = 0 Then MsgBox "没有打印任务!", vbInformation Exit Sub End If If dwBytesNeed > lngSize Then ReDim aJi1(dwBytesNeed - 1) RetVal = EnumJobs(hPrinter, 0, 3, 1, aJi1(0), dwBytesNeed, dwBytesNeed, dwBytesRet) End If ReDim JI1(1 To dwBytesRet) List1.Clear 'For lngCount = 1 To dwBytesRet n = 0 lngCount = 1 Do If lngSize * n > dwBytesRet Then Exit Do Call CopyMemory(JI1(lngCount), aJi1(lngSize * n), lngSize) 'Call CopyMemory(JI1(lngCount), aJi1((lngCount - 1) * lngSize), lngSize) List1.AddItem "打印任务" & lngCount List1.AddItem "JobID:" & JI1(lngCount).JobId List1.AddItem "pPrinterName:" & GetStringFromMem(JI1(lngCount).pPrinterName) List1.AddItem "pMachineName:" & GetStringFromMem(JI1(lngCount).pMachineName) List1.AddItem "pUserName:" & GetStringFromMem(JI1(lngCount).pUserName) List1.AddItem "pDocument:" & GetStringFromMem(JI1(lngCount).pDocument) List1.AddItem "pStatus:" & JI1(lngCount).pStatus List1.AddItem "Status:" & JI1(lngCount).Status List1.AddItem "Priority:" & JI1(lngCount).Priority List1.AddItem "Position:" & JI1(lngCount).Position List1.AddItem "TotalPages:" & JI1(lngCount).TotalPages List1.AddItem "PagesPrinted:" & JI1(lngCount).PagesPrinted List1.AddItem "Year:" & JI1(lngCount).Submitted.wYear List1.AddItem "Month:" & JI1(lngCount).Submitted.wMonth List1.AddItem "Day:" & JI1(lngCount).Submitted.wDay List1.AddItem "DayOfWeek:" & JI1(lngCount).Submitted.wDayOfWeek List1.AddItem "Hour:" & JI1(lngCount).Submitted.wHour List1.AddItem "Minute:" & JI1(lngCount).Submitted.wMinute List1.AddItem "Second:" & JI1(lngCount).Submitted.wSecond List1.AddItem "wMilliseconds:" & JI1(lngCount).Submitted.wMilliseconds List1.AddItem "copies:" & Printer.Copies 'List1.AddItem "dmCopies:" & pd.pDevMode.dmCopies n = n + 1 '★★★★★★注意这里原来少这一句 Loop 'Next ClosePrinter (hPrinter) End Sub Public Function GetAPIError(ByVal API_ERROR As Long) Dim Lret As Long Dim M_Msg As String M_Msg = String(256, " ") Lret = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM Or FORMAT_MESSAGE_IGNORE_INSERTS, 0&, API_ERROR, 0&, M_Msg, Len(M_Msg), 0&) If Lret <> 0 Then M_Msg = Trim(M_Msg) MsgBox M_Msg, , "API错误信息" End If End Function '从给定的内存地址中获得字符串 Private Function GetStringFromMem(ByVal Addr As Long) As String Dim lngSize As Long Dim bytStr() As Byte Dim lngX As Long '获得字符串的长度 Call CopyMemory(lngSize, ByVal Addr - 4, 4) ReDim bytStr(lngSize / 2) Call CopyMemory(bytStr(0), ByVal Addr, lngSize / 2 + 1) GetStringFromMem = StrConv(bytStr, vbUnicode) End Function
hongzm 2017-11-20
  • 打赏
  • 举报
回复
引用 19 楼 hongzm 的回复:
还是不行。我的天。再加分啊。我按代码改了。printer.copies永远是0,我把加的dmCopies也去掉了。
说错了。现在copies是永远为1
hongzm 2017-11-20
  • 打赏
  • 举报
回复
还是不行。我的天。再加分啊。我按代码改了。printer.copies永远是0,我把加的dmCopies也去掉了。
赵4老师 2017-11-20
  • 打赏
  • 举报
回复
Using a Print Dialog Box and Retrieving a Printer Device Context The first step in printing involves setting up the printer and obtaining a printer DC. In the sample application, the File menu contains two options, Print and Print Setup. By selecting either option, the user can configure the printer. When the user selects the Print Setup option, the Print Setup dialog box is displayed and the user can select a printer, a page orientation, a paper size, and so on. When the user selects the Print option, the Print dialog box is displayed and the user can select a range of pages, a print quality, a number of copies, and so on. The user can also display the Print Setup dialog box by clicking the Setup push button. The Print and Print Setup dialog boxes are both displayed by initializing the members of aPRINTDLG structure and calling thePrintDlg function. (For more information about displaying the Print Setup dialog box, seeCommon Dialog Box Library). In addition to retrieving user-specified data, PrintDlg can be used to obtain a printer DC by specifying the PD_RETURNDC value in the Flags member of the PRINTDLG structure. The following code sample shows how to intialize the members of the structure and to display the Print dialog box. // Initialize the PRINTDLG members. pd.lStructSize = sizeof(PRINTDLG); pd.hDevMode = (HANDLE) NULL; pd.hDevNames = (HANDLE) NULL; pd.Flags = PD_RETURNDC; pd.hwndOwner = hwnd; pd.hDC = (HDC) NULL; pd.nFromPage = 1; pd.nToPage = 1; pd.nMinPage = 0; pd.nMaxPage = 0; pd.nCopies = 1; pd.hInstance = (HANDLE) NULL; pd.lCustData = 0L; pd.lpfnPrintHook = (LPPRINTHOOKPROC) NULL; pd.lpfnSetupHook = (LPSETUPHOOKPROC) NULL; pd.lpPrintTemplateName = (LPSTR) NULL; pd.lpSetupTemplateName = (LPSTR) NULL; pd.hPrintTemplate = (HANDLE) NULL; pd.hSetupTemplate = (HANDLE) NULL; // Display the PRINT dialog box. PrintDlg(&pd);
赵4老师 2017-11-20
  • 打赏
  • 举报
回复
n=0 lngCount=1 Do if lngSize * n > dwBytesRet then exit do Call CopyMemory(JI1(lngCount), aJi1(lngSize * n), lngSize) List1.AddItem "打印任务" & lngCount List1.AddItem "JobID:" & JI1(lngCount).JobId List1.AddItem "pPrinterName:" & GetStringFromMem(JI1(lngCount).pPrinterName) List1.AddItem "pMachineName:" & GetStringFromMem(JI1(lngCount).pMachineName) List1.AddItem "pUserName:" & GetStringFromMem(JI1(lngCount).pUserName) List1.AddItem "pDocument:" & GetStringFromMem(JI1(lngCount).pDocument) List1.AddItem "pStatus:" & JI1(lngCount).pStatus List1.AddItem "Status:" & JI1(lngCount).Status List1.AddItem "Priority:" & JI1(lngCount).Priority List1.AddItem "Position:" & JI1(lngCount).Position List1.AddItem "TotalPages:" & JI1(lngCount).TotalPages List1.AddItem "PagesPrinted:" & JI1(lngCount).PagesPrinted List1.AddItem "Year:" & JI1(lngCount).Submitted.wYear List1.AddItem "Month:" & JI1(lngCount).Submitted.wMonth List1.AddItem "Day:" & JI1(lngCount).Submitted.wDay List1.AddItem "DayOfWeek:" & JI1(lngCount).Submitted.wDayOfWeek List1.AddItem "Hour:" & JI1(lngCount).Submitted.wHour List1.AddItem "Minute:" & JI1(lngCount).Submitted.wMinute List1.AddItem "Second:" & JI1(lngCount).Submitted.wSecond List1.AddItem "wMilliseconds:" & JI1(lngCount).Submitted.wMilliseconds List1.AddItem "copyies:" & Printer.Copies n=n+1'★★★★★★注意这里原来少这一句 'Next Loop
赵4老师 2017-11-20
  • 打赏
  • 举报
回复
引用 14 楼 qq574221329 的回复:
[quote=引用 7 楼 zhao4zhong1 的回复:] QQ:511606848 等待发红包中……
应该是有效果的.我测试了一下. 但不知道是数量太多还是什么的.会报错.没深入研究了[/quote] 你原来的代码报错的原因至少有两个: ①MSDN中JOB_INFO_1结构后面没有dmCopies,你无端添加一个,导致计算整个结构的大小 Dim JI_1 As JOB_INFO_1 lngSize = Len(JI_1) 不对。 ②For lngCount = 1 To dwBytesRet Call CopyMemory(JI1(lngCount), aJi1((lngCount - 1) * lngSize), lngSize) 这个循环根本达不到每次取一个JOB_INFO_1结构的目的。 参考我最后给出的代码是怎么做的。
舉杯邀明月 2017-11-20
  • 打赏
  • 举报
回复
引用 12 楼 hongzm 的回复:
[quote=引用 8 楼 Chen8013 的回复:] [quote=引用 7 楼 zhao4zhong1 的回复:] QQ:511606848 等待发红包中……
你想得太天真了…… 你用Printer.Copies肯定不对! (我没有打印机,只能“猜测分析”,也可能我的想法也不对) 这个“值”要么是“所有打印作业”的总份数,要么是在代码中通过Printer对象操作的“当前作业”的打印份数。 肯定会不是打印队列中某个特定作业的份数。 [/quote] 其实要求很简单,得到总份数也行,我会限制打印队列里只有一个任务。[/quote] 那你就准备给赵4发红包吧。
加载更多回复(9)

1,216

社区成员

发帖
与我相关
我的任务
社区描述
VB 数据库(包含打印,安装,报表)
社区管理员
  • 数据库(包含打印,安装,报表)社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧