Newsgroup: it.comp.lang.visual-basic
Titolo: VB2005: come stampare il testo contenuto in una textbox?

Scusate se è una domanda banale, ma ho ancora la forma mentis del Visual 
Basic 6 e la nuova gestione della stampa mi lascia disorientato.
Ho una form contenente una textbox, di cui devo poter stampare tutto il 
contenuto oppure la parte selezionata dall'utente. Ho un pulsante "Stampa" 
che attiva la seguente sub:
Sub FilePrint()
        Dim MyResult As System.Windows.Forms.DialogResult
        With frmMain.cdlPrintPrint
            .AllowSelection = True
            .AllowSomePages = False
            MyResult = frmMain.cdlPrintPrint.ShowDialog()
            If MyResult = DialogResult.Cancel Then
                'L'utente ha scelto il pulsante Annulla
                Err.Clear()
            Else
                frmMain.PrintDocument1.Print()
            End If
        End With
    End Sub
Tutto quello che accade ora eseguendo questa funzione, però, è che la 
stampante si mette a sputare pagine e pagine totalmente vuote.
Ho il sospetto che l'errore sia nell'istruzione 
frmMain.PrintDocument1.Print(), visto che non esiste qualcosa che specifica 
COSA devo stampare. Ma come faccio per specificarlo? 

Ulteriori informazioni. Nella guida in linea ho trovato la seguente sub, che 
ho adattato per usarla nel mio programma:
Private Sub printButton_Click(sender As Object, e As EventArgs)
        Try
            streamToPrint = New StreamReader("C:\My Documents\MyFile.txt")
            Try
                printFont = New Font("Arial", 10)
                Dim pd As New PrintDocument()
                AddHandler pd.PrintPage, AddressOf Me.pd_PrintPage
                pd.Print()
            Finally
                streamToPrint.Close()
            End Try
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
    End Sub
Però quella sub mi dà l'errore "Tipo StreamReader non definito".
Ho letto nella pagina 
http://support.microsoft.com/default.aspx?scid=kb%3Bit%3BI302309
 che per 
usare il tipo StreamReader serve aggiungere i seguenti imports 
nell'assembly:
Imports System
Imports System.IO
Imports System.Collections
Ma io ce li ho già! Perchè mi appare l'errore di tipo non definito? 

 ha scritto nel messaggio 
news:45701308$0$19245$4faf...@reader4.news.tin.it...

Allora, dividiamo i problemi:
1) Lo StreamReader che è definito in System.IO
L'imports è a livello di modulo e non di Assembly, a meno che non lo 
specifichi tra gli imports automatici nelle proprietà di progetto.
2) Devi definire il codice di stampa nella pd_PrintPage che ovviamente avrai 
dichiarato decondo il prototipo del delegate appropriato (vedi la 
definizione di pd.PrintPage a tal proposito, ma credo che VS ti proponga già 
tutto lui).
Se non gli dici di stampare il testo come puoi pretendere di avere qualcosa 
sui forgli?
Se ti interessa puoi anche usare la mia libreria per la stampa 
www.neodatatype.net
Ciao

 già tutto lui).
Questa è una cosa che non ho capito, perchè il componente PrintDocument l'ho 
messo nella form principale dell'applicazione. Inserire la linea "Dim pd As 
New PrintDocument()" come scritto nell'help fa apparire l'errore "Tipo 
"PrintDocument" non definito", mentre la linea "AddHandler pd.PrintPage, 
AddressOf Me.pd_PrintPage" fa apparire la scritta ""Me" non valido 
all'interno di un modulo (ma se metto l'imports all'interno di un modulo, 
devo per forza mettere la funzione di stampa all'interno di quel modulo... 
no?) 

 funzione di stampa all'interno di quel modulo... no?)
No.
Bisogna solo sapere mettere insieme i pezzi, cioè le basi di 
vb.net
Ciao 

 Allora puoi buttare l'addhandler e usare l'evento PrintPage.
Ma... ehm... come gestisco l'evento PrintPage senza l'AddHandler? Devo 
richiamare da qualche parte la sub pd_PrintPage che si trova nella guida?
In quel caso, cosa mi serve per gestire il tipo PrintPageEventArgs? 

> In quel caso, cosa mi serve per gestire il tipo PrintPageEventArgs?
Di questo ho trovato la risposta da solo (Imports System.Drawing.Printing), 
ma l'altra domanda resta: come gestisco l'evento PrintPage senza 
l'AddHandler? 

 ha scritto nel messaggio news:457050d0$0$13753

Doppioclick sul printdocument?
Ciao 


E questo crea la sub "pd_PrintPage_1" (la cui creazione tra l'altro è 
buggata, perchè la variabile di tipo "PrintPageEventArgs" viene chiamata "e" 
nell'intestazione ed "ev" nel corpo della sub, ma pazienza) dentro alla 
quale ho incollato il contenuto della sub "pd_PrintPage" dell'help, ma resta 
ancora un problema: il lancio della stampa fallisce con l'errore 
"Riferimento a un oggetto non impostato su un'istanza di oggetto", mentre di 
pd_PrintPage_1 viene eseguita solo la prima riga (linesPerPage = 
ev.MarginBounds.Height / printFont.GetHeight(ev.Graphics) ) o forse neanche 
quella. Lo stesso problema è presente anche utilizzando l'AddHandler (avevo 
fatto una prova prima che tu mi rispondessi).

Okay, siccome il messaggio precedente potrebbe essere confuso, ricapitolo in 
quest'altro quello che ho fatto.
Precisazione: siccome l'help in linea spiega come stampare il contenuto di 
un file, anch'io ho impostato il progetto in modo da fargli stampare il 
contenuto di un file.
La mia form contiene un controllo di tipo PrintDocument chiamato "pd" e un 
pulsante che richiama una sub chiamata FilePrint.
Il contenuto della sub FilePrint č il seguente:
Sub FilePrint()
        Dim MyResult As System.Windows.Forms.DialogResult
        Dim streamToPrint As StreamReader
        Dim printFont As Font
        With Me.cdlPrintPrint
            .AllowSelection = True
            .AllowSomePages = False
            MyResult = Me.cdlPrintPrint.ShowDialog()
            If MyResult = DialogResult.Cancel Then
                'L'utente ha scelto il pulsante Annulla
                Err.Clear()
            Else
                Try
                    streamToPrint = New StreamReader("c:\provastampa.txt")
                    Try
                        printFont = New Font("Arial", 10)
                        pd.Print() 'pd č un controllo di tipo PrintDocument
                    Finally
                        streamToPrint.Close()
                    End Try
                Catch ex As Exception
                    MessageBox.Show(ex.Message)
                End Try
            End If
        End With
    End Sub
Al controllo di tipo PrintDocument č associata una sub chiamata 
pd_PrintPage_1, che contiene quanto segue:
Private Sub pd_PrintPage_1(ByVal sender As System.Object, ByVal ev As 
System.Drawing.Printing.PrintPageEventArgs) Handles pd.PrintPage
        Dim linesPerPage As Single = 0
        Dim yPos As Single = 0
        Dim count As Integer = 0
        Dim leftMargin As Single = ev.MarginBounds.Left
        Dim topMargin As Single = ev.MarginBounds.Top
        Dim line As String = Nothing
        ' Calculate the number of lines per page.
        linesPerPage = ev.MarginBounds.Height / 
printFont.GetHeight(ev.Graphics)
        ' Print each line of the file.
        While count < linesPerPage
            line = streamToPrint.ReadLine()
            If line Is Nothing Then
                Exit While
            End If
            yPos = topMargin + count * printFont.GetHeight(ev.Graphics)
            ev.Graphics.DrawString(line, printFont, Brushes.Black, 
leftMargin, yPos, New StringFormat())
            count += 1
        End While
        ' If more lines exist, print another page.
        If Not (line Is Nothing) Then
            ev.HasMorePages = True
        Else
            ev.HasMorePages = False
        End If
    End Sub
Quando premo il pulsante nella mia form (quello che dovrebbe avviare la 
stampa), per prima cosa appare (giustamente) la finestra di impostazione 
della stampa.
Dopo che ho premuto OK, la sub FilePrint viene eseguita fino alla linea 
"pd.Print()", e a quel punto l'esecuzione passa alla sub pd_PrintPage_1.
In questa sub, l'unica linea che viene eseguita č "linesPerPage = 
ev.MarginBounds.Height / printFont.GetHeight(ev.Graphics)", poi l'esecuzione 
torna immediatamente alla sub FilePrint, alla linea "Finally".
Viene chiuso streamToPrint, poi viene rilevata un'eccezione, visualizzata 
per mezzo della linea "MessageBox.Show(ex.Message). Il messaggio 
visualizzato č "Riferimento a un oggetto non impostato su un istanza di 
oggetto.".
Ora, capisco che in teoria dovrei fare l'istanza di un oggetto (Dim 
<oggetto> As New <tipo>), ma in pratica... di quale oggetto dovrei farla? 

 <oggetto> As New <tipo>), ma in pratica... di quale oggetto dovrei farla?
Così a occhio ti direi printFont, che non è dichiarato.
Questi problemi li potresti evitare impostando nelle proprietà di progetto 
Option Strict On e Option Explicit On.
Poi, un po' di fantasia!
Metti un breakpoint sulla riga incriminara, rifai il giro passo passo (F8) e 
con il mouse controlli quali sono le variabili a nothing.
Ciao 

 Option Strict On e Option Explicit On.
Ehm, grazie, era proprio quella (tra l'altro, visto che è usata da 2 
funzioni, ora l'ho dichiarata come globale).
Però, risolto questo problemino, resta il problemone che la stampante 
continua a sputare un foglio bianco invece di stampare il contenuto del 
file... 

 ha scritto nel messaggio 
news:457404cd$0$7629$4faf...@reader1.news.tin.it...

Qui non ti posso aiutare: fatti un po' di debug e vedi, ad es. se le 
coordinate sono corrette, se line contiene effettivamente qualcosa ecc...
Eventualmente, se non vuoi buttare un mucchio di fogli in prove assegna il 
pd a un PrintDialog o a un PrintPreviewControl in modo da avere a video 
l'anteprima di stampa.
Ciao