SYMPTOMS
In Microsoft Windows 2000, when you update a printer driver by using the
Advanced tab of the printer properties dialog box, you cannot save the printing preferences.
Note To update the printer
driver, you must follow these steps:
- In Control Panel, open Printers and Faxes.
- Right-click any printer object, and then click Properties.
- Click the Advanced tab.
- Install the new printer driver by clicking New
Driver or by clicking a printer driver in the Driver
list.
Note When you update the printer driver and the new printer driver has a different
DEVMODE data structure, you cannot save the printing preferences.
RESOLUTION
To resolve this problem, the printer driver must confirm and update the
DEVMODE
structure in the
DrvDriverEvent function. Driver developers can modify drivers by using code that is similar to the following code example.
BOOL
IsCompatibleDM(
LPDEVMODE lpDM1,
LPDEVMODE lpDM2
)
{
// Determine whether the DEVMODE structure is compatible.
if((lpDM1 == NULL) || (lpDM2 == NULL)) return FALSE;
return lpDM1->dmSpecVersion == lpDM2->dmSpecVersion &&
lpDM1->dmDriverVersion == lpDM2->dmDriverVersion &&
lpDM1->dmSize == lpDM2->dmSize &&
lpDM1->dmDriverExtra == lpDM2->dmDriverExtra;
}
/*
* If the printer driver is minidrver, you can put this same code into the IPrintOemUI::DriverEvent method of the interface plug-in.
*/
BOOL
DrvPrinterEvent(
PWSTR pPrinterName,
INT DriverEvent,
DWORD Flags,
LPARAM lParam
)
{
LONG cbBuf;
HANDLE hToken;
HANDLE hPrinter = NULL;
LPDEVMODE lpDefDM = NULL;
LPPRINTER_INFO_8 ppi8 = NULL;
PRINTER_DEFAULTS pd;
switch (DriverEvent) {
case PRINTER_EVENT_INITIALIZE:
hToken = RevertToPrinterSelf();
ZeroMemory(&pd, sizeof(pd));
pd.DesiredAccess = PRINTER_ALL_ACCESS;
if(FALSE == OpenPrinter(pPrinterName, &hPrinter, &pd)) goto Done;
// Obtain the global default printer settings.
GetPrinter(hPrinter, 8, NULL, 0, &cbBuf);
if(GetLastError() != ERROR_INSUFFICIENT_BUFFER) goto Done;
ppi8 = (LPPRINTER_INFO_8)GlobalAlloc(GPTR, cbBuf);
if(ppi8 == NULL) goto Done;
if(FALSE == GetPrinter(hPrinter, 8, (LPBYTE)ppi8, cbBuf, &cbBuf)) goto Done;
// Obtain the default DEVMODE structure.
cbBuf = DocumentProperties(NULL, hPrinter, pPrinterName, NULL, NULL, 0); if(cbBuf <= 0) goto Done;
lpDefDM = (LPDEVMODE)GlobalAlloc(GPTR, cbBuf);
if(lpDefDM == NULL) goto Done;
if(0 < DocumentProperties(NULL, hPrinter, pPrinterName, lpDefDM, NULL, DM_OUT_BUFFER)) goto Done;
// Check both DEVMODE structures and modify the structures if it is required.
if(FALSE == IsCompatibleDM(lpDefDM, ppi8->pDevMode)) {
ppi8->pDevMode = lpDefDM;
SetPrinter(hPrinter, 8, (LPBYTE)ppi8, 0);
}
Done:
if(hPrinter) ClosePrinter(hPrinter);
if(lpDefDM) GlobalFree(lpDefDM);
if(ppi8) GlobalFree(ppi8);
ImpersonatePrinterClient(hToken);
break;
default:
break;
}
return TRUE;
}