怎样通过程序判断打印机的各种状态?
我现在知道用GetPrinter,但是我知道打印机有哪些状态。
我就是希望大家能够帮我把 PRINTER_INFO_x中的数据成员列举出来。Help Me..........

解决方案 »

  1.   

    你必须使用Windows API,具体步骤参考:微软的Knowledge Base的文章:“Q160129 OWTO: Get the Status of a Printer and a Print Job”。下面是部分例子: 
         BOOL GetJobs(HANDLE hPrinter, /* Handle to the printer. */ 
         
         JOB_INFO_2 **ppJobInfo, /* Pointer to be filled. */ 
         int *pcJobs, /* Count of jobs filled. */ 
         DWORD *pStatus) /* Print Queue status. */ 
         
         { 
         
         DWORD cByteNeeded, 
         nReturned, 
         cByteUsed; 
         JOB_INFO_2 *pJobStorage = NULL; 
         PRINTER_INFO_2 *pPrinterInfo = NULL; 
         
         /* Get the buffer size needed. */ 
         if (!GetPrinter(hPrinter, 2, NULL, 0, &cByteNeeded)) 
         { 
         if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) 
         return FALSE; 
         } 
         
         pPrinterInfo = (PRINTER_INFO_2 *)malloc(cByteNeeded); 
         if (!(pPrinterInfo)) 
         /* Failure to allocate memory. */ 
         return FALSE; 
         
         /* Get the printer information. */ 
         if (!GetPrinter(hPrinter, 
         2, 
         (LPSTR)pPrinterInfo, 
         cByteNeeded, 
         &cByteUsed)) 
         { 
         /* Failure to access the printer. */ 
         free(pPrinterInfo); 
         pPrinterInfo = NULL; 
         return FALSE; 
         } 
         
         /* Get job storage space. */ 
         if (!EnumJobs(hPrinter, 
         0, 
         pPrinterInfo->cJobs, 
         2, 
         NULL, 
         0, 
         (LPDWORD)&cByteNeeded, 
         (LPDWORD)&nReturned)) 
         { 
         if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) 
         { 
         free(pPrinterInfo); 
         pPrinterInfo = NULL; 
         return FALSE; 
         } 
         } 
         
         pJobStorage = (JOB_INFO_2 *)malloc(cByteNeeded); 
         if (!pJobStorage) 
         { 
         /* Failure to allocate Job storage space. */ 
         free(pPrinterInfo); 
         pPrinterInfo = NULL; 
         return FALSE; 
         } 
         
         ZeroMemory(pJobStorage, cByteNeeded); 
         
         /* Get the list of jobs. */ 
         if (!EnumJobs(hPrinter, 
         0, 
         pPrinterInfo->cJobs, 
         2, 
         (LPBYTE)pJobStorage, 
         cByteNeeded, 
         (LPDWORD)&cByteUsed, 
         (LPDWORD)&nReturned)) 
         { 
         free(pPrinterInfo); 
         free(pJobStorage); 
         pJobStorage = NULL; 
         pPrinterInfo = NULL; 
         return FALSE; 
         } 
         
         /* 
         * Return the information. 
         */ 
         *pcJobs = nReturned; 
         *pStatus = pPrinterInfo->Status; 
         *ppJobInfo = pJobStorage; 
         free(pPrinterInfo); 
         
         return TRUE; 
         
         } 
         
         BOOL IsPrinterError(HANDLE hPrinter) 
         { 
         
         JOB_INFO_2 *pJobs; 
         int cJobs, 
         i; 
         DWORD dwPrinterStatus; 
         
         /* 
         * Get the state information for the Printer Queue and 
         * the jobs in the Printer Queue. 
         */ 
         if (!GetJobs(hPrinter, &pJobs, &cJobs, &dwPrinterStatus)) 
         return FALSE; 
         
         /* 
         * If the Printer reports an error, believe it. 
         */ 
         if (dwPrinterStatus & 
         (PRINTER_STATUS_ERROR | 
         PRINTER_STATUS_PAPER_JAM | 
         PRINTER_STATUS_PAPER_OUT | 
         PRINTER_STATUS_PAPER_PROBLEM | 
         PRINTER_STATUS_OUTPUT_BIN_FULL | 
         PRINTER_STATUS_NOT_AVAILABLE | 
         PRINTER_STATUS_NO_TONER | 
         PRINTER_STATUS_OUT_OF_MEMORY | 
         PRINTER_STATUS_OFFLINE | 
         PRINTER_STATUS_DOOR_OPEN)) 
         { 
         return TRUE; 
         } 
         
         /* 
         * Find the Job in the Queue that is printing. 
         */ 
         for (i=0; i < cJobs; i++) 
         { 
         if (pJobs[i].Status & JOB_STATUS_PRINTING) 
         { 
         /* 
         * If the job is in an error state, 
         * report an error for the printer. 
         * Code could be inserted here to 
         * attempt an interpretation of the 
         * pStatus member as well. 
         */ 
         if (pJobs[i].Status & 
         (JOB_STATUS_ERROR | 
         JOB_STATUS_OFFLINE | 
         JOB_STATUS_PAPEROUT | 
         JOB_STATUS_BLOCKED_DEVQ)) 
         { 
         return TRUE; 
         } 
         } 
         } 
         
         /* 
         * No error condition. 
         */ 
         return FALSE; 
         
         } 
    http://support.microsoft.com/support/kb/articles/Q160/1/29.asp
      

  2.   

    怎么在VB中设定Windows的默认打印机? 
    http://support.microsoft.com/support/kb/articles/Q266/7/67.asp如何检查打印队列中是否还有打印的任务编号:QA003384
    建立日期: 2000年10月10日 最后修改日期:2000年10月10日 
    所属类别: Visual Basic - 打印与报表 chenxixian: 
        操作系统: win98 
        编程工具: VB5 
        问题: 在向打印机发送打印命令前,我想检查一下打印队列中是否还有打印的任务,如有则稍后再发,以免打印队列内的打印任务越来越多导致系统的崩溃,如何实现? 
        水平: 中级 回答:     下面是一个简单的例子: 
        Private Declare Function OpenPrinter Lib "winspool.drv" Alias "OpenPrinterA" (ByVal pPrinterName As String, phPrinter As Long, pDefault As Any) 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 Declare Function ClosePrinter Lib "winspool.drv" (ByVal hPrinter As Long) As Long 
         
        Private Sub Command1_Click() 
         Dim hPrinter As Long 
         Dim dwNeeded, dwReturned As Long 
         Dim b(1000) As Byte 
         
         If OpenPrinter("Canon Bubble-Jet BJ-10e", hPrinter, ByVal 0&) = 0 Then 
         Exit Sub 
         End If 
         
         EnumJobs hPrinter, 0, &HFFFFFFFF, 1, b(0), 1000, dwNeeded, _ 
         dwReturned 
         MsgBox "有" & dwReturned & "个打印任务!" 
         ClosePrinter hPrinter 
        End Sub 
        更完整的例子可以参考微软的Knowledge Base的文章:“Q158828 OWTO: How To Call Win32 Spooler Enumeration APIs Properly”和微软的Knowledge Base的文章:“Q228769 OWTO: Retrieve Print Job Information”。 http://support.microsoft.com/support/kb/articles/Q158/8/28.asp
    http://support.microsoft.com/support/kb/articles/Q228/7/69.asp
    如何更改打印机使用的纸张类型
    http://support.microsoft.com/support/kb/articles/Q180/6/45.asp
    如何实现VB打印预览及更改打印机类型编号:QA000919
    建立日期: 1999年5月4日 最后修改日期:1999年5月4日 
    所属类别: Visual Basic - 打印与报表 Wang LiMing: 
        VB5 
        Win95 
        如何实现VB打印预览及更改打印机类型? 回答:     如果你想了解打印预览的原理,可以参考微软的Knowledge Base的文章:“Q113236 OWTO: Add Print Preview to Visual Basic Applications”。不过这种方法比较麻烦,也可以考虑使用PrintPreview OCX(http://www.geocities.com/ResearchTriangle/6311/)或VsView(http://www.videosoft.com)。 
        打印机对象Printer有众多的属性,你可以通过它进行打印机设置,也可以利用通用对话框控件的打印机设置功能设置打印机。 
    后台监测打印端口,并返回打印的张数编号:QA000646
    建立日期: 1999年3月16日 最后修改日期:1999年3月16日 
    所属类别: Visual Basic - 打印与报表 Cobe: 
        VB5 
        Win98 
        有没有能够监听打印端口的例程或函数?? 我希望能后台监测打印端口,并返回打印的张数。请帮助。 回答:     这个问题对VB来说有困难,尽管Win32 API中有个AddMonitor可以监视打印端口,但VB无法使用这个API。你可以考虑不断调用EnumJobs获得打印任务,从打印任务中可以获得打印的页数。有关EnumJobs的使用,你可以参考微软的Knowledge Base(http://support.microsoft.com)的文章“Q160129 HOWTO: Get the Status of a Printer and a Print Job”。 
      

  3.   

    哦,还这么复杂啊。
    我得好好整理一下思路。
    谢谢cindytsai(笨笨的蔡鸟) ,haohaohappy(爱要冒险,工作要拼) ,HtoFire(冬天里的一把火) 。
      

  4.   

    打印机是一个与主机通讯的外部设备。要知道它是否在工作,可以发送一个命令给它。如果应答正确,就是 OK。例如,
     Dim  n As Integer On Error Resume Next
     n = Printer.Orientation If n > 0 Then Degug.Print "Printer is Ready"
      

  5.   

    谢谢of123()。
    可是不行,我把打印机关了, n=1,返回的值大于0。你的思路是对的,但是Printer.Orientation是不是就是向打印机发送了命令呢?打印机有个状态是OFFLINE,当关闭打印机时,它肯定会向操作系统注册这样的信息的。