Comment faire pour modifier les paramètres de l’imprimante avec la fonction DocumentProperties()


Résumé


Pour modifier les paramètres de l’imprimante à l’aide d’une structure DEVMODE est plus difficile que tout changement des champs de la structure. En particulier, une structure DEVMODE valide pour un périphérique contient des données privées qui ne peuvent être modifiées par la fonction DocumentProperties() .

Cet article explique comment modifier le contenu d’une structure DEVMODE avec la fonction DocumentProperties() .

Plus d'informations


Une structure DEVMODE , comme indiqué par le Kit de développement Win32 contienne public ou « données indépendantes du périphérique » et privé ou « périphérique dépendant des données ». La partie privée d’une structure DEVMODE existe qui suit immédiatement la partie publique, qui est définie par la structure DEVMODE , dans une mémoire tampon contiguë de mémoire.

Un programme ne peut pas prédire la taille de ce tampon car ils sont différents à partir de l’imprimante pour l’imprimante et à partir d’une version à une version de pilote d’imprimante. En outre, une structure DEVMODE qui est simplement déclarée par un programme ne contient-elle pas suffisamment d’espace pour les données de périphérique privé. Si une mémoire tampon DEVMODE qui ne dispose pas des données privées est passée à des fonctions telles que CreateDC(), ResetDC()et DocumentProperties(), la fonction peut échouer.

De manière fiable une structure DEVMODE avec un pilote de périphérique, créer et modifier en procédant comme suit :

  1. Déterminer la taille de la mémoire tampon à partir du périphérique et ensuite allouer suffisamment de mémoire pour lui.

    DocumentProperties() renvoie le nombre d’octets qui sont requises pour un tampon DEVMODE lorsque le dernier paramètre est défini sur 0. L’exemple de code dans cet article utilise cette technique pour déterminer la taille correcte de la mémoire tampon. L’exemple de code utilise ensuite la fonction d’allocation de mémoire d’exécution C de malloc() pour allouer un tampon suffisamment grande. Dans la mesure où DocumentProperties() et des fonctions telles que ResetDC() et CreateDC() des pointeurs vers une structure DEVMODE en tant que paramètre, la plupart des applications peuvent allouer de la mémoire qui est traitée par un pointeur.

    Cependant, des fonctions telles que le courant PrintDlg() prendre des paramètres qui sont nécessaires pour être des handles de mémoire globale. Si un programme utilise le dernier tampon DEVMODE en tant que paramètre à l’une de ces fonctions, il doit allouer de la mémoire à l’aide de GlobalAlloc() et obtenir un pointeur vers la mémoire tampon à l’aide de GlobalLock().
  2. Demandez le pilote de périphérique pour initialiser le tampon DEVMODE avec les paramètres par défaut.

    L’exemple de code appelle DocumentProperties() une seconde fois pour initialiser la mémoire tampon allouée avec les paramètres par défaut en cours. DocumentProperties() remplit la mémoire tampon désignée par le paramètre pDevModeOutput avec les paramètres actuels de l’imprimante lors de la commande DM_OUT_BUFFER est passée dans le paramètre fMode.
  3. Apporter des modifications à la partie publique de la structure DEVMODE et demandez le pilote de périphérique pour fusionner les modifications dans la partie privée de la structure DEVMODE en appelant DocumentProperties().

    Après l’initialisation de la mémoire tampon avec les paramètres actuels à l’étape 2, l’exemple de code modifie la partie publique de la structure DEVMODE. Consultez la documentation du SDK Win32 pour les descriptions des membres DEVMODE . Cet exemple de code détermine si l’imprimante peut utiliser des paramètres d’orientation et duplex (recto verso) et qu’il soit correctement modifiée.

    Remarque: un indicateur dans le membre d’une structure DEVMODE dmFields sert uniquement à indiquer qu’une imprimante utilise le membre de structure associée. Les imprimantes disposent des caractéristiques physiques différentes et, par conséquent, en charge uniquement un sous-ensemble des fonctions documentées d’une structure DEVMODE. Pour déterminer les paramètres de prise en charge du champ d’une structure DEVMODE, les applications doivent utiliser DeviceCapabilities ().



    L’exemple de code effectue une troisième appel vers DocumentProperties() , puis transmet la mémoire tampon DEVMODE dans les paramètres de le pDevModeInput et le pDevModeOutput. Il transmet également les commandes combinées de DM_IN_BUFFER et de DM_OUT_BUFFER dans le paramètre fMode à l’aide de l’opérateur OR("|"). Ces commandes indiquent à la fonction de prendre les paramètres contenus dans la mémoire tampon d’entrée et de les fusionner avec les paramètres actuels pour le périphérique. Puis, il écrit le résultat dans la mémoire tampon spécifiée dans le paramètre de sortie.
Remarque: DocumentProperties() fait référence à une imprimante spécifique par un handle vers une imprimante : hPrinter. Ce handle est obtenu à partir OpenPrinter(), dont l’exemple de code illustre également. OpenPrinter() requiert le nom d’une imprimante, qui est généralement le nom convivial de l’imprimante tel qu’il apparaît dans le shell du système d’exploitation. Ce nom peut être obtenu à partir de EnumPrinters(), de la structure DEVNAMES retourné par PrintDlg()ou à partir de l’imprimante par défaut.

Pour plus d'informations sur l'imprimante par défaut, cliquez sur le numéro ci-dessous pour afficher l'article correspondant dans la base de connaissances Microsoft :

246772 comment récupérer et définir l’imprimante par défaut dans Windows
Remarque: dans cet article, les deux premières étapes d’allouer la taille correcte de la mémoire tampon et de l’initialisation de cette mémoire tampon sont effectuées avec DocumentProperties(). Vous pouvez également suivre ces étapes à l’aide de GetPrinter(). Pour plus d’informations et un exemple, cliquez sur le numéro ci-dessous pour afficher l’article correspondant dans la Base de connaissances Microsoft :

140285 comment modifier les paramètres de l’imprimante à l’aide de SetPrinter

Exemple de Code

L’exemple de code suivant ces trois étapes pour l’obtention et la modification de la mémoire tampon DEVMODE. La fonction prend une imprimante nommée et configure une structure DEVMODE à imprimer recto-verso et dans l’orientation paysage si elle prend en charge ces fonctionnalités. La structure DEVMODE résultante qui est retournée à l’appelant est appropriée pour les autres appels d’API qui utilisent des mémoires tampons de DEVMODE, tels que CreateDC(), SetPrinter(), PrintDlg()ou ResetDC(). Lorsque l’appelant a effectué à l’aide de la mémoire tampon DEVMODE, l’appelant est responsable de la libération de la mémoire.

   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;

}