Поделиться через


Создание подключаемого модуля

Внимание

Современная платформа печати — это предпочтительный способ взаимодействия с принтерами Windows. Рекомендуется использовать драйвер класса "Входящие" Microsoft IPP вместе с приложениями поддержки печати (PSA), чтобы настроить возможности печати в Windows 10 и 11 для разработки устройств принтера.

Дополнительные сведения см. в статье "Современная платформа печати" и руководство по проектированию приложений поддержки печати.

Все подключаемые модули драйвера принтера должны определять функции DllMain, DllGetClassObject и DllCanUnloadNow. Они также должны реализовать интерфейс COM IClassFactory и один из интерфейсов IPrintOemUI, IPrintOemUI2, IPrintOemUni, IPrintOemUni2, IPrintOemUni3, IPrintOemUniPS или IPrintOemPS2 COM.

При создании подключаемого модуля пользовательского интерфейса или подключаемого модуля отрисовки следует на основе кода на основе подключаемого модуля пользовательского интерфейса или примера подключаемых модулей отрисовки, предоставляемых в WDK.

Чтобы создать любой тип подключаемого модуля, необходимо выполнить следующее:

  1. Определите функцию DllMain (описанную в документации по пакету SDK для Windows).

    Это точка входа для всех БИБЛИОТЕК DLL Win32.

  2. Определите и экспортируйте функцию DllGetClassObject (описанную в документации по пакету SDK для Windows).

    Драйвер принтера вызывает эту функцию для получения доступа к реализации подключаемого модуля интерфейса IClassFactory (описано в документации по пакету SDK для Windows). Когда драйвер вызывает DllGetClassObject, он задает один из следующих идентификаторов класса (определенных в prcomoem.h):

    CLSID_OEMUI — для подключаемых модулей пользовательского интерфейса

    CLSID_OEMRENDER — для подготовки подключаемых модулей для отрисовки

    Драйвер также задает идентификатор интерфейса IID_IClassFactory.

    Функция DllGetClassObject должна создать экземпляр своего интерфейса IClassFactory и вернуть указатель на него, как показано в примере кода.

  3. Реализуйте COM-интерфейс IClassFactory.

    Метод CreateInstance интерфейса IClassFactory должен создать экземпляр реализации подключаемого модуля одного из следующих COM-интерфейсов:

    IPrintOemUI, IPrintOemUI2, IPrintOemUni, IPrintOemUni2, IPrintOemUni3, IPrintOemUni3, IPrintOemPS или IPrintOemPS2

    Одним из входных данных метода CreateInstance является идентификатор интерфейса. Драйвер вызывает CreateInstance с идентификатором интерфейса IID_IUnknown, то есть метод CreateInstance должен вернуть указатель на интерфейс IUnknown созданного экземпляра (описано в документации по пакету SDK для Windows), как показано в примере кода.

  4. Реализуйте один из интерфейсов IPrintOemUI, IPrintOemUI2, IPrintOemUni2, IPrintOemUni2, IPrintOemUni3, IPrintOemUniPS или IPrintOemPS2 COM, включая стандартный интерфейс IUnknown, как показано в примере кода.

    Первым из реализованных методов, вызываемых драйвером, является метод QueryInterface интерфейса IUnknown (описанный в документации по пакету SDK для Windows). Этот метод получает один из идентификаторов интерфейса для драйверов принтера в качестве входного аргумента. Драйвер вызывает метод, чтобы определить, какая версия интерфейса поддерживается подключаемым модулем и получает указатель на поддерживаемый интерфейс.

  5. Определите и экспортируйте функцию DllCanUnloadNow (описанную в документации по пакету SDK для Windows).

    Функция DllCanUnloadNow должна возвращать S_OK, если были выпущены все экземпляры подключаемых модулей IPrintOemUI, IPrintOemUI2, IPrintOemUni, IPrintOemUni2, IPrintOemUni3, IPrintOemUniPS или IPrintOemPS2 COM. Возврат S_OK указывает драйверу, что подключаемый модуль можно выгрузить.

    Обратите внимание, что при выгрузке dll подключаемого модуля драйвер принтера сначала вызывает функцию DllCanUnloadNow подключаемого модуля. Независимо от значения, возвращаемого dllCanUnloadNow, драйвер принтера затем выгрузит библиотеку DLL подключаемого модуля, вызвав функцию FreeLibrary. Это делается, чтобы убедиться, что подключаемый модуль DLL выгружается перед выгрузкой драйвера.

    Если подключаемый модуль DLL должен оставаться загруженным (например, при создании потока, использующего библиотеку DLL подключаемого модуля), поток должен загрузить библиотеку DLL с помощью вызова функции LoadLibrary. Когда поток завершится с помощью библиотеки DLL, он должен вызвать функцию FreeLibraryAndExitThread, чтобы выгрузить ее. В ситуации, когда поток называется LoadLibrary, вызов драйвера к FreeLibrary просто уменьшает число ссылок библиотеки DLL, тем самым предотвращая его выгрузку. Функции LoadLibrary, FreeLibrary и FreeLibraryAndExitThread описаны в документации по пакету SDK для Windows.