Link to home
Start Free TrialLog in
Avatar of omegaomega
omegaomegaFlag for Canada

asked on

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

Avatar of Bob Learned
Bob Learned
Flag of United States of America image

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

ASKER

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
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

ASKER CERTIFIED SOLUTION
Avatar of Bob Learned
Bob Learned
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Right again!  Thanks and cheers,
Randy