日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

2.1.2监测当前打印机状态

發(fā)布時(shí)間:2025/7/14 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2.1.2监测当前打印机状态 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

2。1。2監(jiān)測當(dāng)前打印機(jī)狀態(tài)
? Windows標(biāo)準(zhǔn)的打印機(jī)監(jiān)測程序。通過該程序,我們可以了解當(dāng)前打印機(jī)的狀態(tài),包括打印機(jī)任務(wù)隊(duì)列,
? 各項(xiàng)任務(wù)狀態(tài)、所有者、進(jìn)度和開始時(shí)間,并且可以及時(shí)暫停、清除打印任務(wù)。

? 監(jiān)控打印機(jī)就有必要對Windows后臺打印機(jī)制有所了解。后臺程序可以減輕應(yīng)用程序的打印負(fù)擔(dān)。Windows在啟動時(shí)就加載后臺
? 打印程序。因此,當(dāng)應(yīng)用程序開始打印時(shí),它已經(jīng)是活動的了。當(dāng)程序打印一個文件時(shí),GDI模塊創(chuàng)建打印的數(shù)據(jù)文件。后臺
? 打印程序的任務(wù)是將這些文件發(fā)往打印機(jī)。GDI模塊發(fā)出一個消息來通知它開始一個新的打印作業(yè)。然后打印機(jī)開始讀文件,
? 并將文件傳送到打印機(jī)。為了傳送打印文件,后臺程序?yàn)榇蛴C(jī)所連接的并口和串口提供各種通信函數(shù)。在后臺程序向打
? 印機(jī)發(fā)送文件操作結(jié)束的命令后,它就刪除包含輸出數(shù)據(jù)的臨時(shí)文件。

?????????????? 后臺打印程序的組合。
? ----------------------------------------
? 打印請求后臺程序???? | 將數(shù)據(jù)流傳遞給打印機(jī)
? 本地打印提供者?????? | 為本地打印機(jī)創(chuàng)建后臺文件
? 網(wǎng)絡(luò)打印提供者?????? | 為網(wǎng)絡(luò)打印機(jī)創(chuàng)建后臺文件。
? 打印處理程序???????? | 將后臺的設(shè)備無關(guān)數(shù)據(jù)轉(zhuǎn)換為特定打印機(jī)的格式
? 端口監(jiān)視程序???????? | 控制連接打印機(jī)的端口
? 語言監(jiān)視程序???????? | 控制雙向通信的打印機(jī),配置并檢測打印機(jī)的狀態(tài)

? 使用后臺打印程序,真正的文件打印操作是后臺打印程序的任務(wù),而不是應(yīng)用程序的任務(wù)。
? 我們可以暫停打印作業(yè)、改變作業(yè)的優(yōu)先級或者取消打印作業(yè)。這種管理方式使得應(yīng)用程序
? 可能比下面的這種情況“打印”得更快。即作業(yè)以實(shí)時(shí)方式打印,且必須等到打印完一頁后
? 才能處理下一頁。

? 但是如果我們擁有更好的打印機(jī)軟硬件或者在網(wǎng)絡(luò)打印機(jī)等某些特殊的情況下,可以去掉Windows后臺打印程序。
? 去掉Windows后以中打印程序可以加快打印速度。因?yàn)榇蛴≥敵霾槐乇4嬖谟脖P上,而可以直接輸出到打印機(jī),并被
? 外部硬件或軟件后臺程序所接受。

? 實(shí)現(xiàn)類似Windows打印監(jiān)測試程序的功能,需要調(diào)用Win32假脫機(jī)(SPOOL)枚舉API函數(shù)。"[使用Win32假脫機(jī)枚舉函數(shù)需要調(diào)用
? 兩次所需的函數(shù)。這些API函數(shù)通常要填充一組結(jié)構(gòu)。但是,這些結(jié)構(gòu)通常包含指向字符串和其他類型數(shù)據(jù)的指針。
? 這些外來的數(shù)據(jù)必須存儲在返回的內(nèi)存中,使得字符串和其他數(shù)據(jù)存儲在結(jié)構(gòu)中。所以簡單的在堆棧中聲明一組結(jié)構(gòu)變量
? 不足以為API函數(shù)返回的信息設(shè)置足夠的內(nèi)存。]"

? 因此,正確的函數(shù)調(diào)用是:首先調(diào)用API函數(shù)確定需要的內(nèi)存空間,在隨后的調(diào)用中傳入一個指針,該指針指向了一塊動態(tài)
? 分配的大小合適內(nèi)存空間。需要進(jìn)行該類處理的枚舉函數(shù)包括:
? EnumForms(),EnumJobs(),EnumMonitors(),EnumPorts(),EnumPrinterDrivers(),EnumPrinters()和EnumPrinterProcessors()

? 下面這段程序,使用EnumJobs()API函數(shù),枚舉出所選打印機(jī)當(dāng)前的打印任務(wù)。關(guān)于其他打印監(jiān)控函數(shù)的使用大家可以參考
? 微軟平臺SDK中關(guān)于打印函數(shù)和打印假脫機(jī)枚舉函數(shù)的文檔。

? 注意:獨(dú)占設(shè)備是指在一個程序(作業(yè)、用戶)的整個運(yùn)行其間獨(dú)占的設(shè)備,直到該程序(作業(yè)、用戶)完成。系統(tǒng)的獨(dú)占設(shè)備是
? 有限的(譬如一臺計(jì)算機(jī)只能連接一臺打印機(jī)),往往不能滿足多進(jìn)程的要求,會引起大量進(jìn)程由于等待某些獨(dú)占設(shè)備而阻塞,
? 成為系統(tǒng)的“瓶頸”。另一方面,申請到獨(dú)占設(shè)備的進(jìn)程在其整個運(yùn)行期間雖然占有設(shè)備,利用率卻常常很低,設(shè)備還是經(jīng)常
? 處于空閑狀態(tài)。為了解決這種矛盾,最常用的方法就是用共享設(shè)備來模擬獨(dú)占設(shè)備,從而提高系統(tǒng)地效率和設(shè)備利用率.這種
? 技術(shù)稱為虛擬設(shè)備技術(shù).實(shí)現(xiàn)這一技術(shù)的軟、硬件系統(tǒng)被稱為假脫機(jī)(Simultaneous Peripaheral Operation On Line SPOOL)
? 系統(tǒng)。打印機(jī)是典型的獨(dú)占設(shè)備。引入SPOOL技術(shù)后,用戶的打印請求傳遞給SPOOL系統(tǒng),而不是真正的把打印機(jī)分配給用戶。
? SPOOL系統(tǒng)的輸出進(jìn)程是先磁盤上申請一個空閑區(qū)域,把需要打印的數(shù)據(jù)傳輸?shù)嚼锩?#xff0c;再把用戶的打印請求掛到打印機(jī)隊(duì)列上。
? 如果打印機(jī)空閑,就會從打印機(jī)隊(duì)列中取出一個打印請求,再從磁盤上的指定區(qū)域取出數(shù)據(jù),執(zhí)行打印操作。由于磁盤是共享
? 的,SPOOL系統(tǒng)可以隨時(shí)響應(yīng)打印請求并把數(shù)據(jù)緩存起來,這樣獨(dú)占設(shè)備改造成了共享設(shè)備,從而提高了設(shè)備的利用率和系統(tǒng)
? 利用率。

?? /*
?? OpenPrinter
?? Declare Function OpenPrinter Lib "winspool.drv" Alias "OpenPrinterA"(ByVal pPrinterName As String,phPrinter As Long,
?? pDefault As PRINTER_DEFAULTS)As Long

?? 說明:
?? 打開指定的打印機(jī),并獲取打印機(jī)的句柄。
?? 返回值:
?? Long,非零表示成功,零表示失敗。會設(shè)置GetLastError
?? 參數(shù)表:
?? pPrinterName? String,要打開的打印機(jī)的名字
?? phPrinter???? Long,用于裝載打印機(jī)的句柄。
?? pDefault????? PRINTER_DEFAULT,這個結(jié)構(gòu)保存要載入的打印機(jī)信息。
?? */
?? /*
?? 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

?? 說明:
?? 枚舉打印隊(duì)列中的作業(yè)
?? 返回值:
?? Long,非零表示成功,零表示失敗。 可以通過GetLastError獲取錯誤信息。
?? hPrinter:? Long,一個已打開的打印機(jī)對象的句柄(用OpenPrinter獲得)
?? FirstJob:? Long,作業(yè)列表中要枚舉的第一個作業(yè)的索引(注意編號從0開始)
?? NoJobs???? Long,要枚舉的作業(yè)數(shù)量。
?? Level????? Long,1或2
?? pJob?????? Byte,包含JOB_INFO_1或JOB_INFO_2結(jié)構(gòu)的緩沖區(qū)
?? cbBuf????? Long,pJob緩沖區(qū)中的字符數(shù)量。
?? pcbNeeded? Long,指向一個LONG型變量的指針,該變量用于保存請求的緩沖區(qū)長度
????????????? 或者實(shí)際讀入的字節(jié)數(shù)量。
?? pcReturned Long,載入緩沖區(qū)的結(jié)構(gòu)數(shù)量(用于那些能返回多個結(jié)構(gòu)的函數(shù))。
?? */
?? /*
?? GetLastError
?? Declare Function GetLastError lib "kernel32"Alias "GetLastError"As Long
?? 說明:
?? 針對之前調(diào)用的api函數(shù),用這個函數(shù)取得擴(kuò)展錯誤信息
?? 返回值:Long,由api函數(shù)決定.請參考api32.txt文件,其中列出了一系列錯誤常數(shù);都以ERROR_前
?? 綴起頭.常用的錯誤代碼見下表:
?? ERROR_INVALID_HANDLE:無效的句柄作為一個參數(shù)傳遞。
?? ERROR_CALL_NOT_IMPLEMENTED? 在win95下調(diào)用專為win nt設(shè)計(jì)的win32 api函數(shù)
?? ERROR_INVALID_PARAMETER?? 函數(shù)中有個參數(shù)不正確。
?? */
?? /*
?? 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

?? 說明:
?? 枚舉打印隊(duì)列中的作業(yè)
?? 返回值:
?? Long,非零表示成功,零表示失敗。可以通過GetLastError獲取錯誤信息
?? 參數(shù)表:
?? hPrinter???????? Long,一個已打開的打印機(jī)對象的句柄(用OpenPrinter獲得)
?? FirstJob???????? Long,作業(yè)列表中要枚舉的第一個作業(yè)的索引(注意編號從0開始)
?? NoJobs?????????? Long,要枚舉的作業(yè)數(shù)量。
?? Level??????????? Long,1或2
?? pJob???????????? Byte,包含JOB_INFO_1或JOB_INFO_2結(jié)構(gòu)的緩沖區(qū)。
?? cbBuf??????????? Long,pJob緩沖區(qū)中的字符數(shù)量。
?? pcbNeeded??????? Long,指向一個Long型變量的指針,該變量用于保存請求的緩沖區(qū)長度,或者實(shí)際讀入的字節(jié)數(shù)。
?? pcbReturned????? Long,載入緩沖區(qū)的結(jié)構(gòu)數(shù)量。
?? */

?? 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));
???? }
??? }
?? }
?? /*
?? 這個例子啟發(fā)我們,應(yīng)用打印枚舉API函數(shù)可以對打印機(jī)進(jìn)行有效的監(jiān)控。
?? */

轉(zhuǎn)載于:https://www.cnblogs.com/scud001/archive/2010/05/12/1734027.html

總結(jié)

以上是生活随笔為你收集整理的2.1.2监测当前打印机状态的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。