Modifier les paramètres de l’imprimante avec la fonction DocumentProperties()

Cet article explique comment modifier les paramètres de l’imprimante avec la DocumentProperties() fonction .

Version d’origine du produit : Imprimante
Numéro de la base de connaissances d’origine : 167345

Résumé

L’utilisation d’une structure DEVMODE pour modifier les paramètres de l’imprimante est plus difficile que la simple modification des champs de la structure. Plus précisément, une structure DEVMODE valide pour un appareil contient des données privées qui ne peuvent être modifiées que par la DocumentProperties() fonction .

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

Plus d’informations

Une structure DEVMODE, telle que documentée par le Kit de développement logiciel (SDK) Win32, contient des « données indépendantes de l’appareil » et privées ou « données dépendantes de l’appareil ». La partie privée d’un DEVMODE existe immédiatement après 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 cette mémoire tampon, car elle est différente d’une imprimante à l’autre et d’une version à une version du pilote d’imprimante. En outre, une structure DEVMODE déclarée par un programme ne contient pas suffisamment d’espace pour les données d’appareil privé. Si une mémoire tampon DEVMODE dépourvue de données privées est passée à des fonctions telles que CreateDC(), ResetDC()et DocumentProperties(), la fonction peut échouer.

Pour utiliser de manière fiable un DEVMODE avec un pilote de périphérique, créez-le et modifiez-le en procédant comme suit :

  1. Déterminez la taille requise de la mémoire tampon à partir de l’appareil, puis allouez suffisamment de mémoire pour celle-ci.

    DocumentProperties() retourne le nombre d’octets requis pour une mémoire tampon DEVMODE lorsque le dernier paramètre est défini sur 0. L’exemple de code de 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 au moment de l’exécution C de malloc() pour allouer une mémoire tampon suffisamment grande. Étant donné que DocumentProperties() et fonctionnent comme ResetDC() et CreateDC() prennent des pointeurs vers un DEVMODE en tant que paramètre, la plupart des applications peuvent allouer de la mémoire qui est traitée par un pointeur.

    Toutefois, des fonctions telles que les paramètres courants PrintDlg() take qui doivent être gérés en mémoire globale. Si un programme utilise la mémoire tampon DEVMODE finale comme paramètre pour l’une de ces fonctions, il doit allouer de la mémoire à l’aide GlobalAlloc() de et obtenir un pointeur vers la mémoire tampon à l’aide GlobalLock()de .

  2. Demandez au pilote de périphérique d’initialiser la mémoire tampon DEVMODE avec les paramètres par défaut.

    L’exemple de code appelle DocumentProperties() une deuxième fois pour initialiser la mémoire tampon allouée avec les paramètres par défaut actuels. DocumentProperties() remplit la mémoire tampon appelée paramètre pDevModeOutput avec les paramètres actuels de l’imprimante lorsque la DM_OUT_BUFFER commande est passée dans le paramètre fMode.

  3. Apportez des modifications à la partie publique du DEVMODE et demandez au pilote de périphérique de fusionner les modifications dans la partie privée du DEVMODE en appelant DocumentProperties().

    Après avoir initialisé la mémoire tampon avec les paramètres actuels à l’étape 2, l’exemple de code apporte des modifications à la partie publique du DEVMODE. Consultez la documentation du Kit de développement logiciel (SDK) Win32 pour obtenir une description des membres DEVMODE. Cet exemple de code détermine si l’imprimante peut utiliser les paramètres d’orientation et duplex (recto verso) et les modifie de manière appropriée.

    Remarque

    Un indicateur dans le membre dmFields d’un DEVMODE est uniquement une indication qu’une imprimante utilise le membre de structure associé. Les imprimantes ont différentes caractéristiques physiques et, par conséquent, ne peuvent prendre en charge qu’un sous-ensemble des fonctionnalités documentées d’un DEVMODE. Pour déterminer les paramètres pris en charge du champ d’un DEVMODE, les applications doivent utiliser DeviceCapabilities().

    L’exemple de code effectue ensuite un troisième appel à DocumentProperties() et passe la mémoire tampon DEVMODE dans les paramètres pDevModeInput et pDevModeOutput. Il transmet également les commandes combinées de DM_IN_BUFFER et DM_OUT_BUFFER dans le paramètre fMode à l’aide de l’opérateur OR(« | »). Ces commandes indiquent à la fonction d’accepter les paramètres contenus dans la mémoire tampon d’entrée et de les fusionner avec les paramètres actuels de l’appareil. Ensuite, il écrit le résultat dans la mémoire tampon spécifiée dans le paramètre out.

Remarque

DocumentProperties() fait référence à une imprimante spécifique par un handle à une imprimante : hPrinter. Ce handle est obtenu à partir de OpenPrinter(), ce que l’exemple de code illustre également. OpenPrinter() nécessite le nom d’une imprimante, qui est généralement le nom convivial de l’imprimante tel qu’il apparaît dans l’interpréteur de commandes du système d’exploitation. Ce nom peut être obtenu à partir de EnumPrinters(), à partir de la structure DEVNAMES retournée par PrintDlg(), ou à partir de l’imprimante par défaut.

Dans cet article, les deux premières étapes de l’allocation de 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, consultez Modifier les paramètres de l’imprimante à l’aide de la fonction SetPrinter.

Exemple de code

L’exemple de code suit ces trois étapes pour obtenir et modifier la mémoire tampon DEVMODE. La fonction prend une imprimante nommée et configure un DEVMODE pour imprimer recto verso et dans l’orientation paysage si elle prend en charge ces fonctionnalités. Le DEVMODE obtenu retourné à l’appelant convient aux autres appels d’API qui utilisent des mémoires tampons DEVMODE, telles que CreateDC(), SetPrinter(), PrintDlg()ou ResetDC(). Lorsque l’appelant a terminé l’utilisation de la mémoire tampon DEVMODE, l’appelant est chargé de libérer 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;
}