2.1.2监测当前打印机状态
2。1。2監測當前打印機狀態
? Windows標準的打印機監測程序。通過該程序,我們可以了解當前打印機的狀態,包括打印機任務隊列,
? 各項任務狀態、所有者、進度和開始時間,并且可以及時暫停、清除打印任務。
? 監控打印機就有必要對Windows后臺打印機制有所了解。后臺程序可以減輕應用程序的打印負擔。Windows在啟動時就加載后臺
? 打印程序。因此,當應用程序開始打印時,它已經是活動的了。當程序打印一個文件時,GDI模塊創建打印的數據文件。后臺
? 打印程序的任務是將這些文件發往打印機。GDI模塊發出一個消息來通知它開始一個新的打印作業。然后打印機開始讀文件,
? 并將文件傳送到打印機。為了傳送打印文件,后臺程序為打印機所連接的并口和串口提供各種通信函數。在后臺程序向打
? 印機發送文件操作結束的命令后,它就刪除包含輸出數據的臨時文件。
?????????????? 后臺打印程序的組合。
? ----------------------------------------
? 打印請求后臺程序???? | 將數據流傳遞給打印機
? 本地打印提供者?????? | 為本地打印機創建后臺文件
? 網絡打印提供者?????? | 為網絡打印機創建后臺文件。
? 打印處理程序???????? | 將后臺的設備無關數據轉換為特定打印機的格式
? 端口監視程序???????? | 控制連接打印機的端口
? 語言監視程序???????? | 控制雙向通信的打印機,配置并檢測打印機的狀態
? 使用后臺打印程序,真正的文件打印操作是后臺打印程序的任務,而不是應用程序的任務。
? 我們可以暫停打印作業、改變作業的優先級或者取消打印作業。這種管理方式使得應用程序
? 可能比下面的這種情況“打印”得更快。即作業以實時方式打印,且必須等到打印完一頁后
? 才能處理下一頁。
? 但是如果我們擁有更好的打印機軟硬件或者在網絡打印機等某些特殊的情況下,可以去掉Windows后臺打印程序。
? 去掉Windows后以中打印程序可以加快打印速度。因為打印輸出不必保存在硬盤上,而可以直接輸出到打印機,并被
? 外部硬件或軟件后臺程序所接受。
? 實現類似Windows打印監測試程序的功能,需要調用Win32假脫機(SPOOL)枚舉API函數。"[使用Win32假脫機枚舉函數需要調用
? 兩次所需的函數。這些API函數通常要填充一組結構。但是,這些結構通常包含指向字符串和其他類型數據的指針。
? 這些外來的數據必須存儲在返回的內存中,使得字符串和其他數據存儲在結構中。所以簡單的在堆棧中聲明一組結構變量
? 不足以為API函數返回的信息設置足夠的內存。]"
? 因此,正確的函數調用是:首先調用API函數確定需要的內存空間,在隨后的調用中傳入一個指針,該指針指向了一塊動態
? 分配的大小合適內存空間。需要進行該類處理的枚舉函數包括:
? EnumForms(),EnumJobs(),EnumMonitors(),EnumPorts(),EnumPrinterDrivers(),EnumPrinters()和EnumPrinterProcessors()
? 下面這段程序,使用EnumJobs()API函數,枚舉出所選打印機當前的打印任務。關于其他打印監控函數的使用大家可以參考
? 微軟平臺SDK中關于打印函數和打印假脫機枚舉函數的文檔。
? 注意:獨占設備是指在一個程序(作業、用戶)的整個運行其間獨占的設備,直到該程序(作業、用戶)完成。系統的獨占設備是
? 有限的(譬如一臺計算機只能連接一臺打印機),往往不能滿足多進程的要求,會引起大量進程由于等待某些獨占設備而阻塞,
? 成為系統的“瓶頸”。另一方面,申請到獨占設備的進程在其整個運行期間雖然占有設備,利用率卻常常很低,設備還是經常
? 處于空閑狀態。為了解決這種矛盾,最常用的方法就是用共享設備來模擬獨占設備,從而提高系統地效率和設備利用率.這種
? 技術稱為虛擬設備技術.實現這一技術的軟、硬件系統被稱為假脫機(Simultaneous Peripaheral Operation On Line SPOOL)
? 系統。打印機是典型的獨占設備。引入SPOOL技術后,用戶的打印請求傳遞給SPOOL系統,而不是真正的把打印機分配給用戶。
? SPOOL系統的輸出進程是先磁盤上申請一個空閑區域,把需要打印的數據傳輸到里面,再把用戶的打印請求掛到打印機隊列上。
? 如果打印機空閑,就會從打印機隊列中取出一個打印請求,再從磁盤上的指定區域取出數據,執行打印操作。由于磁盤是共享
? 的,SPOOL系統可以隨時響應打印請求并把數據緩存起來,這樣獨占設備改造成了共享設備,從而提高了設備的利用率和系統
? 利用率。
?? /*
?? OpenPrinter
?? Declare Function OpenPrinter Lib "winspool.drv" Alias "OpenPrinterA"(ByVal pPrinterName As String,phPrinter As Long,
?? pDefault As PRINTER_DEFAULTS)As Long
?? 說明:
?? 打開指定的打印機,并獲取打印機的句柄。
?? 返回值:
?? Long,非零表示成功,零表示失敗。會設置GetLastError
?? 參數表:
?? pPrinterName? String,要打開的打印機的名字
?? phPrinter???? Long,用于裝載打印機的句柄。
?? pDefault????? PRINTER_DEFAULT,這個結構保存要載入的打印機信息。
?? */
?? /*
?? Declare Function EnumJobs Lib "winspool.drv"Alias "EnumJobsA"(ByVal hPrinter As Long,
?? ByVal First Job 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
?? 說明:
?? 枚舉打印隊列中的作業
?? 返回值:
?? Long,非零表示成功,零表示失敗。 可以通過GetLastError獲取錯誤信息。
?? hPrinter:? Long,一個已打開的打印機對象的句柄(用OpenPrinter獲得)
?? FirstJob:? Long,作業列表中要枚舉的第一個作業的索引(注意編號從0開始)
?? NoJobs???? Long,要枚舉的作業數量。
?? Level????? Long,1或2
?? pJob?????? Byte,包含JOB_INFO_1或JOB_INFO_2結構的緩沖區
?? cbBuf????? Long,pJob緩沖區中的字符數量。
?? pcbNeeded? Long,指向一個LONG型變量的指針,該變量用于保存請求的緩沖區長度
????????????? 或者實際讀入的字節數量。
?? pcReturned Long,載入緩沖區的結構數量(用于那些能返回多個結構的函數)。
?? */
?? /*
?? GetLastError
?? Declare Function GetLastError lib "kernel32"Alias "GetLastError"As Long
?? 說明:
?? 針對之前調用的api函數,用這個函數取得擴展錯誤信息
?? 返回值:Long,由api函數決定.請參考api32.txt文件,其中列出了一系列錯誤常數;都以ERROR_前
?? 綴起頭.常用的錯誤代碼見下表:
?? ERROR_INVALID_HANDLE:無效的句柄作為一個參數傳遞。
?? ERROR_CALL_NOT_IMPLEMENTED? 在win95下調用專為win nt設計的win32 api函數
?? ERROR_INVALID_PARAMETER?? 函數中有個參數不正確。
?? */
?? /*
?? EnumJobs
?? Declare Function EnumJobs Lib "winspool.drv" alias "EnumJobsA"(ByVal hPrinter As Long,ByVal FirstJob As Long,ByVal NoJobs As Long,By Level As Long
?? pJob As Byte,ByVal cdBuf As Long,pcbNeeded As Long,pcReturned As Long) As Long
?? 說明:
?? 枚舉打印隊列中的作業
?? 返回值:
?? Long,非零表示成功,零表示失敗。可以通過GetLastError獲取錯誤信息
?? 參數表:
?? hPrinter???????? Long,一個已打開的打印機對象的句柄(用OpenPrinter獲得)
?? FirstJob???????? Long,作業列表中要枚舉的第一個作業的索引(注意編號從0開始)
?? NoJobs?????????? Long,要枚舉的作業數量。
?? Level??????????? Long,1或2
?? pJob???????????? Byte,包含JOB_INFO_1或JOB_INFO_2結構的緩沖區。
?? cbBuf??????????? Long,pJob緩沖區中的字符數量。
?? pcbNeeded??????? Long,指向一個Long型變量的指針,該變量用于保存請求的緩沖區長度,或者實際讀入的字節數。
?? pcbReturned????? Long,載入緩沖區的結構數量。
?? */
?? BOOL CPrintListDlg::PrintJobList(LPCTSTR szPrintName)
?? {
??? HANDLE?? hPrinter;
??? DWORD??? dwNeeded,dwReturned,i;
??? JOB_INFO_1? *pJobInfo;
??? if(!OpenPrinter(szPrinterName,&hPrinter,NULL))
???? return FALSE;
??? if(EnumJobs(hPrinter,0,0xFFFFFFFF,NULL,1,NULL,0,&dwNeeded,&dwReturned))
??? {
???? if(GetLastError() != ERROR_INSUFFICIENT_BUFFER)
???? {
????? ClosePrinter(hPrinter);
????? return FALSE;
???? }
??? }
??? if((pJobInfo = (JOB_INFO_1*)malloc(dwNeeded)) == NULL)
??? {
???? ClosePrinter(hPrinter);
???? return FALSE;
??? }
??? if(!EnumJobs(hPrinter,0,0xFFFFFFFF,1,(LPBYTE)pJobInfo,dwNeeded,&dwNeeded,&dwReturned))
??? {
???? ClosePrinter(hPrinter);
???? free(pJobInfo);
???? return FALSE;
??? }
??? ClosePrinter(hPrinter);
???
??? for(UINT i = 0; i < dwReturned; i++)
??? {
???? m_listBox2.AddString(pJobInfo[i].pDocument);
??? }
??? free(pJobInfo);
??? return TRUE;
?? }
?? void CPrintListDlg::OnSelchangePrinters()
?? {
??? int nIndex = m_listBox.GetCurSel();
??? CString strPrinterName;
??? if(nIndex != CB_ERR)
??? {
???? m_listBox.GetText(nIndex,strPrinterName);
???? if(strPrinterName.IsEmpty())
???? {
????? PrintJobList((LPCTSTRstrPrinterName));
???? }
??? }
?? }
?? /*
?? 這個例子啟發我們,應用打印枚舉API函數可以對打印機進行有效的監控。
?? */
轉載于:https://www.cnblogs.com/scud001/archive/2010/05/12/1734027.html
總結
以上是生活随笔為你收集整理的2.1.2监测当前打印机状态的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jQuery Alert Dialogs
- 下一篇: ArcGis For Flex 之 Qu