Newsgroup: it.lavoro.informatica
Titolo: Quiz a oggetti

Il codice riportato qui sotto proviene dal sito-Forum 
VB.NET
.
E' ricco di esempi di ogni tipo.
Affascinato dal fatto di risolvere il mio problema con sole 27 righe di 
codice (di cui 10 commenti), l'ho copiaincollato e messo nel compilatore 
  Visual Basic 2008 Professional.
Il programma causa la scrittura di cinque righe, una per ogni pagina. In 
tutto si hanno cinque pagine perfette.
(Quindi, a rigor di logica, una istruzione 'new Page' deve intervenire 
inqualche modo cinque volte).
Ora, nella pia illusione di poter finalmente capirci qualcosa di più
nelle classi usate nell'esempio, ho voluto fare dei test, cioè 
modificando qui e la, togliendo uno statement  e dopo rimetterlo, per 
vedere il comportamento del programma.
La mia indagine era rivolta a capire *che cosa* causa, in questo 
esempio, il salto di pagina.
(Se voi pensate che sia causato dagli HasMorePages  vi sbagliate di 
grosso. Provate a toglierli, interescambiarli, rimetterli, sarete 
sorpresi dalla varietá di comportamento illogico).
Ebbene, se qualcuno, modificando questo esempio, riesce a far stampare 3 
righe su una pagina e le restanti due righe sulla seguente, mi ha 
aiutato definitivamente a trovare quello che cercavo.
(E se passa da Genova ha vinto una cena in un ristorante eccellente in 
riva al mare).
Grazie per l'attenzione.
----------------------------------------------------------------------------
Private Sub btnPrint_Click(ByVal sender As System.Object, ByVal e As 
System.EventArgs) Handles btnPrint.Click
     Dim prn As New Printing.PrintDocument
     ' Select the PDF Printer
     prn.PrinterSettings.PrinterName = "pdf995"
     ' Handle the page events
     AddHandler prn.PrintPage, AddressOf Me.PrintPageHandler
     ' Do the print (Printing handled by the print page handler)
     prn.Print()
     ' Remove the page handler
     RemoveHandler prn.PrintPage, AddressOf Me.PrintPageHandler
End Sub
Private Sub PrintPageHandler(ByVal sender As Object, ByVal args As 
Printing.PrintPageEventArgs)
     Static i As Integer = 0
     i = i + 1
     ' Print a line on this page
     args.Graphics.DrawString("Printed a Line on page " & i.ToString, 
New Font(Me.Font, FontStyle.Regular), Brushes.Black, 50, 50)
     ' Have we printed enough pages?
     If i >= 5 Then
         ' Done all the pages
         i = 0
         args.HasMorePages = False
     Else
         ' Not finished, yet
         args.HasMorePages = True
    End If
End Sub
-------------------------------------------------------------------------------

 aiutato definitivamente a trovare quello che cercavo.
Scusa, ma ammesso e non concesso che con le classi standard non si
riesca a gestire in modo "tranquillo" la paginazione, perchè non trovi
una via alternativa? Ad esempio una libreria che produce un Pdf.
Non so cosa devi stampare, ma naturalmente non è fantascientifico
scrivere una classe senza fronzoli che stampa solo testo con un font
prefissato su foglio prefissato, es. A4. Per una cosa così, un classe
"standard" con l'evento mi sembra sparare alla mosca con l'88 :-)

 una via alternativa? Ad esempio una libreria che produce un Pdf.
il problema non č il pdf. Infatti io quello statement l'ho tolto.
Il problema č di arrivare a fare stampare  a *chiunque*, con 'qualsiasi 
stampante (quella di default del sistema) usi il programma, tramite una 
opzione sul menu, quello che appare in un testo di RichTextBox.
 > Non so cosa devi stampare, ma naturalmente non č fantascientifico
 > scrivere una classe senza fronzoli che stampa solo testo con un font
 > prefissato su foglio prefissato, es. A4. Per una cosa cosě, un classe
 > "standard" con l'evento mi sembra sparare alla mosca con l'88 :-)
Lo speravo anch'io, ma, dato che non ho ancora abbastanza esperienza con 
le classi .NET speravo almeno di poter 'capire' dagli esempi come si 
doveva procedere.
E invece nisba.
(E non voglio emmeno toccare la vecchia polemica che ai tempi 
'procedurali' risalire a 'quello che faceva un programma', anche se con
spaghetti-code, era immensamente piů facile risalire a fare il 
flow.chart, cioé a capire benissimo quello che faceva.
Con gli oggetti te lo sogni. Ce ne sono migliaia e anche 'nascosti', che 
per capire cosa fa veramente un programma e *come* lo fa,  devi avere 
una biblioteca intera e spenderci degli anni ad analizzarlo).


Non provo, ma a naso modificando così la sub handler dell''evento PrintPage, 
non va? :
Private Sub PrintPageHandler(ByVal sender As Object, ByVal args As
Printing.PrintPageEventArgs)
     Static i As Integer = 0
     i = i + 1
    if i = 1 then
             args.Graphics.DrawString("Printed a Line on page " & 
i.ToString,
New Font(Me.Font, FontStyle.Regular), Brushes.Black, 50, 50)
             args.Graphics.DrawString("Printed a Line on page " & 
i.ToString,
New Font(Me.Font, FontStyle.Regular), Brushes.Black, 50, 50)
             args.Graphics.DrawString("Printed a Line on page " & 
i.ToString,
New Font(Me.Font, FontStyle.Regular), Brushes.Black, 50, 50)
             args.HasMorePages = True
    else
             args.Graphics.DrawString("Printed a Line on page " & 
i.ToString,
New Font(Me.Font, FontStyle.Regular), Brushes.Black, 50, 50)
             args.Graphics.DrawString("Printed a Line on page " & 
i.ToString,
New Font(Me.Font, FontStyle.Regular), Brushes.Black, 50, 50)
             i = 0
            args.HasMorePages = False
    end if
End Sub

 PrintPage, non va? :
hai provato a farlo girare ? Penso che avrai delle sorprese.
Io ho fatto di più : l'ho messo dentro un loop.
sia l' e.Graphics.blablabla, sia il prn.print nella 'calling sub'
Niente da fare.


Ah, pardon, aggiorna la coordinata y in ogni chiamata a DrawString, 
altrimenti immagino che le righe escano una sopra l'altra...


Provato, e funziona, tieni conto come dicevo nell'altro post che devi 
aggiornare la coordinata y per ogni riga, altimenti te le stampa una sopra 
l'altra...
Imports System.Drawing
Module Module1
    Sub Main()
        Dim prn As New Printing.PrintDocument
        ' Select the PDF Printer
        prn.PrinterSettings.PrinterName = "PDFCreator"
        ' Handle the page events
        AddHandler prn.PrintPage, AddressOf PrintPageHandler
        ' Do the print (Printing handled by the print page handler)
        prn.Print()
        ' Remove the page handler
        RemoveHandler prn.PrintPage, AddressOf PrintPageHandler
    End Sub
    Private Sub PrintPageHandler(ByVal sender As Object, ByVal args As 
Printing.PrintPageEventArgs)
        Static i As Integer = 0
        i = i + 1
        If i = 1 Then
            args.Graphics.DrawString("Printed a Line on page " & i.ToString, 
New Font("Arial", 16), Brushes.Black, 50, 50)
            args.Graphics.DrawString("Printed a Line on page " & i.ToString, 
New Font("Arial", 16), Brushes.Black, 50, 150)
            args.Graphics.DrawString("Printed a Line on page " & i.ToString, 
New Font("Arial", 16), Brushes.Black, 50, 250)
            args.HasMorePages = True
        Else
            args.Graphics.DrawString("Printed a Line on page " & i.ToString, 
New Font("Arial", 16), Brushes.Black, 50, 50)
            args.Graphics.DrawString("Printed a Line on page " & i.ToString, 
New Font("Arial", 16), Brushes.Black, 50, 150)
            i = 0
            args.HasMorePages = False
        End If
    End Sub
End Module


Perfetto. Adesso lo trasporto sul mio test (il mio fa un FOR loop)
e ti so dire se fa esattamente quello che voglio.
Se lo fa, passa pure a ritirare il premio :-)))

 seguente, mi ha aiutato definitivamente a trovare quello che cercavo.
Mmm... visto che mi sa che ti manca un po' di teoria, ti do due
indicazioni.
Il sistema di stampa prevede sostanzialmente alcuni message handlers:
il primo viene scatenato per richiedere l'inizializzazione della
pagina, e si chiama, guarda caso, QueryPageSettings; il secondo,
BeginPrint, ti consente di fare tutte le inizializzazioni che ti
possono interesare; il terzo, PrintPage, ti consente la stampa di una
pagina (cosa ci metti è integralmente a carico tuo ); infine, EndPrint
ti consente di eseguire tutte le operazioni di pulizia sugli oggetti
eventualmente creati con BeginPrint.
Cio' che tu vedi come Graphics, e che ti viene passato come argomento,
rappresenta l'area di stampa dove tu, a manina, disporrai i tuoi
elementi grafici. Una volta che hai fatto tutto il lavoro di disegno -
ribadisco, completamente a carico tuo - esci dal message handler,
indicando se vuoi stampare ancora oppure no tramite HasMorePages; se
HasMorePages e' impostato a True, il message handler verra' chiamato
un'altra volta e, fisicamente, alla stampata verrà aggiunta una nuova
pagina.
Detto questo, veniamo alla tua richiesta. Per ottenere cio' che chiedi,
basta modificare l'handler che si occupa della stampa della pagina come
segue (nota, io ti do l'idea, il codice potrebbe essere errato, io
scrivo in C#, non in VB):
Private Sub PrintPageHandler(ByVal sender As Object, ByVal args As
Printing.PrintPageEventArgs)
    Static i As Integer = 0
    Dim index as integer
    Dim max as integer
    i = i + 1
    If i = 1 Then
        max = 3
    Else
        max = 2
    End If
    ' Print lines on this page
    for index = 0 to max
        args.Graphics.DrawString("Printed Line" & index & " on page " &
i.ToString, New Font(Me.Font, FontStyle.Regular), Brushes.Black, 50, 50
+ 15 * index)
    Next
    ' Have we printed enough pages?
    If i = 2 Then
        ' Done all the pages
        i = 0
        args.HasMorePages = False
    Else
        ' Not finished, yet
        args.HasMorePages = True
   End If
End Sub
Cio' che in effetti io vedo fuorviante, in questo esempio, è l'uso di
una variabile di tipo static. Io preferisco sempre metterla come membro
della classe, in modo che sia ben chiaro che il contatore e'
indipendente dell'handler. Aggiungo: nelle tue sperimentazioni, non
aver paura di mettere breackpoints 'per vedere di nascosto l'effetto
che fa': ti avrebbe consentito di scoprire che, per quella funzione, ci
si passava due volte!
-- 
Ciao!
Luca

 riva al mare).
Merda! Una volta tanto che vedo una proposta di lavoro
seria non ho le competenze!