Newsgroup: it.comp.lang.visual-basic
Titolo: [?] API PrintDialog e XP

Cercherò di spiegarmi: Come sapete il normale CommonDialog.ShowPrinter in
ambiente NT/2000/XP crea un po' di pasticci (documentati in MSDN)
nell'operatività.
Bene, allora, per tali SO, uso da molto tempo (VB6 SP5) la PrintDialog,
copiata pari-pari dall'esempio in 
www.allapi.net
. (non la posto perchè è
lunghetta con tutti i suoi TYPE e API collegate)
Ora che succede (sia in ambiente di sviluppo VB che in EXE compilato)?
Sulla mia macchina (XP Pro) quando la PrintDialog mostra la sua finestra,
questa è in primo piano, con il titolo di finestra attiva, ma, di fatto, è
come se fosse trasparente, cioè se ci clicco sopra in realtà clicco sulla
finestra da cui sono venuto che viene messa in primo piano, nascondendo la
PrintDialog che sembra scomparire. (Si noti invece che i tasti vengono
tranquillamente recepiti, compreso Esc che la chiude). La PrintDialog è la
dietro, infatti basta ripetere, ridurre a icona la finestra chiamante e la
PrintDialog è pronta all'uso e perfettamente funzionante. Il problema non si
presenta in ambiente Win9x, pur forzando l'uso della PrintDialog.
Ora, e qui mi sono sdraiato, se metto anche un solo F9 nel mio progetto,
meraviglia delle meraviglie, tutto funziona. Furbo come sono (? sig !) mi
sono detto: Ti frego io, ti strafogo di DoEvents e risolvo. Beh, ne ho messi
tanti quante sono le istruzioni, non c'è verso, il problema permane. Non è
drammatico, ma se ci fosse qualcosa da fare (tranne pregare)... Grazie.

 wrote in message
news:u6rL8.7334$K4.1...@twister2.libero.it...
[CUT]
Ho provato ad utilizzare l'api GetOpenFileName sia su WinXp Pr che su
Win2000 Pro. Non ha nessuno dei problemi da te indicati.
Ti posto il codice (preso pari pari da 
www.allapi.net
 [ma non chiude più?])
che ho utilizzato (magari prima di iniziare a pregare prova a vedere se ci
sono differenze sostanziali).
Spero che il NG non si offenda per la quantità di codice postato.
Option Explicit
Private Declare Function GetOpenFileName Lib "comdlg32.dll" Alias
"GetOpenFileNameA" (pOpenfilename As OPENFILENAME) As Long
Private Type OPENFILENAME
    lStructSize As Long
    hwndOwner As Long
    hInstance As Long
    lpstrFilter As String
    lpstrCustomFilter As String
    nMaxCustFilter As Long
    nFilterIndex As Long
    lpstrFile As String
    nMaxFile As Long
    lpstrFileTitle As String
    nMaxFileTitle As Long
    lpstrInitialDir As String
    lpstrTitle As String
    flags As Long
    nFileOffset As Integer
    nFileExtension As Integer
    lpstrDefExt As String
    lCustData As Long
    lpfnHook As Long
    lpTemplateName As String
End Type
Private Sub Command1_Click()
    'KPD-Team 1998
    'URL: 
http://www.allapi.net/
    'E-Mail: KPD...@Allapi.net
    Dim OFName As OPENFILENAME
    OFName.lStructSize = Len(OFName)
    'Set the parent window
    OFName.hwndOwner = Me.hWnd
    'Set the application's instance
    OFName.hInstance = App.hInstance
    'Select a filter
    OFName.lpstrFilter = "Text Files (*.txt)" + Chr$(0) + "*.txt" + Chr$(0)
+ "All Files (*.*)" + Chr$(0) + "*.*" + Chr$(0)
    'create a buffer for the file
    OFName.lpstrFile = Space$(254)
    'set the maximum length of a returned file
    OFName.nMaxFile = 255
    'Create a buffer for the file title
    OFName.lpstrFileTitle = Space$(254)
    'Set the maximum length of a returned file title
    OFName.nMaxFileTitle = 255
    'Set the initial directory
    OFName.lpstrInitialDir = "C:\"
    'Set the title
    OFName.lpstrTitle = "Open File - KPD-Team 1998"
    'No flags
    OFName.flags = 0
    'Show the 'Open File'-dialog
    If GetOpenFileName(OFName) Then
        MsgBox "File to Open: " + Trim$(OFName.lpstrFile)
    Else
        MsgBox "Cancel was pressed"
    End If
End Sub

Spero che il NG non si offenda per la quantità di codice postato.
Quando il codice funziona, non ci si offende mai, anzi ... ;-)
-- 
ciao, hal

 [CUT]
Pietro, grazie, ma avevo detto PrintDialog...

 ha scritto nel messaggio
news:ZMtL8.8564$K4.1...@twister2.libero.it...

Quindi quella che nell'esempio inizia con:
Public Sub ShowPrinter(frmOwner As Form, Optional PrintFlags As Long)

 ha scritto nel messaggio
news:adlp54$b264$1...@ID-56381.news.dfncis.de...

Per niente, anzi, però ... il codice che interessa (PrintDialog) ... ;-)))

Per niente, anzi, però ... il codice che interessa (PrintDialog) ... ;-)))
Adesso faccio il pigro un po' io ;-)
Cosa hai scritto di preciso?
Ho appena provato con il codice di una classe che uso in diversi programmi,
(ed e' pure un codice vecchio, perche' usa ancora la PrintDlg invece di
PrintDlgEx, come consigliato da m$ per 2000/XP), ma il problema
da te lamentato non si presenta.
Magari il problema non e' nemmeno nella chiamata che fai a PrintDlg,
ma in qualche altra apetta in giro per il tuo programma (magari di
tipo grafico, che usa il parametro hDC).
-- 
ciao, hal

 Cosa hai scritto di preciso?
Ecco, mancheranno un tot di TYPE e di Declare per API richiamate, ma il
nocciolo è qui:
Sub DIALOGO_STAMPA_NT(frmOwner As Form, Optional PrintFlags = 0, Optional
printdlgflags = 0)
NCAR = "DIALOGO_STAMPA_NT"
FSI NCAR
Dim PrintDlg As PRINTDLG_TYPE
Dim DevMode As DEVMODE_TYPE
Dim DevName As DEVNAMES_TYPE
Dim lpDevMode As Long, lpDevName As Long
Dim bReturn As Integer
Dim objPrinter As Printer, NewPrinterName As String
Dim strSetting As String
' Use PrintDialog to get the handle to a memory
' block with a DevMode and DevName structures
PrintDlg.lStructSize = Len(PrintDlg)
PrintDlg.hWndOwner = frmOwner.hwnd
PrintDlg.flags = PrintFlags
' Set the current orientation and duplex setting
DevMode.dmDeviceName = Printer.DeviceName
DevMode.dmSize = Len(DevMode)
'DevMode.dmFields = DM_ORIENTATION Or DM_DUPLEX
DevMode.dmFields = 2 ^ 31 - 1 'Alza tutti i bits di Long meno il piu' alto
(31)
On Error Resume Next
DevMode.dmOrientation = Printer.Orientation
DevMode.dmDuplex = Printer.Duplex
'
DevMode.dmPaperSize = Printer.PaperSize
DevMode.dmPrintQuality = Printer.PrintQuality
DevMode.dmColor = Printer.ColorMode
DevMode.dmDefaultSource = Printer.PaperBin
On Error GoTo errore
'
' Allocate memory for the initialization hDevMode structure
' and copy the settings gathered above into this memory
PrintDlg.hDevMode = GlobalAlloc(GMEM_MOVEABLE Or GMEM_ZEROINIT,
Len(DevMode))
lpDevMode = GlobalLock(PrintDlg.hDevMode)
If lpDevMode > 0 Then
CopyMemory ByVal lpDevMode, DevMode, Len(DevMode)
bReturn = GlobalUnlock(PrintDlg.hDevMode)
End If
' Set the current driver, device, and port name strings
With DevName
.wDriverOffset = 8
.wDeviceOffset = .wDriverOffset + 1 + Len(Printer.DriverName)
.wOutputOffset = .wDeviceOffset + 1 + Len(Printer.Port)
.wDefault = 0
End With
With Printer
DevName.extra = .DriverName & Chr(0) & .DeviceName & Chr(0) & .Port & Chr(0)
End With
' Allocate memory for the initial hDevName structure
' and copy the settings gathered above into this memory
PrintDlg.hDevNames = GlobalAlloc(GMEM_MOVEABLE Or GMEM_ZEROINIT,
Len(DevName))
lpDevName = GlobalLock(PrintDlg.hDevNames)
If lpDevName > 0 Then
CopyMemory ByVal lpDevName, DevName, Len(DevName)
bReturn = GlobalUnlock(lpDevName)
End If
' Call the print dialog up and let the user make changes
If PrintDialog(PrintDlg) Then
' First get the DevName structure.
lpDevName = GlobalLock(PrintDlg.hDevNames)
CopyMemory DevName, ByVal lpDevName, 45
bReturn = GlobalUnlock(lpDevName)
GlobalFree PrintDlg.hDevNames
' Next get the DevMode structure and set the printer
' properties appropriately
lpDevMode = GlobalLock(PrintDlg.hDevMode)
CopyMemory DevMode, ByVal lpDevMode, Len(DevMode)
bReturn = GlobalUnlock(PrintDlg.hDevMode)
GlobalFree PrintDlg.hDevMode
NewPrinterName = UCase(Left(DevMode.dmDeviceName,
InStr(DevMode.dmDeviceName, Chr(0)) - 1))
If Printer.DeviceName <> NewPrinterName Then
For Each objPrinter In Printers
If UCase(objPrinter.DeviceName) = NewPrinterName Then
Set Printer = objPrinter
End If
Next
End If
On Error Resume Next
' Set printer object properties according to selections made by user
DoEvents
On Error Resume Next
With Printer
.Copies = DevMode.dmCopies
.Duplex = DevMode.dmDuplex
.Orientation = DevMode.dmOrientation
.PaperSize = DevMode.dmPaperSize
.PrintQuality = DevMode.dmPrintQuality
.ColorMode = DevMode.dmColor
.PaperBin = DevMode.dmDefaultSource
End With
printdlgflags = PrintDlg.flags 'Per PrintToFile
On Error GoTo errore
End If
FSF
Exit Sub
errore:
Call F_ERRORE(Err)
End Sub
Declare Function PrintDialog Lib "comdlg32.dll" Alias "PrintDlgA" (pPrintdlg
As PRINTDLG_TYPE) As Long
Public Const CCHDEVICENAME = 32
Public Const CCHFORMNAME = 32
Public Const GMEM_FIXED = &H0
Public Const GMEM_MOVEABLE = &H2
Public Const GMEM_ZEROINIT = &H40
Public Const DM_DUPLEX = &H1000&
Public Const DM_ORIENTATION = &H1&
Public Const PD_ALLPAGES = &H0
Public Const PD_COLLATE = &H10
Public Const PD_DISABLEPRINTTOFILE = &H80000
Public Const PD_ENABLEPRINTHOOK = &H1000
Public Const PD_ENABLEPRINTTEMPLATE = &H4000
Public Const PD_ENABLEPRINTTEMPLATEHANDLE = &H10000
Public Const PD_ENABLESETUPHOOK = &H2000
Public Const PD_ENABLESETUPTEMPLATE = &H8000
Public Const PD_ENABLESETUPTEMPLATEHANDLE = &H20000
Public Const PD_HIDEPRINTTOFILE = &H100000
Public Const PD_NONETWORKBUTTON = &H200000
Public Const PD_NOPAGENUMS = &H8
Public Const PD_NOSELECTION = &H4
Public Const PD_NOWARNING = &H80
Public Const PD_PAGENUMS = &H2
Public Const PD_PRINTSETUP = &H40
Public Const PD_PRINTTOFILE = &H20
Public Const PD_RETURNDC = &H100
Public Const PD_RETURNDEFAULT = &H400
Public Const PD_RETURNIC = &H200
Public Const PD_SELECTION = &H1
Public Const PD_SHOWHELP = &H800
Public Const PD_USEDEVMODECOPIES = &H40000
Public Const PD_USEDEVMODECOPIESANDCOLLATE = &H40000
Public Const DLG_PRINT = 0
Public Const DLG_PRINTSETUP = 1
Type PRINTDLG_TYPE
lStructSize As Long
hWndOwner As Long
hDevMode As Long
hDevNames As Long
hdc As Long
flags As Long
nFromPage As Integer
nToPage As Integer
nMinPage As Integer
nMaxPage As Integer
nCopies As Integer
hInstance As Long
lCustData As Long
lpfnPrintHook As Long
lpfnSetupHook As Long
lpPrintTemplateName As String
lpSetupTemplateName As String
hPrintTemplate As Long
hSetupTemplate As Long
End Type
Type DEVNAMES_TYPE
wDriverOffset As Integer
wDeviceOffset As Integer
wOutputOffset As Integer
wDefault As Integer
extra As String * 100
End Type
Type DEVMODE_TYPE
dmDeviceName As String * CCHDEVICENAME
dmSpecVersion As Integer
dmDriverVersion As Integer
dmSize As Integer
dmDriverExtra As Integer
dmFields As Long
dmOrientation As Integer
dmPaperSize As Integer
dmPaperLength As Integer
dmPaperWidth As Integer
dmScale As Integer
dmCopies As Integer
dmDefaultSource As Integer
dmPrintQuality As Integer
dmColor As Integer
dmDuplex As Integer
dmYResolution As Integer
dmTTOption As Integer
dmCollate As Integer
dmFormName As String * CCHFORMNAME
dmUnusedPadding As Integer
dmBitsPerPel As Integer
dmPelsWidth As Long
dmPelsHeight As Long
dmDisplayFlags As Long
dmDisplayFrequency As Long
End Type

nocciolo è qui:
[cuttone bestiale]
L' ho compilato praticamente senza modifiche (a parte l' aggiunta delle dichiarazioni
di GlobalAlloc e compagnia) sotto windows 2000 Pro e l'ho eseguito sotto XP Pro: 
il tuo codice funziona.
Come dice Ugo, il problema e' da un' altra parte.
-- 
ciao, hal

 Come dice Ugo, il problema e' da un' altra parte.
hal, grazie per il tuo tempo. Approfondirò, ma ho poca fiducia, anche perchè
non faccio altro che
una Call DIALOGO_STAMPA_NT(cdl_dialogo.Parent, cdl_dialogo.flags,
printdlgflags),
dove cdl_dialogo è un CommonDialog di cui ho già preparato i parametri per
la ShoPrinter che userei in Win9x.
Ho la certezza (fatto con le mie manine da più di un cliente) che
l'applicativo (così com'è) NON presenta il problema in NT/2000.
Temo che sia solo un problema di XP.

Temo che sia solo un problema di XP.
Ma l'ho appena provato con XP e mi ha funzionato ...
-- 
ciao, hal

 Ma l'ho appena provato con XP e mi ha funzionato ...
Mi era sfuggito, scusami, ma ribadisco che in NT/2000 tutto funziona anche a
me. Ora approfondirò provando con un CommonDialog che appartiene alla
finestra in vista, passando quella.

ESF0MESS.cdl_dialogo.flags, printdlgflags)
Ecco l' errore, devi passare la finestra visibile, non quella nascosta:
Call DIALOGO_STAMPA_NT(Me, ESF0MESS.cdl_dialogo.flags, printdlgflags)
-- 
ciao, hal
che per Lupo ha accettato di sporcarsi le mani con XP :-P

 Call DIALOGO_STAMPA_NT(Me, ESF0MESS.cdl_dialogo.flags, printdlgflags)
Niente. Non va. Non posso usare Me perchč la Sub č in un modulo, ma non va
nemmeno (e credo sia esattamente lo stesso di Me) passando Screen.ActiveForm
o ESF0STAM che č il nome della form chiamante e visibile.
Non va nemmeno usando un CommonDialog (che ho creato appositamente)
appartenente alla finestra chiamante e visibile.
Naturalmente continua ad andare perfettamente se metto anche un solo punto
di interruzione (F9) in qualunque punto prima di PrintDialog.

 di interruzione (F9) in qualunque punto prima di PrintDialog.
A questo punto manca da sapere:
1. cosa c'e' in printdlgflags;
2. se esegui il codice separatamente, cioe' come ho fatto io:
   un piccolo exe giusto con il form chiamante e la sub, il problema
   si ripresenta?
3. c'e' mica qualche rigiro di form modali in quel programma?
-- 
ciao, hal
che qui adesso non ho XP e devo andare a naso :-(
-- 
Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG

 ha scritto nel messaggio
news:251472832aaac55b41...@mygate.mailgate.org...
hal, ho risolto e NON CI CREDERAI MAI!
Ho seguito i tuoi consigli (printdlgflags vale 0 e posso passare impunemente
anche la originaria finestra invisibile) e ho provato a inserire le
istruzioni di chiamata in vari punti del programma, anche in maschere
diverse: Tutto OK!
Sai cos'è? Siediti!
La mia finestra generica di impostazione stampante/font/opzioni ha due
pannelli nei quali espongo la situazione corrente (stampante, formato,
orientamento, font, dimensioni, etc.) e ho usato l'evento Click del pannello
della stampante per avviare la chiamata della mia routine e quindi la
PrintDialog.
Bene, è l'evento Click di quel controllo! E' vecchiotto (forse da VB4), si
chiama SSPanel e fa parte del gruppo "Sheridan 3D controls" (THREED32.OCX
versione 1.0.41.0). Di fatto uso solo quello perchè mi consente di allineare
come voglio il testo e non ho mai più trovato nulla di simile (fra i free).
Soluzione:
Basta spostare le istruzioni di chiamata della routine in uno qualsiasi
degli eventi DoubleClick, MouseDown, persino MouseMove (ma non, appunto,
Click e nemmeno MouseUp) di quello stesso controllo e tutto funziona
perfettamente. Per togliermi ogni dubbio (temevo che ci fossero altre
istruzioni in altri eventi del controllo) ho inserito al volo un altro
SSPanel assolutamente vergine in un'altra finestra e ho avuto gli stessi
identici comportamenti.
Sono basito (ma contento). Grazie ancora del tuo aiuto. Ciao.

 come voglio il testo e non ho mai più trovato nulla di simile (fra i free).
Ah, chi usa il threed32 lo fa a proprio rischio e pericolo.
L'ho usato un paio di volte agli inizi, ma mi sono subito reso
conto del codice terrificante che deve avere internamente
e l'ho felicemente cancellato dalla mia esistenza.
Fallo anche tu, finche' sei in tempo ;-)
-- 
ciao, hal
che prima di usare un ocx ci penso _molto_ bene ...


 Fallo anche tu, finche' sei in tempo ;-)
Lo farò appena trovo un controllo (free e distribuibile) che mi permetta di
esporre il testo (in particolare automaticamente centrato in senso verticale
e orizzontale), come SSPanel... a proposito, qualche idea?
No, non dirmi di crearmelo! ;-)))

 anche la originaria finestra invisibile)
...
Piccola correzione: Passando una finestra invisibile la PrintDialog viene
esposta non modale. Passando la Screen.ActiveForm, la PrintDialog è esposta
regolarmente modale.

regolarmente modale.
Bene, questo conferma le prove fatte ieri sera e il fatto che i componenti
di Sheridan sono un suicidio :-P
-- 
ciao, hal