Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Чтобы установить обработчик печати, приложение установки должно вызвать функцию AddPrintProcessor spooler. Чтобы связать обработчик печати с очередью печати, укажите имя файла в INF-файле в записи PrintProcessor. Эта запись должна быть включена для каждой очереди печати, к которой должен быть связан обработчик печати. Дополнительные сведения см. в разделе "INF-файлы принтера".
Когда приложение установки вызывает функцию AddPrinter spooler, используя структуру {PRINTER_INFO_2](/windows/win32/printdocs/printer-info-2) в качестве входного аргумента, он указывает имя обработчика печати (полученное из INF-файла) в качестве члена структуры.
Связывание процессора печати с установленной очередью печати pnp
Если диспетчер Plug and Play (PnP) обнаруживает и устанавливает очередь печати в системе под управлением Windows 2000 или Windows XP, а если INF-файл, используемый для установки очереди печати, содержит запись PrintProcessor, отличное от процессора печати Windows по умолчанию, WinPrint, обработчик печати не будет связан с очередью печати. Однако процессор печати будет установлен.
Обратите внимание, что при установке очереди печати с помощью мастера добавления принтера обработчик печати правильно связан с очередью печати.
Обратите внимание также, что диспетчер PnP в Microsoft Windows Server 2003 и более поздних версиях правильно связывает обработчик печати с очередью печати.
Чтобы ассоциировать обработчик печати с очередью печати для установок Plug and Play в Windows 2000 и Windows XP, добавьте случай PRINTER_EVENT_INITIALIZE в функцию DrvPrinterEvent DLL интерфейса принтера. Для Microsoft Windows Server 2003 и более поздних версий не требуется добавлять PRINTER_EVENT_INITIALIZE регистр в функцию DrvPrinterEvent .
В следующем примере кода элемент pPrintProcessor структуры PRINTER_INFO_2 присваивается имени обработчика печати, а затем вызывает функцию SetPrinter для обновления параметров принтера. Обратите внимание, что имя обработчика печати в gszPrintProc должно совпадать с именем в записи PrintProcessor в INF-файле.
BOOL
DrvPrinterEvent(
LPWSTR pPrinterName,
INT Event,
DWORD Flags,
LPARAM lParam
)
{
PRINTER_DEFAULTS PrinterDef = {NULL, NULL, PRINTER_ALL_ACCESS};
HANDLE hPrinter;
LPPRINTER_INFO_2 pInfo = NULL;
DWORD cbNeeded;
TCHAR gszPrintProc[] = TEXT("<Print processor name>");
BOOL bRet = TRUE;
switch (Event)
{
case PRINTER_EVENT_INITIALIZE:
if (OpenPrinter(pPrinterName, &hPrinter, &PrinterDef))
{
if ( !GetPrinter( hPrinter, 2, (LPBYTE) pInfo, 0, &cbNeeded ) &&
(GetLastError() != ERROR_INSUFFICIENT_BUFFER) )
{
bRet = FALSE;
}
if (bRet == TRUE)
{
pInfo = (LPPRINTER_INFO_2) LocalAlloc(LPTR, cbNeeded);
bRet = pInfo ? TRUE : FALSE;
}
if (bRet == TRUE)
{
if (GetPrinter(hPrinter, 2, (LPBYTE) pInfo, cbNeeded, &cbNeeded))
{
pInfo->pPrintProcessor = gszPrintProc;
SetPrinter(hPrinter, 2, (LPBYTE) pInfo, 0);
}
else
{
bRet = FALSE;
}
if (pInfo)
{
LocalFree(pInfo);
}
}
ClosePrinter(hPrinter);
}
else // OpenPrinter failed
{
bRet = FALSE;
}
break;
// cases for other events
default:
break;
} // end switch
return bRet;
}
Связывание процессора печати с очередью печати во время обновления драйвера принтера
При обновлении драйвера принтера обработчик печати обновленной очереди печати не изменяется. Если для нового драйвера принтера требуется конкретный процессор печати, функция DRvUpgradePrinter интерфейса принтера должна задать элемент pPrintProcessor структуры PRINTER_INFO_2 именем нового процессора печати. После этого эта функция вызывает SetPrinter для обновления параметров принтера. Spooler вызывает функцию DrvUpgradePrinter один раз для каждого принтера, что гарантирует, что все принтеры, использующие этот драйвер, также используют необходимый процессор печати. В следующем примере кода показаны эти моменты.
BOOL
DrvUpgradePrinter(
DWORD Level,
LPBYTE pDriverUpgradeInfo
)
{
HANDLE hPrinter;
PRINTER_DEFAULTS PrinterDef = {NULL, NULL, PRINTER_ALL_ACCESS};
PDRIVER_UPGRADE_INFO_2 pDUI2;
LPPRINTER_INFO_2 pInfo = NULL;
DWORD cbNeeded;
TCHAR gszPrintProc[] = TEXT("<Print processor name>");
TCHAR gszPrintDriver[] = TEXT("<Printer driver name>");
BOOL bRet = TRUE;
if ((Level == 2) &&
(pDUI2 = (PDRIVER_UPGRADE_INFO_2)pDriverUpgradeInfo) &&
(OpenPrinter(pDUI2->pPrinterName, &hPrinter, &PrinterDef)))
{
if ( !GetPrinter( hPrinter, 2, (LPBYTE) pInfo, 0, &cbNeeded ) &&
(GetLastError() != ERROR_INSUFFICIENT_BUFFER) )
{
bRet = FALSE;
}
if (bRet == TRUE)
{
pInfo = (LPPRINTER_INFO_2) LocalAlloc(LPTR, cbNeeded);
bRet = pInfo ? TRUE : FALSE;
}
if (bRet == TRUE)
{
if (GetPrinter(hPrinter, 2, (LPBYTE) pInfo, cbNeeded, &cbNeeded))
{
//
// This function is called for every printer queue that uses a driver
// for which one or more files were updated. However, we only want to
// update the printer queue's "driver" by a particular driver.
//
if ( !lstrcmpi(pInfo->pDriverName, gszPrintDriver) )
{
pInfo->pPrintProcessor = gszPrintProc;
SetPrinter(hPrinter, 2, (LPBYTE) pInfo, 0);
}
else // GetPrinter
{
bRet = FALSE;
}
if (pInfo)
{
LocalFree(pInfo);
}
ClosePrinter(hPrinter);
}
else // Level != 2 or pDUI2 == NULL or OpenPrinter failed
{
bRet = FALSE;
}
return bRet;
}