FAQ VC++ et MFCConsultez toutes les FAQ
Nombre d'auteurs : 20, nombre de questions : 545, dernière mise à jour : 5 avril 2013 Ajouter une question
Cette faq a été réalisée pour répondre aux questions les plus fréquement posées sur le forum Développement Visual C++
Je tiens à souligner que cette faq ne garantit en aucun cas que les informations qu'elle contient sont correctes ; Les auteurs font le maximum, mais l'erreur est humaine. Si vous trouvez une erreur, ou si vous souhaitez devenir redacteur, lisez ceci.
Sur ce, je vous souhaite une bonne lecture. Farscape
Le principe :
On commence par récupérer le nombre d'imprimante avec EnumPrinters
On alloue un tableau de type PRINTER_INFO_2 pour recevoir les informations et on appelle à nouveau EnumPrinters pour le remplir.
Si on veut récupérer d'autres informations comme le réglage papier par exemple on continuera comme suit :
Ensuite on itère le tableau et pour chaque nom d'imprimante on obtient un handle sur l'imprimante, et enfin un pointeur sur la structure DEVMODE.
Notez que pour la plupart de ces fonctions, un premier appel permet de récupérer la taille de la structure à allouer avant d'effectuer l'appel final…
L'exemple ci-dessus remplit une CCombobox des imprimantes trouvées avec l'indication du format papier (à compléter pour les autres formats).
Code c++ : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | int GetPrinterList(CComboBox *pCombo) { PRINTER_INFO_2* list; DWORD cnt = 0; DWORD sz = 0; int i; int sl; EnumPrinters( PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &sz, &cnt ); if ( (list = (PRINTER_INFO_2*) malloc( sz )) == 0 ) return 0; if (!EnumPrinters( PRINTER_ENUM_LOCAL, NULL, 2, (LPBYTE)list, sz, &sz, &cnt)) { free( list ); return 0; } CString str,strSize; HANDLE hDriver; for ( i = 0, sl = 0; i < (int)cnt; i++ ) { // load printer driver if(!OpenPrinter(list[i].pPrinterName,&hDriver,NULL)) continue; if(!hDriver) continue; DWORD dwBufSize = 0; LPDEVMODE lpDM; // get DEVMODE stuff from driver dwBufSize =DocumentProperties( NULL, (HANDLE)hDriver, (LPSTR)list[i].pPrinterName, (LPDEVMODE)NULL, (LPDEVMODE)NULL, (DWORD) 0); // alloc space for devmode stuff HANDLE hDevMode= GlobalAlloc(GMEM_MOVEABLE, dwBufSize); lpDM = (LPDEVMODE)GlobalLock(hDevMode); dwBufSize =DocumentProperties(NULL, (HANDLE)hDriver, (LPSTR)list[i].pPrinterName, (LPDEVMODE)lpDM, (LPDEVMODE)NULL, (DWORD)DM_COPY); strSize="Autre"; // a faire ... if(lpDM->dmPaperSize==DMPAPER_A4 ) strSize="A4"; ClosePrinter(hDriver); ::GlobalFree(hDevMode); str=list[i].pPrinterName; str+=" "; str+=strSize; pCombo->AddString(str); } free( list ); return cnt; } |
L'imprimante matricielle étant l'utilisation type:
Code c++ : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | HANDLE HandlePrinter=NULL; bool OpenPrinterDirect(char* szPrinterName, char* szDocName) { DOC_INFO_1 di; di.pDocName = szDocName; di.pOutputFile = NULL; di.pDatatype = "RAW"; if ( !OpenPrinter(szPrinterName, &HandlePrinter, NULL ) ) return false; if ( StartDocPrinter( HandlePrinter, 1, (LPBYTE)&di ) == 0 ) return false; if ( !StartPagePrinter( HandlePrinter ) ) return false; return true; } bool ClosePrinterDirect() { if ( !EndPagePrinter(HandlePrinter ) )return false; if ( !EndDocPrinter(HandlePrinter) )return false; if ( !ClosePrinter(HandlePrinter) )return false; HandlePrinter=NULL; return true; } BOOL WritePrinterString(const char *sz) { DWORD bw; return WritePrinter(HandlePrinter, (void*)sz,strlen(sz),&bw); } if(OpenPrinterDirect(“Brother”,”TestsDocument”)) { WritePrinterString(“essai d'impressio\n”); ClosePrinterDirect(); } |
Il est parfois utile de pouvoir changer l'imprimante par défaut Windows par programme.
Exemple concret : Je veux pouvoir lancer l'impression d'un document Word sur une imprimante pdf par une commande ShellExecute, le problème étant alors de spécifier l'imprimante de traitement à Word.
Depuis Windows 2000 on dispose d'une api Windows spécifique pour ce réglage: SetDefaultPrinter.
Si je reprends mon exemple précédent je procèderais comme suit :
Code c++ : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | #include <winspool.h> bool PrintDocument(const TCHAR *szDocument,const TCHAR *szPrinterName) { TCHAR szPrinterOld[256]; // sauvegarde de l'imprimante par défaut initiale DWORD n=sizeof(szPrinterOld)/sizeof(TCHAR); ::GetDefaultPrinter(szPrinterOld,&n); // fixe la nouvelle imprimante if(!::SetDefaultPrinter(szPrinterName)) return false; // appel l'application appropriée pour l'impression du document. HINSTANCE nerror; if((nerror=::ShellExecute(AfxGetMainWnd()->m_hWnd,_T("print"), szDocument, NULL, NULL,SW_HIDE))<=(HINSTANCE)32) { CString mess; mess.Format(_T("Impossible d'imprimer le Document:\n%s Erreur n°:"),szDocument,nerror); AfxMessageBox(mess,MB_ICONEXCLAMATION); } // restitue l'imprimante par défaut. ::SetDefaultPrinter(szPrinterOld); // renvoie true si ok return (nerror >(HINSTANCE)32); } // utilisation: PrintDocument(_T("C:\\testdoc.docx"),_T("GhostScript Pdf Writer")); |
Proposer une nouvelle réponse sur la FAQ
Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour çaLes sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2024 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.