Comparing Printer.PageSettings

omegaomega used Ask the Experts™
Hello, Experts,

I have an application in which I have created a customized "Page Setup" form, but I have run into a performance issue.  When closing this form I want to compare the final PageSettings with the original PageSettings (saved when the form was opened).

I find that getting the various PageSettings properties to make this comparison is VERY slow.  The time required seems to depend on the particular property and also the selected printer, but runs into tenths of seconds per property, which is unacceptably long.

I have attached a snippet that illustrates the problem.

Any ideas on how I can improve the speed of these comparisons (or some other technique for making the comparison) will be greatly appreciated.

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        Dim prdTest As New PrintDocument()
        Debug.WriteLine(Now.ToString("HH:mm:ss.fff") & ": 1 (start)")
        Dim pgsTest As PageSettings = prdTest.DefaultPageSettings
        Dim strPrinterName As String = prdTest.PrinterSettings.PrinterName
        Dim datStart As Date = Now
        Dim intMyKind0 As Integer = pgsTest.PaperSource.RawKind
        Dim strMySourceName As String = pgsTest.PaperSource.SourceName
        Dim ppsMyPaperSource As PaperSource = pgsTest.PaperSource
        Dim intMyKind1 As Integer = ppsMyPaperSource.RawKind
        Dim prkMyKind As PrinterResolutionKind = pgsTest.PrinterResolution.Kind
        Dim datStop As Date = Now
        Debug.WriteLine("Time difference for " & strPrinterName & " = " & datStop.Subtract(datStart).ToString)
        ' Setting the Printer Name to itself improves speed slightly (~30%).
        prdTest.PrinterSettings.PrinterName = prdTest.PrinterSettings.PrinterName
        Dim datStart1 As Date = Now
        Dim intMyKind01 As Integer = pgsTest.PaperSource.RawKind
        Dim strMySourceName1 As String = pgsTest.PaperSource.SourceName
        Dim ppsMyPaperSource1 As PaperSource = pgsTest.PaperSource
        Dim intMyKind11 As Integer = ppsMyPaperSource.RawKind
        Dim prkMyKind1 As PrinterResolutionKind = pgsTest.PrinterResolution.Kind
        Dim datStop1 As Date = Now
        Debug.WriteLine("Time difference for " & strPrinterName & " = " & datStop1.Subtract(datStart1).ToString)
    End Sub

Open in new window

Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Most Valuable Expert 2012
Top Expert 2008

What kind of "comparison" are you talking about?  You might be able to create a custom print settings class that implements IComparable.


Hi, Bob,

Originally I thought that I wanted to do a "value equals" comparison (or Not Equals, actually) on the PageSettings properties that might be modified by the user through the Options/Printer Properties dialog that is accessed via the DocumentProperties API.  In particular, the following properties: Color, Landscape, Margins, PaperSize, PaperSource, PrinterResolution.  I also wanted to compare the modifiable properties of the PrinterSettings property, but this didn't seem to cause a performance problem.

But now I see that each printer can also have its own specialized properties, and I should also be checking these.

At the moment, I'm thinking that if I could compare the buffers returned by the PrinterSettings' GetHdevmode method that might provide a fast and complete comparison.  The two problems I am having with that are:
     - I don't know the final size of the buffers.
     - VB doesn't really seem to give me a convenient way to translate the pointer that is returned to a type (such as a byte array) that I can easily compare.
I think that I can get the buffer's size from the DocumentProperties API.  Do you have any suggestions about how I can best compare the buffers in VB (when all I have are the pointers)?



Hello, Experts,

I believe that I have a workable solution using the techniques outlined in my previous post.   I have shown the essence of the solution in the attached snippet (untested).  

CompareBuffers is a simple (unsafe) comparison function that I added to a pre-existing DLL used by the application.  I imagine that there must be some convenient API that would do this.  But I had trouble locating it and found it easier just to write my own.  If anyone can point me to that API, I'll allocate the question points for the reference.

    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
    Private Function EquivalentPrinterSettings(ByVal PrinterSettings1 As PrinterSettings, _
                                                ByVal PrinterSettings2 As PrinterSettings) As Boolean
        If (PrinterSettings1.PrinterName <> PrinterSettings2.PrinterName) Then Return False
        Dim iptDM1 As IntPtr
        Dim iptDM2 As IntPtr
            iptDM1 = PrinterSettings1.GetHdevmode(PrinterSettings1.DefaultPageSettings)
            iptDM2 = PrinterSettings2.GetHdevmode(PrinterSettings2.DefaultPageSettings)
            Dim BufferSize As Integer = DocumentProperties(IntPtr.Zero, IntPtr.Zero, _
                                                           PrinterSettings1.PrinterName, _
                                                           IntPtr.Zero, IntPtr.Zero, 0)
            Dim booEquivalent As Boolean = CompareBuffers(iptDM1, iptDM2, BufferSize)
            Return booEquivalent
        End Try
    End Function

Open in new window

Most Valuable Expert 2012
Top Expert 2008
If that works, go with it, because I don't have anything better, and I don't think any one will join in now.


Right again!  Thanks and cheers,

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial