Questo sito utilizza cookies, anche di terze parti, per mostrare pubblicità e servizi in linea con il tuo account. Leggi l'informativa sui cookies.
Username: Password: oppure
Guida al Visual Basic .NET - Usare la stampante

Guida al Visual Basic .NET

Capitolo 98° - Usare la stampante

<< Precedente Prossimo >>

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.

<< Precedente Prossimo >>
A proposito dell'autore

Programmatore e analista .NET 2005/2008/2010 (in particolare C# e VB.NET), anche nell'implementazione Mono per Linux. Conoscenze approfondite di Pascal, PHP, XML, HTML 4.01/5, CSS 2.1/3, Javascript (e jQuery). Conoscenze buone di C, LUA, GML, Ruby, XNA, AJAX e Assembly 68000. Competenze basilari di C++, SQL, Hlsl, Java.