Click here to Skip to main content
15,886,842 members
Articles / Web Development / HTML

Printing Framework

Rate me:
Please Sign up or sign in to vote.
3.77/5 (10 votes)
22 Nov 20032 min read 65.1K   3.3K   28  
Simple framework for text and graphic Printing/Previewing
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>Printer Pr�sentation</title>
<link href="doxygen.css" rel="stylesheet" type="text/css">
</head><body>
<!-- G�n�r� par Doxygen 1.3 -->
<center>
<a class="qindex" href="index.html">Page principale</a> &nbsp; <a class="qindex" href="namespaces.html">Liste des namespaces</a> &nbsp; <a class="qindex" href="hierarchy.html">Hi�rarchie des classes</a> &nbsp; <a class="qindex" href="classes.html">Liste par ordre alphab�tique</a> &nbsp; <a class="qindex" href="annotated.html">Liste des composants</a> &nbsp; <a class="qindex" href="files.html">Liste des fichiers</a> &nbsp; <a class="qindex" href="functions.html">Composants</a> &nbsp; </center>
<hr><h1>Printer Pr�sentation</h1>
<p>
<h2><a name="PrinterIntro"></a>
Introduction</h2>
Ce composant facilite la gestion de l'impression dans un d�veloppement C++. Il automatise l'aper�u et l'impression d'une fen�tre Windows en mode texte et en mode graphique :<p>
<ul>
<li>A partir de l'image de cette fen�tre, on obtient une impression et un aper�u graphique</li><li>A partir d'une repr�sentation des �l�ments graphiques pr�sents dans cette fen�tre, on obtient un aper�u et une impression texte.</li><li>Le composant autorise �galement la cr�ation d'un haut de page et d'un bas de page personnalis�s.</li></ul>
<p>
Le module s'appuie sur les m�canismes standards fournis par les MFC. Un effort de refactoring important a �t� fait pour faciliter l'int�gration dans le programme utilisateur.<h3><a name="PrinterIntroRappel"></a>
Rappel sur l'existant</h3>
Les programmes d�velopp�s avec les MFC b�n�ficient des services mis en place par Windows :<p>
<ul>
<li>Configuration de l'impression (bo�te de dialogue pour mise en page)</li><li>D�tection automatique des drivers de l'imprimante</li><li>Prise en compte des imprimantes distantes</li><li>Aper�u avant impression</li></ul>
<p>
La gestion de l'aper�u est une fonction complexe qui utilise la notion de p�riph�rique de sortie abstrait (device context DC). L'id�e poursuivie par les MFC est d'utiliser le m�me code pour obtenir l'impression � l'�cran ou sur l'imprimante.<p>
Le document suivant (il provient des MSDN) montre comment une classe vue doit surcharger certaines de ses m�thodes pour s'int�grer dans le canevas existant. On remarque �galement comment le contexte d'impression (classe CDC) est utilis� pour repr�senter le p�riph�rique de sortie (�cran ou imprimante). L'utilisateur dispose de cinq m�thodes pour mettre en place son code :<p>
<ul>
<li>OnPreparePrinting</li><li>OnBeginPrinting</li><li>OnPrepareDC</li><li>OnPrint</li><li>OnEndPrinting</li></ul>
<p>
Le r�le respectif de chacune des m�thodes est pr�cis� dans les commentaires du sch�ma. A chaque fois, il s'agit d'un code de bas niveau et assez complexe. Par exemple pour fonctionner avec n'importe quelle imprimante, le dessin sur le contexte d'impression doit �tre proportionnel � la taille relative disponible du p�riph�rique.<p>
<div align="center">
<img src="ArchitectureMFC.png" alt="ArchitectureMFC.png">
</div>
<p>
Enfin pour activer l'impression, il faut mettre en place les handlers d'impression en interceptant les messages ad�quats de Windows (ID_FILE_PRINT, ID_FILE_PRINT_DIRECT, ID_FILE_PRINT_PREVIEW). Au final, si l'utilisateur d�finit ses propres messages, c'est plus d'une dizaine de m�thodes qui doivent �tre r��crites (avec les cinq pr�c�dentes).<h3><a name="PrinterIntroObjectifs"></a>
Objectifs</h3>
Malgr� tout, la gestion de l'aper�u et de l'impression restent des t�ches tr�s lourdes � r�aliser. Il n'existe aucun moyen standard pour obtenir rapidement ces services. Chaque projet doit les red�velopper.<p>
L'id�e cl� de ce composant est de d�finir une classe abstraite d'impression. Elle fournit une interface compl�te pour param�trer le haut de page, le bas de page, le nom du job dans la file d'impression. Et surtout, la classe propose un 'refactoring' complet du m�canisme d'impression : Toutes les fonctions virtuelles pr�c�dentes sont 'encapsul�es' dans le composant. D�sormais les fonctions Print() et Preview() suffisent � d�rouler tout cycle d'appel.<p>
A partir de cette classe, deux classes sont sp�cialis�es. L'une CPrinterAbstract g�re une impression et un aper�u graphique. L'autre fournit les m�mes fonctionnalit�s en mode texte.<p>
Pour l'utilisateur, il suffit alors 'd'embarquer' dans son code, une instance de ces objets pour mettre en place l'impression.<h2><a name="PrinterArchi"></a>
Architecture</h2>
<h3><a name="PrinterArchiRefactoring"></a>
Refactoring</h3>
Ce premier diagramme illustre la mise en place de l'impression dans l'esprit des MFC. M�me si l'on dispose d'un objet CMyPrinter qui regroupe tout le code d'impression, il reste � surcharger les m�thodes virtuelles de la vue (sur le sch�ma on n'a repr�sent� que la premi�re et la derni�re).<p>
<div align="center">
<img src="PrintMfc.png" alt="PrintMfc.png">
</div>
<p>
Pour �viter ce travail, le composant red�finie la m�thode Print et redirige lui-m�me les appels standards sur ses propres m�thodes. Pour l'utilisateur, un seul appel � Print suffit � d�rouler le code d'impression. On obtient une meilleure isolation du code et l'int�gration est plus facile.<p>
<div align="center">
<img src="PrintRefactor.png" alt="PrintRefactor.png">
</div>
<p>
Le canevas g�n�rique de l'aper�u avant impression est r��crit dans le m�me esprit. Il est bas� sur la m�thode originale des MFC. L'id�e est de construire une application SDI simplifi�e qui vient remplacer celle en cours. Cette application utilise une vue sp�ciale CViewPrintPreview qui impl�mente les m�thodes virtuelles du canevas MFC et qui les redirige sur les m�thodes correspondantes du composant. Voici un diagramme tr�s simplifi� :<p>
<div align="center">
<img src="PreviewRefactor.png" alt="PreviewRefactor.png">
</div>
<p>
D'un autre point de vue, l'id�e g�n�rale consiste � tromper les MFC en substituant une vue pr�fabriqu�e � la vue initiale. Cette vue tr�s particuli�re code l'aper�u en exploitant le canevas standard et en redirigeant les appels sur notre propre classe qui d�tient l'impl�mentation r�elle de l'impression. Le m�canisme prend en charge la sauvegarde des �tats et des threads de Windows.<p>
<em>Ce code complexe est d�pendant de la version de Visual Studio (VC 6.0). De plus pour acc�l�rer sa cr�ation, le clone de l'application est construit avec un document vide. Il est donc impossible d'acc�der au document durant le code d'impression.</em><p>
Dans la pratique, cette limitation n'est pas g�nante : il suffit de charger les informations utiles juste avant.<h3><a name="PrinterArchiIndex"></a>
Index des classes</h3>
Ce paragraphe liste les classes de la dll et en donne une br�ve description.<p>
<ul>
<li>Les classes export�es :</li></ul>
<p>
<ul>
<li>CPrinterAbstract : Une classe abstraite qui factorise le code commun � l'impression texte et � l'impression graphique.</li><li>CPrinterHard : La classe charg�e de l'impression graphique</li><li>CPrinterTxt : Responsable de l'impression textuelle d'une fen�tre</li><li>CPrinterXcpt : La classe d�finit les exceptions susceptibles d'�tre lev�es</li><li>SDataPrint : Une structure qui contient les donn�es utiles � l'impression</li><li>CTextTable : Une table g�n�rique (plusieurs colonnes et plusieurs lignes)</li><li>CTextLineFree : Une ligne libre (plusieurs colonnes et plusieurs lignes)</li></ul>
<p>
<ul>
<li>Les classes locales � la dll</li></ul>
<p>
<ul>
<li>CDocText : Une classe repr�sentant le document texte. Il contient une liste des �l�ments � afficher</li><li>CInterfaceElement : L'interface (classe abstraite) des �l�ments de texte possibles</li><li>CTextLineEmpty : La repr�sentation d'une ligne vide</li><li>CTextTitle : Le titre d'un paragraphe</li><li>CTextData : Un doublon constitu� d'un libell� et d'une valeur</li><li>CTextList : Un adaptateur en CTextTable pour un CListCtrl</li><li>CViewPrintPreview : Une classe d'aide pour la pr�visualisation</li></ul>
<h3><a name="PrinterArchiSchema"></a>
Sch�ma de la dll</h3>
<div align="center">
<img src="UMLPrinter.png" alt="UMLPrinter.png">
</div>
<h2><a name="PrinterPrincipe"></a>
Principes</h2>
<h3><a name="PrinterPrincipeMarges"></a>
Marges, Ent�tes et bas de page</h3>
Quelque soit le type d'impression, une page comporte toujours trois parties : un ent�te, un bas de page et la page proprement dite. Pour obtenir une impression coh�rente, les marges hautes et basses doivent tenir compte du nombre de lignes occup�es par l'ent�te et le bas de page (et dans une certaine mesure, de la taille de la police). Par d�faut les marges utilis�es sont : (droite =0, haut=2, gauche=0, bas=2). L'ent�te se compose du nom du job comme titre, suivi d'une ligne de s�paration. Le bas de page comporte une ligne de s�paration, suivie � gauche du nombre de page et de la date � droite.<h3><a name="PrinterPrincipeTexte"></a>
Impression  texte</h3>
L'id�e sous-jacente � l'impression texte est l'utilisation d'un document CDocText qui contient une description ligne � ligne des donn�es � afficher. Ces donn�es sont stock�es sous la forme de CFormatString ce qui leur permet de s'auto-dimensionner et de s'afficher ainsi sur plusieurs lignes. Le CDocText n'est rien d'autre qu'un tableau d'objets polymorphes qui impl�mentent l'interface minimum CInterfaceElement. La cr�ation des objets de base et le remplissage du tableau sont g�r�s via des appels aux m�thodes de CPrinterText.<p>
Le composant prend � sa charge toute la mise en page. En fonction des caract�ristiques de l'imprimante et des marges, il calcule le nombre de caract�res par ligne et le nombre de lignes par page. Il en d�duit le nombre de pages et g�re automatiquement l'aper�u et l'impression.<p>
Pour parvenir � ce r�sultat des concessions sont in�vitables. Premi�rement, tout le code se base sur la notion de <em>taille moyenne de caract�re</em>. Ceci implique que la police utilis�e est fixe. Par d�faut il s'agit de la police Times New Roman de taille 10. De plus, les �l�ments propos�s doivent �tre capable de s'auto-dimensionner sur le p�riph�rique de sortie.<p>
Par cons�quent, il n'est pas possible de d�finir un saut de page universel (en fonction de la d�finition de l'imprimante, le nombre de ligne n�cessaire pour compl�ter la page varie).<h3><a name="PrinterPrincipeGra"></a>
Impression graphique</h3>
Le principe de fonctionnement est tr�s simple : Le code recopie l'image de la fen�tre Windows dans un CBitmap (Data Dependant Bitmap ou DDB). Comme la taille de l'image d�pend du contexte, il faut ensuite cr�er un Data Independant Bitmap (DIB) pour obtenir une image capable de s'afficher � la m�me �chelle sur n'importe quel p�riph�rique. Il ne reste plus qu'� envoyer le DIB vers l'imprimante ou le presse-papier, puis � nettoyer le GDI.<h2><a name="PrinterDocText"></a>
Le document</h2>
Ce paragraphe d�crit en d�tail, les classes et les m�thodes utilis�es par le composant pour d�finir dans le document CDocText la repr�sentation textuelle de la sortie attendue. Il faut consid�rer ces classes comme un mini-langage de description des pages � imprimer.<h3><a name="PrinterDocTextEmpty"></a>
CTextEmpty</h3>
Cette classe repr�sente un saut de ligne sur le p�riph�rique de sortie. On l'ajoute tr�s facilement gr�ce � la m�thode <em>AddEmpty()</em>.<h3><a name="PrinterDocTextData"></a>
CTextData</h3>
La classe repr�sente le libell� d'un champ, suivi de sa valeur en gras. Dans l'esprit du composant, il s'agit de l'�l�ment le plus important : Une impression texte reste essentiellement une suite de libell�s et de valeurs.<p>
Pour obtenir une impression agr�able, les donn�es sont align�es sur deux abcisses qui restent fixes pour tout le document. Avant l'impression, on peut ajuster la position de ces colonnes avec la m�thode <em>SetDataColumns(int nLib, int nVal)</em>.<p>
Le libell� et la valeur s'auto-formattent dans la place qui leur est impartie. Si n�cessaire, plusieurs lignes du p�riph�riques de sortie sont utilis�es. Lorsqu'il le peut, le composant place les c�sures sur les espaces blancs de la donn�e.<p>
L'ajout d'un couple au document se fait tr�s facilement avec la m�thode <em>void AddData(LPCTSTR lpszLib, LPCTSTR lpszVal)</em>.<h3><a name="PrinterDocTextTitle"></a>
CTextTitle</h3>
Cette classe repr�sente un titre sur le p�riph�rique de sortie. Un titre comprend :<ul>
<li>Un saut de ligne</li><li>Le libell� centr� et en gras</li><li>Un saut de ligne</li></ul>
<p>
Typiquement, il sert � regrouper sous un m�me titre les libell�s et les valeurs d'un groupe de contr�les. On l'ajoute tr�s facilement gr�ce � la m�thode <em>void AddTitle(LPCTSTR lpszTitle)</em><h3><a name="PrinterDocTextList"></a>
CTextList</h3>
La classe permet de placer dans le document une liste graphique. On obtient :<ul>
<li>Un saut de ligne</li><li>Les titres des colonnes en gras</li><li>Un saut de ligne</li><li>Les donn�es de la liste.</li></ul>
<p>
Chaque �l�ment (item) est auto-formatable et est capable de s'afficher (si n�cessaire) sur plusieurs lignes du p�riph�rique de sortie. Lorsque cela se produit, les autres colonnes formatent � l'identique les �l�ments de la ligne pour maintenir un affichage coh�rent.<p>
Le formatage des colonnes et les libell�s sont r�cup�r�s directement � partir du contr�le graphique. Le facteur nPercent fournit le facteur d'�chelle entre le contr�le graphique et la sortie texte : on peut ainsi choisir d'imprimer la liste sur toute la largeur de la page. On ajoute facilement une liste au document avec la m�thode <em>AddList(CListCtrl* pList, int nPercent)</em>.<p>
Il faut noter que l'impl�mentation s'appuie sur un objet CTextTable d�crit ci-dessous.<h3><a name="PrinterDocTextTable"></a>
CTextTable</h3>
Cette classe permet de construire un tableau g�n�rique, de le remplir, puis de l'ajouter au document. Utiliser un CTextTable demande plus de travail que d'utiliser un CTextLine. Mais en contrepartie, on obtient une bien plus grande souplesse.<p>
Par rapport aux �l�ments pr�c�dents, il faut pouvoir manipuler directement l'objet pour d�finir les colonnes et ajouter les lignes. Afin d'�viter les fuites de m�moire, le module utilise une ar�ne pour construire la table. Les paragraphes suivants explicitent une utilisation r�elle de l'objet.<p>
<em> Attention : Les extraits de code doivent �tre prot�g�s par un bloc try/catch. Pour simplifier les exemples, ils ne sont pas reproduits.</em><p>
<dl compact><dt><b>Etape 1 : Cr�ation d'une table avec 2 colonnes</b></dt><dd></dd></dl>
<div class="fragment"><pre> 
  CTextTable* pTable = m_printerText.CreateTable(2);
  pTable-&gt;SetColumn (0, 35, DT_CENTER,"Protocole :");
  pTable-&gt;SetColumn (1, 35, DT_CENTER,"Longueur :");
  </pre></div><p>
A noter :<ul>
<li>La cr�ation de l'objet via la fabrication de CPrinterText. En r�alit�, l'objet est cr�� sur la pile et plac� dans l'ar�ne. Le constructeur attend le nombre de colonnes.</li><li>L'initialisation des colonnes.</li></ul>
<p>
<dl compact><dt><b>Etape 2: Remplissage de la table</b></dt><dd></dd></dl>
<div class="fragment"><pre>
_AddLine(pTable, &amp;m_EditLGMX1, &amp;m_ComboPCLX1);
_AddLine(pTable, &amp;m_EditLGMX2, &amp;m_ComboPCLX2);
_AddLine(pTable, &amp;m_EditLGMX3, &amp;m_ComboPCLX3);
_AddLine(pTable, &amp;m_EditLGMX4, &amp;m_ComboPCLX4);

avec :

  void
  _AddLine(CTextTable* pTable, CEdit* pEdit, CComboBox* pCombo)
  {
    CStringArray array;
    array.RemoveAll();
    array.Add(pCombo-&gt;CtrlGetValue());
    array.Add(pEdit-&gt;CtrlGetValue());
    pTable-&gt;AddLine(array); 
  } 
  </pre></div><p>
A noter :<ul>
<li>Pour remplir une ligne de la table, on lui passe un CStringArray qui contient l'ensemble des informations.</li></ul>
<p>
<dl compact><dt><b>Etape 3 : Ajout de la table au document</b></dt><dd></dd></dl>
<div class="fragment"><pre>
  m_printerText.AddTable(pTable);
  </pre></div><p>
A noter :<ul>
<li>Le code ajoute la table au document texte.</li><li>En interne l'objet est retir� de l'ar�ne et le document conserve le pointeur sur cet objet.</li></ul>
<h3><a name="PrinterDocTextFreeLine"></a>
CTextFreeLine</h3>
Ce dernier type d'�l�ment permet de composer une ligne en y pla�ant un nombre variable d'informations. Ce m�canisme apporte plus de souplesse au composant. Une utilisation typique est de pouvoir afficher des donn�es qui comportent 3 ou 4 informations. Exemples d'informations :<p>
<ul>
<li>Dur�es : 3 jours</li><li>Cr�er le : 15/10/02 � 20h03</li></ul>
<p>
Dans le premier cas, on souhaite :<p>
<ul>
<li>'Dur�es :", police normale, texte align� sur les libell�s des 'data'</li><li>'3', en gras, texte align� sur les valeurs des 'data'</li><li>'jour', police normale, texte � la suite de '3'</li></ul>
<p>
Dans le second cas, on souhaite :<p>
<ul>
<li>'Cr�er le :", police normale, texte align� sur les libell�s des CData</li><li>'15/10/02', en gras, texte align� sur les valeurs des CData</li><li>'�', police normale, texte � la suite de '3'</li><li>'20h0"', en gras, texte � la suite de '�'</li></ul>
<p>
Les paragraphes suivants explicitent une utilisation r�elle de l'objet.<p>
<em> Attention : Les extraits de code doivent �tre prot�g�s par un bloc try/catch. Pour simplifier, ils ne sont pas reproduits.</em><p>
<dl compact><dt><b>Etape 1 : Cr�ation d'une ligne 'libre' </b></dt><dd></dd></dl>
<div class="fragment"><pre>  
  CTextFreeLine* pTextFree = m_printerText.CreateFreeLine();
</pre></div><p>
A noter :<ul>
<li>La cr�ation de l'objet via la fabrication de CPrinterText. En r�alit�, l'objet est cr�� sur la pile et plac� dans l'ar�ne.</li></ul>
<p>
<dl compact><dt><b>Etape 2: Remplissage de la ligne</b></dt><dd></dd></dl>
<div class="fragment"><pre>
  pTextFree-&gt;Add("Une", 3, true);
  pTextFree-&gt;Add("Ligne", 20, false);
  pTextFree-&gt;Add("'libre'", 40, true);
</pre></div><p>
A noter :<ul>
<li>On remplit la ligne avec la m�thode Add. On lui passe le libell�, la position et un bool�en qui indique si le texte est normal ou en gras.</li><li>Une ligne libre ne tient que sur une seule ligne ! Il n'y a pas de contr�le, ni d'ajustement possible. Si le texte est trop long, il sera tronqu�.</li></ul>
<p>
<dl compact><dt><b>Etape 3 : Ajout de la ligne</b></dt><dd></dd></dl>
<div class="fragment"><pre>
  m_textPrinter.AddFreeLine(pTextFree); 
</pre></div><p>
A noter :<ul>
<li>Le code ajoute la ligne au document texte.</li><li>En interne l'objet est retir� de l'ar�ne et le document conserve le pointeur sur cet objet.</li></ul>
<h2><a name="PrinterSources"></a>
Sources</h2>
La dll printer simplifie l'impression texte et l'impression graphique d'une fen�tre Windows. Il s'agit d'une dll r�guli�re au sens MFC qui ne propose aucun contr�le �tendu, mais qui prend en charge une partie du canevas MFC de l'impression.<p>
Printer est situ� dans l'environnement de d�veloppement sous le r�pertoire $Devp\Sources\Printer. Voici sa structure :<p>
<ul>
<li><b>Sources</b> : contient le source de la dll.</li><li><b>Doc</b> : Le projet Doxygen pour la documentation.</li><li><b>Test</b> : Un exemple d'utilisation.</li></ul>
<p>
<div align="center">
<img src="PrinterPath.png" alt="PrinterPath.png">
</div>
<p>
Le projet inclut des options de post-compilation qui recopie automatiquement les .lib et .dll sous les r�pertoires standards de l'environnement : $Devp\Lib &amp; $Devp\Bin. En mode debug, on obtient les fichiers PrinterD.lib &amp; PrinterD.dll, en mode release, on obtient les fichiers Printer.lib et Printer.dll.<p>
Le projet printer, comprend �galement le fichier "printer.h" situ� sous $Devp\Include. Inclure ce fichier dans un source permet d'obtenir toute les d�clarations n�cessaires.<p>
Enfin l'ensemble du code est plac� dans le namespace printer. Pour utiliser les composants du module il suffit d'importer le namespace (instruction <em>using namespace printer;</em>) ou d'utiliser le nom qualifi� (exemple <em><a class="el" href="classprinter_1_1CPrinterText.html">printer::CPrinterText</a> printerText;</em>).<h2><a name="PrinterUsage"></a>
Usage</h2>
Le projet montre une utilisation du composant. L'impression et l'aper�u graphique sont r�alis�s avec CPrinterHard original. On obtient alors les hauts et les bas de page d�finis par d�faut.<p>
Pour les m�mes fonctionnalit�s en mode texte, une version personnalis�e de CPrinterText est utilis�e. Ceci se fait simplement en surchargeant les m�thodes <em>PrintPageHeader</em> et <em>PrintPageFooter</em> dans une classe d�riv�e.<p>
L'autre point int�ressant du projet est qu'il montre comment automatiser le remplissage du document texte � partir du contenu d'une fen�tre graphique. L'id�e est de confier l'analyse � une classe 'Fabrication' qui va lire un � un le contenu des contr�les. Pour cela il est n�cessaire d'activer la RTTI et de conc�der une r�gle de nommage sur les contr�les 'GROUP'.<p>
Evidemment, la classe fournie ici est embryonnaire. Elle ne reconna�t que quelques types de contr�le et ne permet pas une lecture partielle de la vue. Mais il est assez facile de l'am�liorer.<h3><a name="PrinterUsageRes"></a>
Ressource</h3>
Le menu est modifi� afin de pr�senter les options suivantes :<p>
<ul>
<li>Fichier<ul>
<li>Imprimer Texte ID_FILE_PRINT_TEXT</li><li>Imprimer Ecran ID_FILE_PRINT_GRA</li><li>Aper�u<ul>
<li>Aper�u Texte ID_FILE_PREVIEW_TEXT</li><li>Aper�u Ecran ID_FILE_PREVIEW_GRA</li></ul>
</li></ul>
</li></ul>
<h3><a name="PrinterUsageTestDocH"></a>
TestDoc.h</h3>
On place dans le document les instances des objets d'impression. Le mode permet de distinguer l'impression graphique de l'impression texte.<p>
<div class="fragment"><pre>
...
// Attributes
public:
  enum Mode {PRINTER_TEXT, PRINTER_GRA};
  void SetMode(Mode mode);  
  void PrinterPreview();
  void PrinterPrint();
  void CreateDocText(CTestView* pView);
  void InitPrinter();
...
private :
  CPrinterHard m_hardPrinter;
  CMyPrinter   m_textPrinter;
  Mode m_nMode;
</pre></div><h3><a name="PrinterUsageTestDocCpp"></a>
TestDoc.cpp</h3>
La m�thode SetMode permet de changer le type d'impression. Il est n�cessaire de conserver cette information � cause du m�canisme de la pr�visualisation. Le code de PrinterPrint et PrinterPreview est tr�s classique. Il faut noter que les exceptions CPrinterXcpt sont intercept�es (c'est indispensable).<p>
<div class="fragment"><pre>
void 
CTestDoc::SetMode(Mode mode) 
{
  m_nMode = mode;
}

void 
CTestDoc::PrinterPrint() 
{
  try {
    switch (m_nMode) {
      case PRINTER_TEXT :
        m_textPrinter.Print();
        break;
      case PRINTER_GRA :
        m_hardPrinter.Print();
        break;
      default:
        ASSERT(FALSE);
    }
  }
  catch (CPrinterXcpt&amp; xcpt) {
    AfxMessageBox( xcpt.GetErrorMsg() );
  }
}

void 
CTestDoc::PrinterPreview() 
{
  try {
    switch (m_nMode) {
      case PRINTER_TEXT :
        m_textPrinter.Preview();
        break;
      case PRINTER_GRA :
        m_hardPrinter.Preview();
        break;
      default:
        ASSERT(FALSE);
    }
  }
  catch (CPrinterXcpt&amp; xcpt) {
    AfxMessageBox( xcpt.GetErrorMsg() );
  }
}
</pre></div><p>
La m�thode suivante initialise les objets charg�s de l'impression. A cause de la d�finition de bas de page et de haut de page personnalis�s, il faut ajuster les marges de l'impression texte.<p>
Il est important de passer � la m�thode SetWindow, l'adresse valide de la fen�tre. Dans le cas de la vue, ceci ne peut �tre accompli qu'� partir du OnInitialUpdate.<p>
Enfin, on fixe le message du job dans la file d'impression de Windows. <div class="fragment"><pre>
void 
CTestDoc::InitPrinter() 
{
  m_textPrinter.SetMargins(0,6,0,3);


  m_hardPrinter.SetWindow(AfxGetMainWnd());
  m_hardPrinter.SetTitleDoc("Test Impression graphique");

  m_textPrinter.SetWindow(AfxGetMainWnd());
  m_textPrinter.SetTitleDoc("Test Impression texte");
}
</pre></div><p>
La derni�re m�thode initialise le document texte avec les informations de la vue. On remarque l'utilisation de la classe CFacteur pour un remplissage automatique du document.<p>
Le code montre �galement comment ajouter un texte libre. Il faut bien r�aliser que tout ce qui est plac� sur le p�riph�rique de sortie, n'a pas forc�ment une existence physique dans la fen�tre...<p>
<div class="fragment"><pre>
void 
CTestDoc::CreateDocText(CTestView* pView)
{
  try {

    // Partir d'un document propre
    m_textPrinter.ClearDoc();

    // Ajouts automatique
    CFacteur facteur;
    facteur.Analyser(pView, &amp;m_textPrinter);

    //
    // On peut ajouter des valeurs autres...
    //

    m_textPrinter.AddTitle("Ajouts libres....");

    // On ajoute une ligne libre
    CTextFreeLine* pTextFree = m_textPrinter.CreateFreeLine();
    pTextFree-&gt;Add("Un", 3, true);
    pTextFree-&gt;Add("exemple", 20, false);
    pTextFree-&gt;Add("de ligne", 40, true);
    pTextFree-&gt;Add("libre.", 70, false);
    m_textPrinter.AddFreeLine(pTextFree);

  } 
  catch (CPrinterXcpt&amp; xcpt) {
    AfxMessageBox( xcpt.GetErrorMsg() );
  } 
}
</pre></div><h3><a name="PrinterUsageTestViewh"></a>
TestView.h</h3>
Le fichier "Printer.h" (sous $Devp\Include) permet d'obtenir toutes les d�clarations n�cessaires. On d�clare aussi les handlers pour ces messages et ceux des MFC. Les instances de CPrinterHard et CMyPrinter sont d�tenues par le document.<p>
<div class="fragment"><pre>
class CTestView : public CFormView
{
  ...
// Generated message map functions
protected:
  //{{AFX_MSG(CTestView)
  afx_msg void OnFilePrintPreviewText(); // ID_FILE_PREVIEW_TEXT (dll)
  afx_msg void OnFilePrintPreviewGra();  // ID_FILE_PREVIEW_GRA (dll)
  afx_msg void OnFilePrintGra();         // ID_FILE_PRINT_GRA (dll)
  afx_msg void OnFilePrintText();        // ID_FILE_PRINT_TEXT (dll)
  afx_msg void OnFilePrintPreview();     // ID_FILE_PREVIEW (standard mfc)
  afx_msg void OnFilePrint();            // ID_FILE_PRINT (standard mfc)
  //}}AFX_MSG

</pre></div><h3><a name="PrinterUsageTestViewCpp"></a>
TestView.cpp</h3>
La table des messages reprend la d�finition des menus (branchement des commandes d'impression sur les handlers). Elle comporte des entr�es � la fois pour les commandes du menu et aussi pour le canevas MFC (ID_FILE_PRINT, ID_FILE_PRINT_DIRECT, ID_FILE_PRINT_PREVIEW). L'impl�mentation est tr�s simple : OnFilePrint et OnFilePrintPreview font le travail en redirigeant l'appel sur la bonne impression. Les handlers sp�cifiques du menu, ne font que mettre � jour le mode, et rediriger l'appel sur OnFilePrint et OnFilePrintPreview.<p>
Les exceptions sont capt�es dans les m�thodes du document.<p>
<div class="fragment"><pre>
  BEGIN_MESSAGE_MAP(CTestView, CFormView)
  //{{AFX_MSG_MAP(CTestView)
  ON_COMMAND(ID_FILE_PRINT_PREVIEW_TEXT, OnFilePrintPreviewText )
  ON_COMMAND(ID_FILE_PRINT_PREVIEW_GRA, OnFilePrintPreviewGra)
  ON_COMMAND(ID_FILE_PRINT_TEXT, OnFilePrintText)
  ON_COMMAND(ID_FILE_PRINT_GRA, OnFilePrintGra)
  //}}AFX_MSG_MAP
  // Standard printing commands
  ON_COMMAND(ID_FILE_PRINT, OnFilePrint)
  ON_COMMAND(ID_FILE_PRINT_DIRECT, OnFilePrint)
  ON_COMMAND_EX(ID_FILE_PRINT_PREVIEW, OnFilePrintPreview)
  END_MESSAGE_MAP()

  ....
  
/////////////////////////////////////////////////////////////////////////////
// Impression MFC standard
// Les Fcts sont INDISPENSABLES pour pouvoir Imprimer � partir de la Pr�visualisation.
/////////////////////////////////////////////////////////////////////////////

void CTestView::OnFilePrint() 
{
  GetDocument()-&gt;PrinterPrint();
}

void CTestView::OnFilePrintPreview() 
{
  GetDocument()-&gt;PrinterPreview();
}

/////////////////////////////////////////////////////////////////////////////
// Branchement de l'impression sur le cannevas
// On utilise un 'mode' pour discriminer les choix possibles
/////////////////////////////////////////////////////////////////////////////

void CTestView::OnFilePrintPreviewText() 
{

  GetDocument()-&gt;SetMode(CTestDoc::PRINTER_TEXT);
  GetDocument()-&gt;CreateDocText(this);
  OnFilePrintPreview();
}


void CTestView::OnFilePrintText() 
{
  GetDocument()-&gt;SetMode(CTestDoc::PRINTER_TEXT);
  GetDocument()-&gt;CreateDocText(this);
  OnFilePrint();
}


void CTestView::OnFilePrintPreviewGra() 
{
  GetDocument()-&gt;SetMode(CTestDoc::PRINTER_GRA);
  OnFilePrintPreview();
}

void CTestView::OnFilePrintGra() 
{
  GetDocument()-&gt;SetMode(CTestDoc::PRINTER_GRA);
  OnFilePrint();
}

// Un raccourci pour le test
void CTestView::OnButton1() 
{
  OnFilePrintPreviewText();
}
</pre></div><h2><a name="Credits"></a>
Cr�dits</h2>
MSDN : print &amp; preview<p>
Mac Graven : a sample "How to make a WYSIWYG hardcopy" in CodeGuru<p>
Chris Maunder : a sample "Printing without the DocText/View framework" in CodeGuru<p>
Koay Kah Hoe : a sample "Print Previewing without the DocText/View Framework" in CodeProject<hr><address style="align: right;"><small>G�n�r� le Fri Oct 31 11:09:00 2003 pour Printer par 
<a href="http://www.doxygen.org/index.html">
<img src="doxygen.png" alt="doxygen" align="middle" border=0 
width=110 height=53></a>1.3 </small></address>
</body>
</html>

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions