TUTORIEL TECHNOS .NET 
WinForms : imprimer un contenu textuel
Utiliser les composants de .NET avec C#, afin d'envoyer le texte d'un éditeur vers l'imprimante. (28/11/2005)
Nous reprenons aujourd'hui notre construction d'un petit éditeur de texte, que nous avions élaboré pour découvrir le fonctionnement des formulaires Windows, WinForms. Nous allons ajouter à notre application les moyens d'imprimer ce texte via, de toute évidence, l'imprimante par défaut de la machine.

L'intérêt de travailler avec C# et .NET est que nous sommes en environnement propriétaire, donc le langage est conçu pour fonctionner correctement et directement avec ce qu'offre le système - sans devoir passer par un outil tiers. En l'occurrence, .NET nous offre exactement les composants donc nous avons besoin pour mener à bien cette tâche ardue. Ces composants sont contenus dans l'espace de nom System.Drawing.Printing - à inclure donc en en-tête du fichier : using System.Drawing;.

Une fois l'espace de nom établi, mettons en place un simple ajout au menu "Fichier", dont la sélection lancera directement l'impression.

    miFile.MenuItems.Add(new MenuItem("Enregistrer so&us...", new EventHandler(this.EnregistrerSous_Clicked)));
    miFile.MenuItems.Add("-");
    miFile.MenuItems.Add(new MenuItem("Imprimer", new EventHandler(this.Imprimer_Clicked)));


Et la méthode qui va avec :

  private void Imprimer_Clicked(object sender, System.EventArgs e)
    {
    }


Mais tout n'est pas si facile. La base des fonctionnalités est certes fournie par nos composants, mais reste à les exploiter correctement. En effet, il ne suffit pas d'appeler la méthode Print() pour se retrouver avec un beau document bien propre.

Tout d'abord, il nous fait disposer de deux objets, correspondant à deux aspects que nous allons manipuler : le texte, et sa police. Nos objets, définis au début de notre classe FenetreSimple, seront Font printFont; et StringReader stringToPrint;. La première gère l'aspect graphique de l'impression, la seconde le contenu.

Car graphisme il y a. Une imprimante n'imprime pas du texte à la demande, mais il faut lui indiquer correctement les pixels à traiter, la couleur, et plus prosaïquement, la police. Ce sera le rôle de notre printFont.

Voici le contenu complet de notre méthode Imprimer_Clicked() :

  private void Imprimer_Clicked(object sender, EventArgs e) {
    try {
      stringToPrint = new StringReader(txt.Text);
      try {
        printFont = new Font("Arial", 10);
        PrintDocument pd = new PrintDocument();
        pd.PrintPage += new PrintPageEventHandler(this.pd_PrintPage);
        pd.Print();
        }
      finally {
        stringToPrint.Close();
        }
      }
    catch(Exception ex) {
      MessageBox.Show(ex.Message);
      }
    }


Les deux gestionnaires d'exceptions permettent d'intercepter les erreurs potentielles tant au moment de l'impression elle-même, que simplement lors de la récupération du texte en provenance de notre petite application. Une fois le texte récupéré, nous assignons une police et une taille à printFont, et créons le nécessaire objet PrintDocument.

PrintDocument est nécessaire, car c'est lui qui définit l'objet interne qui dialoguera avec l'imprimante. C'est lui, et sa méthode Print(), qui est central au processus d'impression.

Entre ensuite en jeu PrintPageEventHandler(), qui comme son nom l'indique est un gestionnaire d'évènements rattachés à l'impression de pages. Il nous sert à récupérer les informations sur chaque page à imprimer, au travers de la méthode pd_PrintPage().

pd.PrintPage est un évènement appelé pour chaque page. Nous nous en servons pour construire, pour chaque page, l'aspect de l'impression, via notre méthode pd_PrintPage(). Dans celle-ci, nous définissons nombre de détails à traiter par la classe Graphics, qui traduire notre demande d'impression en langage imprimante, via sa méthode DrawString. Voici le code complet de cette méthode :

  private void pd_PrintPage(object sender, PrintPageEventArgs ev) {
    float linesPerPage = 0;
    float yPos = 0;
    float count = 0;
    float leftMargin = ev.MarginBounds.Left;
    float topMargin = ev.MarginBounds.Top;
    string line = null;
  
    linesPerPage = ev.MarginBounds.Height / printFont.GetHeight(ev.Graphics);
  
    while (count < linesPerPage && ( (line = stringToPrint.ReadLine()) != null) )  {
      yPos = topMargin + (count * printFont.GetHeight(ev.Graphics));
      ev.Graphics.DrawString(line, printFont, Brushes.Black, leftMargin, yPos, new StringFormat() );
      count++;
      }
  
    if (line != null)
      ev.HasMorePages = true;
    else
      ev.HasMorePages = false;
    }


  Forum

Réagissez dans les forums de JDN Développeurs

Outre la gestion des marges, nous définissons la taille et la couleur du "pinceau", et parcourons petit à petit notre chaîne. Au final, nous testons le nombre de ligne restant à traiter : s'il n'y en a plus, le traitement des données se termine et l'impression se lance...
 
Xavier Borderie, JDN Développeurs
 
Accueil | Haut de page
 
 





Quand achetez-vous le plus en ligne ?
Du lundi au vendredi
Le samedi
Le dimanche

Tous les sondages