Usuário com melhor resposta
How do I Persist PrinterDialog settings between different documents

Pergunta
-
I am writing an application for user documents printing. This application is supposed to be able to print multiple (say more than 100) documents at once. And some printers have stapling option and user may want to staple EACH document separately.
I could show a PrinterDialog for the first document and let the application remember all settings. But different departments have different printers and printer settings. I think the application must be written in more general way like somehow persisting the selected printer settings for the next printing.
For example, Internet Explorer and Acrobat PDF Reader remembers printer settings once changed by user inside the application as long as the application is running but does not change the printer's default settings (in Windows Control Panel). I want to achieve the same thing in my application.
Could anybody show me how to achieve this hopefully including some code snippet?
Respostas
-
I resolved the issue. Pinvoke.net helped me greatly to write correct VB.NET signature of Win32 functions. Here I want to share my codes for people who are trying to get similar goal :
Code SnippetImports System.Drawing.Printing
Imports System.Runtime.InteropServices
Public Class PrinterNative'Refer http://msdn.microsoft.com/en-us/library/ms535735(VS.85).aspx
' http://support.microsoft.com/kb/167345
' http://www.pinvoke.net/default.aspx
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 IntPtrPrivate 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 IntegerPublic Declare Function GetPrinter Lib "winspool.drv" Alias "GetPrinterW" _
(ByVal hPrinter As IntPtr, ByVal Level As Integer, ByVal pPrinter As IntPtr, _
ByVal cbBuf As Integer, ByRef pcbNeeded As Integer) As IntegerPrivate Declare Function SetPrinter Lib "winspool.drv" Alias "SetPrinterA" _
(ByVal hPrinter As IntPtr, ByVal level As Integer, ByVal pPrinterInfoIn As IntPtr, _
ByVal command As Int32) As Boolean<DllImport("winspool.drv", EntryPoint:="OpenPrinterA", ExactSpelling:=True, _
SetLastError:=True, CallingConvention:=CallingConvention.StdCall, _
CharSet:=CharSet.Ansi)> _
Private Shared Function OpenPrinter(ByVal pPrinterName As String, _
ByRef hPrinter As IntPtr, ByRef pDefault As PRINTER_DEFAULTS) As Boolean
End Function<DllImport("winspool.drv", EntryPoint:="ClosePrinter", SetLastError:=True, ExactSpelling:=True, _
CallingConvention:=CallingConvention.StdCall)> _
Private Shared Function ClosePrinter(ByVal hPrinter As Int32) As Boolean
End FunctionDeclare Function GetDefaultPrinter Lib "winspool.drv" Alias "GetDefaultPrinterA" _
(ByVal pszBuffer As System.Text.StringBuilder, ByRef pcchBuffer As Int32) As BooleanDeclare Function SetDefaultPrinter Lib "winspool.drv" Alias "SetDefaultPrinterA" _
(ByVal pszPrinter As String) As BooleanPublic Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
(ByVal hpvDest As IntPtr, ByVal hpvSource As IntPtr, ByVal cbCopy As Long)
Private Structure PRINTER_DEFAULTS
Dim pDatatype As String
Dim pDevMode As Long
Dim pDesiredAccess As Long
End StructurePrivate Const STANDARD_RIGHTS_REQUIRED = &HF0000
Private Const PRINTER_ACCESS_ADMINISTER = &H4
Private Const PRINTER_ACCESS_USE = &H8
Private Const PRINTER_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED Or PRINTER_ACCESS_ADMINISTER Or PRINTER_ACCESS_USE)Private Const DM_IN_BUFFER As Integer = 8
Private Const DM_IN_PROMPT As Integer = 4
Private Const DM_OUT_BUFFER As Integer = 2Private Structure PRINTER_INFO_9
Dim pDevMode As IntPtr
End Structure<StructLayout(LayoutKind.Sequential)> _
Private Structure PRINTER_INFO_2
<MarshalAs(UnmanagedType.LPTStr)> Public pServerName As String
<MarshalAs(UnmanagedType.LPTStr)> Public pPrinterName As String
<MarshalAs(UnmanagedType.LPTStr)> Public pShareName As String
<MarshalAs(UnmanagedType.LPTStr)> Public pPortName As String
<MarshalAs(UnmanagedType.LPTStr)> Public pDriverName As String
<MarshalAs(UnmanagedType.LPTStr)> Public pComment As String
<MarshalAs(UnmanagedType.LPTStr)> Public pLocation As StringPublic pDevMode As IntPtr
<MarshalAs(UnmanagedType.LPTStr)> Public pSepFile As String
<MarshalAs(UnmanagedType.LPTStr)> Public pPrintProcessor As String
<MarshalAs(UnmanagedType.LPTStr)> Public pDatatype As String
<MarshalAs(UnmanagedType.LPTStr)> Public pParameters As StringPublic pSecurityDescriptor As IntPtr
Public Attributes As Integer
Public Priority As Integer
Public DefaultPriority As Integer
Public StartTime As Integer
Public UntilTime As Integer
Public Status As Integer
Public cJobs As Integer
Public AveragePPM As Integer
End Structure<StructLayout(LayoutKind.Sequential)> _
Public Structure DEVMODE
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=32)> Dim dmDeviceName As String
Dim dmSpecVersion As Short
Dim dmDriverVersion As Short
Dim dmSize As Short
Dim dmDriverExtra As Short
Dim dmFields As IntegerDim dmOrientation As Short
Dim dmPaperSize As Short
Dim dmPaperLength As Short
Dim dmPaperWidth As ShortDim dmScale As Short
Dim dmCopies As Short
Dim dmDefaultSource As Short
Dim dmPrintQuality As Short
Dim dmColor As Short
Dim dmDuplex As Short
Dim dmYResolution As Short
Dim dmTTOption As Short
Dim dmCollate As Short
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=32)> Public dmFormName As String
Dim dmLogPixels As Short
Dim dmBitsPerPel As Integer
Dim dmPelsWidth As Integer
Dim dmPelsHeight As Integer
Dim dmDisplayFlags As Integer
Dim dmDisplayFrequency As IntegerDim dmICMMethod As Integer
Dim dmICMIntent As Integer
Dim dmMediaType As Integer
Dim dmDitherType As Integer
Dim dmReserved1 As Integer
Dim dmReserved2 As Integer
Dim dmPanningWidth As Integer
Dim dmPanningHeight As Integer
End Structure'Global variables
Private PrinterName As String = ""
Private pOriginalDEVMODE As IntPtrPublic Function OpenPrinterPropertiesDialog() As Boolean
Dim hPrinter As IntPtr
Dim Needed As Integer
Dim buffer As New System.Text.StringBuilder(256)'Get default printer's name
GetDefaultPrinter(buffer, 256)
PrinterName = buffer.ToString
If PrinterName = "" Then
MsgBox("Can't find default printer.")
Return False
End IfOpenPrinter(PrinterName, hPrinter, Nothing)
'Save original printer settings data (DEVMODE structure)
Needed = DocumentProperties(Form1.Handle, hPrinter, PrinterName, Nothing, Nothing, 0)
Dim pFullDevMode As IntPtr = Marshal.AllocHGlobal(Needed) 'buffer for DEVMODE structure
DocumentProperties(Form1.Handle, hPrinter, PrinterName, pFullDevMode, Nothing, DM_OUT_BUFFER)
pOriginalDEVMODE = Marshal.AllocHGlobal(Needed)
CopyMemory(pOriginalDEVMODE, pFullDevMode, Needed)'Make desired changes by showing user a printer dialog
Dim ret As DialogResult
ret = DocumentProperties(Form1.Handle, hPrinter, PrinterName, pFullDevMode, Nothing, DM_IN_PROMPT Or DM_OUT_BUFFER)'Change the default settings of the printer
If ret = DialogResult.OK Then
Dim PI9 As New PRINTER_INFO_9
PI9.pDevMode = pFullDevMode
Dim pPI9 As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(PI9))
Marshal.StructureToPtr(PI9, pPI9, True)
SetPrinter(hPrinter, 9, pPI9, 0&)
Marshal.FreeHGlobal(pPI9) 'pFullDevMode will be free too
Else
Marshal.FreeHGlobal(pFullDevMode)
End IfClosePrinter(hPrinter)
Return IIf(ret = DialogResult.OK, True, False)
End FunctionPublic Sub RestorePrinterSettings()
Dim hPrinter As IntPtr
If PrinterName = "" Then Exit SubTry
If OpenPrinter(PrinterName, hPrinter, Nothing) = False Then Exit Sub
Dim PI9 As New PRINTER_INFO_9
PI9.pDevMode = pOriginalDEVMODE
Dim pPI9 As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(PI9))
Marshal.StructureToPtr(PI9, pPI9, True)
SetPrinter(hPrinter, 9, pPI9, 0&)
Marshal.FreeHGlobal(pPI9) 'pOriginalDEVMODE will be free too
ClosePrinter(hPrinter)Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
End Class'In the main form...
Imports
CrystalDecisions.CrystalReports.EngineImports
CrystalDecisions.SharedImports
System.CollectionsImports
System.IOPublic
Class Form1Dim MyReportDocument As New ReportDocument
'...
Private Function printPrO(ByVal PrO As String) As String
Dim Errormessage As String = ""Try
SetReportDocumentParameters(PrO)
MyReportDocument.PrintToPrinter(1, True, 0, 0) 'nCopies,bCollated,iStart,iEnd. Will not load dialog
Catch ex As Exception
Errormessage = PrO + " print failed. Error=" + ex.Message
End TryReturn Errormessage
End FunctionDim myPrinterNative As New PrinterNative
Private Sub printAll_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPrintAll.Click
Dim nPro As Integer = ListBox1.Items.Count
If nPro <= 0 Then Exit Sub
Dim dlgResult As DialogResult = _
MsgBox("It will print total " + LTrim(Str(nPro)) + " Production Orders at once." _
+ vbCr + "Do you want to continue?", MsgBoxStyle.OkCancel)
If dlgResult = Windows.Forms.DialogResult.Cancel Then Exit SubIf myPrinterNative.OpenPrinterPropertiesDialog() = False Then
Exit Sub
End IfDim errorList As New ArrayList
System.Windows.Forms.Cursor.Current = Cursors.WaitCursor
Try
For Each item As String In ListBox1.Items
Dim err As String = printPrO(item.Trim)
If err.Trim.Length > 0 Then
errorList.Add(err)
End If
Next
Catch ex As Exception
Finally
myPrinterNative.RestorePrinterSettings()
End TryIf errorList.Count > 0 Then
Dim mergedString As String = ""
Dim n As Integer = errorList.Count
If n > 20 Then n = 20
For i As Integer = 0 To n
mergedString = mergedString + errorList(i) + vbCr
Next
MsgBox("There was one or more error in printing. " + vbCr + mergedString)
End IfSystem.Windows.Forms.Cursor.Current = Cursors.Default
End Sub'...
End Class
Todas as Respostas
-
Hi fudata
I think you’d better use Settings.settings to remember each setting changed by the user. So the next time you run your application, it can read the settings from the Settings.settings file and do not rasie a PrintDialog to let the user set again.
Here is the step with screenshot
System generated code of Settings.settings
In the system generated code, you can find the generated property name (PrinterName)
The class name is Settings and the namespace is Test.Properties
Use the following code to read settings from the Settings.settings
Code SnippetTest.Properties.Settings settings = new Test.Properties.Settings();
PrintDocument printDoc = new PrintDocument();
printDoc.PrinterSettings.PrinterName = settings.PrinterName;
Write setting to the Settings.settings
Code Snippetsettings.PrinterName = "HP xxx-xx Printer";if you want more information about this. please look at this.
http://msdn.microsoft.com/en-us/library/aa730869(VS.80).aspx
Sincerely,
Kira Qian
-
Thank you for the feedback, Kira.
Maybe I didn't explain my situation correctly. Actually it is a CrystalReport printing issue. Last time when I posted the same issue, the moderator moved my post to CrystalReport forum so I didn't exposed the document type this time. Please don't move this post to CrystalReport. The question is all about how to handle printers in general not about Crystal Reports.
Simple method which reads printer settings in printDoc.PrinterSettings and keep using it will not work because the settings we really want to persist is STAPLING option, which is printer's native ("private") data.
During the time, I tried a lot of ways suggested by Microsoft about how to modify DEVMODE structure and persist it such as :
How to modify printer Settings with the DocumentProperties() Function
MSDN Windows GDI DocumentProperties Reference
But I couln't make my program works and now I realized the real problem might lie in the BusinessObjects' API routine I was using.
What my application is trying to achieve is to let user load several CrystalReports name in a listbox and print them all. Ideally the application should open a general printer dialog and let the user choose the printer and possibly change printer properties like stapling option. And then using the printer parameters chosen by the user, the application must print all crystal reports one by one without asking any more.
BusinessObjects provides two API functions for printing reports:
1. CrystalDecisions.CrystalReports.Engine.ReportDocument.PrintToPrinter
(ByVal nCopies As Integer, ByVal collated As Boolean, ByVal startPageN As Integer, ByVal endPageN As Integer)
2. CrystalDecisions.Windows.Forms.CrystalReportViewer.PrintReport()
The second function opens printer dialog first and print the current report loaded in the viewer. I can't use this function because it will display printer dialog each time when it is inside a loop.
The first function looked promising at first. But now it seems like that it COPIES printer's default settings (which I believe saved in Windows Registry) first overwriting the current printers' DEVMODE structure, which I modified before calling this function, and add those four arguments on top of that and prints. So whatever I played with DEVMODE before reaching this function call, my change will be negated by the original printer's default settings.
When I ran my application (with BO API function #2) after changing printer default setting with stapled option outside the application in WINDOWS PRINTING PREFRENCES dialog, it printed all crystal reports stapled beautifully.
So my question in this forum reaches to this point:
Inside an application, I mean programmatically, how do I show a Printer Dialog and change permanently the printer's WINDOWS default printing preferences (in Registry maybe) by the values selected from the user including native(private) data? Of course I have to reset back to the original settings again when my print loop is done.
Thank you guys.
-
Hi fudata
I don’t think you need to show a printer setting dialog to the user when doing a loop print. Anyway, you can set all printing preferences directly to the .Net PrintDocument class. Just show the PrintDialog at the beginning of the printing process. Then set all the preferences to the next PrintDocument instance. This is the only way Winform can do.
Sincerely,
Kira Qian
-
-
I resolved the issue. Pinvoke.net helped me greatly to write correct VB.NET signature of Win32 functions. Here I want to share my codes for people who are trying to get similar goal :
Code SnippetImports System.Drawing.Printing
Imports System.Runtime.InteropServices
Public Class PrinterNative'Refer http://msdn.microsoft.com/en-us/library/ms535735(VS.85).aspx
' http://support.microsoft.com/kb/167345
' http://www.pinvoke.net/default.aspx
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 IntPtrPrivate 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 IntegerPublic Declare Function GetPrinter Lib "winspool.drv" Alias "GetPrinterW" _
(ByVal hPrinter As IntPtr, ByVal Level As Integer, ByVal pPrinter As IntPtr, _
ByVal cbBuf As Integer, ByRef pcbNeeded As Integer) As IntegerPrivate Declare Function SetPrinter Lib "winspool.drv" Alias "SetPrinterA" _
(ByVal hPrinter As IntPtr, ByVal level As Integer, ByVal pPrinterInfoIn As IntPtr, _
ByVal command As Int32) As Boolean<DllImport("winspool.drv", EntryPoint:="OpenPrinterA", ExactSpelling:=True, _
SetLastError:=True, CallingConvention:=CallingConvention.StdCall, _
CharSet:=CharSet.Ansi)> _
Private Shared Function OpenPrinter(ByVal pPrinterName As String, _
ByRef hPrinter As IntPtr, ByRef pDefault As PRINTER_DEFAULTS) As Boolean
End Function<DllImport("winspool.drv", EntryPoint:="ClosePrinter", SetLastError:=True, ExactSpelling:=True, _
CallingConvention:=CallingConvention.StdCall)> _
Private Shared Function ClosePrinter(ByVal hPrinter As Int32) As Boolean
End FunctionDeclare Function GetDefaultPrinter Lib "winspool.drv" Alias "GetDefaultPrinterA" _
(ByVal pszBuffer As System.Text.StringBuilder, ByRef pcchBuffer As Int32) As BooleanDeclare Function SetDefaultPrinter Lib "winspool.drv" Alias "SetDefaultPrinterA" _
(ByVal pszPrinter As String) As BooleanPublic Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
(ByVal hpvDest As IntPtr, ByVal hpvSource As IntPtr, ByVal cbCopy As Long)
Private Structure PRINTER_DEFAULTS
Dim pDatatype As String
Dim pDevMode As Long
Dim pDesiredAccess As Long
End StructurePrivate Const STANDARD_RIGHTS_REQUIRED = &HF0000
Private Const PRINTER_ACCESS_ADMINISTER = &H4
Private Const PRINTER_ACCESS_USE = &H8
Private Const PRINTER_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED Or PRINTER_ACCESS_ADMINISTER Or PRINTER_ACCESS_USE)Private Const DM_IN_BUFFER As Integer = 8
Private Const DM_IN_PROMPT As Integer = 4
Private Const DM_OUT_BUFFER As Integer = 2Private Structure PRINTER_INFO_9
Dim pDevMode As IntPtr
End Structure<StructLayout(LayoutKind.Sequential)> _
Private Structure PRINTER_INFO_2
<MarshalAs(UnmanagedType.LPTStr)> Public pServerName As String
<MarshalAs(UnmanagedType.LPTStr)> Public pPrinterName As String
<MarshalAs(UnmanagedType.LPTStr)> Public pShareName As String
<MarshalAs(UnmanagedType.LPTStr)> Public pPortName As String
<MarshalAs(UnmanagedType.LPTStr)> Public pDriverName As String
<MarshalAs(UnmanagedType.LPTStr)> Public pComment As String
<MarshalAs(UnmanagedType.LPTStr)> Public pLocation As StringPublic pDevMode As IntPtr
<MarshalAs(UnmanagedType.LPTStr)> Public pSepFile As String
<MarshalAs(UnmanagedType.LPTStr)> Public pPrintProcessor As String
<MarshalAs(UnmanagedType.LPTStr)> Public pDatatype As String
<MarshalAs(UnmanagedType.LPTStr)> Public pParameters As StringPublic pSecurityDescriptor As IntPtr
Public Attributes As Integer
Public Priority As Integer
Public DefaultPriority As Integer
Public StartTime As Integer
Public UntilTime As Integer
Public Status As Integer
Public cJobs As Integer
Public AveragePPM As Integer
End Structure<StructLayout(LayoutKind.Sequential)> _
Public Structure DEVMODE
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=32)> Dim dmDeviceName As String
Dim dmSpecVersion As Short
Dim dmDriverVersion As Short
Dim dmSize As Short
Dim dmDriverExtra As Short
Dim dmFields As IntegerDim dmOrientation As Short
Dim dmPaperSize As Short
Dim dmPaperLength As Short
Dim dmPaperWidth As ShortDim dmScale As Short
Dim dmCopies As Short
Dim dmDefaultSource As Short
Dim dmPrintQuality As Short
Dim dmColor As Short
Dim dmDuplex As Short
Dim dmYResolution As Short
Dim dmTTOption As Short
Dim dmCollate As Short
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=32)> Public dmFormName As String
Dim dmLogPixels As Short
Dim dmBitsPerPel As Integer
Dim dmPelsWidth As Integer
Dim dmPelsHeight As Integer
Dim dmDisplayFlags As Integer
Dim dmDisplayFrequency As IntegerDim dmICMMethod As Integer
Dim dmICMIntent As Integer
Dim dmMediaType As Integer
Dim dmDitherType As Integer
Dim dmReserved1 As Integer
Dim dmReserved2 As Integer
Dim dmPanningWidth As Integer
Dim dmPanningHeight As Integer
End Structure'Global variables
Private PrinterName As String = ""
Private pOriginalDEVMODE As IntPtrPublic Function OpenPrinterPropertiesDialog() As Boolean
Dim hPrinter As IntPtr
Dim Needed As Integer
Dim buffer As New System.Text.StringBuilder(256)'Get default printer's name
GetDefaultPrinter(buffer, 256)
PrinterName = buffer.ToString
If PrinterName = "" Then
MsgBox("Can't find default printer.")
Return False
End IfOpenPrinter(PrinterName, hPrinter, Nothing)
'Save original printer settings data (DEVMODE structure)
Needed = DocumentProperties(Form1.Handle, hPrinter, PrinterName, Nothing, Nothing, 0)
Dim pFullDevMode As IntPtr = Marshal.AllocHGlobal(Needed) 'buffer for DEVMODE structure
DocumentProperties(Form1.Handle, hPrinter, PrinterName, pFullDevMode, Nothing, DM_OUT_BUFFER)
pOriginalDEVMODE = Marshal.AllocHGlobal(Needed)
CopyMemory(pOriginalDEVMODE, pFullDevMode, Needed)'Make desired changes by showing user a printer dialog
Dim ret As DialogResult
ret = DocumentProperties(Form1.Handle, hPrinter, PrinterName, pFullDevMode, Nothing, DM_IN_PROMPT Or DM_OUT_BUFFER)'Change the default settings of the printer
If ret = DialogResult.OK Then
Dim PI9 As New PRINTER_INFO_9
PI9.pDevMode = pFullDevMode
Dim pPI9 As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(PI9))
Marshal.StructureToPtr(PI9, pPI9, True)
SetPrinter(hPrinter, 9, pPI9, 0&)
Marshal.FreeHGlobal(pPI9) 'pFullDevMode will be free too
Else
Marshal.FreeHGlobal(pFullDevMode)
End IfClosePrinter(hPrinter)
Return IIf(ret = DialogResult.OK, True, False)
End FunctionPublic Sub RestorePrinterSettings()
Dim hPrinter As IntPtr
If PrinterName = "" Then Exit SubTry
If OpenPrinter(PrinterName, hPrinter, Nothing) = False Then Exit Sub
Dim PI9 As New PRINTER_INFO_9
PI9.pDevMode = pOriginalDEVMODE
Dim pPI9 As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(PI9))
Marshal.StructureToPtr(PI9, pPI9, True)
SetPrinter(hPrinter, 9, pPI9, 0&)
Marshal.FreeHGlobal(pPI9) 'pOriginalDEVMODE will be free too
ClosePrinter(hPrinter)Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
End Class'In the main form...
Imports
CrystalDecisions.CrystalReports.EngineImports
CrystalDecisions.SharedImports
System.CollectionsImports
System.IOPublic
Class Form1Dim MyReportDocument As New ReportDocument
'...
Private Function printPrO(ByVal PrO As String) As String
Dim Errormessage As String = ""Try
SetReportDocumentParameters(PrO)
MyReportDocument.PrintToPrinter(1, True, 0, 0) 'nCopies,bCollated,iStart,iEnd. Will not load dialog
Catch ex As Exception
Errormessage = PrO + " print failed. Error=" + ex.Message
End TryReturn Errormessage
End FunctionDim myPrinterNative As New PrinterNative
Private Sub printAll_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPrintAll.Click
Dim nPro As Integer = ListBox1.Items.Count
If nPro <= 0 Then Exit Sub
Dim dlgResult As DialogResult = _
MsgBox("It will print total " + LTrim(Str(nPro)) + " Production Orders at once." _
+ vbCr + "Do you want to continue?", MsgBoxStyle.OkCancel)
If dlgResult = Windows.Forms.DialogResult.Cancel Then Exit SubIf myPrinterNative.OpenPrinterPropertiesDialog() = False Then
Exit Sub
End IfDim errorList As New ArrayList
System.Windows.Forms.Cursor.Current = Cursors.WaitCursor
Try
For Each item As String In ListBox1.Items
Dim err As String = printPrO(item.Trim)
If err.Trim.Length > 0 Then
errorList.Add(err)
End If
Next
Catch ex As Exception
Finally
myPrinterNative.RestorePrinterSettings()
End TryIf errorList.Count > 0 Then
Dim mergedString As String = ""
Dim n As Integer = errorList.Count
If n > 20 Then n = 20
For i As Integer = 0 To n
mergedString = mergedString + errorList(i) + vbCr
Next
MsgBox("There was one or more error in printing. " + vbCr + mergedString)
End IfSystem.Windows.Forms.Cursor.Current = Cursors.Default
End Sub'...
End Class