Comparing Printer.PageSettings

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.

Cheers,
Randy
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

LVL 12
omegaomegaDeveloperAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Bob LearnedCommented:
What kind of "comparison" are you talking about?  You might be able to create a custom print settings class that implements IComparable.
0
omegaomegaDeveloperAuthor Commented:
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)?

Cheers,
Randy
0
omegaomegaDeveloperAuthor Commented:
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.

Cheers,
Randy
    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
        Try
            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
        Finally
            GlobalFree(iptDM1)
            GlobalFree(iptDM2)
        End Try
 
    End Function

Open in new window

0
Bob LearnedCommented:
If that works, go with it, because I don't have anything better, and I don't think any one will join in now.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
omegaomegaDeveloperAuthor Commented:
Right again!  Thanks and cheers,
Randy
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic.NET

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.