Newsgroup: it.comp.lang.visual-basic
Titolo: [VB6] Problema impostazioni stampa (printer e CommonDialog)

Ciao a tutti :)
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

 non ha tutte le proprietà di commondialog.
Commondialog.PrinterDefault = true
Bye, G. 

Paperino ha scritto:

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

 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

 completo :)
posta, posta :)
grazie e ciao, a.

andrea palazzi ha scritto:

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

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.
