Criando o plug-in
Importante
A plataforma de impressão moderna é o meio preferido do Windows para se comunicar com as impressoras. Recomendamos que você use o driver de classe de caixa de entrada IPP da Microsoft juntamente com PSA (Aplicativos de Suporte à Impressão) para personalizar a experiência de impressão no Windows 10 e 11 para o desenvolvimento de dispositivos de impressora.
Para obter mais informações, consulte Plataformade impressão moderna e o Guia de design do aplicativo de suporte de impressão.
Todos os plug-ins de driver de impressora devem definir as funções DllMain, DllGetClassObject e DllCanUnloadNow. Eles também devem implementar a interface COM IClassFactory e uma das interfaces COM IPrintOemUI, IPrintOemUI2, IPrintOemUni, IPrintOemUni2, IPrintOemUni3, IPrintOemPS, ou IPrintOemPS2.
Quando você cria um plug-in de interface de usuário ou um plug-in de renderização, você deve basear seu código em plug-in de IU de amostra ou em plug-ins de renderização de amostra fornecido no WDK.
Para criar qualquer tipo de plug-in, você deve fazer o seguinte:
Defina uma função DllMain (descrita na documentação do SDK do Windows).
Esse é o ponto de entrada para todas as DLLs do Win32.
Defina e exporte uma função DllGetClassObject (descrita na documentação do SDK do Windows).
O driver de impressora chama essa função para obter acesso à implementação do plug-in da interface IClassFactory (descrita na documentação do SDK do Windows). Quando o driver chama DllGetClassObject, ele especifica um dos seguintes identificadores de classe (definidos em prcomoem.h):
CLSID_OEMUI - para plug-ins de interface do usuário
CLSID_OEMRENDER - para renderizar plug-ins
O driver também especifica um identificador de interface de IID_IClassFactory.
A função DllGetClassObject deve criar uma instância de sua interface IClassFactory e retornar um ponteiro para ela, conforme ilustrado no código de exemplo.
Implemente a interface COM IClassFactory.
O método CreateInstance da interface IClassFactory deve criar uma instância da implementação do plug-in de uma das seguintes interfaces COM:
IPrintOemUI, IPrintOemUI2, IPrintOemUni, IPrintOemUni2, IPrintOemUni3, IPrintOemPS, ou IPrintOemPS2
Uma das entradas do método CreateInstance é um identificador de interface. O driver chama CreateInstance com um identificador de interface de IID_IUnknown, o que significa que o método CreateInstance deve retornar um ponteiro para a interface IUnknown da instância criada (descrita na documentação do SDK do Windows), conforme ilustrado no código de exemplo.
Implemente uma das interfaces COM IPrintOemUI, IPrintOemUI2, IPrintOemUni, IPrintOemUni2, IPrintOemUni3, IPrintOemPS ou IPrintOemPS2, incluindo a interface IUnknown padrão, conforme ilustrado no código de exemplo.
O primeiro dos métodos implementados a serem chamados pelo driver é o método QueryInterface da interface IUnknown (descrito na documentação do SDK do Windows). Esse método recebe um dos identificadores de interface para drivers de impressora como um argumento de entrada. O driver chama o método para determinar qual versão da interface é compatível com o plug-in e para receber um ponteiro para a interface com suporte.
Defina e exporte uma função DllCanUnloadNow (descrita na documentação do SDK do Windows).
A função DllCanUnloadNow deve retornar S_OK se todas as instâncias das interfaces COM IPrintOemUI, IPrintOemUI2, IPrintOemUni, IPrintOemUni2, IPrintOemUni3, IPrintOemPS ou IPrintOemPS2 implementadas por plug-in tiverem sido lançadas. O retorno S_OK indica ao driver que o plug-in pode ser descarregado.
Observe que, quando o driver da impressora descarrega a DLL do plug-in, ele primeiro chama a função DllCanUnloadNow do plug-in. Independentemente do valor retornado por DllCanUnloadNow, o driver de impressora descarrega a DLL do plug-in chamando a função FreeLibrary . Isso é feito para garantir que a DLL do plug-in seja descarregada antes que o driver seja descarregado.
Se a DLL do plug-in precisar permanecer carregada (por exemplo, quando ela cria um thread que usa a DLL do plug-in), o thread deverá carregar a DLL, usando uma chamada para a função LoadLibrary . Quando o thread for concluído com a DLL, ele deverá chamar a função FreeLibraryAndExitThread para descarregá-lo. Em uma situação em que um thread chamou LoadLibrary, a chamada do driver para FreeLibrary apenas diminui a contagem de referência da DLL, impedindo assim que ela seja descarregada. As funções LoadLibrary, FreeLibrary e FreeLibraryAndExitThread são descritas na documentação do SDK do Windows.