Vorrei stampare il contenuto del mio form non usando form.printform e
perciò catturo lo schermo nella clipboard e poi stampo l'immagine presa
da quest'ultima. La cosa funziona ma ho problemi quando richiamo
Form.CommonDialog1.ShowPrinter: la finestra stampante & opzioni viene
mostrata correttamente, gestisco l'handler dell'errore 32755 (caso
pressione bottone annulla) senza problemi ma le impostazioni di carta e
qualità non vengono applicate correttamente. Per l'orientamento del
foglio, il problema è risolubile con Printer.Orientation =
Form.CommonDialog1.Orientation ma per tutte le altre opzioni (qualità,
formato carta, colori etc) l'oggetto printer non ha tutte le proprietà
di commondialog.
Riporto il codice, che è praticamente uno dei tanti esempi che si
trovano in rete:
-begin_code
Const KEYEVENTF_KEYUP = &H2
Dim pic As StdPicture
Dim larghezza As Long
Dim altezza As Long
Dim correzione As Long
Dim Faktor1 As Single
Dim Faktor2 As Single
On Error GoTo ErrorHandler
Me.MousePointer = 11
Set pic = Clipboard.GetData(vbCFBitmap)
keybd_event vbKeyMenu, 0, 0, 0
keybd_event vbKeySnapshot, 0, 0, 0
DoEvents
keybd_event vbKeySnapshot, 0, KEYEVENTF_KEYUP, 0
keybd_event vbKeyMenu, 0, KEYEVENTF_KEYUP, 0
DoEvents
Set SaveFormPic = Clipboard.GetData(vbCFBitmap)
Clipboard.SetData pic, vbCFBitmap
Form.CommonDialog1.ShowPrinter
Form.CommonDialog1.PrinterDefault = True
Printer.ScaleMode = vbPixels
larghezza = Printer.ScaleX(SaveFormPic.Width, vbHimetric, vbPixels)
altezza = Printer.ScaleY(SaveFormPic.Height, vbHimetric, vbPixels)
correttore = 30
Faktor1 = (Printer.ScaleWidth - correttore) / larghezza
Faktor2 = (Printer.ScaleHeight - correttore) / altezza
If Faktor2 < Faktor1 Then
Faktor1 = Faktor2
End If
Printer.PaintPicture SaveFormPic, 0, 0, larghezza * Faktor1, altezza *
Faktor1
Printer.EndDoc
Set SaveFormPic = Nothing
Me.MousePointer = 0
ErrorHandler:
If Err.Number = 32755 Then
Me.MousePointer = 0
Exit Sub
End If
--end_code
In pratica, vorrei che la stampa seguisse le opzioni che imposto dalla
proprietà stampante :)
Grazie in anticipo
Lenny
Commondialog.PrinterDefault = true
Bye, G.
Grazie, ma se leggi con attenzione il mio post puoi notare che nel
codice riportato c'è già l'impostazione Commondialog.PrinterDefault =
true. E' stata la prima cosa che ho controllato, ma sembra non avere
alcun effetto sulla stampa: le impostazioni della stampante che cambio
mediante Commondialog non vengono "applicate" alla stampa che ne consegue.
Uso Windows XP SP3 e Visual Basic 6 sp6.
Ciao :)
Lenny
Sì, vedo, ma siccome il problema è esattamente quello tipico,
sono andato tranquillo senza leggere il codice.
E sai una cosa ? Mi sa che avevo ragione lo stesso...
> E' stata la prima cosa che ho controllato, ma sembra non avere alcun effetto
> sulla stampa
Se lo usi "dopo" lo .showprinter, ci credo :-).
Bye, G.
Hehe, ho controllato anche questa eventualità prima di postare il mio
primo messaggio. Non cavando il classico ragno dal buco, ho optato per
una soluzione radicale: la libreria VBPrnDlg.dll che viene da una KB
Microsoft (http://support.microsoft.com/kb/322710/en-us). Ora la stampa
funziona perfettamente, e questa dll espone tutte le altre proprietà di
stampa che CommonDialog non ha. Se a qualcuno interessa, posto il codice
completo :)
Ti ringrazio comunque dei suggerimenti :)
Lenny
posta, posta :)
grazie e ciao, a.
Accludo il codice VB6 che serve a stampare il Form attivo (con le
impostazioni della stampante desiderate):
'---BEGIN---
Private Sub Imposta_stampante_Click()
Const KEYEVENTF_KEYUP = &H2
Dim printDlg As PrinterDlg
Set printDlg = New PrinterDlg
Dim NewPrinterName As String
Dim objPrinter As Printer
Dim strsetting As String
Dim pic As StdPicture
Dim Larghezza As Long
Dim Altezza As Long
Dim correzione As Long
Dim Fattore1 As Single
Dim Fattore2 As Single
On Error GoTo ErrorHandler
' Qui salvo una snapshot del form nella clipboard;
' successivamente (una volta impostata la stampante)
' stampo questa immagine recuperandola dalla clipboard.
Me.MousePointer = 11
' Salvo il contenuto corrente della clipboard in pic
Set pic = Clipboard.GetData(vbCFBitmap)
keybd_event vbKeyMenu, 0, 0, 0
keybd_event vbKeySnapshot, 0, 0, 0
DoEvents
keybd_event vbKeySnapshot, 0, KEYEVENTF_KEYUP, 0
keybd_event vbKeyMenu, 0, KEYEVENTF_KEYUP, 0
DoEvents
Set SaveFormPic = Clipboard.GetData(vbCFBitmap)
' Ora nella clipboard c'è una snapshot del form
' Ripristino il contenuto originale della clipboard
Clipboard.SetData pic, vbCFBitmap
Printer.ScaleMode = vbPixels
Larghezza = Printer.ScaleX(SaveFormPic.Width, vbHimetric, vbPixels)
Altezza = Printer.ScaleY(SaveFormPic.Height, vbHimetric, vbPixels)
correttore = 30
Fattore1 = (Printer.ScaleWidth - correttore) / Larghezza
Fattore2 = (Printer.ScaleHeight - correttore) / Altezza
If Fattore2 < Fattore1 Then Fattore1 = Fattore2
' Imposto i settaggi iniziali per il dialog box della stampante
' ricavandoli dalle impostazioni correnti dell'oggetto printer
printDlg.PrinterName = Printer.DeviceName
printDlg.DriverName = Printer.DriverName
printDlg.Port = Printer.Port
' imposto il cassetto di alimentazione predefinito per la stampante '
(PaperBin)
' in modo da avere un valore di default anche se si preme il tasto Cancel.
printDlg.PaperBin = Printer.PaperBin
' Set the flags for the PrinterDlg object using the same flags as in the
' common dialog control. The structure starts with VBPrinterConstants.
printDlg.Flags = VBPrinterConstants.cdlPDNoSelection _
Or VBPrinterConstants.cdlPDNoPageNums _
Or VBPrinterConstants.cdlPDReturnDC
Printer.TrackDefault = False
If Not printDlg.ShowPrinter(Me.hWnd) Then Exit Sub
' Individua la stampante selezionata dall'utente nel dialog box stampante
NewPrinterName = UCase$(printDlg.PrinterName)
If Printer.DeviceName <> NewPrinterName Then
For Each objPrinter In Printers
If UCase$(objPrinter.DeviceName) = NewPrinterName Then
Set Printer = objPrinter
End If
Next
End If
' Copia delle impostazioni stampante da printDialog a oggetto printer
' Defaults:
printDlg.ColorMode = 1
'
Printer.Copies = printDlg.Copies
Printer.Orientation = printDlg.Orientation
Printer.ColorMode = printDlg.ColorMode
Printer.Duplex = printDlg.Duplex
Printer.PaperBin = printDlg.PaperBin
Printer.PaperSize = printDlg.PaperSize
Printer.PrintQuality = printDlg.PrintQuality
' Print quality is the number of dots per inch.
With Printer
If .Orientation = 1 Then
strsetting = "Portrait. "
Else
strsetting = "Landscape. "
End If
If .ColorMode = 1 Then
strsetting = "Black and White. "
Else
strsetting = "Color. "
End If
If .Duplex = 1 Then
strsetting = "None. "
ElseIf .Duplex = 2 Then
strsetting = "Horizontal/Long Edge. "
ElseIf .Duplex = 3 Then
strsetting = "Vertical/Short Edge. "
Else
strsetting = "Unknown. "
End If
End With
' Ora posso stampare il contenuto della clipboard con le impostazioni
prescelte
Printer.PaintPicture SaveFormPic, 0, 0, Larghezza * Fattore1, Altezza
* Fattore1
Printer.EndDoc
Set SaveFormPic = Nothing
Me.MousePointer = 0
ErrorHandler:
If Err.Number = 32755 Then
Me.MousePointer = 0
Exit Sub
End If
End Sub
'---END---
Ciao, Lenny
ROTFL
--
-> GbC|
www.gbcweb.com
www.chiappori.com
Hai forse trovato qualche bug (o il codice non funziona)? O c'è
qualcos'altro? Sai, mi interessa molto l'opinione uno che "si occupa di
consulenza e sviluppo di applicazioni in ambiente Windows", hai visto
mai che possa migliorare il codice o sistemare qualche bug...
Lenny
>> ROTFL
>>
>
>Hai forse trovato qualche bug (o il codice non funziona)? O c'è
>qualcos'altro? Sai, mi interessa molto l'opinione uno che "si occupa di
>consulenza e sviluppo di applicazioni in ambiente Windows", hai visto
>mai che possa migliorare il codice o sistemare qualche bug...
Secondo me il suo ROTFL era perchè in VB6 per stampare il form attivo basta fare
Me.PrintForm
http://msdn.microsoft.com/it-it/library/3e2c3t1z(VS.80).aspx
Metodo PrintForm
Comunque ci sono diversi modi per ottenere la stessa funzione, forse il tuo non
è il + breve, ma non ti scoraggiare.
--
ciao
Stefano
No Lenny, non mi sento di commentare il codice; non credo ne valga la
pena perché è lineare e semplice :) Piuttosto... Vedo che hai aperto il
mio sito. Si, sviluppo sw da 15 anni. Hai presente il link ai prodotti
Buffetti in alto a destra? Ne ho circa 6.000 licenziati in Italia ed uno
di quei programmi è ancora il più venduto dalla catena Buffetti. Per
questo la mia opinione non è puramente 'estetica' ma orientata agli
aspetti speculativi della programmazione: tendo ad apprezzare di più ciò
che è pratico e vendibile piuttosto che il codioce bellissimo ma
inutilizzabile.
Veniamo a noi.
Sparare alle mosche col cannone non mi trova mai daccordo: tutto quel
codice in alternativa ad un PrintForm mi pare eccessivo. L'ho capito che
scala il form, ma anche questo ha poco senso perché dipende dalle
impostazioni di uindos e comunque, a parte poche eccezioni, non è una
logica di stampa perseguibile.
Per le stampe ho implementato in un form specifico, che generalmente
utilizzo sempre; eccone un esempio di utilizzo:
http://www.gbcweb.com/_d-eazyreport/_images/ER08_RepPrn_b.jpg
espone tutti gli attributi delle stampanti; uso sempre quello e poi
stampo da codice...
Mi creo le stampe a manina con un tool (questo è un esempio di una sua
applicazione)
http://www.gbcweb.com/_d-eazyreport/_images/prvrep_b.jpg
che ho scritto tanto ma tanto tempo fa.
Trovo che la complicazione in queste faccende non sia 'stampare' ma
'stampare quello che vuole il committente', che normalmente chiede anche
l'impossibile. Se poi sviluppi sw la possibilità di accedere alle
proprietà della stampante con una interfaccia standard e la possibilità
di generare e modificare facilmente e rapidamente una stampa sono la
differenza tra guadagnare e rimetterci.
Ciao cia' e scusa per il ROTFL che forse è esagerato.