|
Site |
Cours VB.net |
|
|
|
Imprimer. |
|
|
Comment Imprimer ?
Prévoir une longue soirée, au calme, un bon siège, 1 g de paracétamol et un gros thermos de café!!
On verra que l'on peut utiliser pour imprimer:
A- La méthode .Net
Soit avec un composant 'PrintDocument'.
Soit avec une instance de 'la Class PrintDocument'.
B- On peut, en ajoutant une référence, imprimer comme en VB6 et c'est plus simple!!
A- Avec PrintDocument
1 Imprimer 'Hello' avec le composant 'PrintDocument'
L'utilisateur clique sur un bouton, cela imprime 'Hello'
Cet exemple utilise un 'composant PrintDocument'
Comment faire en théorie?
C'est le composant PrintDocument qui imprime.
En prendre un dans la boite à outils, le mettre dans un formulaire. Il apparaît sous le formulaire et se nomme PrintDocument1.
Pour imprimer il faut utiliser la méthode Print de ce composant PrintDocument; Il faut donc écrire l'instruction suivante:
PrintDocument1.Print
Cette instruction appelle la procédure évènement PrintDocument1_PrintPage du composant PrintDocument et qui contient la logique d'impression. Un paramètre de cet évènement PrintPage est l'objet graphique envoyé à l'imprimante (nommé e). C'est à vous de dessiner dans l'objet graphique (e) ce que vous voulez imprimer . En fin de routine, l'objet graphique sera imprimé (automatiquement).
En pratique:
Sub PrintDocument1_PrintPage(ByVal sender As System.Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPagePrivate
End Sub
C'est cette procédure qui est fondamentale et qui contient les routines d'impression écrites par le programmeur. Les routines d'impression agissent sur l'objet graphique qui sera utilisé pour imprimer , cet objet graphique est fourni dans les paramètres de la procédure(ici c'est e qui est de type PrintPageEventArgs)
e.Graphics.DrawString("Hello", New Font("Arial", 80, FontStyle.Bold), Brushes.Black, 150, 125)
PrintDocument1.Print()
Voici le code complet:
Private
Sub PrintDocument1_PrintPage(ByVal sender As System.Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPageNew Font("Arial", 80, FontStyle.Bold), Brushes.Black, 150, 125) End Sub Private Sub ButtonPrint_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonPrint.Clicke.Graphics.DrawString("Hello",
End SubPrintDocument1.Print()
Si je clique sur le bouton 'ImprimerHello' cela imprime un gros 'Hello'.
La méthode
Print d'un PrintDocument déclenche l'évènement PrintPage de ce
PrintDocument qui contient le code dessinant sur le graphique de la page à
imprimer. En fin de routine PrintPage le graphique est imprimer sur la feuille
de l'imprimante.
Toutes les méthodes graphiques écrivant, dessinant, traçant des lignes... sur un graphique permettent donc d'imprimer.
Imprimer un dessin:
Créons une ellipse bleue à l'intérieur d'un rectangle avec la position et les dimensions suivantes : début à 100, 150 avec une largeur de 250 et une hauteur de 250.
Private Sub PrintDocument1_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage e.Graphics.FillEllipse(Brushes.Blue, New Rectangle(100, 150, 250, 250)) End Sub
Afficher un Message Box indiquant 'Fin d'impression'.
On a étudié l'évènement PrintPage, mais il existe aussi les évènements:
BeginPrint et
EndPrint respectivement déclenchés en début et fin
d'impression
Il suffit d'utiliser l'évènement EndPrint pour prévenir que l'impression est terminée:
Private Sub PrintDocument1_EndPrint(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintEventArgs) Handles PrintDocument1.EndPrint
MessageBox.Show("Fin d'impression")
End Sub
On peut même fignoler et afficher "Fin d'impression de Nom du document"
Il faut avoir renseigné le DocumentName:
PrintDocument1.DocumentName = "MyTextFile"
Puis écrire:
Private Sub PrintDocument1_EndPrint(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintEventArgs) Handles PrintDocument1.EndPrint
MessageBox.Show( "Fin d'impression de "+PrintDocument1.DocumentName)
End Sub
2-Même programme: Imprimer 'Hello' mais avec la Classe PrintDocument
L'utilisateur clique sur un bouton, cela imprime 'Hello'
Cet exemple utilise 'une instance de la Classe PrintDocument'. On ne met pas de composant 'PrintDocument' dans le formulaire.
Comment faire en théorie?
Il faut importer l'espace de nom 'Printing' par :
System.Drawing.PrintingImports
Il faut créez une instance de la Classe PrintDocument dans le module.
Dim pd As new PrintDocument()
Private Sub pd_PrintPage(sender As object, ev As System.Drawing.Printing.PrintPageEventArgs)
End sub
Il faut indiquer le "lien" entre l'objet pd et la routine évènement PrintPage
AddHandler pd.PrintPage, AddressOf Me.pd_PrintPage
Dans la procédure Button_Click d'un bouton "Imprimer" il faut appeler la méthode Print du PrintDocument pour effectuer l'impression du document .
pd.Print
ev.Graphics.DrawString ("Hello", printFont, Brushes.Black, leftMargin, yPos, new StringFormat()).
Imports
System.Drawing.Printing
Public
Class Form1 Inherits System.Windows.Forms.Form
Dim pd As New PrintDocument 'Assumes the default printer
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
AddHandler pd.PrintPage, AddressOf Me.Pd_PrintPage
End Sub
Private Sub Pd_PrintPage(ByVal sender As System.Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs)
e.Graphics.DrawString("Hello", New Font("Arial", 80, FontStyle.Bold), Brushes.Black, 150, 125)
End Sub
Private Sub ButtonPrint_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonPrint.Click
pd.Print()
End Sub
End Class
Comment choisir l'imprimante?
Le composant PrintDialog permet le choix de l'imprimante, de la zone à imprimer (tout, la sélection..) et donne accès aux caractéristiques de l'imprimante.
Comment l'utiliser?
Il faut créer une instance de PrintDialog:
Dim dlg As New PrintDialog
Il faut indiquer au PrintDialog sur quel PrintDocument travailler:
dlg.Document = pd
Puis ouvrir la fenêtre PrintDialog avec la méthode ShowDialog.
L'utilisateur choisit son imprimante puis clique sur 'Ok'.
Si elle retourne Ok, on imprime.
Quand l'utilisateur clique sur le bouton ButtonPrint ('Imprimer') la fenêtre PrintDialog s'ouvre:
Voici le code complet:
Private
Sub ButtonPrint_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonPrint.Click Dim dlg As New PrintDialogdlg.Document = pd
Dim result As DialogResult = dlg.ShowDialog() If (result = System.Windows.Forms.DialogResult.OK) Thenpd.Print()
End IfEnd Sub
Comment modifier la page à imprimer?
Comment choisir d'imprimer en portrait ou paysage? modifier les marges..
Il faut utiliser un composant PageSetUpDialog.
Pour stocker les informations sur la page (marges...) il faut un PageSetting
Je lie le PageSetting au PageSetUpDialog en donnant à la propriété PageSettings du PageSetUpDialog le nom du PageSetting.
puis j'ouvre le PageSetUpDialog.
Au retour le PageSetting contient les modifications, je les 'passe' au PrintDocument avant d'imprimer.
Cela donne:
Dim psDlg As New PageSetupDialogDim LePageSettings As New PageSettings
psDlg. PageSettings = LePageSettings
psDlg.ShowDialog()
Prévisualisation de la page à imprimer?
On utilise pour cela un PrintPreviewDialog, on lui indique quel PrintDocument pré visualiser en l'assignant à sa méthode document puis on l'affiche par ShowDialog().Dim
dllg As New PrintPreviewDialogdllg.Document = pd
dllg.ShowDialog()
Comment imprimer le contenu d'un fichier texte?
Tous les didacticiels (Microsoft compris) donnent cet exemple.
La première chose que vous devez faire est d'écrire votre logique d'impression. Pour cela, quand la méthode PrintDocument.Print() est appelée, les événements suivants sont déclenchés.
La fonction PrintPage est appelée autant de fois qu'il y a de page.
Par défaut une document à une seule page. Si en imprimant la page on veut faire un saut de page, on positionne:e.HasMorePages = true
Cela fait un saut de page et déclenche de nouveau PrintPage pour la page suivante. Il faut donc incrémenter une variable à chaque appel de cette fonction afin de savoir quelle est la page courante.
L'argument d'événement de PagePrint (PagePrintEventArgs) comprend une propriété HasMorePages. Si celle-ci a la valeur True lors du retour de votre gestionnaire d'événements, PrintDocument définit une nouvelle page et déclenche de nouveau l'événement PagePrint.
Voyons la logique dans votre gestionnaire d'événements PagePrint :
Il faut dans la procédure PagePrint imprimer ligne par ligne en se déplaçant à chaque fois vers le bas d'une hauteur de ligne.
Pour 'simplifier', on considère que chaque ligne ne déborde pas à droite!!
Public Class
ExampleImpression
Inherits System.Windows.Forms.Form
....
private printFont As Font
private streamToPrint As StreamReader
Public Sub New ()
MyBase.New
InitializeComponent()
End Sub
'Evénement survenant lorsque
l'utilisateur clique sur le bouton 'Imprimer'
Private Sub printButton_Click(sender As object, e As System.EventArgs)
Try
streamToPrint = new StreamReader ("PrintMe.Txt")
Try
printFont = new Font("Arial", 10)
Dim pd as PrintDocument = new PrintDocument()
'déclaration du PrintDocument
AddHandler pd.PrintPage, AddressOf Me.pd_PrintPage
pd.Print()
Finally
streamToPrint.Close()
End Try
Catch ex As Exception
MessageBox.Show("Une
erreur est survenue: - " + ex.Message)
End Try
End Sub
'Evènement survenant pour chaque
page imprimer
Private Sub pd_PrintPage(sender As object, ev As System.Drawing.Printing.PrintPageEventArgs)
Dim lpp As Single = 0
'nombre de ligne par page
Dim yPos As Single = 0
'ordonnée
Dim count As Integer = 0
'numéro de ligne
Dim leftMargin As Single = ev.MarginBounds.Left
Dim topMargin As Single = ev.MarginBounds.Top
Dim line as String
'calcul
le nombre de ligne par page
' hauteur de la page/hauteur de la
police de caractère
lpp = ev.MarginBounds.Height / printFont.GetHeight(ev.Graphics)
'lit une
ligne dans le fichier
line=streamToPrint.ReadLine()
'Boucle affichant chaque ligne
while (count < lpp AND line <> Nothing)
yPos = topMargin + (count * printFont.GetHeight(ev.Graphics))
'Ecrit le texte dans l'objet graphique
ev.Graphics.DrawString (line, printFont, Brushes.Black, leftMargin, _
yPos, new StringFormat())
count = count + 1
if (count < lpp) then
line=streamToPrint.ReadLine()
end if
End While
'S'il y
a encore des lignes, on réimprime une page
If (line <> Nothing) Then
ev.HasMorePages = True
Else
ev.HasMorePages = False
End If
End Sub
....
End Class
On a vu que pour 'simplifier', on considère que chaque ligne ne déborde pas à droite.
Dans la pratique, pour gérer les retours à la ligne automatiques on peut dessiner dans un rectangle en utilisant une surcharge de DrawString.
Dim rectangle As New RectangleF (100, 100, 150, 150 )
Dim T as String= "Chaîne de caractères très longue"
g.DrawString (T, Me.Font, New SolidBrush (ColorBlack), Rectangle)
On peut mesurer la longueur (ou le nombre de lignes) d'une chaîne:
Avec MeasureString
(Voir la page sur les graphiques.)
On peut sans passer par une 'boite de dialog' gérer directement l'imprimante, les marges, le nombre de copies..
Si pd est le PrintDocument:
pd.PrinterSetting désigne l'imprimante en cours
pd.PrinterSetting.PrinterName retourne ou définit le nom de cet imprimante
pd.PrinterSetting.Printerresolution donne la résolution de cette imprimante.
pd.PrinterSetting.installedPrinted donne toutes les imprimantes installées.
La propriété DefaultPageSetting est en rapport avec les caractéristiques de la page.
pd.PrinterSetting.DefaultPageSetting.Margins donne les marges
pd.PrinterSetting.PrinttoFile permettrait d'imprimer dans un fichier (non testé)
Imprime le formulaire en cours.
La routine CaptureScreen capture l'image du formulaire en cours et la met dans memoryImage. puis memoryImage est passé dans l'objet graphique e qui est imprimé.
Private Declare Function BitBlt Lib "gdi32.dll" Alias "BitBlt" (ByVal _
hdcDest As IntPtr, ByVal nXDest As Integer, ByVal nYDest As _
Integer, ByVal nWidth As Integer, ByVal nHeight As Integer, ByVal _
hdcSrc As IntPtr, ByVal nXSrc As Integer, ByVal nYSrc As Integer, _
ByVal dwRop As System.Int32) As Long
Dim memoryImage As Bitmap
Private Sub CaptureScreen()
Dim mygraphics As Graphics = Me.CreateGraphics()
Dim s As Size = Me.Size
memoryImage = New Bitmap(s.Width, s.Height, mygraphics)
Dim memoryGraphics As Graphics = Graphics.FromImage(memoryImage)
Dim dc1 As IntPtr = mygraphics.GetHdc
Dim dc2 As IntPtr = memoryGraphics.GetHdc
BitBlt(dc2, 0, 0, Me.ClientRectangle.Width, _
Me.ClientRectangle.Height, dc1, 0, 0, 13369376)
mygraphics.ReleaseHdc(dc1)
memoryGraphics.ReleaseHdc(dc2)
End Sub
Private Sub PrintDocument1_PrintPage(ByVal sender As System.Object, _
ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles _
PrintDocument1.PrintPage
e.Graphics.DrawImage(memoryImage, 0, 0)
End Sub
Private Sub PrintButton_Click(ByVal sender As System.Object, ByVal e As _
System.EventArgs) Handles PrintButton.Click
CaptureScreen()
PrintDocument1.Print()
End Sub
Imprime un contrôle DataGrid.
Cet exemple nécessite :
Comme d'habitude PrintPage imprime e.Graphics.
D'après ce que j'ai compris, l'évènement Paint redessine un contrôle
mais on peut choisir le contrôle et l'endroit ou le redessiner,
Je redessine donc grâce à Paint,le DataGrid dans e.graphics.
PaintEventArgs Fournit les données pour l'événement Paint:
PaintEventArgs spécifie l'objet graphics à utiliser pour peindre le contrôle, ainsi que le ClipRectangle dans lequel le peindre.
InvokePaint déclenche l'évènement Paint
Private Sub ImprimerGrid_Click(ByVal sender As System.Object, ByVal e As _
System.EventArgs) Handles PrintGrid.Click
PrintDocument1.Print()
End Sub
Private Sub PrintDocument1_PrintPage(ByVal sender As System.Object, _
ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles _
PrintDocument1.PrintPage
Dim myPaintArgs As New PaintEventArgs(e.Graphics, New Rectangle(New _
Point(0, 0), Me.Size))
Me.InvokePaint(DataGrid1, myPaintArgs)
End Sub
Voir Imprimer le contenu d'une RichtextBox
B- Imprimer comme en VB6 avec un objet 'Printer'
Microsoft propose un PowerPack de compatibilité vb6 le 'Microsoft.VisualBasic.PowerPacks.Printing.Printer' qui ajoute à VB 2005 une Classe permettant d'imprimer 'comme en VB6'; cela permet d'utiliser votre code de routine d'impression VB6 ou de créer des routines d'impression beaucoup plus simple!!
Télécharger le PowerPack Printercompatibility 1
Voir la Documentation complète
Après avoir installé le Pack, aller dans le menu Project cliquer sur 'Ajouter une référence'.
Sur l'onglet NET , cliquez sur Microsoft.VisualBasic.PowerPacks.Printing.Printer, puis sur OK.
Dans le Code, ajouter en haut du module:
Imports Microsoft.VisualBasic.PowerPacks.Printing.Compatibility.VB6
Maintenant on peut utiliser du code VB6 pour imprimer:
Dim pr As New Printer 'Instanciation de l'imprimante par défaut
Dim pFont As New Font("Arial", 14) 'Une nouvelle font
pr.Font = pFont
pr.Print("This text will print in 14 point ") 'Texte à imprimer
pr.EndDoc() 'fin, on lance l'impression
Simple, non!! Je plaisante pas!!
DrawMode, DriverName, hDC, Port, TrackDefault, et Zoom n'existent plus.
Par contre il y a en plus: PrintAction property qui permet un print preview ou permet d'imprimer dans un fichier.
Il y a aussi la PrinterCollection class qui contient les imprimantes . La global Printers collection permet de sélectionner une imprimante.