打印程序開發(fā)資料_第1頁
打印程序開發(fā)資料_第2頁
打印程序開發(fā)資料_第3頁
打印程序開發(fā)資料_第4頁
打印程序開發(fā)資料_第5頁
已閱讀5頁,還剩24頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、基于組件模型的虛擬打印系統(tǒng)的研究與實(shí)現(xiàn)虛擬打印是利用某種方式截獲操作系統(tǒng)的打印任務(wù),將打印任務(wù)轉(zhuǎn)換為圖像文件并保存在指定目錄的系統(tǒng)。通過虛擬打印系統(tǒng),用戶可以將任意可打印的文檔轉(zhuǎn)換為統(tǒng)一的圖像文件,由一種應(yīng)用程序進(jìn)行瀏覽。因此在Web環(huán)境、多客戶端情況下,客戶端不需要為瀏覽多種應(yīng)用程序的文件而安裝多種應(yīng)用程序,便于實(shí)現(xiàn)瘦客戶端和降低系統(tǒng)的軟件成本。本文通過研究比較現(xiàn)有的虛擬打印系統(tǒng),提出建立基于組件模型的虛擬打印系統(tǒng),主要介紹的技術(shù)包括:虛擬打印機(jī)的實(shí)現(xiàn)、虛擬打印機(jī)的安裝卸載、系統(tǒng)二次開發(fā)接口等。1 Windows打印系統(tǒng)結(jié)構(gòu)虛擬打印基于Windows打印體系,是對Windows打印系統(tǒng)的一種

2、應(yīng)用及拓展。微軟的Windows NT系列打印體系結(jié)構(gòu)由打印假脫機(jī)和一套打印驅(qū)動(dòng)程序組成。應(yīng)用程序?qū)in32 GDI函數(shù)的調(diào)用傳送到GDI圖形引擎,GDI圖形引擎可以將繪制指令假脫到一個(gè)EMF文件中,或者與打印驅(qū)動(dòng)程序連接,向假脫機(jī)繪制一個(gè)可打印的圖像。假脫機(jī)組件解釋EMF文件,他們可以在數(shù)據(jù)流中插入頁面布局信息以及作業(yè)控制指令。然后假脫機(jī)將數(shù)據(jù)流發(fā)送給具有目標(biāo)打印機(jī)IO端口的串行、并行或網(wǎng)絡(luò)端口的驅(qū)動(dòng)程序。其體系結(jié)構(gòu)如圖1所示。2 虛擬打印系統(tǒng)的研究按照獲取打印任務(wù)方式的不同,可以將虛擬打印系統(tǒng)分為3種類型:重寫Print Processor,在假托模塊中實(shí)現(xiàn)轉(zhuǎn)換,例如Mabuse.De的

3、VPrinter;采用回調(diào)機(jī)制在打印任務(wù)發(fā)送到Spoolez之前獲取打印數(shù)據(jù)流,例如NortheastData公司的Image Printer Driver;通過監(jiān)視Port Monitor獲取打印任務(wù)數(shù)據(jù),例如Adobe公司的Adobe AcrobatWriter。目前絕大部分虛擬打印系統(tǒng)都是獨(dú)立的系統(tǒng),使用各自的文件格式來保存打印結(jié)果,很少以組件的方式提供二次開發(fā)接口,使得上述虛擬打印系統(tǒng)很難與其他應(yīng)用系統(tǒng)進(jìn)行集成。本文研發(fā)的基于組件模型的虛擬打印系統(tǒng),采用重寫Print Processor方式實(shí)現(xiàn)打印任務(wù)的獲取。該系統(tǒng)提供了豐富的二次開發(fā)接口,可以按照應(yīng)用系統(tǒng)集成商的要求提供文檔轉(zhuǎn)換功能

4、,最大限度地降低了應(yīng)用系統(tǒng)的成本。3 虛擬打印系統(tǒng)的實(shí)現(xiàn)基于組件模型的虛擬打印系統(tǒng)主要包括2部分:打印機(jī)驅(qū)動(dòng)程序模塊和二次開發(fā)接口模塊。其體系結(jié)構(gòu)如圖2所示:3.1 獲取打印任務(wù)打印任務(wù)的截取,是整個(gè)虛擬打印系統(tǒng)的關(guān)鍵部分。從圖1中可以看出,Print Processor負(fù)責(zé)將打印任務(wù)處理后發(fā)送到Port Monitor,Print Processor是一個(gè)可替換的DLL,安裝DDK中的約定,實(shí)現(xiàn)以下6個(gè)函數(shù),就可以自定義一個(gè)Print Processor。(1)EnumPrintProcessorDatatypes,該函數(shù)主要處理并返回打印處理器所能處理的數(shù)據(jù)類型;(2)ControlPri

5、ntProcessor,該函數(shù)主要提供方法供用戶控制打印處理器,如停止、刪除、重新開始打印任務(wù)等;(3)GetPrintProcessorCapabilities,該函數(shù)主要供Windows系統(tǒng)獲取針對某種輸入數(shù)據(jù)的處理能力;(4)OpenPrintProcessor,返回該打印處理器的句柄給系統(tǒng);(5)PrintDocumentOnPrintProcessor,處理打印任務(wù),將處理后的數(shù)據(jù)發(fā)送到Port Monitor或者轉(zhuǎn)換為圖像文件等;(6)ClosePrintProcessor,關(guān)閉打印處理器。圖3詳細(xì)說明在PrintDocumentOnPrintProcessor中如何將打印任務(wù)轉(zhuǎn)換

6、為圖像文件的過程。3.2 生成指定格式、大小的圖像虛擬打印系統(tǒng)獲取的打印頁面原始數(shù)據(jù)是EMF矢量圖形文件。如果轉(zhuǎn)換前的文檔中沒有大量的圖片信息,那么轉(zhuǎn)換后的EMF文件是比較小的,一般1頁Word轉(zhuǎn)換后在2050 k大小。因此本系統(tǒng)提供了配置接口供用戶選擇最終保存的圖像格式,目前支持JPG,GIF,PNG等常用的圖像格式??梢园凑杖缦路绞叫薷膱D像的格式和大?。篒mageInfoImageWidth=1024ImageHeight=768ImageType=JPG以上信息設(shè)定后,轉(zhuǎn)換生成的圖片為JPG格式文件,圖片寬為1 024 pixel,高為768 pixel。3.3 封裝組件,提供二次開發(fā)接

7、口二次開發(fā)接口是虛擬打印系統(tǒng)提供給第三方應(yīng)用系統(tǒng)調(diào)用或設(shè)置的方法。良好豐富的二次開發(fā)接口,使得本系統(tǒng)可以快速便捷的與第三方應(yīng)用系統(tǒng)進(jìn)行集成,大大提高系統(tǒng)的應(yīng)用范圍。按照組件模型的思想,本系統(tǒng)中將二次開發(fā)接口封裝成Activex組件,使得用戶可以通過簡單的JavaScript調(diào)用接口方法。3.3.1 安裝、卸載打印機(jī)接口一般采用由最終用戶通過在控制面板中選擇添加打印機(jī)的方式來安裝打印機(jī)。這種方法對最終用戶要求比較高,不適合大規(guī)模的應(yīng)用。因此,封裝了一個(gè)Acitvex實(shí)現(xiàn)打印機(jī)的安裝和卸載,使得第三方應(yīng)用系統(tǒng)可以非常方便地安裝、卸載虛擬打印機(jī)。該Activex提供以下2個(gè)方法:(1)Install

8、VirtualPrint,實(shí)現(xiàn)安裝打印機(jī),關(guān)鍵部分解釋如下:(2)UnInstallVirtualPrint,實(shí)現(xiàn)卸載打印機(jī),關(guān)鍵部分解釋如下:3.3.2 打印機(jī)信息設(shè)置接口為了方便第三方系統(tǒng)集成,打印機(jī)基本信息存儲在系統(tǒng)INI文件中。集成用戶按照標(biāo)準(zhǔn)可以非常方便地修改打印機(jī)的相關(guān)信息,例如:轉(zhuǎn)換后圖像文件的保存路徑,當(dāng)前文件的前綴等。以上信息設(shè)定后,轉(zhuǎn)換生成的圖像文件就保存在c:123目錄下,文件名稱按以下規(guī)則形成“123_頁碼”。第三方系統(tǒng)也可以通過編程的方式動(dòng)態(tài)修改配置文件。3.3.3 圖像生成事件通知接口在第三方系統(tǒng)集成時(shí),希望實(shí)時(shí)知道什么時(shí)候轉(zhuǎn)換完成,什么時(shí)候轉(zhuǎn)換了某一頁。因此本系統(tǒng)

9、采用Windows廣播消息的方式來通知集成系統(tǒng)。廣播消息是Windows系統(tǒng)中,不同進(jìn)程之間通信最實(shí)時(shí)、最快捷的方式。廣播消息分為2個(gè)步驟:利用RegisterWindowMessage函數(shù)向Windows系統(tǒng)注冊消息句柄;利用PostMessage函數(shù)寄送消息,需要注意的是第一個(gè)參數(shù)必須為HWND_BROAD-CAST。集成系統(tǒng)可以在消息循環(huán)中獲取廣播的消息,以VC開發(fā)工具為例,如下過程就可以獲取廣播的消息:利用RegisterWindowMessage注冊同一消息句柄;利用ON_REGISTERED_MESSAGE宏,映射消息句柄到消息處理函數(shù)。4 結(jié) 語在研究現(xiàn)有虛擬打印系統(tǒng)的基礎(chǔ)上,指

10、出這些系統(tǒng)存在的問題,研究并實(shí)現(xiàn)基于組件模型的虛擬打印系統(tǒng)。該系統(tǒng)具有轉(zhuǎn)換快速、二次開發(fā)接口豐富等特點(diǎn),并且已經(jīng)應(yīng)用在第三方系統(tǒng)中,如:iWebOffice網(wǎng)絡(luò)文檔、iSignatureGDF電子簽章系統(tǒng)。定制打印假脫機(jī)組件本章解釋怎樣定制打印機(jī)假脫機(jī)組件,并提供了以下這些主題: 編寫打印處理器 編寫打印監(jiān)示器 編寫網(wǎng)絡(luò)打印提供者 8.1編寫打印處理器本部分提供下面的主題: 8.1.1對打印處理器的介紹 8.1.2打印處理器示例 8.1.3由打印處理器定義的函數(shù) 8.1.4處理一個(gè)打印作業(yè) 8.1.5安裝一個(gè)打印處理器 8.1.1對打印處理器的介紹打印處理器是用戶模式的一些DLL,主要負(fù)責(zé)轉(zhuǎn)換

11、打印作業(yè)的假脫數(shù)據(jù)到打印機(jī)監(jiān)示器的格式。也負(fù)責(zé)處理應(yīng)用程序?qū)和?、重新開始及撤消打印作業(yè)等的請求。 打印作業(yè)的假脫數(shù)據(jù)包含在一個(gè)假脫文件中。打印處理器讀取這些文件,在數(shù)據(jù)流上執(zhí)行轉(zhuǎn)換操作,并將轉(zhuǎn)換的數(shù)據(jù)寫到假脫機(jī)。假脫機(jī)然后發(fā)送數(shù)據(jù)流到合適的打印機(jī)監(jiān)示器。 微軟Windows 2000包括列在下表中的打印處理器。 打印處理器 輸入數(shù)據(jù)類型 輸出數(shù)據(jù)類型 winprint.dll EMF RAW TEXT RAW stmpsprt.dll PSCRIPT1 RAW 關(guān)于數(shù)據(jù)類型的信息,參考下面的主題: EMF數(shù)據(jù)類型 RAW數(shù)據(jù)類型 TEXT數(shù)據(jù)類型 PSCRIPT1數(shù)據(jù)類型 可以創(chuàng)建一個(gè)定制的

12、打印處理器以支持一個(gè)Windows 2000不支持的數(shù)據(jù)類型。也可以提供一個(gè)定制的打印處理器以支持一種或更多種的被支持的數(shù)據(jù)類型,這樣,就允許修改由打印處理器所提供的能力。 打印處理器與在打印機(jī)驅(qū)動(dòng)程序安裝時(shí)與打印機(jī)的驅(qū)動(dòng)程序相關(guān),因此,可以并存多個(gè)打印處理器支持同一種數(shù)據(jù)類型。更多的信息,參考安裝打印機(jī)處理器部分的內(nèi)容。 EMF數(shù)據(jù)類型 增強(qiáng)型元文件(EMF:Enhanced Metafile)數(shù)據(jù)類型由調(diào)用GDI函數(shù)的指令構(gòu)成。打印處理器必須調(diào)用GDI函數(shù)以繪制可打印的圖像。GDI函數(shù)對打印驅(qū)動(dòng)程序的打印機(jī)圖形DLL做調(diào)用,它繪制圖像并將它作為RAW數(shù)據(jù)向假脫機(jī)發(fā)送(通過調(diào)用EngWrit

13、ePrinter)。 Windows NT®/Windows 2000客戶端發(fā)送EMF數(shù)據(jù)到Windows NT/Windows 2000打印服務(wù)器。EMF數(shù)據(jù)是設(shè)備獨(dú)立并可以比RAW數(shù)據(jù)類型更快速地發(fā)送到服務(wù)器。當(dāng)一個(gè)應(yīng)用程序請求是從本地到服務(wù)器,打印作業(yè)也就被假脫處理為EMF數(shù)據(jù),這樣就允許在作業(yè)被后臺假脫機(jī)繪制時(shí)能夠?qū)?yīng)用程序的快速返回。 更多的關(guān)于EMF數(shù)據(jù)類型的信息,參考Windows 2000專業(yè)版資源包(Windows 2000 Professional Resource Kit)或Windows 2000服務(wù)器版的資源包(Windows 2000 Server Res

14、ource Kit)。更多的關(guān)于增強(qiáng)型元文件的信息,參考平臺SDK文檔。 RAW數(shù)據(jù)類型 RAW數(shù)據(jù)可以不用進(jìn)一步處理就被發(fā)送到打印機(jī)監(jiān)示器。打印機(jī)處理器只發(fā)送這一數(shù)據(jù)到假脫機(jī)(通過調(diào)用WritePrinter,在平臺的SDK文檔中描述),有時(shí)插入表格。一個(gè)RAW數(shù)據(jù)文件的實(shí)例是一個(gè)由PCL命令組成的。無論客戶端或服務(wù)器端那一方不支持Windows NT/Windows 2000 EMF或者服務(wù)器管理員禁止了EMF支持,打印作業(yè)以RAW數(shù)據(jù)格式從客戶端發(fā)送到服務(wù)器端。在這些情況下,客戶端的圖像繪制在打印作業(yè)發(fā)送到服務(wù)器端之前進(jìn)行。 (Postscript命令可以被當(dāng)作RAW數(shù)據(jù),如果目標(biāo)打印機(jī)

15、支持Postscript。另一方面,stmpsprt.dll打印處理器將Postscript的輸入向非Postscript的打印機(jī)進(jìn)行解釋,在這種情況下,Postscript不是RAW數(shù)據(jù)。) 更多的關(guān)于RAW數(shù)據(jù)類型的信息,參考Windows NT工作站資源指南或者Windows NT資源指南部分的內(nèi)容。 TEXT數(shù)據(jù)類型 單純由ANSI文本構(gòu)成的。打印機(jī)處理器調(diào)用GDI以用打印機(jī)設(shè)備容錯(cuò)字體繪制字母,并發(fā)送RAW格式的結(jié)果輸出到假脫機(jī)(通過調(diào)用Writeprinter,在平臺的SDK文檔中描述)。處理器等同于用寫字板打開輸入文件并然后打印文件(該格式用于不能打印文本字符的打印機(jī))。 更多的

16、關(guān)于TEXT數(shù)據(jù)類型的信息,參考Windows NT工作站資源指南或者Windows NT 服務(wù)器資源指南部分的內(nèi)容。 PSCRIPT1數(shù)據(jù)類型 PSCRIPT1數(shù)據(jù)的目的是要在一個(gè)非Postscript打印機(jī)上打印的Postscript數(shù)據(jù)。打印處理器解釋Postscript命令并且向輸出文件寫RAW格式的結(jié)果數(shù)據(jù)。 更多的關(guān)于PSCRIPT1數(shù)據(jù)類型的信息,參考參考Windows NT工作站資源指南或者Windows NT 服務(wù)器資源指南部分的內(nèi)容。 8.1.2打印處理器示例genprint.dll的源代碼,一個(gè)接受EMF數(shù)據(jù)、RAW數(shù)據(jù)及TEXT數(shù)據(jù)作為輸入的打印處理器的實(shí)例,包含于本D

17、DK中。其代碼位于DDK實(shí)例的目錄樹中的genprint的子目錄中。 8.1.3由打印處理器定義的函數(shù)打印機(jī)處理器必須導(dǎo)出下表列出的函數(shù): 函數(shù)名稱 描述 ClosePrintProcessor 關(guān)閉打印處理器 ControlPrintProcessor 提供對打印文檔的控制 EnumPrintProcessorDatatypes 枚舉打印機(jī)處理器支持的數(shù)據(jù)類型 GetPrintProcessorCapabilities 為專用的輸入數(shù)據(jù)類型返回打印處理器的能力 OpenPrintProcessor 為打印打開打印處理器 PrintDocumentOnPrintProcessor 在一個(gè)打印處

18、理器上打印文檔 8.1.4處理一個(gè)打印作業(yè)當(dāng)一個(gè)假脫機(jī)準(zhǔn)備發(fā)送一個(gè)打印作業(yè)到打印處理器時(shí),它調(diào)用打印處理器的OpenPrintProcessor函數(shù)。這一函數(shù)執(zhí)行初始化活動(dòng)并返回一個(gè)句柄。 假脫機(jī)可以調(diào)用PrintDocumentOnPrintProcessor,它是打印處理器的一個(gè)函數(shù),可以從輸入格式到輸出格式轉(zhuǎn)換數(shù)據(jù)流,并返回被轉(zhuǎn)換的流到假脫機(jī)。 如果輸入的格式是Windows NT/Windows 2000的EMF,則PrintDocumentOnPrintProcessor函數(shù)將通過使用GDI的打印處理器函數(shù)來控制EMF記錄的回放。這些函數(shù)提供了一個(gè)打印處理器與打印機(jī)驅(qū)動(dòng)程序之間的接口

19、。該接口允許打印處理器控制打印機(jī)頁面的物理布局及實(shí)現(xiàn)諸如在一個(gè)物理頁面上打印多個(gè)文檔頁面(“N-up”打印)、反向打印、每頁打印多個(gè)拷貝等等。 一個(gè)打印處理器的輸出數(shù)據(jù)流必須返回到假脫機(jī)。通常,如果數(shù)據(jù)轉(zhuǎn)換需要與打印機(jī)驅(qū)動(dòng)程序的打印機(jī)圖形DLL(對EMF格式作為輸入數(shù)據(jù)時(shí))之間交互作用,則圖形DLL通過調(diào)用EngWritePrinter。另外一方面,如果轉(zhuǎn)換不調(diào)用打印機(jī)圖形DLL(當(dāng)輸入數(shù)據(jù)是RAW類型時(shí)),則打印處理器調(diào)用WritePrinter(在平臺的SDK文檔中描述)。 PrintDocumentOnPrintProcessor函數(shù)可以從假脫機(jī)到打印處理器的ControlPrintPr

20、ocessor函數(shù)同步調(diào)用中斷。這一函數(shù)實(shí)現(xiàn)應(yīng)用程序的暫停、恢復(fù)及撤消一個(gè)打印作業(yè)等能力。 在PrintDocumentOnPrintProcessor結(jié)束轉(zhuǎn)換數(shù)據(jù)流并返回后,假脫機(jī)調(diào)用打印機(jī)處理器的ClosePrintProcessor函數(shù)。 8.1.4.1為打印處理器使用GDI函數(shù)一套用戶模式的GDI函數(shù)被gdi32.dll導(dǎo)出,對被打印處理器用于處理Windows NT/Windows 2000的EMF作為輸入格式。下面的表列出了可以提供的函數(shù): 函數(shù)名稱 描述 GdiDeleteSpoolFileHandle 釋放一個(gè)假脫機(jī)文件句柄 GdiEndDocEMF 對一個(gè)打印文檔完成EMF回

21、放操作 GdiEndPageEMF 為一個(gè)物理頁面完成EMF回放操作,并從打印機(jī)跳頁 GdiGetDC 返回一個(gè)打印機(jī)設(shè)備設(shè)備環(huán)境的句柄 GdiGetDevmodeForPage 返回一個(gè)文檔頁面的DEVMODE結(jié)構(gòu) GdiGetPageCount 返回文檔頁面的數(shù)字 GdiGetPageHandle 返回文檔頁面的句柄 GdiGetSpoolFileHandle 返回一個(gè)假脫文件的句柄,它對其他的GDI函數(shù)是作為一個(gè)必需的輸入 GdiPlaypageEMF 播放與文檔頁面相關(guān)的EMF記錄 GdiResetDCEMF 重置打印機(jī)的設(shè)備設(shè)備環(huán)境 GdiStartDocEMF 對打印作業(yè)執(zhí)行初始化

22、操作 GdiStartPageEMF 對物理頁面執(zhí)行初始化操作 一個(gè)EMF打印處理器的PrintDocumentOnPrintProcessor應(yīng)當(dāng)調(diào)用GdiGetSpoolFileHandle以獲得假脫文件的句柄及調(diào)用GdiGetDC以獲得打印機(jī)設(shè)備設(shè)備環(huán)境句柄。然后它可以執(zhí)行下面的操作: 對每一個(gè)打印作業(yè)文檔,GdiStartDocEMF必須在任何EMF記錄被運(yùn)行之前調(diào)用并且GdiEndDocEMFnt必須在EMF記錄運(yùn)行完之后被調(diào)用。 對每一個(gè)要被打印的物理頁面來說,GdiStartPageEMF必須在任何文檔頁面在頁面上被繪制之前被調(diào)用,GdiEndPageEMF必須在最后一個(gè)文檔頁面

23、被在物理頁面上繪制完之后被調(diào)用 對每一個(gè)將要繪制在物理頁上的文檔頁面來說,GdiGetDevmodeForPage是否必須被調(diào)用取決于DEVMODE結(jié)構(gòu)的內(nèi)容是否在最后一個(gè)文檔頁被繪制之后改變。如果DEVMODE已經(jīng)改變,一個(gè)新的物理頁而必須開始(通過調(diào)用GdiEndPageEMF及GdiStartPageEMF),打印機(jī)的設(shè)備設(shè)備環(huán)境必須通過調(diào)用GdiResetDCEMF來改變。一個(gè)文檔頁面必須被繪制在物理頁面上,通過首先調(diào)用GdiGetPageHandle以獲得文檔頁面句柄,并然后調(diào)用GdiPlayPageEMF以繪制頁面。 在打印作業(yè)已經(jīng)完成繪制后,打印處理器必須調(diào)用GdiDeleteS

24、poolFileHandle。 如果一個(gè)打印處理器在它開始打印頁面之前需要知道總的打印頁數(shù)(如反向打印時(shí)),它可以調(diào)用GdiGetPageCount,但是這一函數(shù)將一直到假脫過程完成并且在假脫時(shí)禁止了打印能力時(shí)才返回。 如果一個(gè)打印處理器用這些GDI函數(shù),它的EnumPrintProcessorDataTypes函數(shù)必須返回“NT EMF”作為一個(gè)支持的數(shù)據(jù)類型,它表示一般的Windows 2000 EMF格式。打印處理器不能修改EMF記錄。 8.1.5安裝一個(gè)打印處理器為安裝一個(gè)打印處理器,一個(gè)安裝應(yīng)用程序必須調(diào)用假脫機(jī)的AddPrintProcessor函數(shù),它在平臺的SDK文檔中描述。

25、為關(guān)聯(lián)一個(gè)打印機(jī)處理器與一個(gè)打印機(jī)驅(qū)動(dòng)程序,它的文件名稱必須通過使用PintProcessor條目而被列在.inf文件中。這一條目必須為每一個(gè)將要被與打印處理器關(guān)聯(lián)的打印機(jī)驅(qū)動(dòng)程序所包含。更多的信息,可以參考第10章的打印機(jī)INF文件部分的內(nèi)容。 當(dāng)一個(gè)安裝應(yīng)用程序調(diào)用假脫機(jī)的AddPrinter函數(shù),指定一個(gè)PRINTER_INFO_2結(jié)構(gòu)作為一個(gè)輸入?yún)?shù),它指定打印機(jī)處理器名稱(從.inf文件獲得)作為一個(gè)結(jié)構(gòu)成員。(AddPrinter函數(shù)及PRINTER_INFO_2結(jié)構(gòu)在平臺的SDK文檔中描述)。 8.2編寫打印監(jiān)示器打印監(jiān)示器負(fù)責(zé)傳送打印機(jī)數(shù)據(jù)流從打印假脫機(jī)到一個(gè)合適的端口驅(qū)動(dòng)程序

26、。兩種類型的打印機(jī)監(jiān)示器被定義,即語言監(jiān)示器(language monitors)及端口監(jiān)示器(port monitors)。這一章將描述兩種監(jiān)示器,并提供設(shè)計(jì)與實(shí)現(xiàn)的指南。 提供以下內(nèi)容的主題: 8.2.1語言監(jiān)示器 8.2.2端口監(jiān)示器 8.2.3語言和端口監(jiān)示器交互 8.2.4由打印監(jiān)示器定義的函數(shù) 8.2.5初始化一個(gè)打印監(jiān)示器 8.2.6打開及關(guān)閉一個(gè)端口 8.2.7打印一個(gè)打印作業(yè) 8.2.8管理端口 8.2.9為在集群打印服務(wù)器中使用轉(zhuǎn)換打印監(jiān)示器 8.2.10安裝打印監(jiān)示器 8.2.1語言監(jiān)示器語言監(jiān)示器是一些用戶模式的DLL,主要用于兩個(gè)目的: 它們在打印機(jī)假脫機(jī)與雙向打印機(jī)

27、之間提供了一個(gè)全雙工的通信通道,從而具有了提供軟件可存取的狀態(tài)信息的能力。 增加打印機(jī)控制信息到數(shù)據(jù)流,如由打印機(jī)作業(yè)語言定義的命令等。 微軟提供了一個(gè)語言監(jiān)示器pjlmon.dll,它支持打印作業(yè)語言(PJL:Printer Job Language),并為PJL打印機(jī)提供雙向通訊。這一監(jiān)示器被作為語言監(jiān)示器示例包含在這一DDK中。 對單向或雙向打印機(jī)來說,定制的語言監(jiān)示器可編寫用于支持其他作業(yè)控制語言。 語言監(jiān)示器是可選的,并且只與特殊的包含在打印機(jī)的.inf中的打印機(jī)類型相關(guān),如在安裝打印監(jiān)示器部分所描述的。 如果一個(gè)語言監(jiān)示器與打印機(jī)關(guān)聯(lián),語言監(jiān)示器從打印機(jī)處理器收到打印機(jī)的數(shù)據(jù)流,修

28、改它并將之傳遞到打印機(jī)的端口端示器。更多的信息,可參考語言監(jiān)示器及端口監(jiān)視器交互部分的內(nèi)容。 8.2.1.1語言監(jiān)示器示例pjlmon.dll的源代碼,支持雙向PJL語言的語言監(jiān)示器就包括在這一DDK中。其代碼位于DDK的實(shí)例目錄樹中的pjlmon子目錄中。 8.2.2端口監(jiān)示器端口監(jiān)示器由用戶模式的一些DLL組成。它們負(fù)責(zé)在用戶模式的打印假脫機(jī)及訪問I/O硬件端口的內(nèi)核模式的端口驅(qū)動(dòng)程序之間提供通訊。一個(gè)端口監(jiān)示器通常使用CreateFile,WriteFile,ReadFile及DeviceIOControl函數(shù),在平臺的SDK文檔中描述的,以與內(nèi)核模式的端口驅(qū)動(dòng)程序通訊。端口監(jiān)示器也負(fù)責(zé)

29、管理及配置一個(gè)服務(wù)器的打印機(jī)端口,如在管理端口部分所描述的。 Windows NT/Windows 2000用戶的“打印機(jī)”視圖實(shí)際上是一個(gè)打印隊(duì)列,是一個(gè)或多個(gè)物理打印機(jī)設(shè)備都可以連接到的隊(duì)列。一個(gè)端口是一個(gè)在打印隊(duì)列及一個(gè)單一打印機(jī)設(shè)備之間的物理連接。每一個(gè)端口端示器支持一個(gè)或多個(gè)的一種或多種端口類型的實(shí)例。例如,localmon.dll這一示例的端口監(jiān)示器可以支持所有的服務(wù)器的本地COM及LTP端口。(打印機(jī)文件夾)通過調(diào)用平臺SDK文檔中描述的AddPrinter函數(shù)來分配端口到端口監(jiān)視器)。 對表示多個(gè)打印機(jī)設(shè)備(通過多個(gè)端口)的打印機(jī)隊(duì)列來說,假脫機(jī)發(fā)送每個(gè)打印作業(yè)到第一個(gè)可用的端

30、口。如果端口監(jiān)示器指明一個(gè)可用端口忙或者遇到錯(cuò)誤,假脫機(jī)將重新提交作業(yè)到隊(duì)列,指定另外一個(gè)端口監(jiān)示器支持的可用端口。 除了localmon.dll,Windows 2000提供幾個(gè)附加的端口監(jiān)示器。Windows NT服務(wù)器資源開發(fā)包中對每一個(gè)這樣的端口監(jiān)示器都做了描述。 可以寫定制的端口監(jiān)示器以支持附加類型的硬件I/O端口。 對Windows 2000來說,每一個(gè)端口監(jiān)示器被分為兩個(gè)DLL。 端口監(jiān)示器UI DLL 端口監(jiān)示器的用戶接口DLL包含用戶接口的功能并在打印客戶系統(tǒng)上執(zhí)行。 這一DLL必須駐留在客戶系統(tǒng)的System32子目錄中。 端口監(jiān)示服務(wù)器DLL 一個(gè)端口監(jiān)示器的服務(wù)器DLL

31、包含端口通訊功能及在打印服務(wù)器上執(zhí)行。它必須顯示一個(gè)用戶的接口。 UI DLL通過調(diào)用假脫機(jī)的Xcvdata函數(shù)與服務(wù)器的DLL通訊,在該DDK中包含一個(gè)端口監(jiān)示器實(shí)例。 8.2.2.1端口監(jiān)示器實(shí)例localmonn.dll的源代碼,即支持本地LPT及COM端口的端口監(jiān)示器也在DDK中包含著。其代碼位于DDK實(shí)例目錄樹的localmon及l(fā)ocalui子目錄中。 8.2.3語言和端口監(jiān)示器交互下面的圖顯示了打印機(jī)數(shù)據(jù)從打印處理器到打印機(jī)的路徑圖。其中圖(a)包含一個(gè)與它相關(guān)聯(lián)的語言監(jiān)示器,圖(b)不包含相關(guān)聯(lián)的語言監(jiān)示器。 插入圖(a)(b)? 如果一個(gè)語言監(jiān)示器在打印機(jī)的安裝過程中與打印機(jī)

32、關(guān)聯(lián),語言監(jiān)示器從假脫機(jī)打印處理器中收到打印機(jī)的數(shù)據(jù)流。語言監(jiān)示器修改數(shù)據(jù)流并將它傳遞到打印機(jī)的監(jiān)示器。 許多由打印機(jī)定義的監(jiān)示器對語言監(jiān)示器及端口監(jiān)示器是相同的。通常,如果一個(gè)語言監(jiān)示器在數(shù)據(jù)流通道中,假脫機(jī)將調(diào)用端口監(jiān)示器的實(shí)現(xiàn)函數(shù)而語言監(jiān)示器將調(diào)用端口監(jiān)示器的同樣的實(shí)現(xiàn)函數(shù)。例如,在PJL語言監(jiān)示器(pjlmon.dll)中的WritePort函數(shù)增加PJL命令到數(shù)據(jù)流然后調(diào)用端口監(jiān)示器的WritePort并將該流發(fā)送給端口驅(qū)動(dòng)程序。 如果沒有安裝語言監(jiān)示器,假脫機(jī)調(diào)用端口監(jiān)示器的函數(shù)實(shí)現(xiàn)。 由于語言監(jiān)示器及端口監(jiān)示器是打印體系中分散的組件,定制的及微軟提供的監(jiān)示器可以被一起應(yīng)用。這樣,

33、可以提供一個(gè)與微軟提供的端口監(jiān)示器一起工作的定制的語言監(jiān)示器,反之亦然。 也可以提供一個(gè)單一的語言和端口監(jiān)示器構(gòu)成(combined language and port monitor)的組合式打印監(jiān)示器。 8.2.3.1組合式語言和端口監(jiān)示器專用的打印機(jī)硬件可以被一個(gè)單一的定制打印監(jiān)示器支持,它實(shí)際作為一個(gè)組合式的語言和端口監(jiān)示器。如果這樣一個(gè)監(jiān)示器需要用戶的交互以獲得配置參數(shù),它必須被分成UI DLL及一個(gè)服務(wù)器的DLL,下面的模型是對端口監(jiān)示器的。而語言相關(guān)的功能則屬于服務(wù)器DLL。 一個(gè)組合的監(jiān)示器UI DLL必須定義端口監(jiān)示器客戶端DLL函數(shù)。它的服務(wù)器DLL必須定義端口監(jiān)示器服務(wù)器

34、DLL的函數(shù)及語言監(jiān)示器的函數(shù)。 8.2.4由打印監(jiān)示器定義的函數(shù)下面的部分列出了在打印監(jiān)示器中必須定義的函數(shù): 8.2.4.1語言監(jiān)示器函數(shù) 8.2.4.2端口監(jiān)示器客戶DLL函數(shù) 8.2.4.3端口監(jiān)示器服務(wù)器DLL函數(shù) 8.2.4.1語言監(jiān)示器函數(shù)下表列出了語言監(jiān)示器必須定義的函數(shù): 函數(shù)名稱 描述 DllEntryPoint DLL入口點(diǎn),通常稱為DLLMain,它在平臺的SDK文檔中描述 ClosePort 關(guān)閉一個(gè)端口,在沒有打印機(jī)與它相連時(shí) EndDocPort 在一個(gè)端口上執(zhí)行打印作業(yè)完成的任務(wù) GetPrinterDataFromPort (可選)輪詢存儲在注冊表中的端口值

35、InitializePrintMonitor2 初始化打印監(jiān)示器并返回一個(gè)實(shí)例句柄 OpenPortEx 為一個(gè)新連接的打印機(jī)打開一個(gè)端口 ReadPort 從一個(gè)打印機(jī)端口讀數(shù)據(jù) StartDocPort 執(zhí)行在一個(gè)端口上開始打印作業(yè)的操作 WritePort 向打印機(jī)端口寫數(shù)據(jù) 8.2.4.2端口監(jiān)示器客戶DLL函數(shù)下面的表格列出了一個(gè)端口監(jiān)示器UI DLL必須定義的函數(shù): 函數(shù)名稱 描述 DllEntryPoint DLL入口點(diǎn),通常稱為DLLMain,它在平臺的SDK文檔中描述 AddPortUI 創(chuàng)建一個(gè)端口并通過顯示一個(gè)通話框獲得配置信息 ConfigurePortUI 配置一個(gè)前

36、面增加的端口 DeletPortUI 刪除一個(gè)端口 InitializePrintMonitorUI 初始化端口監(jiān)示器的DLL 8.2.4.3端口監(jiān)示器服務(wù)器DLL函數(shù)下面的表中列出了端口監(jiān)示器服務(wù)器DLL必須定義的函數(shù): 函數(shù)名稱 描述 DllEntryPoint DLL入口點(diǎn),通常稱為DLLMain,它在平臺的SDK文檔中描述 ClosePort 關(guān)閉一個(gè)端口,在沒有打印機(jī)與它連接時(shí) EndDocPort 在端口上執(zhí)行打印作業(yè)完成的任務(wù) EnumPorts 枚舉打印機(jī)可用的服務(wù)器上的端口 GetPrinterDataFromPort (可選)發(fā)送一個(gè)I/O控制代碼到端口驅(qū)動(dòng)程序并返回結(jié)果

37、InitializePrintMonitor2 初始化打印監(jiān)示器并返回一個(gè)實(shí)例句柄 OpenPort 打開一個(gè)打印機(jī)端口 ReadPort 從一個(gè)打印機(jī)端口讀數(shù)據(jù) SetPortTimeOuts (可選)在一個(gè)打開的端口上設(shè)置超時(shí)值 StartDocPort 執(zhí)行在一個(gè)端口上要開始打印作業(yè)的任務(wù) WritePort 向打印機(jī)端口寫數(shù)據(jù) XcvClosePort 在端口管理完成之后關(guān)閉一個(gè)端口 XcvDataPort 處理端口管理任務(wù) XcvOpenPort 因?yàn)楣芾砟康拇蜷_一個(gè)端口 8.2.5初始化打印監(jiān)示器當(dāng)假脫機(jī)調(diào)用LoadLibrary以裝載一個(gè)打印監(jiān)示器DLL,系統(tǒng)立即調(diào)用DLL的Dl

38、lEntryPoint函數(shù)。有一個(gè)一般情況都比較好的方法是,對入口函數(shù)都調(diào)用DisableThreadLibraryCalls函數(shù)(在平臺的SDK文檔中有描述),這樣DLL就在線程被創(chuàng)建或刪除時(shí)就不會沒有通知到。 每一個(gè)DLL導(dǎo)出一個(gè)初始化函數(shù),它在假脫機(jī)調(diào)用LoadLibrary之后調(diào)用。語言監(jiān)示器DLL及端口監(jiān)示器服務(wù)器DLL導(dǎo)出一個(gè)InitializePrintMonitor2函數(shù)。端口監(jiān)示器UI DLL導(dǎo)出一個(gè)InitaializePrintMonitorUI函數(shù)。 這兩個(gè)初始化函數(shù)負(fù)責(zé)給打印監(jiān)示器定義的其余的函數(shù)返回指針,這樣假脫機(jī)可以調(diào)用他們。初始化函數(shù)可以執(zhí)行裝載時(shí)的初始化操作。

39、顯示器的InitalizePrintMonitor2函數(shù)返回一個(gè)監(jiān)示器的實(shí)例句柄。監(jiān)示器應(yīng)當(dāng)分配本地內(nèi)存以存儲特定實(shí)例的信息,并使用監(jiān)示器句柄作為一個(gè)分配內(nèi)存的標(biāo)識符。 第一次調(diào)用假脫機(jī)時(shí),它裝載所有的已經(jīng)被安裝的監(jiān)示器DLL。在調(diào)用了監(jiān)示器函數(shù)之后,假脫機(jī)調(diào)用每一個(gè)端口監(jiān)示器的EnumPorts函數(shù),它枚舉監(jiān)示器支持的端口。(一個(gè)監(jiān)示器支持一個(gè)端口,是看是否該端口已被加到監(jiān)示器的數(shù)據(jù)庫中,如在增加一個(gè)端口中所描述的。)每一個(gè)支持的端口這時(shí)才被打開,如在打開及關(guān)閉端口部分中所描述的。 8.2.6打開及關(guān)閉一個(gè)端口在增加一個(gè)端口之后,如在增加端口部分所描述的,假脫機(jī)就能通過調(diào)用合適的語言監(jiān)示器的

40、OpenPortEx函數(shù)打開它。 語言監(jiān)示器用OpenPortEx函數(shù)以創(chuàng)建并返回端口句柄。通常,語言監(jiān)示器調(diào)用它相關(guān)的端口監(jiān)示器的OpenPort函數(shù),并且語言監(jiān)示器只返回從端口監(jiān)示器的OpenPort函數(shù)獲得的句柄。 如果語言監(jiān)示器與一個(gè)端口不相關(guān),假脫機(jī)直接調(diào)用端口監(jiān)示器的OpenPort函數(shù)。 假脫機(jī)不允許在同一時(shí)間有多于一個(gè)的通道。這樣,當(dāng)它在一個(gè)特殊的監(jiān)示器中調(diào)用OpenPortEx(或OpenPort)之后,就不會在關(guān)閉它之前企圖打開同一個(gè)端口。 在一個(gè)端口被打開之后,假脫機(jī)能調(diào)用附加的函數(shù)以打印作業(yè),如在打印一個(gè)打印作業(yè)部分中所描述的,用端口的句柄作為一個(gè)輸入的參數(shù)。應(yīng)當(dāng)編寫一

41、個(gè)監(jiān)示器,在一個(gè)端口被打開之后,假脫機(jī)可以在關(guān)閉端口之前發(fā)送多個(gè)打印作業(yè)。 若一個(gè)作業(yè)必須通過一個(gè)不同的語言監(jiān)示器發(fā)送,如果沒有與端口相關(guān)的打印隊(duì)列或者當(dāng)系統(tǒng)關(guān)閉時(shí),則假脫機(jī)關(guān)閉一個(gè)端口。為關(guān)閉端口,假脫機(jī)調(diào)用語言監(jiān)示器的ClosePort函數(shù),該函數(shù)使端口被打開時(shí)創(chuàng)建的句柄無效。語言監(jiān)示器通常調(diào)用ClosePort函數(shù),該函數(shù)是由它相關(guān)的端口監(jiān)示器定義的。 8.2.7打印一個(gè)打印作業(yè)在一個(gè)端口被打開之后,如在打開及關(guān)閉端口部分所描述的,假脫機(jī)可以發(fā)送打印作業(yè)到端口。 每個(gè)打印作業(yè)通過假脫機(jī)調(diào)用語言或端口監(jiān)示器的StartDocPort或EndDocPort函數(shù)來被分隔開。假脫機(jī)在打印處理器調(diào)

42、用假脫機(jī)的StartDocPrinter及EndDocPrinter函數(shù)時(shí)調(diào)用這些函數(shù),這些函數(shù)都在平臺的SDK文檔中有描述。在StartDocPort及EndDocPort函數(shù)的范圍之間,可以出現(xiàn)對監(jiān)示器的WritePort,ReadPort,GetPrinterDataFromPort函數(shù)的不限次數(shù)的調(diào)用。 這些函數(shù)中的每一個(gè)都需要由OpenPortEx(或OpenPort)返回的端口句柄做為一個(gè)輸入?yún)?shù)來指定。通常,語言監(jiān)示器通過調(diào)用在它的相關(guān)的端口監(jiān)示器中的相同名字的函數(shù)來實(shí)現(xiàn)每一個(gè)函數(shù)。 當(dāng)假脫機(jī)調(diào)用一個(gè)語言監(jiān)示器的WritePort函數(shù)以發(fā)送數(shù)據(jù)流到一個(gè)端口,函數(shù)經(jīng)常增加一些特定語

43、言的信息(如PJL命令)到收到的數(shù)據(jù)流中,并且是在它被傳送到相關(guān)聯(lián)的端口的WritePort函數(shù)之前。 ReadPort函數(shù)用于獲得雙向打印機(jī)硬件的狀態(tài)信息,雙向打印機(jī)硬件的語言監(jiān)示器可以通過調(diào)用SetPort向假脫機(jī)發(fā)送,在平臺的SDK文檔中描述。假脫機(jī)不調(diào)用ReadPort函數(shù)。 如果打印機(jī)硬件是雙向的,它的語言監(jiān)示器或端口監(jiān)示器應(yīng)當(dāng)支持GetPrinterDataFromPort函數(shù)。語言監(jiān)示器的GetPrinterDataFromPort函數(shù)應(yīng)當(dāng)接受一個(gè)注冊表的值名稱作為輸入,并從那個(gè)名稱(一般是調(diào)用相關(guān)端口的WritePort及ReadPort函數(shù))獲得一個(gè)值并將值返回給調(diào)用者。一個(gè)

44、端口監(jiān)示器的GetPrinterDataFromPort 函數(shù)應(yīng)當(dāng)接受一個(gè)I/O控制的代碼作為輸入,調(diào)用DeviceIoControl(在平臺的SDK文檔中有描述)以傳遞控制代碼到端口的驅(qū)動(dòng)程序,并返回結(jié)果。 8.2.8管理端口端口管理活動(dòng)由增加端口、配置端口及刪除端口等對應(yīng)用程序(如打印文件夾)的響應(yīng)活動(dòng)構(gòu)成。這些端口管理活動(dòng)被端口監(jiān)示器處理,不是語言監(jiān)示器,并需要管理員的優(yōu)先權(quán)限。對存儲端口配置信息有特殊的規(guī)則。 一個(gè)附加的、可選的管理活動(dòng)包括設(shè)置端口超時(shí)值。 8.2.8.1增加端口增加一個(gè)端口由存儲端口的名字及用戶可修改的在端口監(jiān)示器服務(wù)器DLL的本地存儲中或注冊表中的配置信息構(gòu)成。 當(dāng)

45、應(yīng)用程序調(diào)用打印假脫機(jī)的AddPort函數(shù)(在平臺的SDK文檔中描述),它指定端口監(jiān)示器的名稱作為函數(shù)的參數(shù)。假脫機(jī)調(diào)用包含在指定的端口監(jiān)示器UI DLL中的AddPortUI函數(shù)。 端口監(jiān)示器的UI DLL的AddPortUI函數(shù)應(yīng)當(dāng)執(zhí)行下面的操作: 1調(diào)用打印假脫機(jī)的OpenPrinter函數(shù)(在平臺的SDK文檔中有描述),它引起端口監(jiān)示器服務(wù)器DLL中的XcvOpenPort被調(diào)用。 2多次調(diào)用打印假脫機(jī)的xcvData函數(shù),以請求端口監(jiān)示器服務(wù)器DLL增加端口并在UI DLL和服務(wù)器DLL之間傳遞配置信息。XcvData函數(shù)調(diào)用服務(wù)器DLL的XcvDataPort函數(shù)。AddPortU

46、I函數(shù)通常獲得從用戶顯示對話框欄顯示配置信息。 3調(diào)用打印假脫機(jī)的ClosePrinter函數(shù)(在平臺的SDK文檔中描述),它引起端口監(jiān)示器服務(wù)器DLL中的XcvClosePort函數(shù)被調(diào)用。 關(guān)于這些操作的更多信息,參考AddPortUI函數(shù)的描述,也可以參考存儲端口配置部分的內(nèi)容。 端口監(jiān)示器的EnumPorts函數(shù)必須枚舉所有被增加的端口。假脫機(jī)可以調(diào)用每一個(gè)端口監(jiān)示器的EnumPorts函數(shù)以確定在一個(gè)打印機(jī)服務(wù)器上可支持的端口集合。 8.2.8.2配置端口配置一個(gè)端口是指修改一個(gè)端口監(jiān)示器服務(wù)器的DLL的以前增加的端口的存儲的配置信息。 當(dāng)一個(gè)應(yīng)用程序調(diào)用打印假脫機(jī)的ConfigPo

47、rt函數(shù)(在平臺的SDK文檔中有描述)。ConfigurePort函數(shù)調(diào)用包含在適當(dāng)?shù)亩丝诒O(jiān)示器UI DLL中的ConfiguePortUI函數(shù)。 端口監(jiān)示器的UI DLL的ConfigPortUI函數(shù)應(yīng)當(dāng)執(zhí)行下面的操作: 1調(diào)用打印假脫機(jī)的OpenPrinter函數(shù)(在平臺的SDK文檔中有描述),它引起在端口監(jiān)示器服務(wù)器DLL中的XcvOpenPort函數(shù)被調(diào)用。 2一次或多次調(diào)用打印假脫機(jī)的XcvData函數(shù),以在UI DLL及服務(wù)器DLL之間傳輸配置信息。XcvData函數(shù)調(diào)用服務(wù)器DLL的XcvDataPort函數(shù),ConfigurePortUI函數(shù)通常通過從用戶顯示的對話框獲得配置信

48、息。 3調(diào)用打印假脫機(jī)的ClosePrinter函數(shù)(在平臺的SDK文檔中有描述),它導(dǎo)致端口監(jiān)示器服務(wù)器DLL中的XcvClosePort函數(shù)被調(diào)用。 關(guān)于這些操作的更多信息,可以參考ConifigurePortUI的描述。也可以參考存儲端口配置信息部分的內(nèi)容。 8.2.8.3刪除端口刪除端口由刪除端口的名稱及刪除用戶可修改的端口監(jiān)示器服務(wù)器DLL本地存儲或注冊表中的配置信息構(gòu)成。 當(dāng)一個(gè)應(yīng)用程序調(diào)用打印假脫機(jī)的DeletePort函數(shù)(在平臺的SDK文檔中描述),DeletePort函數(shù)調(diào)用包含在適當(dāng)?shù)亩丝诒O(jiān)示器UI DLL中的DeletePortUI函數(shù)。 端口監(jiān)示器的UI DLL的De

49、letePortUI函數(shù)應(yīng)當(dāng)執(zhí)行下面的操作: 1調(diào)用打印假脫機(jī)的OpenPrinter函數(shù)(在平臺的SDK文檔中描述),它導(dǎo)致端口監(jiān)示器服務(wù)器DLL中的XcvOpenPort函數(shù)被調(diào)用。 2一次或多次調(diào)用打印假脫機(jī)的XcvData函數(shù),以請求端口監(jiān)示器服務(wù)器DLL刪除端口。XcvData函數(shù)調(diào)用服務(wù)器DLL的XcvDataPort函數(shù)。 3調(diào)用打印假脫機(jī)的ClosePrinter函數(shù)(在平臺的SDK文檔中描述),它導(dǎo)致端口監(jiān)示器服務(wù)器DLL中的XcvClosePort函數(shù)被調(diào)用。 關(guān)于這些操作的更多信息,參考DeletePortUI的描述。 8.2.8.4設(shè)定端口超時(shí)值如果為一個(gè)具有可修改的超

50、時(shí)值的端口寫端口監(jiān)示器,超時(shí)值應(yīng)當(dāng)被監(jiān)示器的OpenPort函數(shù)初始化。例如,在localmon.dll中的OpenPort函數(shù),即端口監(jiān)示器實(shí)例,為了這個(gè)目的調(diào)用SetCommTimeouts函數(shù)(在平臺的SDK文檔中描述)。 8.2.8.5存儲端口配置信息Windows 2000打印假脫機(jī)可以在集群或非集群的服務(wù)器環(huán)境中執(zhí)行。當(dāng)假脫機(jī)在一個(gè)服務(wù)器集群中時(shí),打印監(jiān)示器配置信息必須被存儲在集群注冊表中。另一方面,如果假脫機(jī)運(yùn)行在一個(gè)單一的、非集群的服務(wù)器系統(tǒng)中,所有配置數(shù)據(jù)必須被存儲在服務(wù)器的本地注冊表中。 打印假脫機(jī)定義了一套注冊表函數(shù)以備打印監(jiān)示器使用。這些函數(shù)傳送配置數(shù)據(jù)到適當(dāng)?shù)淖员碇?/p>

51、,因此,打印監(jiān)示器不需要決定服務(wù)器是否集群。打印監(jiān)示器不能直接使用Win32注冊表API或者集群注冊表API;所有的配置數(shù)據(jù)必須可以用假脫機(jī)的注冊表函數(shù)來存儲和存取。當(dāng)假脫機(jī)調(diào)用監(jiān)示器的InitializePrintMonitor2函數(shù)時(shí),這些函數(shù)的地址在一個(gè)MONITORREG結(jié)構(gòu)中被提供給打印監(jiān)示器。 在一個(gè)服務(wù)器集群中,可以并存多個(gè)假脫機(jī)的實(shí)例。特別是,每個(gè)集群結(jié)點(diǎn)處理它自身的實(shí)例,并且一個(gè)附加的實(shí)例為集群自身存在。假脫機(jī)注冊表函數(shù)的一個(gè)輸入?yún)?shù)是假脫機(jī)句柄。這一句柄由監(jiān)示器的InitializePrintMoitor2函數(shù)收到并標(biāo)識假脫機(jī)已經(jīng)打開的監(jiān)示器的實(shí)例(結(jié)點(diǎn)或集群)。用假脫機(jī)句

52、柄,假脫機(jī)注冊表函數(shù)對每一個(gè)假脫機(jī)實(shí)例保持一個(gè)子鍵。 8.2.9為在集群打印服務(wù)器中使用轉(zhuǎn)換打印監(jiān)示器打印服務(wù)器集群是Windows 2000的新特性。任一準(zhǔn)備運(yùn)行于Windows2000集群的打印機(jī)端口監(jiān)示器都需要修改,這樣才可以被假脫機(jī)的實(shí)例(結(jié)點(diǎn)的假脫機(jī)及一個(gè)集群的假脫機(jī))所調(diào)用。下面的步驟必須執(zhí)行: 監(jiān)示器的InitializePrintMonitor函數(shù)必須被InitializePrintMonitor2函數(shù)替換。后一個(gè)函數(shù)返回一個(gè)監(jiān)示器實(shí)例句柄。 全局存儲變量必須被移動(dòng)到本地分配的內(nèi)存,并且這一內(nèi)存必須與由InitializePrintMonitor2函數(shù)返回的監(jiān)示器句柄相關(guān)聯(lián)。

53、對Win32注冊表API的調(diào)用必須被對假脫機(jī)注冊表的調(diào)用函數(shù)所替換,它的地址在MONITORREG結(jié)構(gòu)中傳遞到監(jiān)示器(參考存儲端口配置信息)。 端口監(jiān)示器必須被分成一個(gè)端口監(jiān)示器UI DLL和一個(gè)端口監(jiān)示器服務(wù)器DLL。UI DLL必須通過調(diào)用假脫機(jī)的XcvData函數(shù)與服務(wù)器DLL通訊。 必須增加一個(gè)Shutdown函數(shù)。 那些沒有被轉(zhuǎn)換的打印監(jiān)示器只能被用于一個(gè)非集群的環(huán)境中。他們不能被用于集群服務(wù)器。 一旦一個(gè)運(yùn)行在Windows2000的集群結(jié)點(diǎn)上的打印機(jī)端口監(jiān)示器已經(jīng)建立起了連接(跨網(wǎng)絡(luò)或者本地),端口監(jiān)示器應(yīng)當(dāng)從假脫機(jī)在適當(dāng)?shù)臅r(shí)間里進(jìn)行的調(diào)用返回。(默認(rèn)的假脫機(jī)資源超時(shí)值是180秒

54、,參考設(shè)置端口超時(shí)值部分的內(nèi)容獲得更多信息。) 當(dāng)發(fā)生從一個(gè)集群結(jié)點(diǎn)到另外一個(gè)結(jié)點(diǎn)的失效情況,假脫機(jī)必須等待所有當(dāng)前打印作業(yè)完成或失敗。如果一個(gè)未完成的作業(yè)保持在一個(gè)端口監(jiān)示器中期待著假脫機(jī)資源的超時(shí),隨著打印機(jī)的臨時(shí)性丟失,假脫機(jī)也許可以在線返回到一個(gè)不完全的狀態(tài)。這將會影響那些連接到這些丟失的打印機(jī)上的用戶。 8.2.10安裝打印監(jiān)示器這一部分描述可以用于安裝打印監(jiān)示器的方法(注意,如果打印機(jī)如果不被ntprint.inf支持,必須提供一個(gè).inf文件來指定打印機(jī)。關(guān)于.inf文件的更多信息,可以參考即插即用、電源管理及建立設(shè)計(jì)向?qū)Р糠值膬?nèi)容。) 安裝語言監(jiān)示器 為安裝一個(gè)語言監(jiān)示器,必須

55、使用LanguageMonitor條目在.inf文件中列出它的文件名。這一條目必須被每一個(gè)控制打印機(jī)時(shí)需要使用語言監(jiān)示器的打印機(jī)驅(qū)動(dòng)程序都包括。更多的信息,參考第10章打印機(jī)INF文件部分。 增加驅(qū)動(dòng)程序向?qū)Щ蛘咴黾哟蛴C(jī)向?qū)プx這個(gè).inf文件并安裝與打印機(jī)驅(qū)動(dòng)程序相關(guān)的的語言監(jiān)示器。 作為選擇,定制安裝程序也可以通過調(diào)用假脫機(jī)的AddMonitor函數(shù)來安裝語言監(jiān)示器,并明確地只安裝一個(gè)專用的監(jiān)示器DLL。 (AddMonitor函數(shù)在平臺的SDK文檔中有描述) 安裝一個(gè)端口監(jiān)示器 為安裝一個(gè)端口監(jiān)示器,安裝媒體必須包括一個(gè)叫做monitor.inf的打印機(jī).inf文件。這個(gè).inf文件必須基于%windir%system32printmon.inf,即默認(rèn)的安裝端口監(jiān)示器的.inf文件。應(yīng)當(dāng)制做一份printmon.inf的拷貝,將它改名為monitor

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論