2009-03-24 7 views
0

J'ai une ancienne application dont j'ai besoin pour imprimer en mode paysage. La documentation que j'ai trouvé dit avoir une structure DEVMODE, changer quelques champs, et le mettre dans ce que j'ai est:.Impression Win32 - impossible de définir le mode paysage

HANDLE printer_handle; 
    LPHANDLE printer_handle_pointer(&printer_handle); 
    OpenPrinter(printer_name.get(), printer_handle_pointer, NULL); 
    size_t devmode_size = DocumentProperties(hWnd, printer_handle_pointer, printer_name.get(), NULL, NULL, 0); 
    DEVMODE * devmode = reinterpret_cast<DEVMODE *>(new char[devmode_size]); 
    DocumentProperties(NULL, printer_handle_pointer, printer_name.get(), devmode, NULL, DM_OUT_BUFFER); 
    devmode->dmSize = sizeof(DEVMODE); 
    devmode->dmFields |= DM_ORIENTATION; 
    devmode->dmOrientation = DMORIENT_LANDSCAPE; 
    DocumentProperties(NULL, printer_handle_pointer, printer_name.get(), devmode, devmode, DM_IN_BUFFER | DM_OUT_BUFFER); 
    hdcPrint = CreateDC(NULL, printer_name.get(), NULL, devmode); 

Mon problème actuel est que les premiers PropriétésDocument (celui qui renvoie la taille de la structure DEVMODE) renvoie -1 (en fait l'équivalent non signé), ce qui signifie une condition d'erreur. Cela se produit en mode Debug et Release (un rapport que j'ai vu sur le web a rencontré ce problème dans Debug mais pas Release). Le printer_name.get() est valide, mais je ne sais pas comment vérifier le hWnd ou printer_handle_pointer pour l'exactitude dans le débogueur. Donc, j'aimerais que quelqu'un me dise ce que je fais de mal, ou comment le diagnostiquer mieux, ou comment savoir si les poignées sont valides et indiquent des informations valides, j'apprécierais . J'utilise VS 2008SP1 sur Vista Business SP1, si cela fait une différence. L'application originale a été écrite avec une version antérieure de VS sur une version de XP.

Répondre

2

Avez-vous posté le vrai code?

Aussi, jetez un oeil à la signature de la fonction DocumentProperties:

LONG DocumentProperties(
    __in HWND hWnd, 
    __in HANDLE hPrinter,   
    __in LPTSTR pDeviceName, 
    __out PDEVMODE pDevModeOutput, 
    __in PDEVMODE pDevModeInput, 
    __in DWORD fMode 

Le troisième paramètre prend un HANDLE et non un pointeur vers une HANDLE (ou LPHANDLE) que vous avez dans votre code:

DocumentProperties(NULL, 
        printer_handle_pointer, /* <--- ? */ 
        printer_name.get(), 
        devmode, 
        NULL, 
        DM_OUT_BUFFER); 

Utilisez plutôt:

DocumentProperties(NULL, 
        printer_handle, /* <--- ? */ 
        printer_name.get(), 
        devmode, 
        NULL, 
        DM_OUT_BUFFER); 

Jetez un oeil à this exemple de code à modifier Devmode en utilisant la fonction DocumentProperties.

J'utilise généralement GetPrinterW pour obtenir une structure PRINTER_INFO_2W. Le membre pDevMode vous renvoie le devmode. J'ai eu de la chance en utilisant ce devmode.

+0

Merci pour le pointeur, mais la technique GetPrinter() n'a pas fonctionné mieux pour moi. –

+0

Merci beaucoup. Ça l'a cloué. –

2

De la documentation Microsoft pour DocumentProperties:

Pour modifier les paramètres d'impression qui sont locaux à une application, une application doit procédez comme suit:

  1. Obtenez le nombre d'octets requis pour la structure complète DEVMODE en appelant DocumentProperties et en spécifiant zéro dans le paramètre fMode.
  2. Allouer de la mémoire pour la structure DEVMODE complète.
  3. Obtenez les paramètres d'imprimante en cours en appelant DocumentProperties. Passez un pointeur vers la structure DEVMODE allouée à l'étape 2 en tant que paramètre pDevModeOutput et spécifiez la valeur DM_OUT_BUFFER.
  4. Modifiez les membres appropriés de la structure DEVMODE renvoyée et indiquez les membres qui ont été modifiés en définissant les bits correspondants dans le membre dmFields du DEVMODE.
  5. Appelez DocumentProperties et transmettez la structure DEVMODE modifiée en tant que paramètres pDevModeInput et pDevModeOutput et spécifiez les valeurs DM_IN_BUFFER et DM_OUT_BUFFER (qui sont combinées à l'aide de l'opérateur OR). La structure DEVMODE renvoyée par le troisième appel de DocumentProperties peut être utilisée en tant qu'argument dans un appel à la fonction CreateDC.

Il semble que vous étape manquante 1, qui peut être la raison pour laquelle votre premier appel à PropriétésDocument échoue.

Dans mon propre programme, je définis également la taille de la page, la longueur et la largeur de permutation. C'est pour une petite imprimante d'étiquettes spéciale avec un format de papier personnalisé cependant, je ne sais pas si une imprimante plus de variété de jardin aurait besoin de cela.

double width = 8.5; 
double height = 11.0; 
devmode.dmFields = DM_ORIENTATION | DM_PAPERSIZE | DM_PAPERLENGTH | DM_PAPERWIDTH; 
devmode.dmOrientation = DMORIENT_LANDSCAPE; 
devmode.dmPaperSize = DMPAPER_USER; 
devmode.dmPaperLength = (short)(width * 25.4 * 10); 
devmode.dmPaperWidth = (short)(height * 25.4 * 10); 
+0

En fait, j'ai l'étape 1 là (la ligne commence "size_t devmode_size"), et le problème est que devmode_size (la valeur retournée) n'est pas exacte. J'étais apparemment pas clair. –

+0

J'ai légèrement changé la question, pour le rendre plus clair. J'espère que cela t'aides. –

+0

Mon mauvais, j'ai besoin de lire un peu mieux. –

Questions connexes