Results 1 to 6 of 6

Thread: Print Dialog box modal

  1. #1

    Thread Starter
    New Member
    Join Date
    Mar 2000
    Posts
    3
    I'm trying to make the printdialog (found in comdlg32.dll) window modal. Is it possible? If yes, how do I do it.

  2. #2

    A General Answer

    Here's what I would do if I had that question.

    This will apply to other similar dilemmas where one has a question and no answer about a programable object in Visual Basic.

    Put an instance of the object on a form. Be sure it has focus and press F2. Voila, you are in the Object Browser. Browse its Properties, Methods, Events and the Constants with hopefully nice little logical names.

    In your instance, you will probably find a boolean constant listed such as cmdIsModal or the like.

    You might also press F1 and a help file just for that control should be rendered for your lunch hour study.

    Or, you might want to save it for when you wake up in the middle of the night and want to program...

    [Edited by 23yearsofit on 03-23-2000 at 12:12 PM]

  3. #3

    Thread Starter
    New Member
    Join Date
    Mar 2000
    Posts
    3
    I was refering to the API PrintDialog (which is in comdlg32.dll), this is not an object that I can put on a form. I already searched the object browser. I know that I can modify the behavior of the PrintDialog by changing the Flags in the structure passed to the PrintDialog API, but I can't find one that will make the window modal (I'm talking here about the window opened by PrintDialog, which allows the user to select the printer and so on). I don't wanna use the ShowPrinter method from the common dialog control (this one from comdlg32.ocx) which has problems with NT.
    Thanx.
    Bye gone!

  4. #4
    Well, I suggest since it is code you have written, post the Declaration and enough of a code snippet so anyone can run it immediately...and perhaps hack out a little solution...





  5. #5
    I'm about to be a PowerPoster! Joacim Andersson's Avatar
    Join Date
    Jan 1999
    Location
    Sweden
    Posts
    14,649
    If you set the hwndOwner member of the PrintDlg structure the dialog will be shown modal.
    Code:
    Private Type PrintDlg
        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
    
    Private Declare Function PrintDlg _
     Lib "comdlg32.dll" Alias "PrintDlgA" ( _
     pPrintdlg As PrintDlg) As Long
    
    Private Sub Command1_Click()
        Dim udtPrDlg As PrintDlg
        Dim lngRetVal As Long
        
        With udtPrDlg
            .lStructSize = Len(udtPrDlg)
            .hwndOwner = Me.hWnd
            'set other struct members here
        End With
        lngRetVal = PrintDlg(udtPrDlg)
    End Sub
    Good luck!

  6. #6

    Thread Starter
    New Member
    Join Date
    Mar 2000
    Posts
    3
    Thanx Joacim, in deed, by setting the hwndOwner member of the PrintDlg structure the dialog will be shown modal. But when you have more than one form in your project, the dialog is modal only for the form you did set as hwndOwner, allowing the user to perform any operations on other opened forms. Then, it is possible to type something in a 3 veiw control on a form which is not set as the hwndOwner, in that case, the form keypress event is not raised. So, what I would like, is to have the print dialog modal to the whole application.

    Here is a simple test that will show what I experienced:
    1)create a new project with 2 forms an one module;
    2)on form1, add a cmd button;
    3)on form2, add a TreeView control (you must add 'MICROSOFT WINDOWS COMMON CONTROLS 6.0 component before);
    4)in the module, add this code:
    ----------------------------------------------------------- Option Explicit

    ' Global constants for Win32 API
    Public Const CCHDEVICENAME = 32
    Public Const CCHFORMNAME = 32
    Public Const GMEM_FIXED = &H0
    Public Const GMEM_MOVEABLE = &H2
    Public Const GMEM_ZEROINIT = &H40

    ' Add appropriate Constants for what you want to change
    Public Const DM_DUPLEX = &H1000&
    Public Const DM_ORIENTATION = &H1&
    Public Const DM_COPIES = &H100&
    Public Const DMDUP_HORIZONTAL = 3
    Public Const DMDUP_SIMPLEX = 1
    Public Const DMDUP_VERTICAL = 2

    ' Constants for PrintDialog
    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

    ' Constants for PAGESETUPDLG
    Public Const PSD_DEFAULTMINMARGINS = &H0
    Public Const PSD_DISABLEMARGINS = &H10
    Public Const PSD_DISABLEORIENTATION = &H100
    Public Const PSD_DISABLEPAGEPAINTING = &H80000
    Public Const PSD_DISABLEPAPER = &H200
    Public Const PSD_DISABLEPRINTER = &H20
    Public Const PSD_ENABLEPAGEPAINTHOOK = &H40000
    Public Const PSD_ENABLEPAGESETUPHOOK = &H2000
    Public Const PSD_ENABLEPAGESETUPTEMPLATE = &H8000
    Public Const PSD_ENABLEPAGESETUPTEMPLATEHANDLE = &H20000
    Public Const PSD_INHUNDREDTHSOFMILLIMETERS = &H8
    Public Const PSD_INTHOUSANDTHSOFINCHES = &H4
    Public Const PSD_INWININIINTLMEASURE = &H0
    Public Const PSD_MARGINS = &H2
    Public Const PSD_MINMARGINS = &H1
    Public Const PSD_NOWARNING = &H80
    Public Const PSD_RETURNDEFAULT = &H400
    Public Const PSD_SHOWHELP = &H800

    ' Custom Global Constants
    Public Const DLG_PRINT = 0
    Public Const DLG_PRINTSETUP = 1

    ' type definitions:
    Public Type RECT
    Left As Long
    Top As Long
    Right As Long
    Bottom As Long
    End Type

    Public Type POINTAPI
    X As Long
    Y As Long
    End Type

    Type PRINTSETUPDLG_TYPE
    lStructSize As Long
    hwndOwner As Long
    hDevMode As Long
    hDevNames As Long
    flags As Long
    ptPaperSize As POINTAPI
    rtMinMargin As RECT
    rtMargin As RECT
    hInstance As Long
    lCustData As Long
    lpfnPageSetupHook As Long ' LPPAGESETUPHOOK
    lpfnPagePaintHook As Long ' LPPAGESETUPHOOK
    lpPageSetupTemplateName As String
    hPageSetupTemplate As Long ' HGLOBAL
    End Type

    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

    ' API declarations:
    Public Declare Function PrintDialog Lib "comdlg32.dll" _
    Alias "PrintDlgA" (pPrintdlg As PRINTDLG_TYPE) As Long

    Public Declare Sub CopyMemory Lib "kernel32" _
    Alias "RtlMoveMemory" _
    (hpvDest As Any, hpvSource As Any, ByVal cbCopy As Long)

    Public Declare Function GlobalLock Lib "kernel32" _
    (ByVal hMem As Long) As Long

    Public Declare Function GlobalUnlock Lib "kernel32" _
    (ByVal hMem As Long) As Long

    Public Declare Function GlobalAlloc Lib "kernel32" _
    (ByVal wFlags As Long, ByVal dwBytes As Long) As Long

    Public Declare Function GlobalFree Lib "kernel32" _
    (ByVal hMem As Long) As Long

    Public Sub ShowPrinter(frmOwner As Form, _
    Optional PrintFlags As Long)

    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 PrintSetupDialog 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 _
    Or DM_COPIES
    DevMode.dmOrientation = Printer.Orientation
    DevMode.dmCopies = Printer.Copies
    On Error Resume Next
    DevMode.dmDuplex = Printer.Duplex
    On Error GoTo 0

    ' 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
    With Printer
    .Copies = DevMode.dmCopies
    .Duplex = DevMode.dmDuplex
    .Orientation = DevMode.dmOrientation
    End With
    On Error GoTo 0
    End If

    End Sub
    -----------------------------------------------------------

    5)in form1, add this code:
    -----------------------------------------------------------
    Private Sub Command1_Click()
    ShowPrinter Me, PD_HIDEPRINTTOFILE
    End Sub

    Private Sub Form_Load()
    Form2.Show
    End Sub
    -----------------------------------------------------------

    6)in form2, add this code:
    -----------------------------------------------------------
    Private Sub Form_KeyPress(KeyAscii As Integer)
    Debug.Print "form2 key pressed"
    End Sub
    -----------------------------------------------------------

    NOW, test it!

    Thanx in advance to anyone who will help!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width