Instalar um processador de impressão
Para instalar um processador de impressão, um aplicativo de instalação deve chamar a função AddPrintProcessor do spooler. Para associar um processador de impressão a uma fila de impressão, liste seu nome de arquivo em um arquivo INF em uma entrada printProcessor. Essa entrada deve ser incluída para cada fila de impressão à qual o processador de impressão deve ser associado. Para obter mais informações, consulte Arquivos INF da impressora.
Quando um aplicativo de instalação chama a função AddPrinter do spooler , usando uma estrutura {PRINTER_INFO_2](/windows/win32/printdocs/printer-info-2) como um argumento de entrada, ele especifica o nome do processador de impressão (obtido do arquivo INF) como um membro da estrutura.
Associando um processador de impressão a uma fila de impressão instalada por pnp
Se o gerenciador de Plug and Play (PnP) detectar e instalar uma fila de impressão em um sistema que executa o Windows 2000 ou o Windows XP e se o arquivo INF usado para instalar a fila de impressão contiver uma entrada printProcessor diferente do processador de impressão padrão do Windows, WinPrint, o processador de impressão não será associado à fila de impressão. No entanto, o processador de impressão será instalado.
Observe que, se você instalar a fila de impressão usando o assistente Adicionar Impressora, o processador de impressão estará corretamente associado à fila de impressão.
Observe também que o gerenciador PnP no Microsoft Windows Server 2003 e posterior associa corretamente um processador de impressão à fila de impressão.
Para associar o processador de impressão à fila de impressão para instalações Plug and Play no Windows 2000 e no Windows XP, inclua um caso de PRINTER_EVENT_INITIALIZE na função DrvPrinterEvent da interface da impressora. Para o Microsoft Windows Server 2003 e posterior, não é necessário adicionar um caso de PRINTER_EVENT_INITIALIZE na função DrvPrinterEvent .
O exemplo de código a seguir define o membro pPrintProcessor da estrutura PRINTER_INFO_2 como o nome do processador de impressão e, em seguida, chama a função SetPrinter para atualizar as configurações da impressora. Observe que o nome do processador de impressão em gszPrintProc deve ser o mesmo que na entrada PrintProcessor no arquivo 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;
}
Associar um processador de impressão a uma fila de impressão durante a atualização do driver de impressora
Quando um driver de impressora é atualizado, o processador de impressão da fila de impressão atualizada não é alterado. Se o novo driver de impressora exigir um processador de impressão específico, a função DrvUpgradePrinter da interface da impressora deverá definir o membro pPrintProcessor da estrutura PRINTER_INFO_2 como o nome do novo processador de impressão. Depois que isso ocorrer, essa função chamará SetPrinter para atualizar as configurações da impressora. O spooler chama a função DrvUpgradePrinter uma vez para cada impressora, o que garante que todas as impressoras que usam esse driver também usem o processador de impressão necessário. O exemplo de código a seguir demonstra esses pontos.
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;
}