begin process at 2012 05 27 19:59:56
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

API

 > IMPRESSION EN WIN32 API AVEC OPTIONS

IMPRESSION EN WIN32 API AVEC OPTIONS


 Information sur la source

Note :
9 / 10 - par 2 personnes
9,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
Catégorie :API Niveau :Débutant Date de création :11/10/2009 Vu / téléchargé :4 325 / 301

Auteur : racpp

Ecrire un message privé
Commentaire sur cette source (8)
Ajouter un commentaire et/ou une note

 Description

Cliquez pour voir la capture en taille normale
Vu le très peu de codes sources traitant de l'impression sur le site, et en réponse à certaines questions du forum, voici un petit projet montrant comment définir les options d'impression avant de lancer le tirage sur papier. Ce petit programme permet de définir les options suivantes:
- Choisir l'imprimante à utiliser.
- Choisir le format de papier pour l'imprimante choisie.
- Choisir entre l'impression en couleur ou en noir et blanc pour les imprimantes couleur.
- Choisir la qualité d'impression.
- Choisir le mode d'impression portrait ou paysage.
- Choisir le nombre de copies.
A noter que ces options sont applicables seulement pendant l'impression du document en cours pour notre application. Ce qui présente l'avantage de ne pas toucher aux paramètres de l'imprimante. La boite de dialogue commune PrintDlg n'est pas utilisée afin de communiquer directement avec le spooler. Le code récupère la structure DEVMODE associée à une imprimante grâce à la fonction DocumentProperties(). Il suffit de modifier certains membres de cette strucure pour définir les options voulues. Elle sera ensuite passée en dernier paramètre à la fonction CreateDC(). Cette dernière retourne le HDC de l'imprimante permettant ainsi d'écrire ou de dessiner dessus.
Ce petit projet a été réalisé en C sous Visual C 2005. Etant en Win32 API, il est facilement adaptable aux autres outils.
Pour tester directement l'exécutable figurant dans le dossier Release, renommez le en impression.exe
Ce programme a été testé sans problème sous XP et Vista.
Toutes les questions, commentaires ou remarques sont les bienvenus.

Source

  • #include <windows.h>
  • #include <commctrl.h>
  • #pragma comment(lib,"comctl32.lib")
  • #define EDIT_COPIES 1001 // Identificateur de l'Edit du nombre de copies
  • BOOL CALLBACK ImpressionProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  • {
  • static HWND hsImprimante,hsPapier,hsCouleur,hsQualite,hsMode,hsCopies;
  • static HWND hradioPortrait,hradioPaysage,hudCopies,heCopies,hbImprimer;
  • static HWND hcomboImprimantes,hcomboPapier,hcomboQualite,hcheckCouleur;
  • static HBRUSH hbrFond;
  • static UINT nmaxcopies;
  • static HICON hicon;
  • static char buffer[260];
  • static char* szqualite[]={"Meilleure","Moyenne","Basse","Brouillon"};
  • switch (message)
  • {
  • case WM_INITDIALOG:
  • {
  • BOOL bret;
  • UINT i;
  • DWORD dwneeded=0;
  • DWORD dwreturned=0;
  • HFONT guifont;
  • HWND hwndchild=0;
  • // Charger l'icone depuis les ressources et l'appliquer à notre boite de dialogue:
  • hicon=(HICON)LoadImage(GetModuleHandle(0),"IDI_00",IMAGE_ICON,16,16,0);
  • SendMessage(hwnd,WM_SETICON,0,(LPARAM)hicon);
  • // Mettre le texte de la barre de titre:
  • SetWindowText(hwnd," Impression en Win32 avec options");
  • // Créer un brush pour la couleur du fond de la boite:
  • hbrFond=CreateSolidBrush(RGB(124,164,224));
  • // Créer les controles:
  • hsImprimante=CreateWindowEx(0,"static","Imprimante : ",WS_CHILD | WS_VISIBLE | SS_RIGHT ,20,22,80,20,hwnd,0,0,0);
  • hsPapier=CreateWindowEx(0,"static","Papier : ",WS_CHILD | WS_VISIBLE | SS_RIGHT ,20,62,80,20,hwnd,0,0,0);
  • hsCouleur=CreateWindowEx(0,"static","Couleur : ",WS_CHILD | WS_VISIBLE | SS_RIGHT,20,102,80,20,hwnd,0,0,0);
  • hsQualite=CreateWindowEx(0,"static","Qualité : ",WS_CHILD | WS_VISIBLE | SS_RIGHT ,20,142,80,20,hwnd,0,0,0);
  • hsMode=CreateWindowEx(0,"static","Mode : ",WS_CHILD | WS_VISIBLE | SS_RIGHT,20,182,80,20,hwnd,0,0,0);
  • hsCopies=CreateWindowEx(0,"static","Copies : ",WS_CHILD | WS_VISIBLE | SS_RIGHT,20,222,80,20,hwnd,0,0,0);
  • hcomboImprimantes=CreateWindowEx(WS_EX_CLIENTEDGE ,"combobox",0,WS_CHILD | WS_VISIBLE | WS_VSCROLL| CBS_DROPDOWNLIST | WS_TABSTOP,100,20,250,300,hwnd,0,0,0);
  • hcomboPapier=CreateWindowEx(WS_EX_CLIENTEDGE ,"combobox",0,WS_CHILD | WS_VISIBLE | WS_VSCROLL| CBS_DROPDOWNLIST | WS_TABSTOP,100,60,250,250,hwnd,0,0,0);
  • hcheckCouleur=CreateWindowEx(0,"button","Oui",WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX | WS_TABSTOP,100,100,60,20,hwnd,0,0,0);
  • hcomboQualite=CreateWindowEx(WS_EX_CLIENTEDGE ,"combobox",0,WS_CHILD | WS_VISIBLE | WS_VSCROLL| CBS_DROPDOWNLIST | WS_TABSTOP,100,140,100,500,hwnd,0,0,0);
  • hradioPortrait=CreateWindowEx(0,"button","Portrait",WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON | WS_TABSTOP,100,180,60,20,hwnd,0,0,0);
  • hradioPaysage=CreateWindowEx(0,"button","Paysage",WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON | WS_TABSTOP,180,180,60,20,hwnd,0,0,0);
  • heCopies=CreateWindowEx(WS_EX_CLIENTEDGE,TEXT("edit"),"1",WS_CHILD | WS_VISIBLE | ES_NUMBER | ES_CENTER | WS_TABSTOP,100,220,70,20,hwnd,(HMENU)EDIT_COPIES,0,0);
  • hudCopies=CreateWindowEx(0,UPDOWN_CLASS,0,WS_CHILD | WS_VISIBLE | UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_ARROWKEYS,0,0,20,20,hwnd,0,0,0);
  • hbImprimer=CreateWindowEx(0,"button","Imprimer la page de test",WS_CHILD | WS_VISIBLE | WS_DISABLED | WS_TABSTOP,120,280,160,20,hwnd,0,0,0);
  • // Attacher notre controle UpDown à l'Edit du nombre de copies:
  • SendMessage(hudCopies,UDM_SETBUDDY ,(WPARAM)heCopies,0);
  • // Obtenir la police par défaut des boites de dialogue:
  • guifont=(HFONT)GetStockObject(DEFAULT_GUI_FONT);
  • //Appliquer cette police à tous les controles:
  • while(hwndchild=FindWindowEx(hwnd,hwndchild,0,0)) SendMessage(hwndchild,WM_SETFONT,(WPARAM)guifont,0);
  • // Déterminer la quatité de mémoire nécessaire pour charger les noms des imprimantes installées:
  • bret=EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS,NULL,4,0,0,&dwneeded,&dwreturned);
  • // Vérifier que bret est null. dwneeded contient la quantité de mémoire requise:
  • if(!bret && dwneeded)
  • {
  • // Allouer la quantité de mémoire requise:
  • PRINTER_INFO_4 *ppi=(PRINTER_INFO_4*)GlobalAlloc(GPTR,dwneeded);
  • if(ppi)// mémoire allouée avec succès
  • {
  • // Remplir notre mémoire avec les infos sur les imprimantes installées:
  • bret=EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS,NULL,4,(PBYTE)ppi,dwneeded,&dwneeded,&dwreturned);
  • // Activer le combobox des imprimantes si au moins une a été trouvée:
  • EnableWindow(hcomboImprimantes,dwreturned);
  • // Remplir le combobox avec les noms des imprimantes trouvées:
  • for(i=0;i<dwreturned;i++) SendMessage(hcomboImprimantes,CB_ADDSTRING,0,(LPARAM)ppi[i].pPrinterName);
  • // Selectionner l'imprimante par défaut si des imprimantes ont été trouvées:
  • if(dwreturned)SendMessage(hcomboImprimantes,CB_SETCURSEL,0,(LPARAM)0);
  • GlobalFree(ppi);
  • }
  • }
  • // Remplir le combobox des qualités d'impression:
  • for(i=0;i<4;i++) SendMessage(hcomboQualite,CB_ADDSTRING,0,(LPARAM)szqualite[i]);
  • // Simuler changement de sélection du combo des imprimantes pour forcer l'initialisation des autres controles:
  • SendMessage(hwnd,WM_COMMAND,MAKEWPARAM(0,CBN_SELCHANGE),(LPARAM)hcomboImprimantes);
  • //Simulation de l'appui sur la touche ALT pour permettre l'affichage du rectangle de focus sur les controles:
  • keybd_event(VK_MENU,0,0,0);
  • keybd_event(VK_MENU,0,KEYEVENTF_KEYUP,0);
  • // Rendre notre boite active suite à la simulation d'appui sur la touche ALT:
  • SetForegroundWindow(hwnd);
  • }
  • break;
  • case WM_CTLCOLORDLG:
  • // Appliquer la couleur du fond de notre boite de dialogue:
  • return (BOOL)hbrFond;
  • case WM_CTLCOLORSTATIC:
  • // Rendre le fond des statics, radios et checkboxes transparent:
  • SetBkMode((HDC)wParam,TRANSPARENT);
  • // Leur appliquer la couleur de fond:
  • return (BOOL)hbrFond;
  • case WM_COMMAND:
  • if(HIWORD(wParam)==EN_CHANGE)
  • {
  • BOOL b1,b2,b3;
  • UINT copies;
  • // S'assurer que le contenu des controles est valide:
  • b1=SendMessage(hcomboImprimantes,CB_GETCURSEL,0,0)>=0;
  • b2=SendMessage(hcomboPapier,CB_GETCURSEL,0,0)>=0;
  • copies=GetDlgItemInt(hwnd,EDIT_COPIES,0,0);
  • b3=copies>0 && copies<=nmaxcopies;
  • // Griser ou dégriser le bouton d'impression selon le cas:
  • EnableWindow(hbImprimer,b1 && b2 && b3);
  • return 0;
  • }
  • if(HIWORD(wParam)==CBN_SELCHANGE)
  • {
  • if((HWND)lParam==hcomboImprimantes)
  • {
  • DWORD dwreturned;
  • UINT i;
  • int cursel;
  • // Griser le bouton d'impression:
  • EnableWindow(hbImprimer,0);
  • // Vider le combobox contenant les formats de papier:
  • SendMessage(hcomboPapier,CB_RESETCONTENT,0,0);
  • // Initialiser les autres controles:
  • SendMessage(hcomboQualite,CB_SETCURSEL,0,0);
  • SendMessage(hradioPortrait,BM_SETCHECK,1,0);
  • SendMessage(hradioPaysage,BM_SETCHECK,0,0);
  • SendMessage(hcheckCouleur,BM_SETCHECK,0,0);
  • SetWindowText(heCopies,"1");
  • // Déterminer la sélection courante du combobox des imprimantes:
  • cursel=(int)SendMessage(hcomboImprimantes,CB_GETCURSEL,0,0);
  • // Récupérer le nom de l'imprimante sélectionnée:
  • SendMessage(hcomboImprimantes,CB_GETLBTEXT,cursel,(LPARAM)buffer);
  • // Obtenir le nombre de formats de papier pour l'imprimante sélectionnée:
  • dwreturned=DeviceCapabilities(buffer,0,DC_PAPERNAMES,0,0);
  • if(dwreturned)
  • {
  • // Allouer la quantité de mémoire requise pour les noms de formats de papiers:
  • char* pnames=(char*)GlobalAlloc(GPTR,dwreturned*64);
  • if(pnames)
  • {
  • // Récupérer les noms de formats de papier:
  • dwreturned=DeviceCapabilities(buffer,0,DC_PAPERNAMES,pnames,0);
  • // Remplir le combobox des formats de papiers:
  • for(i=0;i<dwreturned;i++)SendMessage(hcomboPapier,CB_ADDSTRING,0,(LPARAM)pnames+(i*64));
  • // Libérer la mémoire allouée:
  • GlobalFree(pnames);
  • }
  • }
  • // Déterminer le nombre maximal de copies autorisé par l'imprimante sélectionnée:
  • nmaxcopies=DeviceCapabilities(buffer,0,DC_COPIES,0,0);
  • // Appliquer ce nombre comme limite supérieure de notre controle UpDown:
  • SendMessage(hudCopies,UDM_SETRANGE ,0,MAKELONG(nmaxcopies,1));
  • // S'assurer que l'imprimante sélectionnée supporte le mode paysage:
  • dwreturned=DeviceCapabilities(buffer,0,DC_ORIENTATION,0,0);
  • // Griser ou dégriser le bouton radio paysage selon le cas:
  • EnableWindow(hradioPaysage,dwreturned);
  • //S'assurer que l'imprimante sélectionnée supporte la couleur:
  • dwreturned=DeviceCapabilities(buffer,0,DC_COLORDEVICE,0,0);
  • // Griser ou dégriser le checkbox couleur selon le cas:
  • EnableWindow(hcheckCouleur,dwreturned);
  • // Rendre le checkbox couleur coché par défaut si la couleur est supportée:
  • SendMessage(hcheckCouleur,BM_SETCHECK,dwreturned,0);
  • }
  • // Simuler un chagement dans un Edit pour actualiser l'état du bouton d'impression:
  • SendMessage(hwnd,WM_COMMAND,MAKEWPARAM(0,EN_CHANGE),(LPARAM)0);
  • return 0;
  • }
  • if((HWND)lParam==hbImprimer)
  • {
  • BOOL bret;
  • HANDLE hprinter;
  • int cursel;
  • // Déterminer la sélection courante du combobox des imprimantes:
  • cursel=(int)SendMessage(hcomboImprimantes,CB_GETCURSEL,0,0);
  • // Récupérer le nom de l'imprimante sélectionnée:
  • SendMessage(hcomboImprimantes,CB_GETLBTEXT,cursel,(LPARAM)buffer);
  • // Ouvrir l'imprimante sélectionnée:
  • bret=OpenPrinter(buffer,&hprinter,0);
  • if(bret)
  • {
  • DEVMODE* dvm;
  • DWORD dwRet;
  • BOOL bcheck;
  • RECT rect;
  • HDC pDC;
  • DOCINFO di;
  • HFONT hpolice,oldfont;
  • HBRUSH oldbrush,hbrush;
  • int cursel,largeur,hauteur,taillepolice;
  • char szpapername[64];
  • // Obtenir la taille de la structure DEVMODE utilisée par cette imprimante:
  • dwRet = DocumentProperties( 0,hprinter, 0, 0,0, 0 );
  • //Allouer la mémoire nécessaire pour notre structure:
  • dvm=(DEVMODE*)GlobalAlloc(GPTR ,dwRet);
  • // Copier le contenu de la strcture DEVMODE de l'imprimante dans la notre:
  • dwRet = DocumentProperties( 0,hprinter,buffer, dvm, 0, DM_OUT_BUFFER);
  • // Obtenir l'état du checkbox paysage:
  • bcheck=(BOOL)SendMessage(hradioPaysage,BM_GETCHECK,0,0);
  • // Mettre la valeur correspondante dans le membre définissant l'orientation de l'impression:
  • if(bcheck)dvm->dmOrientation=DMORIENT_LANDSCAPE;
  • else dvm->dmOrientation=DMORIENT_PORTRAIT;
  • // Obtenir le nom du format de papier sélectionné:
  • cursel=(int)SendMessage(hcomboPapier,CB_GETCURSEL,0,0);
  • SendMessage(hcomboPapier,CB_GETLBTEXT,cursel,(LPARAM)szpapername);
  • // Limiter la longueur du nom à 31 pour compatibilité avec la structure DEVMODE:
  • if(lstrlen(szpapername)>31)szpapername[31]=0;
  • // Copier le nom du format dans le membre correspondant de la structure DEVMODE:
  • lstrcpy(dvm->dmFormName,szpapername);
  • // Récupérer et définir le nombre de copies à imprimer:
  • dvm->dmCopies=GetDlgItemInt(hwnd,EDIT_COPIES,0,0);
  • // Appliquer ou nom la couleur selon l'état du checkbox couleur:
  • if(SendMessage(hcheckCouleur,BM_GETCHECK,0,0))dvm->dmColor=DMCOLOR_COLOR;
  • else dvm->dmColor=DMCOLOR_MONOCHROME;
  • // Récupérer et définir la qualité d'impression:
  • dvm->dmPrintQuality=(short)SendMessage(hcomboQualite,CB_GETCURSEL,0,0)-4;
  • // Définir les membres à prendre en charge de notre structure DEVMODE:
  • dvm->dmFields= DM_FORMNAME | DM_ORIENTATION | DM_COPIES | DM_COLOR | DM_PRINTQUALITY;
  • // Fermer le handle de l'imprimante:
  • ClosePrinter(hprinter);
  • // Créer le HDC de l'imprimante en l'associant à notre structure DEVMODE:
  • pDC = CreateDC (0,buffer, 0, dvm) ;
  • // Initialiser les membres de la structure DOCINFO
  • memset(&di, 0, sizeof(DOCINFO));
  • di.cbSize = sizeof(DOCINFO);
  • di.lpszDocName = "RACPP Impression";
  • // Obtenir les dimensions de la zone imprimable:
  • largeur=GetDeviceCaps(pDC, HORZRES);
  • hauteur=GetDeviceCaps(pDC, VERTRES);
  • SetRect(&rect,0,0,largeur,hauteur);
  • // Calculer la taille de notre police selon le mode portrait ou paysage:
  • if(dvm->dmOrientation==DMORIENT_PORTRAIT)taillepolice=largeur/16;
  • else taillepolice=hauteur/16;
  • // Créer notre police:
  • hpolice=CreateFont(taillepolice,0,0,0,0,0,0,0,0,0,0,0,0,"Arial");
  • // Appliquer notre police:
  • oldfont=(HFONT)SelectObject(pDC,hpolice);
  • // Créer un brush de couleur jaune pour la coloriation des formes:
  • hbrush=CreateSolidBrush(RGB(255,255,0));
  • // Appliquer notre brush:
  • oldbrush=(HBRUSH)SelectObject(pDC,hbrush);
  • // Initialiser l'impression de notre document:
  • StartDoc(pDC, &di);
  • // Initialiser l'impression de notre page:
  • StartPage(pDC);
  • // Dessiner une ellipse jaune:
  • Ellipse(pDC,0,0,largeur,hauteur);
  • // Définir la couleur du texte à imprimer:
  • SetTextColor(pDC,RGB(0,0,255));
  • // Rendre le fond du texte transparent:
  • SetBkMode(pDC,TRANSPARENT);
  • // Ecrire le texte avec centrage horizontal et vertical:
  • DrawText(pDC,"Ceci est une page de test",-1,&rect,DT_SINGLELINE | DT_VCENTER | DT_CENTER);
  • // Lancer l'impression de la page:
  • EndPage(pDC);
  • // Fermer notre document:
  • EndDoc(pDC);
  • // Restaurer la police et le brush originaux de notre HDC de l'imprimante:
  • SelectObject(pDC,oldfont);
  • SelectObject(pDC,oldbrush);
  • // Détruire notre HDC de l'imprimante:
  • DeleteDC(pDC);
  • // Détruire notre police et notre brush:
  • DeleteObject(hbrush);
  • DeleteObject(hpolice);
  • // Libérer la mémoire allouée pour notre structure DEVMODE:
  • GlobalFree(dvm);
  • }
  • return 0;
  • }
  • break;
  • case WM_CLOSE:
  • // Fermer la boite de dialogue:
  • EndDialog(hwnd,0);
  • break;
  • case WM_DESTROY:
  • // Détruire le brush de la couleur de fond et notre icone:
  • DeleteObject(hbrFond);
  • DestroyIcon(hicon);
  • break;
  • default:
  • break;
  • }
  • return 0;
  • }
  • int APIENTRY WinMain(HINSTANCE hinst, HINSTANCE hprev, LPSTR szcmd, int ishow)
  • {
  • LPDLGTEMPLATE lpdt;
  • INITCOMMONCONTROLSEX icm;
  • icm.dwSize=sizeof(INITCOMMONCONTROLSEX);
  • icm.dwICC=ICC_UPDOWN_CLASS;
  • // Initialiser la librairie common controls pour le controle UpDown:
  • InitCommonControlsEx(&icm);
  • //Allouer de la mémoire pour notre dialog template:
  • lpdt = ( LPDLGTEMPLATE) GlobalAlloc(GPTR, 512);
  • // Définir les styles de la boite de dialogue:
  • lpdt->style = WS_DLGFRAME| DS_CENTER |WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
  • // Définir les dimensions de la boite de dialogue:
  • lpdt->cx = 200; lpdt->cy = 160;
  • //Lancer la boite de dialogue
  • DialogBoxIndirectParam(hinst,lpdt,0,(DLGPROC)ImpressionProc,0);
  • //Libération de la mémoire allouée:
  • GlobalFree((HGLOBAL)lpdt);
  • return 0;
  • }
#include <windows.h>
#include <commctrl.h>

#pragma comment(lib,"comctl32.lib")

#define EDIT_COPIES 1001 // Identificateur de l'Edit du nombre de copies

BOOL CALLBACK ImpressionProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	static HWND hsImprimante,hsPapier,hsCouleur,hsQualite,hsMode,hsCopies;
	static HWND hradioPortrait,hradioPaysage,hudCopies,heCopies,hbImprimer;
	static HWND hcomboImprimantes,hcomboPapier,hcomboQualite,hcheckCouleur;
	static HBRUSH hbrFond;
	static UINT nmaxcopies;
	static HICON hicon;
	static char buffer[260];
	static char* szqualite[]={"Meilleure","Moyenne","Basse","Brouillon"};
	switch (message)
	{
	case WM_INITDIALOG:
		{
			BOOL bret;
			UINT i;
			DWORD dwneeded=0;
			DWORD dwreturned=0;
			HFONT guifont;
			HWND hwndchild=0;
			// Charger l'icone depuis les ressources et l'appliquer à notre boite de dialogue:
			hicon=(HICON)LoadImage(GetModuleHandle(0),"IDI_00",IMAGE_ICON,16,16,0);
			SendMessage(hwnd,WM_SETICON,0,(LPARAM)hicon);
			// Mettre le texte de la barre de titre:
			SetWindowText(hwnd," Impression en Win32 avec options");
			// Créer un brush pour la couleur du fond de la boite:
			hbrFond=CreateSolidBrush(RGB(124,164,224));
			// Créer les controles:
			hsImprimante=CreateWindowEx(0,"static","Imprimante :  ",WS_CHILD | WS_VISIBLE | SS_RIGHT ,20,22,80,20,hwnd,0,0,0);
			hsPapier=CreateWindowEx(0,"static","Papier :  ",WS_CHILD | WS_VISIBLE | SS_RIGHT ,20,62,80,20,hwnd,0,0,0);
			hsCouleur=CreateWindowEx(0,"static","Couleur :  ",WS_CHILD | WS_VISIBLE  | SS_RIGHT,20,102,80,20,hwnd,0,0,0);
			hsQualite=CreateWindowEx(0,"static","Qualité :  ",WS_CHILD | WS_VISIBLE | SS_RIGHT ,20,142,80,20,hwnd,0,0,0);
			hsMode=CreateWindowEx(0,"static","Mode :  ",WS_CHILD | WS_VISIBLE  | SS_RIGHT,20,182,80,20,hwnd,0,0,0);
			hsCopies=CreateWindowEx(0,"static","Copies :  ",WS_CHILD | WS_VISIBLE  | SS_RIGHT,20,222,80,20,hwnd,0,0,0);
			hcomboImprimantes=CreateWindowEx(WS_EX_CLIENTEDGE ,"combobox",0,WS_CHILD | WS_VISIBLE  | WS_VSCROLL| CBS_DROPDOWNLIST | WS_TABSTOP,100,20,250,300,hwnd,0,0,0);
			hcomboPapier=CreateWindowEx(WS_EX_CLIENTEDGE ,"combobox",0,WS_CHILD | WS_VISIBLE  | WS_VSCROLL| CBS_DROPDOWNLIST | WS_TABSTOP,100,60,250,250,hwnd,0,0,0);
			hcheckCouleur=CreateWindowEx(0,"button","Oui",WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX | WS_TABSTOP,100,100,60,20,hwnd,0,0,0);
			hcomboQualite=CreateWindowEx(WS_EX_CLIENTEDGE ,"combobox",0,WS_CHILD | WS_VISIBLE  | WS_VSCROLL| CBS_DROPDOWNLIST | WS_TABSTOP,100,140,100,500,hwnd,0,0,0);
			hradioPortrait=CreateWindowEx(0,"button","Portrait",WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON | WS_TABSTOP,100,180,60,20,hwnd,0,0,0);
			hradioPaysage=CreateWindowEx(0,"button","Paysage",WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON | WS_TABSTOP,180,180,60,20,hwnd,0,0,0);
			heCopies=CreateWindowEx(WS_EX_CLIENTEDGE,TEXT("edit"),"1",WS_CHILD | WS_VISIBLE | ES_NUMBER | ES_CENTER | WS_TABSTOP,100,220,70,20,hwnd,(HMENU)EDIT_COPIES,0,0);
			hudCopies=CreateWindowEx(0,UPDOWN_CLASS,0,WS_CHILD | WS_VISIBLE | UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_ARROWKEYS,0,0,20,20,hwnd,0,0,0);
			hbImprimer=CreateWindowEx(0,"button","Imprimer la page de test",WS_CHILD | WS_VISIBLE | WS_DISABLED | WS_TABSTOP,120,280,160,20,hwnd,0,0,0);
			// Attacher notre controle UpDown à l'Edit du nombre de copies:
			SendMessage(hudCopies,UDM_SETBUDDY  ,(WPARAM)heCopies,0);
			// Obtenir la police par défaut des boites de dialogue:
			guifont=(HFONT)GetStockObject(DEFAULT_GUI_FONT);
			//Appliquer cette police à tous les controles:
			while(hwndchild=FindWindowEx(hwnd,hwndchild,0,0)) SendMessage(hwndchild,WM_SETFONT,(WPARAM)guifont,0);
			// Déterminer la quatité de mémoire nécessaire pour charger les noms des imprimantes installées:
			bret=EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS,NULL,4,0,0,&dwneeded,&dwreturned);
			// Vérifier que bret est null. dwneeded contient la quantité de mémoire requise:
			if(!bret && dwneeded)
			{
				// Allouer la quantité de mémoire requise:
				PRINTER_INFO_4 *ppi=(PRINTER_INFO_4*)GlobalAlloc(GPTR,dwneeded);
				if(ppi)// mémoire allouée avec succès
				{
					// Remplir notre mémoire avec les infos sur les imprimantes installées:
					bret=EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS,NULL,4,(PBYTE)ppi,dwneeded,&dwneeded,&dwreturned);
					// Activer le combobox des imprimantes si au moins une a été trouvée:
					EnableWindow(hcomboImprimantes,dwreturned);
					// Remplir le combobox avec les noms des imprimantes trouvées:
					for(i=0;i<dwreturned;i++) SendMessage(hcomboImprimantes,CB_ADDSTRING,0,(LPARAM)ppi[i].pPrinterName);
					// Selectionner l'imprimante par défaut si des imprimantes ont été trouvées:
					if(dwreturned)SendMessage(hcomboImprimantes,CB_SETCURSEL,0,(LPARAM)0);
					GlobalFree(ppi);
				}
			}
			// Remplir le combobox des qualités d'impression:
			for(i=0;i<4;i++) SendMessage(hcomboQualite,CB_ADDSTRING,0,(LPARAM)szqualite[i]);
			// Simuler changement de sélection du combo des imprimantes pour forcer l'initialisation des autres controles:
			SendMessage(hwnd,WM_COMMAND,MAKEWPARAM(0,CBN_SELCHANGE),(LPARAM)hcomboImprimantes);
			//Simulation de l'appui sur la touche ALT pour permettre l'affichage du rectangle de focus sur les controles:
			keybd_event(VK_MENU,0,0,0);
			keybd_event(VK_MENU,0,KEYEVENTF_KEYUP,0);
			// Rendre notre boite active suite à la simulation d'appui sur la touche ALT:
			SetForegroundWindow(hwnd);
		}
		break;

	case WM_CTLCOLORDLG:
		// Appliquer la couleur du fond de notre boite de dialogue:
		return (BOOL)hbrFond;

	case WM_CTLCOLORSTATIC:
		// Rendre le fond des statics, radios et checkboxes transparent:
		SetBkMode((HDC)wParam,TRANSPARENT);
		// Leur appliquer la couleur de fond:
		return (BOOL)hbrFond;

	case WM_COMMAND:
		if(HIWORD(wParam)==EN_CHANGE)
		{
			BOOL b1,b2,b3;
			UINT copies;
			// S'assurer que le contenu des controles est valide:
			b1=SendMessage(hcomboImprimantes,CB_GETCURSEL,0,0)>=0;
			b2=SendMessage(hcomboPapier,CB_GETCURSEL,0,0)>=0;
			copies=GetDlgItemInt(hwnd,EDIT_COPIES,0,0);
			b3=copies>0 && copies<=nmaxcopies;
			// Griser ou dégriser le bouton d'impression selon le cas:
			EnableWindow(hbImprimer,b1 && b2 && b3);
			return 0;
		}
		if(HIWORD(wParam)==CBN_SELCHANGE)
		{
			if((HWND)lParam==hcomboImprimantes)
			{
				DWORD dwreturned;
				UINT i;
				int cursel;
				// Griser le bouton d'impression:
				EnableWindow(hbImprimer,0);
				// Vider le combobox contenant les formats de papier:
				SendMessage(hcomboPapier,CB_RESETCONTENT,0,0);
				// Initialiser les autres controles:
				SendMessage(hcomboQualite,CB_SETCURSEL,0,0);
				SendMessage(hradioPortrait,BM_SETCHECK,1,0);
				SendMessage(hradioPaysage,BM_SETCHECK,0,0);
				SendMessage(hcheckCouleur,BM_SETCHECK,0,0);
				SetWindowText(heCopies,"1");
				// Déterminer la sélection courante du combobox des imprimantes:
				cursel=(int)SendMessage(hcomboImprimantes,CB_GETCURSEL,0,0);
				// Récupérer le nom de l'imprimante sélectionnée:
				SendMessage(hcomboImprimantes,CB_GETLBTEXT,cursel,(LPARAM)buffer);
				// Obtenir le nombre de formats de papier pour l'imprimante sélectionnée:
				dwreturned=DeviceCapabilities(buffer,0,DC_PAPERNAMES,0,0);
				if(dwreturned)
				{
					// Allouer la quantité de mémoire requise pour les noms de formats de papiers:
					char* pnames=(char*)GlobalAlloc(GPTR,dwreturned*64);
					if(pnames)
					{
						// Récupérer les noms de formats de papier:
						dwreturned=DeviceCapabilities(buffer,0,DC_PAPERNAMES,pnames,0);
						// Remplir le combobox des formats de papiers:
						for(i=0;i<dwreturned;i++)SendMessage(hcomboPapier,CB_ADDSTRING,0,(LPARAM)pnames+(i*64));
						// Libérer la mémoire allouée:
						GlobalFree(pnames);
					}
				}
				// Déterminer le nombre maximal de copies autorisé par l'imprimante sélectionnée:
				nmaxcopies=DeviceCapabilities(buffer,0,DC_COPIES,0,0);
				// Appliquer ce nombre comme limite supérieure de notre controle UpDown:
				SendMessage(hudCopies,UDM_SETRANGE ,0,MAKELONG(nmaxcopies,1));
				// S'assurer que l'imprimante sélectionnée supporte le mode paysage:
				dwreturned=DeviceCapabilities(buffer,0,DC_ORIENTATION,0,0);
				// Griser ou dégriser le bouton radio paysage selon le cas:
				EnableWindow(hradioPaysage,dwreturned);
				//S'assurer que l'imprimante sélectionnée supporte la couleur:
				dwreturned=DeviceCapabilities(buffer,0,DC_COLORDEVICE,0,0);
				// Griser ou dégriser le checkbox couleur selon le cas:
				EnableWindow(hcheckCouleur,dwreturned);
				// Rendre le checkbox couleur coché par défaut si la couleur est supportée:
				SendMessage(hcheckCouleur,BM_SETCHECK,dwreturned,0);
			}
			// Simuler un chagement dans un Edit pour actualiser l'état du bouton d'impression:
			SendMessage(hwnd,WM_COMMAND,MAKEWPARAM(0,EN_CHANGE),(LPARAM)0);
			return 0;
		}
		if((HWND)lParam==hbImprimer)
		{
			BOOL bret;
			HANDLE hprinter;
			int cursel;
			// Déterminer la sélection courante du combobox des imprimantes:
			cursel=(int)SendMessage(hcomboImprimantes,CB_GETCURSEL,0,0);
			// Récupérer le nom de l'imprimante sélectionnée:
			SendMessage(hcomboImprimantes,CB_GETLBTEXT,cursel,(LPARAM)buffer);
			// Ouvrir l'imprimante sélectionnée:
			bret=OpenPrinter(buffer,&hprinter,0);
			if(bret)
			{
				DEVMODE* dvm;
				DWORD dwRet;
				BOOL bcheck;
				RECT rect;
				HDC pDC;
				DOCINFO di;
				HFONT hpolice,oldfont;
				HBRUSH oldbrush,hbrush;
				int cursel,largeur,hauteur,taillepolice;
				char szpapername[64];
				// Obtenir la taille de la structure DEVMODE utilisée par cette imprimante:
				dwRet = DocumentProperties( 0,hprinter, 0, 0,0, 0 ); 
				//Allouer la mémoire nécessaire pour notre structure:
				dvm=(DEVMODE*)GlobalAlloc(GPTR ,dwRet);
				// Copier le contenu de la strcture DEVMODE de l'imprimante dans la notre:
				dwRet = DocumentProperties( 0,hprinter,buffer, dvm,  0, DM_OUT_BUFFER); 
				// Obtenir l'état du checkbox paysage:
				bcheck=(BOOL)SendMessage(hradioPaysage,BM_GETCHECK,0,0);
				// Mettre la valeur correspondante dans le membre définissant l'orientation de l'impression:
				if(bcheck)dvm->dmOrientation=DMORIENT_LANDSCAPE;
				else dvm->dmOrientation=DMORIENT_PORTRAIT;
				// Obtenir le nom du format de papier sélectionné:
				cursel=(int)SendMessage(hcomboPapier,CB_GETCURSEL,0,0);
				SendMessage(hcomboPapier,CB_GETLBTEXT,cursel,(LPARAM)szpapername);
				// Limiter la longueur du nom à 31 pour compatibilité avec la structure DEVMODE:
				if(lstrlen(szpapername)>31)szpapername[31]=0;
				// Copier le nom du format dans le membre correspondant de la structure DEVMODE:
				lstrcpy(dvm->dmFormName,szpapername);
				// Récupérer et définir le nombre de copies à imprimer:
				dvm->dmCopies=GetDlgItemInt(hwnd,EDIT_COPIES,0,0);
				// Appliquer ou nom la couleur selon l'état du checkbox couleur:
				if(SendMessage(hcheckCouleur,BM_GETCHECK,0,0))dvm->dmColor=DMCOLOR_COLOR;
				else dvm->dmColor=DMCOLOR_MONOCHROME;
				// Récupérer et définir la qualité d'impression:
				dvm->dmPrintQuality=(short)SendMessage(hcomboQualite,CB_GETCURSEL,0,0)-4;
				// Définir les membres à prendre en charge de notre structure DEVMODE:
				dvm->dmFields= DM_FORMNAME | DM_ORIENTATION | DM_COPIES  | DM_COLOR | DM_PRINTQUALITY;
				// Fermer le handle de l'imprimante:
				ClosePrinter(hprinter);
				// Créer le HDC de l'imprimante en l'associant à notre structure DEVMODE:
				pDC = CreateDC (0,buffer, 0, dvm) ;
				// Initialiser les membres de la structure DOCINFO
				memset(&di, 0, sizeof(DOCINFO));
				di.cbSize = sizeof(DOCINFO);
				di.lpszDocName = "RACPP Impression";
				// Obtenir les dimensions de la zone imprimable:
				largeur=GetDeviceCaps(pDC, HORZRES);
				hauteur=GetDeviceCaps(pDC, VERTRES);
				SetRect(&rect,0,0,largeur,hauteur);
				// Calculer la taille de notre police selon le mode portrait ou paysage:
				if(dvm->dmOrientation==DMORIENT_PORTRAIT)taillepolice=largeur/16;
				else taillepolice=hauteur/16;
				// Créer notre police:
				hpolice=CreateFont(taillepolice,0,0,0,0,0,0,0,0,0,0,0,0,"Arial");
				// Appliquer notre police:
				oldfont=(HFONT)SelectObject(pDC,hpolice);
				// Créer un brush de couleur jaune pour la coloriation des formes:
				hbrush=CreateSolidBrush(RGB(255,255,0));
				// Appliquer notre brush:
				oldbrush=(HBRUSH)SelectObject(pDC,hbrush);
				// Initialiser l'impression de notre document:
				StartDoc(pDC, &di);
				// Initialiser l'impression de notre page:
				StartPage(pDC);
				// Dessiner une ellipse jaune:
				Ellipse(pDC,0,0,largeur,hauteur);
				// Définir la couleur du texte à imprimer:
				SetTextColor(pDC,RGB(0,0,255));
				// Rendre le fond du texte transparent:
				SetBkMode(pDC,TRANSPARENT);
				// Ecrire le texte avec centrage horizontal et vertical:
				DrawText(pDC,"Ceci est une page de test",-1,&rect,DT_SINGLELINE | DT_VCENTER | DT_CENTER);
				// Lancer l'impression de la page:
				EndPage(pDC);
				// Fermer notre document:
				EndDoc(pDC);
				// Restaurer la police et le brush originaux de notre HDC de l'imprimante:
				SelectObject(pDC,oldfont);
				SelectObject(pDC,oldbrush);
				// Détruire notre HDC de l'imprimante:
				DeleteDC(pDC);
				// Détruire notre police et notre brush:
				DeleteObject(hbrush);
				DeleteObject(hpolice);
				// Libérer la mémoire allouée pour notre structure DEVMODE:
				GlobalFree(dvm);
			}
			return 0;
		}
		break;

	case WM_CLOSE:
		// Fermer la boite de dialogue:
		EndDialog(hwnd,0);
		break;

	case WM_DESTROY:
		// Détruire le brush de la couleur de fond et notre icone:
		DeleteObject(hbrFond);
		DestroyIcon(hicon);
		break;

	default:
		break;
	}
	return 0;
}
int APIENTRY WinMain(HINSTANCE hinst, HINSTANCE hprev, LPSTR szcmd, int ishow)
{
	LPDLGTEMPLATE lpdt;
	INITCOMMONCONTROLSEX icm;
	icm.dwSize=sizeof(INITCOMMONCONTROLSEX);
	icm.dwICC=ICC_UPDOWN_CLASS;
	// Initialiser la librairie common controls pour le controle UpDown:
	InitCommonControlsEx(&icm);
	//Allouer de la mémoire pour notre dialog template:
	lpdt = ( LPDLGTEMPLATE) GlobalAlloc(GPTR, 512);   
	// Définir les styles de la boite de dialogue:
	lpdt->style =  WS_DLGFRAME| DS_CENTER  |WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
	// Définir les dimensions de la boite de dialogue:
	lpdt->cx = 200; lpdt->cy = 160;       
	//Lancer la boite de dialogue
	DialogBoxIndirectParam(hinst,lpdt,0,(DLGPROC)ImpressionProc,0);
	//Libération de la mémoire allouée:
	GlobalFree((HGLOBAL)lpdt);
	return 0;
}

 Conclusion

Le projet complet est dans le zip.

 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip


 Sources du même auteur

Source avec Zip Source avec une capture SOUS-CLASSEMENT DE FENÊTRE D'UN AUTRE PROCESS PAR INJECTION ...
Source avec Zip Source avec une capture FENÊTRE FLOTTANTE SANS FOCUS (WIN32 API)
Source avec Zip Source avec une capture SERVICE WINDOWS DANS UNE DLL LANCÉ PAR SVCHOST.EXE
Source avec Zip Source avec une capture INFOTIP SHELL EXTENSION (BULLE DE L'EXPLORATEUR WINDOWS) (WI...
Source avec Zip Source avec une capture APPLICATION MULTILINGUE UTILISANT UNICODE (WIN32)

 Sources de la même categorie

Source avec Zip WIN32 TLS LENT par dguilmain
Source avec Zip VIDER ELEMENTS DE CORBEILLE WINDOWS7 (WIN64) par BruNews
Source avec Zip Source avec une capture FIND TEXT (WIN64) par BruNews
Source avec Zip DELETE DIRECTORY (WIN64) par BruNews
Source avec Zip ENUM DIRECTORY (WIN64) par BruNews

Commentaires et avis

Commentaire de DeAtHCrAsH le 13/10/2009 15:32:26

Salut,

Trois petites remarques :
- Ne pas mettre le code directement dans la fonction de callback. A mon sens il est preferable de separer le code en plusieurs fonctions distinctes.
- Pourquoi ne pas mettre toute la partie UI dans un fichier de ressource afin d'alleger le code et de mieux mettre en evidence les fonctions utiles à l'impression
- Eviter de mettre des noms de variables en francais puis en anglais, tout doit etre en anglais au possible.

Sinon, très bon code bien commenter.

Commentaire de racpp le 13/10/2009 20:04:38 administrateur CS

Merci DEATHCRASH pour les remarques. Tu as raison mais on n'est pas toujours obligés de respecter ces consignes.
- Je ne mets le code du callback dans des fonctions que quand c'est vraiment nécessaire. Ici le code est petit donc inutile de mettre une fonction pour chaque traitement de message.
- Je n'aime pas les éditeurs de ressources à cause de leurs limitations malgré les facilités qu'ils apportent. Je pense qu'à l'exécution le résultat est le même.
- Je n'aime pas trop les nommages standards des variables. Je mets les noms en français pour les variables qui correspondent à des éléments de l'interface graphique qui doit d'ailleurs être en français dans notre cas. Je fais également des applications en anglais et en arabe. Je fais de même pour l'arabe en donnant des noms de variables en arabe transcris en lettres latines. Cela me facilite beaucoup les choses pour la maintenance et la maitrise du code. Pour les autres variables je peux les mettre en anglais pour ne pas trop s'éloigner de la documentation originale des fonctions.  
Voilà chacun à ses habitudes en programmation mais ce qui m'importe ici, puisque le code est destiné aux visiteurs d'un site de partage, c'est la clarté pour en faire profiter même les tout débutants.

Commentaire de DeAtHCrAsH le 13/10/2009 20:43:17

Salut RACPP,

En effet, le but du code est bien présent.
Il est sure que chacun est libre d'utiliser ses propres conventions, mais par expérience je préfère rester sur des conventions "standard" afin de faciliter la lecture et la compréhension du code par mes collègues de boulot. Nous sommes nombreux et cela aide grandement, mais bon je t'avouerai que nous avons parfois des dérapages ;-)

Commentaire de jfrancois le 19/10/2009 19:23:05

Un bon code pour comprendre l'impression sous l'API Win32 malgré un nommage des variables assez particulier en effet.
MAIS ...
J'ai testé par curiosité, sans avoir vu les détails de la page imprimée, et là l'horreur !!! Une ellipse remplie de jaune sur toute la page (gondollée vu la quantité d'encre) !!! ASSASSIN !!! Une tonne d'encre bousillée ! Et je ne peux même pas essorer la page et remettre l'encre dans la cartouche ! Rien que ça cela mériterait un zéro pointé mais je mets 9, bon tutoriel quand même !

Commentaire de deck_bsd le 19/10/2009 20:37:04 9/10

Source très intéressante RACPP :) comme d'habitude ;)

Commentaire de racpp le 19/10/2009 23:14:49 administrateur CS

Merci pour les commentaires et la  note.
JFRANCOIS >> Désolé pour l'encre. Tu aurais pu décocher la case couleur avant l'impression afin d'imprimer en noir et blanc. Il est également possible d'imprimer sur une imprimante virtuelle donnant du pdf. J'avais beaucoup hésité pour le choix de l'image d'aperçu du code source. J'ai finalement penché pour l'interface du programme au lieu de la page de test imprimée. Je pense que je devrais les mettre tous les deux. J'avais également hésité sur le contenu de la page de test mais j'ai finalement opté pour la simplicité du code source.

Commentaire de zizou1987 le 03/01/2010 19:07:00 9/10

Salut,
vraiment c'est un code très intéressant mais je me demande comment je pourrais spécifier le fichier à imprimer ou le voir avant l'impression car j'ai un problème dans l'exécution du crystal report dans mon application win32.
Merci

Commentaire de joan001 le 15/09/2010 13:31:33

Super, très clair. Et quelque soit le nommage... très compréhensif et utile.
Merci

 Ajouter un commentaire




Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Mai 2012
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Consulter la suite du CalendriCode

A découvrir



 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,374 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales