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


Plug-Ins отрисовки, не основанные на COM

Важно!

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

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

Мини-драйвер принтера уведомляет основной драйвер о своих возможностях, реализуя функцию OEMEnableDriver , которая заполняет элементы структуры DRVENABLEDATA . Элемент pdrvfn этой структуры должен быть задан с адресом массива структур DRVFN . Каждый элемент этого массива должен быть инициализирован с помощью индекса функции и адреса одной из функций OEMXxx , которую реализует IHV соответственно. (Подробное описание каждой функции OEMXxx см. в разделе Функции Hook-Out DDI, не основанные на COM.)

Когда приложение вызывает Microsoft Win32 GDI для выполнения задачи отрисовки, Win32 GDI, в свою очередь, вызывает основной драйвер Unidrv или Pscript5, который обычно обрабатывает задачу. Однако если мини-драйвер принтера указал, что способен подключить определенную операцию отрисовки, основной драйвер передает задачу отрисовки в подключаемый модуль отрисовки IHV.

Например, рассмотрим приложение, которое вызывает API LineTo Win32 (описано в документации по Windows SDK). Как правило, это приведет к еще одному вызову DDI основного драйвера DrvLineTo для рисования линии. Если мини-драйвер принтера указал, что он намерен подключить вызовы к этому DDI, DrvLineTo немедленно перенаправит вызов в функцию OEMLineTo IHV.

IHV может реализовать OEMLineTo или любые другие функции подключения, описанные в разделе Функции DDI, не основанные на COM, Hook-Out, чтобы он полностью обрабатывал операцию отрисовки, или может выполнить обратный вызов, чтобы основной драйвер обработал такую операцию.

OEMLineTo можно реализовать, как показано в следующем примере псевдокода:

BOOL APIENTRY
  OEMLineTo(
    SURFOBJ  *pso,
    CLIPOBJ  *pco,
    BRUSHOBJ  *pbo,
    LONG  x1,
    LONG  y1,
    LONG  x2,
    LONG  y2,
    RECTL  *prclBounds,
    MIX  mix
)
{
if ( OEM intends to handle the call ) {
 code to handle the call
}
else
// OEM calls Unidrv's DrvLineTo DDI
  bRetVal = (((PFN_DrvLineTo)(poempdev->pfnUnidrv[UD_DrvLineTo])) (
 pso,
            pco,
            pbo,
            x1,
            x2,
 y1,
            y2,
            prclBounds,
            mix,));
}

В предыдущем примере выражение

poempdev->pfnUnidrv[UD_DrvLineTo]

вычисляет адрес DDI DrvLineTo основного драйвера. Выражение (PFN_DrvLineTo), предшествующее ему, приводит указатель функции к соответствующему типу. Каждая из функций-перехватчиков, перечисленных в этом разделе, связана с собственным указателем функции.

Обратите внимание, что когда OEMXxx DDI вызывает драйвер ядра Unidrv, а задействованная поверхность является поверхностью, управляемой устройством, Unidrv может просто игнорировать вызов, возвращая значение FALSE.