Answered by:
Multiple pages per sheet

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
-
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.
- Edited by Alan_YaoMicrosoft employee Tuesday, October 23, 2012 3:06 PM
- Marked as answer by Alan_YaoMicrosoft employee Monday, October 29, 2012 2:44 PM
Tuesday, October 23, 2012 3:05 PM
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/
- Edited by Andrea Montanari Tuesday, October 23, 2012 10:58 AM
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.
- Edited by Alan_YaoMicrosoft employee Tuesday, October 23, 2012 3:06 PM
- Marked as answer by Alan_YaoMicrosoft employee Monday, October 29, 2012 2:44 PM
Tuesday, October 23, 2012 3:05 PM