Het wijzigen van printerinstellingen met de functie DocumentProperties()


Samenvatting


Printerinstellingen wijzigen met een DEVMODE -structuur is moeilijker dan de velden van de structuur te wijzigen. Met name bevat een geldige DEVMODE -structuur voor een apparaat persoonlijke gegevens die alleen kunnen worden gewijzigd door de functie DocumentProperties() .

In dit artikel wordt uitgelegd hoe de inhoud van een DEVMODE -structuur met de functie DocumentProperties() niet wijzigen.

Meer informatie


DEVMODE -structuur, zoals aangegeven door de Win32 SDK bevat openbare of 'apparaat-onafhankelijke gegevens' en particuliere of "device afhankelijke gegevens." Het persoonlijke gedeelte van een DEVMODE komt direct na het openbare gedeelte dat wordt gedefinieerd door de structuur DEVMODE in een buffer aaneengesloten geheugen.

Een programma kan niet de grootte van deze buffer voorspellen omdat het verschilt van printer tot printer en van versie tot versie van het printerstuurprogramma. Een DEVMODE -structuur die alleen door een programma wordt gedeclareerd bevatten ook niet genoeg ruimte voor persoonlijke gegevens. Als een buffer DEVMODE zonder persoonlijke gegevens wordt doorgegeven aan functies als CreateDC(), ResetDC()en DocumentProperties(), kan de functie niet.

Op betrouwbare wijze een DEVMODE gebruiken met een apparaatstuurprogramma, maken en wijzigen door de volgende stappen:

  1. Bepalen van de vereiste grootte van de buffer van het apparaat en vervolgens voldoende geheugen toewijzen voor deze.

    DocumentProperties() geeft als resultaat het aantal bytes die vereist voor een buffer DEVMODE zijn wanneer de laatste parameter is ingesteld op 0. De voorbeeldcode in dit artikel wordt deze techniek gebruikt om te bepalen van de juiste grootte van de buffer. De voorbeeldcode vervolgens wordt de functie C runtime-geheugen toewijzing van malloc() een buffer groot genoeg is. Omdat functies zoals ResetDC() en CreateDC() en DocumentProperties() houden met verwijzingen naar een DEVMODE als parameter, kunnen geheugen dat wordt verholpen door een verwijzing in de meeste toepassingen toewijzen.

    Functies zoals het gemeenschappelijk PrintDlg() nemen echter parameters die nodig zijn om de ingangen naar het algemene geheugen. Als een programma gebruikmaakt van de uiteindelijke DEVMODE-buffer als een parameter voor een van deze functies, moet het toewijzen van geheugen gebruikt door GlobalAlloc() en een pointer naar de buffer met behulp van GlobalLock()te verkrijgen.
  2. Vraag het stuurprogramma initialiseren van de DEVMODE-buffer met de standaardinstellingen.

    De voorbeeldcode roept DocumentProperties() een tweede keer aan de toegewezen buffer met de huidige standaardinstellingen initialiseren. DocumentProperties() vult de buffer die is aangeduid als de parameter pDevModeOutput met de huidige instellingen van de printer wanneer u de opdracht DM_OUT_BUFFER wordt doorgegeven in de parameter fMode.
  3. Wijzigingen aanbrengen in het openbare gedeelte van de DEVMODE en vraag het stuurprogramma voor het samenvoegen van de wijzigingen in het persoonlijke gedeelte van de DEVMODE door het aanroepen van DocumentProperties().

    Na het initialiseren van de buffer met de huidige instellingen in stap 2 aanbrengt het voorbeeld met programmacode wijzigingen in het openbare gedeelte van de DEVMODE. Zie de Win32 SDK-documentatie voor een beschrijving van de DEVMODE -leden. Deze voorbeeldcode bepaalt of de printer, afdrukstand en dubbelzijdig afdrukken (dubbelzijdig) instellingen gebruiken kunt en op de juiste wijze kunnen worden aangepast.

    Opmerking: een markering in het dmFields -lid van een DEVMODE wordt alleen de vermelding dat het lid van de bijbehorende structuur maakt gebruik van een printer. Printers hebben een groot aantal verschillende fysieke kenmerken en daarom kunnen ondersteunen alleen een subset van een DEVMODE-gedocumenteerde functies. Toepassingen moeten DeviceCapabilities()gebruiken om te bepalen van de ondersteunde instellingen van het veld van een DEVMODE.



    De voorbeeldcode vervolgens kunt u een andere aanroep naar DocumentProperties() en wordt de DEVMODE-buffer wordt doorgegeven in de pDevModeInput- en pDevModeOutput. De gecombineerde opdrachten van DM_IN_BUFFER en DM_OUT_BUFFER in de fMode-parameter wordt doorgegeven met behulp van de operator OR("|"). Deze opdrachten geven de functie van de instellingen die zijn opgenomen in de invoerbuffer nemen en deze samenvoegen met de huidige instellingen voor het apparaat. Wordt het resultaat naar de buffer die is opgegeven in de uitvoerparameter.
Opmerking: DocumentProperties() verwijst naar een specifieke printer door een ingang naar een printer: hPrinter. Deze ingang wordt verkregen uit OpenPrinter(), die ook een voorbeeld van de voorbeeldcode. OpenPrinter() is de naam van een printer, gewoonlijk de beschrijvende naam van de printer is zoals deze wordt weergegeven in de shell van het besturingssysteem vereist. Deze naam kan worden opgehaald uit de EnumPrinters(), de structuur DEVNAMES die is geretourneerd door PrintDlg()of de standaardprinter.

Voor meer informatie over de printer, klikt u op het volgende artikelnummer om het artikel in de Microsoft Knowledge Base:

Het 246772 voor het ophalen en instellen van de Printer in Windows
Opmerking: In dit artikel wordt de eerste twee stappen van de juiste grootte van de buffer toewijzen en het initialiseren van de buffer die worden uitgevoerd met DocumentProperties(). U kunt deze stappen ook volgen via GetPrinter(). Klik op het onderstaande artikelnummer om het artikel in de Microsoft Knowledge Base voor meer informatie en een voorbeeld:

140285 hoe u printerinstellingen wijzigen met behulp van SetPrinter

Voorbeeld van Code

De voorbeeldcode volgt deze drie stappen voor het verkrijgen en het wijzigen van de DEVMODE-buffer. De functie heeft een printer met de naam en configureert u een DEVMODE dubbelzijdig en de afdrukstand Liggend afdrukken als deze functies ondersteunt. De resulterende DEVMODE die wordt geretourneerd naar de aanroeper is geschikt voor andere API-aanroepen die DEVMODE buffers, zoals CreateDC(), SetPrinter(), PrintDlg()of ResetDC()gebruiken. Als de beller is voltooid met behulp van de DEVMODE-buffer, is de beller verantwoordelijk voor het geheugen wordt vrijgemaakt.

   LPDEVMODE GetLandscapeDevMode(HWND hWnd, char *pDevice)
{

HANDLE hPrinter;
LPDEVMODE pDevMode;
DWORD dwNeeded, dwRet;

/* Start by opening the printer */
if (!OpenPrinter(pDevice, &hPrinter, NULL))
return NULL;

/*
* Step 1:
* Allocate a buffer of the correct size.
*/
dwNeeded = DocumentProperties(hWnd,
hPrinter, /* Handle to our printer. */
pDevice, /* Name of the printer. */
NULL, /* Asking for size, so */
NULL, /* these are not used. */
0); /* Zero returns buffer size. */
pDevMode = (LPDEVMODE)malloc(dwNeeded);

/*
* Step 2:
* Get the default DevMode for the printer and
* modify it for your needs.
*/
dwRet = DocumentProperties(hWnd,
hPrinter,
pDevice,
pDevMode, /* The address of the buffer to fill. */
NULL, /* Not using the input buffer. */
DM_OUT_BUFFER); /* Have the output buffer filled. */
if (dwRet != IDOK)
{
/* If failure, cleanup and return failure. */
free(pDevMode);
ClosePrinter(hPrinter);
return NULL;
}

/*
* Make changes to the DevMode which are supported.
*/
if (pDevMode->dmFields & DM_ORIENTATION)
{
/* If the printer supports paper orientation, set it.*/
pDevMode->dmOrientation = DMORIENT_LANDSCAPE;
}

if (pDevMode->dmFields & DM_DUPLEX)
{
/* If it supports duplex printing, use it. */
pDevMode->dmDuplex = DMDUP_HORIZONTAL;
}

/*
* Step 3:
* Merge the new settings with the old.
* This gives the driver an opportunity to update any private
* portions of the DevMode structure.
*/
dwRet = DocumentProperties(hWnd,
hPrinter,
pDevice,
pDevMode, /* Reuse our buffer for output. */
pDevMode, /* Pass the driver our changes. */
DM_IN_BUFFER | /* Commands to Merge our changes and */
DM_OUT_BUFFER); /* write the result. */

/* Finished with the printer */
ClosePrinter(hPrinter);

if (dwRet != IDOK)
{
/* If failure, cleanup and return failure. */
free(pDevMode);
return NULL;
}

/* Return the modified DevMode structure. */
return pDevMode;

}