建立外掛程式
重要
新式列印平臺是 Windows 與印表機通訊的慣用方法。 我們建議您使用Microsoft的 IPP 收件匣類別驅動程式,以及列印支援應用程式 (PSA),自定義 Windows 10 和 11 中的列印體驗,以進行印表機裝置開發。
如需詳細資訊,請參閱 新式列印平臺 和 列印支援應用程式設計指南。
所有印表機驅動程式外掛程式都必須定義 DllMain、DllGetClassObject 和 DllCanUnloadNow 函式。 它們也必須實作 IClassFactory COM 介面和其中一個 IPrintOemUI、IPrintOemUI2、IPrintOemUni、IPrintOemUni2、IPrintOemUni3、IPrintOemPS 或 IPrintOemPS2 COM 介面。
當您建立使用者介面外掛程式或轉譯外掛程式時,您應該以範例 UI 外掛程式或 WDK 中提供的範例轉譯外掛程式作為程式代碼基底。
若要建立任一類型的外掛程式,您必須執行下列動作:
定義 DllMain 函式(如 Windows SDK 檔中所述)。
這是所有 Win32 DLL 的進入點。
定義和導出 DllGetClassObject 函式(如 Windows SDK 檔中所述)。
印表機驅動程式會呼叫此函式,以取得 IClassFactory 介面實作的存取權(如 Windows SDK 檔所述)。 當驅動程式呼叫 DllGetClassObject 時,它會指定下列其中一個類別標識碼(定義於 prcomoem.h):
CLSID_OEMUI - 適用於 UI 外掛程式
CLSID_OEMRENDER - 用於轉譯外掛程式
驅動程式也會指定IID_IClassFactory的介面標識碼。
DllGetClassObject 函式必須建立其 IClassFactory 介面的實例,並傳回指標,如範例程式代碼所示。
實作 IClassFactory COM 介面。
IClassFactory 介面的 CreateInstance 方法應該建立外掛程式實作下列其中一個 COM 介面的實例:
IPrintOemUI、IPrintOemUI2、IPrintOemUni、IPrintOemUni2、IPrintOemUni3、IPrintOemPS 或 IPrintOemPS2
CreateInstance 方法的其中一個輸入是介面標識碼。 驅動程式會使用介面標識符 IID_IUnknown呼叫 CreateInstance,這表示 CreateInstance 方法必須傳回所建立實例 IUnknown 介面的指標(如 Windows SDK 檔中所述),如範例程式代碼所示。
實作其中一個 IPrintOemUI、IPrintOemUI2、IPrintOemUni、IPrintOemUni2、IPrintOemUni3、IPrintOemPS 或 IPrintOemPS2 COM 介面,包括標準 IUnknown 介面,如範例程式代碼所示。
驅動程式要呼叫的第一個實作方法是 IUnknown 介面的 QueryInterface 方法(如 Windows SDK 檔中所述)。 這個方法會接收印表機驅動程式的其中一個介面標識碼做為輸入自變數。 驅動程式會呼叫 方法來判斷外掛程式所支援的介面版本,以及接收支援介面的指標。
定義和匯出 DllCanUnloadNow 函式(如 Windows SDK 檔中所述)。
如果已發行外掛程式實作 IPrintOemUI、IPrintOemUI2、IPrintOemUni、IPrintOemUni2、IPrintOemUni2、IPrintOemUni3、IPrintOemPSPS 或 IPrintOemPS2 COM 介面的所有實例,DllCanUnloadNow 函式必須傳回S_OK。 S_OK傳回會向驅動程式指出可以卸除外掛程式。
請注意,當印表機驅動程式卸除外掛程式 DLL 時,它會先呼叫外掛程式的 DllCanUnloadNow 函式。 不論 DllCanUnloadNow 傳回的值為何,印表機驅動程式都會呼叫 FreeLibrary 函式來卸除外掛程式 DLL。 這樣做可確保在卸除驅動程式之前卸除外掛程式 DLL。
如果外掛程式 DLL 必須保持載入狀態(例如,當它建立使用外掛程式 DLL 的線程時),線程必須使用 LoadLibrary 函式的呼叫來載入 DLL。 當線程完成 DLL 時,它應該呼叫 FreeLibraryAndExitThread 函式來卸除它。 在線程呼叫 LoadLibrary 的情況下,驅動程式對 FreeLibrary 的呼叫只會遞減 DLL 的參考計數,進而防止它卸除。 Windows SDK 文件中會說明 LoadLibrary、FreeLibrary 和 FreeLibraryAndExitThread 函式。