locked
Multiple pages per sheet RRS feed

  • Question

  • hi All,

    using the Winforms PrintDialog, I'd like to know if and how the user set the "Multiple Pages per Sheet" property... I can see the .Duplex property, but nothing about the pages/sheet...

    tia


    http://www.asql.biz - DbaMgr2k - DbaMgr and further SQL Tools http://www.hotelsole.com/

    Thursday, October 18, 2012 4:57 PM

Answers

All replies

  • Hi Andrea,

    PrintDocument doesn't support this feature right now. However, you can implement the custom class MultipagePrintDocument class as is shown in this link:http://www.aspose.com/docs/display/wordsnet/How+to++print+multiple+pages+on+one+sheet.

    Hope this helps.

    This response contains a reference to a third party World Wide Web site. Microsoft is providing this information as a convenience to you. Microsoft does not control these sites and has not tested any software or information found on these sites; therefore, Microsoft cannot make any representations regarding the quality, safety, or suitability of any software or information found there. There are inherent dangers in the use of any software found on the Internet, and Microsoft cautions you to make sure that you completely understand the risk before retrieving any software from the Internet.

    Best regards,


    Shanks Zen
    MSDN Community Support | Feedback to us

    Friday, October 19, 2012 6:46 AM
  • hi Shanks, and thank you for your support...

    I already saw the implementation of the custom PrintDocument class, but I'm still stuck a little bit earlier... as you already saw in the implemetation code, the class constructor expects the pagesPerSheet integer parameter... and that should be obviously collected from somewhere... I'd like to get it from the WindowsForm PrintDialog dialog, but I'm unable to find it within it's properties... I'm aware of the WPF PrintTicket implementation, but this project still is WindowsForm based...

    so the final question is not "how to print multiple pages per sheet", but "how to collect the value of N pages per sheet from the PrintDialog"

    tia


    http://www.asql.biz - DbaMgr2k - DbaMgr and further SQL Tools http://www.hotelsole.com/

    Friday, October 19, 2012 9:41 AM
  • PrintDislog is a sealed class. I suppose it may be impossible to implement custom property. Since this control can't be inherited, the question "how to collect the value of N pages per sheet from the PrintDialog" has no meaning then. My suggestion is add something like textbox to get this input to decide pagesPerSheet property of printdocument class.

    Sorry for my humble opinion if I misunderstood.


    Think again!

    Monday, October 22, 2012 3:07 AM
  • hi Edward,

    thank you for your input, and yes, this is what I wanted to know... it seems then, the "N pages per sheet" value is not exposed to the developer from the PrintDialog class... that's to bad :)

    adding a "textBox" to get that value is, in our scenario, a bad costume, probably it will be a better idea a custom PrintDialog from the ground up... and this is not trivial as well... hope Shanks (or someone other) comes back with other idea, and this is the reason I do not mark your post as "answer"..

    tia


    http://www.asql.biz - DbaMgr2k - DbaMgr and further SQL Tools http://www.hotelsole.com/

    Monday, October 22, 2012 2:03 PM
  • Hi Andrea,

    Thanks for your reply. After some research I realize this is beyond my capability and I'll involve some senior engineers into this  thread. It may take a bit more time.

    Moreover, you can submit this feature request to http://connect.microsoft.com/.

    Best regards,


    Shanks Zen
    MSDN Community Support | Feedback to us


    • Edited by Youen Zen Tuesday, October 23, 2012 6:07 AM add connect link
    Tuesday, October 23, 2012 6:04 AM
  • Hi Andrea,

    As Edward said, it's impossible to implement custom property from PrintDialog. PrintDialog is a sealed class because it contains some unmanaged code.

    So I think you can follow Edward's suggestion.

    Actually, you can implement your own printdialog using unmanaged code(http://msdn.microsoft.com/en-us/library/windows/desktop/ms646964(v=vs.85).aspx#_win32_Customizing_the_Print_Dialog_Box). However, it will spend much of your time.

    Regards,


    Alan Yao [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Tuesday, October 23, 2012 9:05 AM
  • hi Alan,

    thank to Shanks for escalating that to you, and thank you for your feedback...

    I'm ending up with, perhaps, a cleaner and simpler solution... it turns out I do not have to "add" something (other controls) to the dialog as all I need is already there... I just need to get the info there provided...

    so I can perhaps just call the standard winspool API to open the printer's properties dialog where the "additional information is natively provided"... I've found something on the web that can help... I'm not very faithfull with it as it resorts on interop and is not that clean as we wished... and it's terribly slow as we have to manually inspect System.Drawing.Printing.PrinterSettings.InstalledPrinters to enlist available printers, similarly

    #Region "#---   External APIs   ---#"
        ' native functions
        Private Declare Auto Function GlobalLock Lib "kernel32.dll" _
            (ByVal handle As IntPtr) As IntPtr
        Private Declare Auto Function GlobalUnlock Lib "kernel32.dll" _
            (ByVal handle As IntPtr) As Integer
        Private Declare Auto Function GlobalFree Lib "kernel32.dll" _
            (ByVal handle As IntPtr) As IntPtr
        Private Declare Auto Function DocumentProperties Lib "winspool.drv" _
            (ByVal hWnd As IntPtr, ByVal hPrinter As IntPtr, _
            ByVal pDeviceName As String, ByVal pDevModeOutput As IntPtr, _
            ByVal pDevModeInput As IntPtr, ByVal fMode As Int32) As Integer
    
    #End Region
    
     Private Sub OpenPrinterPropertiesDialog(ByVal Settings As System.Drawing.Printing.PrinterSettings)
            ' PrinterSettings+PageSettings -> hDEVMODE
            Dim hDevMode As IntPtr = _
             Settings.GetHdevmode(Settings.DefaultPageSettings)
    
            ' Show Dialog ( [In,Out] pDEVMODE )
            Dim pDevMode As IntPtr = GlobalLock(hDevMode)
            DocumentProperties(Me.Handle, IntPtr.Zero, _
                Settings.PrinterName, pDevMode, pDevMode, 14)
            GlobalUnlock(hDevMode)
    
            ' hDEVMODE -> PrinterSettings+PageSettings
            Settings.SetHdevmode(hDevMode)
            Settings.DefaultPageSettings.SetHdevmode(hDevMode)
    
            ' cleanup
            GlobalFree(hDevMode)
        End Sub

    so that we have all Settings.DefaultPageSettings loaded as "traditionally and natively" with all the supported settings, but now I've to "read" those "extra settings"  as well... info that should be stored in the pmDriverExtra extra structure... does the pDevMode contains the pmDriverExtra info to get that info? and, if yes, how can that be transferred/marshalled from the DEVMODE structure to a private/custom boolean VB property/field?

    probably better is http://nicholas.piasecki.name/blog/2008/11/programmatically-selecting-complex-printer-options-in-c-shar/ but it's beyound our c# to vb translation capabilities, and again the pmDriverExtra info is still there to be "extracted" and read :(

    tia


    http://www.asql.biz - DbaMgr2k - DbaMgr and further SQL Tools http://www.hotelsole.com/


    Tuesday, October 23, 2012 10:43 AM
  • Hi Andrea,

    Actually, you can understand DEVMODE structure as:

    1. The DEVMODE structure contains two parts : basic info and private driver specific info.

    2. Basic info is stored in the first N(dmSize) bytes and Private info is stored in the Last M(dmDriverExtra) bytes.

    To read the DEVMODE structure you need to read dmSize+dmDriverExtra bytes to get the complete structure data. The c# example is a interesting example, but I don't think the c# example meet your requirements. The c# example just apply the dumped settings to printers but cannot change specific property on demand.

    Generally, we do not need to consider any settings defined in driver specific info. In my opinion, you can refer to http://stackoverflow.com/questions/2810284/bring-up-the-printer-settings-dialog-and-have-the-changes-saved

    I did not test the code included in above link, but I believe the direction is correct. By that way, you can easily change the setting by modify DEVMODE structure. Please refer to http://msdn.microsoft.com/en-us/library/windows/desktop/dd183565(v=vs.85).aspx to check what properties we can modify.

    Regards,

     


    Alan Yao [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.



    Tuesday, October 23, 2012 3:05 PM