|
C'è un motivo per cui ho posizionato proprio qui questo capitolo, che in apparenza avrebbe dovuto trovarsi nella sezione B: per
stampare bisogna usare... la grafica! E già, bisogna disegnarsi tutto da sé.
Il controllo PrintDialog serve soltanto a scegliere le impostazioni adatte e la stampante giusta, ma il resto viene fatto per mezzo di un
altro oggetto PrintDocument, che espone il metodo Print. Non deve ingannare questo nome, poiché dà solamente inizio al processo,
ma ogni operazione deve essere svolta dal programmatore. Infatti, una volta avviato, viene lanciato l'evento PrintPage, generato ogniqualvolta
ci sono una o più pagine da stampare. All'intero del sottoscrittore di questo evento va scritto il codice. Ad esempio, si prenda
l'esempio del capitolo F5, aggiungendo poi un pulsante cmdPrint (Text = "Stampa"). Ecco il codice:
'Ricordarsi di importare questo namespace
Imports System.Drawing.Printing
Class Form1
'...
Private Sub cmdPrint_Click(ByVal sender As Object, _
ByVal e As EventArgs) Handles cmdPrint.Click
'Una nuova finestra di dialogo per la stampante
Dim PrintDialog As New PrintDialog
'Il nuovo oggetto che fa da mediatore tra l'utente e
'la stampante
Dim PrintDoc As New PrintDocument
With PrintDialog
'Determina se sia possibile stampare su un file
.AllowPrintToFile = False
'Determina se sia possibile stampare solo la
'selezione. In questo caso non c'è nessuna selezione
'quindi non ci sono problemi a disativare
'l'impostazione
.AllowSelection = False
'Determina se sia possibile stampare delle pagine in
'particolare. Vale lo stesso discorso fatto sopra
.AllowSomePages = False
'Assegna l'oggetto PrintDoc a Document, così da
'collegare le impostazioni selezionate al documento
.Document = PrintDoc
End With
If PrintDialog.ShowDialog = Windows.Forms.DialogResult.OK Then
'Copia le impostazioni di stampa nel documento
PrintDoc.PrinterSettings = PrintDialog.PrinterSettings
'Quindi aggiunge l'handler d'evento per Printpage
AddHandler PrintDoc.PrintPage, AddressOf PrintDocument_PrintPage
'Il nome del documento visualizzato sulla finestra
'di stampa
PrintDoc.DocumentName = "Grafico a torta"
'Fa partire il processo di stampa
PrintDoc.Print()
End If
End Sub
Private Sub PrintDocument_PrintPage(ByVal sender As Object, _
ByVal e As PrintPageEventArgs)
'Bisogna considerare anche i margini della pagina, perciò
'sposta l'origine più in basso, come specificato
'dai margini superiore e sinistro selezionati in PrintDialog
e.Graphics.RenderingOrigin = New Point(e.MarginBounds.Left, _
e.MarginBounds.Top)
'In questo caso le operazioni sono molto semplici: basta
'"disegnare" sulla stampante (ossia sullo stream che
'permette l'interazione con essa) gli stessi elementi
'presenti nella lista Items
For Each Item As GraphItem In Me.Items
Item.Draw(e.Graphics)
Next
'Sicuramente ci sta tutto in una pagina, quindi specifica
'che non ci sono più pagine da stampare.
e.HasMorePages = False
End Sub
End Class
Ora spostiamoci su qualcosa di meno semplice. Bisogna stampare un file di testo. Ecco un esempio del codice di stampa:
Class Form1
Private Reader As IO.StreamReader
Private Sub cmdPrintFile_Click(ByVal sender As Object, _
ByVal e As EventArgs) Handles cmdPrintFile.Click
Dim PrintDialog As New PrintDialog
Dim Open As New OpenFileDialog
Dim PrintDoc As New PrintDocument
With PrintDialog
.AllowPrintToFile = False
.AllowSelection = False
.AllowSomePages = False
.Document = PrintDoc
End With
Open.Filter = "File di testo|*.txt"
If Open.ShowDialog = Windows.Forms.DialogResult.OK Then
Reader = New IO.StreamReader(Open.FileName)
Else
Exit Sub
End If
If PrintDialog.ShowDialog = Windows.Forms.DialogResult.OK Then
PrintDoc.PrinterSettings = PrintDialog.PrinterSettings
AddHandler PrintDoc.PrintPage, AddressOf PrintFile_PrintPage
PrintDoc.DocumentName = IO.Path.GetFileName(Open.FileName)
PrintDoc.Print()
End If
End Sub
Private Sub PrintFile_PrintPage(ByVal sender As Object, _
ByVal e As PrintPageEventArgs)
'Imposta l'unità di misura per le misurazioni
'successive
e.Graphics.PageUnit = GraphicsUnit.Pixel
'Il font per il testo da stampare: Times New Romand 12pt
Static Font As New Font("Times New Roman", 12)
'Per sapere quante righe ci possono stare nella pagine,
'bisogna misurare l'altezza dei caratteri
Static CharHeight As Single = Font.GetHeight(e.Graphics)
'Calcola le linee di testo che possono stare in una pagina
Static TotalLines As Int16 = e.MarginBounds.Height / CharHeight
'La linea a cui si è arrivati a leggere
Dim LineIndex As Int16 = 1
'Il testo della riga
Dim Line As String
'Tiene conto della posizione attuale
Dim Y As Int16 = e.MarginBounds.Top
e.Graphics.RenderingOrigin = New Point(e.MarginBounds.Left, _
e.MarginBounds.Top)
Do
'Legge la riga di testo dal file
Line = Reader.ReadLine
'Si suppone che la larghezza della stringa sia minore
'di quella della pagina
e.Graphics.DrawString(Line, Font, Brushes.Black, _
e.MarginBounds.Left, Y)
Y += CharHeight
LineIndex += 1
Loop While (LineIndex < TotalLines) And Not (Reader.EndOfStream)
'Se il file è alla fine, non ci sono più pagine
'da stampare, altrimenti continua
e.HasMorePages = Not Reader.EndOfStream
If Reader.EndOfStream Then
Reader.Close()
End If
End Sub
End Class
In conclusione, si tratta di fare pratica, poiché la teoria è molto semplice.
Eccezioni alla regola
È pur vero che per stampare dati che abbiamo creato noi, nel nostro programma, è necessario usare un codice simile a quelli
sopra riportati, tuttavia esiste una scappatoia a questa fatica. Se il nostro obiettivo consiste solamente nello stampare un file per cui
esista un programma che ne gestisca la stampa, allora basta eseguire queste poche righe di codice:
Dim P As New Process
P.StartInfo.FileName = "file da stampare"
P.StartInfo.Verb = "Print"
P.Start()
Il processo avviato gestirà la stampa del file mediante un programma esterno. Come già detto, però, è necessario
che esista un programma del genere installato sulla macchina dell'utente. Per controllare la possibilità di eseguire questo codice,
bisogna verificare l'esistenza della chiave HKEY_CLASSES_ROOT[extkey]shellprintcommand, dove [extkey] è il valore predefinito
della chiave il cui nome corrisponde all'estensione del file da stampare. Ad esempio, vogliamo stampare il file "readme.txt". Essendo
un file di testo, cerchiamo nel registro di sistema la chiave HKEY_CLASSES_ROOT.txt. Il suo valore (Predefinito) è "txtfile".
Rechiamoci allora alla chiave HKEY_CLASSES_ROOT xtfile: verifichiamo che esista la sottochiave shellprintcommand. Esiste! Quindi siamo
a posto.
Si può ripetere lo stesso procedimento per tutti i tipi di file. Per sapere come ispezionare il registro di sistema da codice,
vedere capitolo relativo. |
|