]> git.saurik.com Git - wxWidgets.git/commitdiff
Applied patch #11078 - DEVMODE creation in wxWindowsPrintNativeData::TransferFrom...
authorJulian Smart <julian@anthemion.co.uk>
Thu, 24 Sep 2009 09:54:25 +0000 (09:54 +0000)
committerJulian Smart <julian@anthemion.co.uk>
Thu, 24 Sep 2009 09:54:25 +0000 (09:54 +0000)
by Martin Perktold

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@62065 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/msw/private.h
src/msw/printdlg.cpp

index 9e40732a3796b0a9559ec572788f4ef3fd530c9d..fa95062dc0dee2e70e764d79966707aa6da9746a 100644 (file)
@@ -727,6 +727,52 @@ private:
     wxDECLARE_NO_COPY_CLASS(GlobalPtrLock);
 };
 
+// smart pointer like class using OpenPrinter and ClosePrinter
+class WinPrinter
+{
+public:
+    // default ctor
+    WinPrinter()
+    {
+        m_hPrinter = (HANDLE)NULL;
+    }
+
+    WinPrinter( const wxString& printerName )
+    {
+        Open( printerName );
+    }
+
+    ~WinPrinter()
+    {
+        Close();
+    }
+
+    BOOL Open( const wxString& printerName, LPPRINTER_DEFAULTS pDefault=(LPPRINTER_DEFAULTS)NULL )
+    {
+        Close();
+        return OpenPrinter( (LPTSTR)printerName.wx_str(), &m_hPrinter, pDefault );
+    }
+
+    BOOL Close()
+    {
+        BOOL result = TRUE;
+        if( m_hPrinter )
+        {
+            result = ClosePrinter( m_hPrinter );
+            m_hPrinter = (HANDLE)NULL;
+        }
+        return result;
+    }
+
+    operator HANDLE() { return m_hPrinter; }
+    operator bool() { return m_hPrinter != (HANDLE)NULL; }
+
+private:
+    HANDLE m_hPrinter;
+
+    wxDECLARE_NO_COPY_CLASS(WinPrinter);
+};
+
 // register the class when it is first needed and unregister it in dtor
 class ClassRegistrar
 {
index 37bdfd3abad39e63848e81f8c5cc7de2e86d43d6..b9b89b6210c8b18e9383f745873c3f1fa9efae54 100644 (file)
@@ -339,6 +339,55 @@ bool wxWindowsPrintNativeData::TransferTo( wxPrintData &data )
 bool wxWindowsPrintNativeData::TransferFrom( const wxPrintData &data )
 {
     HGLOBAL hDevMode = static_cast<HGLOBAL>(m_devMode);
+    WinPrinter printer;
+    LPTSTR szPrinterName = (LPTSTR)data.GetPrinterName().wx_str();
+
+    // From MSDN: How To Modify Printer Settings with the DocumentProperties() Function
+    // The purpose of this is to fill the DEVMODE with privdata from printer driver.
+    // If we have a printer name and OpenPrinter sucessfully returns
+    // this replaces the PrintDlg function which creates the DEVMODE filled only with data from default printer.
+    if ( !m_devMode && !data.GetPrinterName().IsEmpty() )
+    {
+        // Open printer
+        if ( printer.Open( data.GetPrinterName() ) == TRUE )
+        {
+            DWORD dwNeeded, dwRet;
+
+            // Step 1:
+            // Allocate a buffer of the correct size.
+            dwNeeded = DocumentProperties( NULL,
+                printer,         // Handle to our printer.
+                szPrinterName,   // Name of the printer.
+                NULL,            // Asking for size, so
+                NULL,            // these are not used.
+                0 );             // Zero returns buffer size.
+
+            LPDEVMODE tempDevMode = static_cast<LPDEVMODE>( GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT, dwNeeded ) );
+
+            // Step 2:
+            // Get the default DevMode for the printer
+            dwRet = DocumentProperties( NULL,
+                printer,
+                szPrinterName,
+                tempDevMode,     // The address of the buffer to fill.
+                NULL,            // Not using the input buffer.
+                DM_OUT_BUFFER ); // Have the output buffer filled.
+
+            if ( dwRet != IDOK )
+            {
+                // If failure, cleanup
+                GlobalFree( tempDevMode );
+                printer.Close();
+            }
+            else
+            {
+                hDevMode = tempDevMode;
+                m_devMode = hDevMode;
+                tempDevMode = NULL;
+            }
+        }
+    }
+
     if ( !m_devMode )
     {
         // Use PRINTDLG as a way of creating a DEVMODE object
@@ -508,6 +557,8 @@ bool wxWindowsPrintNativeData::TransferFrom( const wxPrintData &data )
                 break;
             default:
                 quality = (short)data.GetQuality();
+                devMode->dmYResolution = quality;
+                devMode->dmFields |= DM_YRESOLUTION;
                 break;
         }
         devMode->dmPrintQuality = quality;
@@ -549,6 +600,21 @@ bool wxWindowsPrintNativeData::TransferFrom( const wxPrintData &data )
             devMode->dmMediaType = data.GetMedia();
             devMode->dmFields |= DM_MEDIATYPE;
         }
+
+        if( printer )
+        {
+            // Step 3:
+            // Merge the new settings with the old.
+            // This gives the driver an opportunity to update any private
+            // portions of the DevMode structure.
+            DocumentProperties( NULL,
+                printer,
+                szPrinterName,
+                (LPDEVMODE)hDevMode, // Reuse our buffer for output.
+                (LPDEVMODE)hDevMode, // Pass the driver our changes
+                DM_IN_BUFFER |       // Commands to Merge our changes and
+                DM_OUT_BUFFER );     // write the result.
+        }
     }
 
     if ( m_devNames )