]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/printdlg.cpp
use (new) safer GetTraitsIfExists() in wxMutexGuiEnter/Leave() to avoid crashing...
[wxWidgets.git] / src / msw / printdlg.cpp
index 378044bb5e681182fc5cc2ae39e2a9b4ad0115bc..cedf15ad4609b5f1646aff2a5d185620ea5b9ef7 100644 (file)
@@ -1,5 +1,5 @@
 /////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////
-// Name:        printdlg.cpp
+// Name:        src/msw/printdlg.cpp
 // Purpose:     wxPrintDialog, wxPageSetupDialog
 // Author:      Julian Smart
 // Modified by:
 // Purpose:     wxPrintDialog, wxPageSetupDialog
 // Author:      Julian Smart
 // Modified by:
 // headers
 // ---------------------------------------------------------------------------
 
 // headers
 // ---------------------------------------------------------------------------
 
-#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
-    #pragma implementation "printdlg.h"
-#endif
-
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
 
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
 
 #if wxUSE_PRINTING_ARCHITECTURE && (!defined(__WXUNIVERSAL__) || !wxUSE_POSTSCRIPT_ARCHITECTURE_IN_MSW)
 
 #ifndef WX_PRECOMP
 #if wxUSE_PRINTING_ARCHITECTURE && (!defined(__WXUNIVERSAL__) || !wxUSE_POSTSCRIPT_ARCHITECTURE_IN_MSW)
 
 #ifndef WX_PRECOMP
+    #include "wx/msw/wrapcdlg.h"
     #include "wx/app.h"
     #include "wx/app.h"
+    #include "wx/dcprint.h"
+    #include "wx/cmndata.h"
 #endif
 
 #endif
 
-#include "wx/cmndata.h"
 #include "wx/printdlg.h"
 #include "wx/msw/printdlg.h"
 #include "wx/printdlg.h"
 #include "wx/msw/printdlg.h"
-#include "wx/dcprint.h"
+#include "wx/msw/dcprint.h"
 #include "wx/paper.h"
 
 #include <stdlib.h>
 
 #include "wx/paper.h"
 
 #include <stdlib.h>
 
-#include "wx/msw/wrapcdlg.h"
-
 #ifndef __WIN32__
     #include <print.h>
 #endif
 #ifndef __WIN32__
     #include <print.h>
 #endif
@@ -99,19 +95,19 @@ static HGLOBAL wxCreateDevNames(const wxString& driverName, const wxString& prin
     else
     {
         hDev = GlobalAlloc(GPTR, 4*sizeof(WORD)+
     else
     {
         hDev = GlobalAlloc(GPTR, 4*sizeof(WORD)+
-                           ( driverName.Length() + 1 +
-            printerName.Length() + 1 +
-                             portName.Length()+1 ) * sizeof(wxChar) );
+                           ( driverName.length() + 1 +
+            printerName.length() + 1 +
+                             portName.length()+1 ) * sizeof(wxChar) );
         LPDEVNAMES lpDev = (LPDEVNAMES)GlobalLock(hDev);
         lpDev->wDriverOffset = sizeof(WORD) * 4 / sizeof(wxChar);
         wxStrcpy((wxChar*)lpDev + lpDev->wDriverOffset, driverName);
 
         lpDev->wDeviceOffset = (WORD)( lpDev->wDriverOffset +
         LPDEVNAMES lpDev = (LPDEVNAMES)GlobalLock(hDev);
         lpDev->wDriverOffset = sizeof(WORD) * 4 / sizeof(wxChar);
         wxStrcpy((wxChar*)lpDev + lpDev->wDriverOffset, driverName);
 
         lpDev->wDeviceOffset = (WORD)( lpDev->wDriverOffset +
-                                       driverName.Length() + 1 );
+                                       driverName.length() + 1 );
         wxStrcpy((wxChar*)lpDev + lpDev->wDeviceOffset, printerName);
 
         lpDev->wOutputOffset = (WORD)( lpDev->wDeviceOffset +
         wxStrcpy((wxChar*)lpDev + lpDev->wDeviceOffset, printerName);
 
         lpDev->wOutputOffset = (WORD)( lpDev->wDeviceOffset +
-                                       printerName.Length() + 1 );
+                                       printerName.length() + 1 );
         wxStrcpy((wxChar*)lpDev + lpDev->wOutputOffset, portName);
 
         lpDev->wDefault = 0;
         wxStrcpy((wxChar*)lpDev + lpDev->wOutputOffset, portName);
 
         lpDev->wDefault = 0;
@@ -126,111 +122,136 @@ IMPLEMENT_CLASS(wxWindowsPrintNativeData, wxPrintNativeDataBase)
 
 wxWindowsPrintNativeData::wxWindowsPrintNativeData()
 {
 
 wxWindowsPrintNativeData::wxWindowsPrintNativeData()
 {
-    m_devMode = (void*) NULL;
-    m_devNames = (void*) NULL;
+    m_devMode = NULL;
+    m_devNames = NULL;
     m_customWindowsPaperId = 0;
 }
 
 wxWindowsPrintNativeData::~wxWindowsPrintNativeData()
 {
     m_customWindowsPaperId = 0;
 }
 
 wxWindowsPrintNativeData::~wxWindowsPrintNativeData()
 {
-    HGLOBAL hDevMode = (HGLOBAL)(DWORD) m_devMode;
-    if ( hDevMode )
-        GlobalFree(hDevMode);
-    HGLOBAL hDevNames = (HGLOBAL)(DWORD) m_devNames;
-    if ( hDevNames )
-        GlobalFree(hDevNames);
+    if ( m_devMode )
+        ::GlobalFree(wx_static_cast(HGLOBAL, m_devMode));
+
+    if ( m_devNames )
+        ::GlobalFree(wx_static_cast(HGLOBAL, m_devNames));
 }
 
 }
 
-bool wxWindowsPrintNativeData::Ok() const
+bool wxWindowsPrintNativeData::IsOk() const
 {
     return (m_devMode != NULL) ;
 }
 
 bool wxWindowsPrintNativeData::TransferTo( wxPrintData &data )
 {
 {
     return (m_devMode != NULL) ;
 }
 
 bool wxWindowsPrintNativeData::TransferTo( wxPrintData &data )
 {
-    HGLOBAL hDevMode = (HGLOBAL)(DWORD) m_devMode;
-    HGLOBAL hDevNames = (HGLOBAL)(DWORD) m_devNames;
-
-    if (!hDevMode)
-    {
+    if ( !m_devMode )
         return false;
         return false;
-    }
-    else
-    {
-        LPDEVMODE devMode = (LPDEVMODE)GlobalLock(hDevMode);
-
-        //// Orientation
-        if (devMode->dmFields & DM_ORIENTATION)
-            data.SetOrientation( devMode->dmOrientation );
 
 
-        //// Collation
-        if (devMode->dmFields & DM_COLLATE)
-        {
-            if (devMode->dmCollate == DMCOLLATE_TRUE)
-                data.SetCollate( true );
-            else
-                data.SetCollate( false );
-        }
+    GlobalPtrLock lockDevMode(m_devMode);
 
 
-        //// Number of copies
-        if (devMode->dmFields & DM_COPIES)
-            data.SetNoCopies( devMode->dmCopies );
+    LPDEVMODE devMode = wx_static_cast(LPDEVMODE, lockDevMode.Get());
 
 
-        if (devMode->dmFields & DM_DEFAULTSOURCE)
-            data.SetBin( (wxPrintBin)devMode->dmDefaultSource );
+    //// Orientation
+    if (devMode->dmFields & DM_ORIENTATION)
+        data.SetOrientation( devMode->dmOrientation );
 
 
-        //// Printer name
-        if (devMode->dmDeviceName[0] != 0)
-            data.SetPrinterName( devMode->dmDeviceName );
+    //// Collation
+    if (devMode->dmFields & DM_COLLATE)
+    {
+        if (devMode->dmCollate == DMCOLLATE_TRUE)
+            data.SetCollate( true );
+        else
+            data.SetCollate( false );
+    }
 
 
-        //// Colour
-        if (devMode->dmFields & DM_COLOR)
-        {
-            if (devMode->dmColor == DMCOLOR_COLOR)
-                data.SetColour( true );
-            else
-                data.SetColour( false );
+    //// Number of copies
+    if (devMode->dmFields & DM_COPIES)
+        data.SetNoCopies( devMode->dmCopies );
+
+    //// Bin
+    if (devMode->dmFields & DM_DEFAULTSOURCE) {
+        switch (devMode->dmDefaultSource) {
+            case DMBIN_ONLYONE        : data.SetBin(wxPRINTBIN_ONLYONE       ); break;
+            case DMBIN_LOWER          : data.SetBin(wxPRINTBIN_LOWER         ); break;
+            case DMBIN_MIDDLE         : data.SetBin(wxPRINTBIN_MIDDLE        ); break;
+            case DMBIN_MANUAL         : data.SetBin(wxPRINTBIN_MANUAL        ); break;
+            case DMBIN_ENVELOPE       : data.SetBin(wxPRINTBIN_ENVELOPE      ); break;
+            case DMBIN_ENVMANUAL      : data.SetBin(wxPRINTBIN_ENVMANUAL     ); break;
+            case DMBIN_AUTO           : data.SetBin(wxPRINTBIN_AUTO          ); break;
+            case DMBIN_TRACTOR        : data.SetBin(wxPRINTBIN_TRACTOR       ); break;
+            case DMBIN_SMALLFMT       : data.SetBin(wxPRINTBIN_SMALLFMT      ); break;
+            case DMBIN_LARGEFMT       : data.SetBin(wxPRINTBIN_LARGEFMT      ); break;
+            case DMBIN_LARGECAPACITY  : data.SetBin(wxPRINTBIN_LARGECAPACITY ); break;
+            case DMBIN_CASSETTE       : data.SetBin(wxPRINTBIN_CASSETTE      ); break;
+            case DMBIN_FORMSOURCE     : data.SetBin(wxPRINTBIN_FORMSOURCE    ); break;
+            default:
+                if (devMode->dmDefaultSource>=DMBIN_USER) {
+                    data.SetBin((wxPrintBin)((devMode->dmDefaultSource)-DMBIN_USER+(int)wxPRINTBIN_USER));
+                } else {
+                    data.SetBin(wxPRINTBIN_DEFAULT);
+                }
+                break;
         }
         }
-        else
+    } else {
+        data.SetBin(wxPRINTBIN_DEFAULT);
+    }
+    if (devMode->dmFields & DM_MEDIATYPE)
+    {
+        wxASSERT( (int)devMode->dmMediaType != wxPRINTMEDIA_DEFAULT );
+        data.SetMedia(devMode->dmMediaType);
+    }
+    //// Printer name
+    if (devMode->dmDeviceName[0] != 0)
+        // This syntax fixes a crash when using VS 7.1
+        data.SetPrinterName( wxString(devMode->dmDeviceName, CCHDEVICENAME) );
+
+    //// Colour
+    if (devMode->dmFields & DM_COLOR)
+    {
+        if (devMode->dmColor == DMCOLOR_COLOR)
             data.SetColour( true );
             data.SetColour( true );
+        else
+            data.SetColour( false );
+    }
+    else
+        data.SetColour( true );
 
 
-        //// Paper size
+    //// Paper size
 
 
-        // We don't know size of user defined paper and some buggy drivers
-        // set both DM_PAPERSIZE and DM_PAPERWIDTH & DM_PAPERLENGTH. Since
-        // dmPaperSize >= DMPAPER_USER wouldn't be in wxWin's database, this
-        // code wouldn't set m_paperSize correctly.
+    // We don't know size of user defined paper and some buggy drivers
+    // set both DM_PAPERSIZE and DM_PAPERWIDTH & DM_PAPERLENGTH. Since
+    // dmPaperSize >= DMPAPER_USER wouldn't be in wxWin's database, this
+    // code wouldn't set m_paperSize correctly.
 
 
-        bool foundPaperSize = false;
-        if ((devMode->dmFields & DM_PAPERSIZE) && (devMode->dmPaperSize < DMPAPER_USER))
+    bool foundPaperSize = false;
+    if ((devMode->dmFields & DM_PAPERSIZE) && (devMode->dmPaperSize < DMPAPER_USER))
+    {
+        if (wxThePrintPaperDatabase)
         {
         {
-            if (wxThePrintPaperDatabase)
+            wxPrintPaperType* paper = wxThePrintPaperDatabase->FindPaperTypeByPlatformId(devMode->dmPaperSize);
+            if (paper)
             {
             {
-                wxPrintPaperType* paper = wxThePrintPaperDatabase->FindPaperTypeByPlatformId(devMode->dmPaperSize);
-                if (paper)
-                {
-                    data.SetPaperId( paper->GetId() );
-                    data.SetPaperSize( wxSize(paper->GetWidth() / 10,paper->GetHeight() / 10) );
-                    m_customWindowsPaperId = 0;
-                    foundPaperSize = true;
-                }
-            }
-            else
-            {
-                // Shouldn't really get here
-                wxFAIL_MSG(wxT("Paper database wasn't initialized in wxPrintData::ConvertFromNative."));
-                data.SetPaperId( wxPAPER_NONE );
-                data.SetPaperSize( wxSize(0,0) );
+                data.SetPaperId( paper->GetId() );
+                data.SetPaperSize( wxSize(paper->GetWidth() / 10,paper->GetHeight() / 10) );
                 m_customWindowsPaperId = 0;
                 m_customWindowsPaperId = 0;
-
-                GlobalUnlock(hDevMode);
-                return false;
+                foundPaperSize = true;
             }
         }
             }
         }
+        else
+        {
+            // Shouldn't really get here
+            wxFAIL_MSG(wxT("Paper database wasn't initialized in wxPrintData::ConvertFromNative."));
+            data.SetPaperId( wxPAPER_NONE );
+            data.SetPaperSize( wxSize(0,0) );
+            m_customWindowsPaperId = 0;
+
+            return false;
+        }
+    }
 
 
-        if (!foundPaperSize && (devMode->dmFields & DM_PAPERWIDTH) && (devMode->dmFields & DM_PAPERLENGTH))
+    if (!foundPaperSize) {
+        if ((devMode->dmFields & DM_PAPERWIDTH) && (devMode->dmFields & DM_PAPERLENGTH))
         {
         {
-            // DEVMODE is in tenths of a milimeter
+            // DEVMODE is in tenths of a millimeter
             data.SetPaperSize( wxSize(devMode->dmPaperWidth / 10, devMode->dmPaperLength / 10) );
             data.SetPaperId( wxPAPER_NONE );
             m_customWindowsPaperId = devMode->dmPaperSize;
             data.SetPaperSize( wxSize(devMode->dmPaperWidth / 10, devMode->dmPaperLength / 10) );
             data.SetPaperId( wxPAPER_NONE );
             m_customWindowsPaperId = devMode->dmPaperSize;
@@ -245,76 +266,71 @@ bool wxWindowsPrintNativeData::TransferTo( wxPrintData &data )
             data.SetPaperId( wxPAPER_NONE );
             m_customWindowsPaperId = devMode->dmPaperSize;
         }
             data.SetPaperId( wxPAPER_NONE );
             m_customWindowsPaperId = devMode->dmPaperSize;
         }
+    }
 
 
-        //// Duplex
+    //// Duplex
 
 
-        if (devMode->dmFields & DM_DUPLEX)
+    if (devMode->dmFields & DM_DUPLEX)
+    {
+        switch (devMode->dmDuplex)
         {
         {
-            switch (devMode->dmDuplex)
-            {
-                case DMDUP_HORIZONTAL:   data.SetDuplex( wxDUPLEX_HORIZONTAL ); break;
-                case DMDUP_VERTICAL:     data.SetDuplex( wxDUPLEX_VERTICAL ); break;
-                default:
-                case DMDUP_SIMPLEX:      data.SetDuplex( wxDUPLEX_SIMPLEX ); break;
-            }
+            case DMDUP_HORIZONTAL:   data.SetDuplex( wxDUPLEX_HORIZONTAL ); break;
+            case DMDUP_VERTICAL:     data.SetDuplex( wxDUPLEX_VERTICAL ); break;
+            default:
+            case DMDUP_SIMPLEX:      data.SetDuplex( wxDUPLEX_SIMPLEX ); break;
         }
         }
-        else
-            data.SetDuplex( wxDUPLEX_SIMPLEX );
+    }
+    else
+        data.SetDuplex( wxDUPLEX_SIMPLEX );
 
 
-        //// Quality
+    //// Quality
 
 
-        if (devMode->dmFields & DM_PRINTQUALITY)
+    if (devMode->dmFields & DM_PRINTQUALITY)
+    {
+        switch (devMode->dmPrintQuality)
         {
         {
-            switch (devMode->dmPrintQuality)
+            case DMRES_MEDIUM:  data.SetQuality( wxPRINT_QUALITY_MEDIUM ); break;
+            case DMRES_LOW:     data.SetQuality( wxPRINT_QUALITY_LOW ); break;
+            case DMRES_DRAFT:   data.SetQuality( wxPRINT_QUALITY_DRAFT ); break;
+            case DMRES_HIGH:    data.SetQuality( wxPRINT_QUALITY_HIGH ); break;
+            default:
             {
             {
-                case DMRES_MEDIUM:  data.SetQuality( wxPRINT_QUALITY_MEDIUM ); break;
-                case DMRES_LOW:     data.SetQuality( wxPRINT_QUALITY_LOW ); break;
-                case DMRES_DRAFT:   data.SetQuality( wxPRINT_QUALITY_DRAFT ); break;
-                case DMRES_HIGH:    data.SetQuality( wxPRINT_QUALITY_HIGH ); break;
-                default:
-                {
-                    // TODO: if the printer fills in the resolution in DPI, how
-                    // will the application know if it's high, low, draft etc.??
-                    //                    wxFAIL_MSG("Warning: DM_PRINTQUALITY was not one of the standard values.");
-                    data.SetQuality( devMode->dmPrintQuality );
-                    break;
+                // TODO: if the printer fills in the resolution in DPI, how
+                // will the application know if it's high, low, draft etc.??
+                //                    wxFAIL_MSG("Warning: DM_PRINTQUALITY was not one of the standard values.");
+                data.SetQuality( devMode->dmPrintQuality );
+                break;
 
 
-                }
             }
         }
             }
         }
-        else
-            data.SetQuality( wxPRINT_QUALITY_HIGH );
-
-        if (devMode->dmDriverExtra > 0)
-            data.SetPrivData( (char *)devMode+devMode->dmSize, devMode->dmDriverExtra );
-        else
-            data.SetPrivData( NULL, 0 );
-
-        GlobalUnlock(hDevMode);
     }
     }
+    else
+        data.SetQuality( wxPRINT_QUALITY_HIGH );
+
+    if (devMode->dmDriverExtra > 0)
+        data.SetPrivData( (char *)devMode+devMode->dmSize, devMode->dmDriverExtra );
+    else
+        data.SetPrivData( NULL, 0 );
 
 
-    if (hDevNames)
+    if ( m_devNames )
     {
     {
-        LPDEVNAMES lpDevNames = (LPDEVNAMES)GlobalLock(hDevNames);
-        if (lpDevNames)
-        {
-            // TODO: Unicode-ification
+        GlobalPtrLock lockDevNames(m_devNames);
+        LPDEVNAMES lpDevNames = wx_static_cast(LPDEVNAMES, lockDevNames.Get());
 
 
-            // Get the port name
-            // port is obsolete in WIN32
-            // m_printData.SetPortName((LPSTR)lpDevNames + lpDevNames->wDriverOffset);
+        // TODO: Unicode-ification
 
 
-            // Get the printer name
-            wxString printerName = (LPTSTR)lpDevNames + lpDevNames->wDeviceOffset;
+        // Get the port name
+        // port is obsolete in WIN32
+        // m_printData.SetPortName((LPSTR)lpDevNames + lpDevNames->wDriverOffset);
 
 
-            // Not sure if we should check for this mismatch
-//            wxASSERT_MSG( (m_printerName.empty() || (devName == m_printerName)), "Printer name obtained from DEVMODE and DEVNAMES were different!");
+        // Get the printer name
+        wxString printerName = (LPTSTR)lpDevNames + lpDevNames->wDeviceOffset;
 
 
-            if (!printerName.empty())
-                data.SetPrinterName( printerName );
+        // Not sure if we should check for this mismatch
+//            wxASSERT_MSG( (m_printerName.empty() || (devName == m_printerName)), "Printer name obtained from DEVMODE and DEVNAMES were different!");
 
 
-            GlobalUnlock(hDevNames);
-        }
+        if (!printerName.empty())
+            data.SetPrinterName( printerName );
     }
 
     return true;
     }
 
     return true;
@@ -322,9 +338,8 @@ bool wxWindowsPrintNativeData::TransferTo( wxPrintData &data )
 
 bool wxWindowsPrintNativeData::TransferFrom( const wxPrintData &data )
 {
 
 bool wxWindowsPrintNativeData::TransferFrom( const wxPrintData &data )
 {
-    HGLOBAL hDevMode = (HGLOBAL)(DWORD) m_devMode;
-    HGLOBAL hDevNames = (HGLOBAL)(DWORD) m_devNames;
-    if (!hDevMode)
+    HGLOBAL hDevMode = wx_static_cast(HGLOBAL, m_devMode);
+    if ( !m_devMode )
     {
         // Use PRINTDLG as a way of creating a DEVMODE object
         PRINTDLG pd;
     {
         // Use PRINTDLG as a way of creating a DEVMODE object
         PRINTDLG pd;
@@ -370,7 +385,7 @@ bool wxWindowsPrintNativeData::TransferFrom( const wxPrintData &data )
         else
         {
             hDevMode = pd.hDevMode;
         else
         {
             hDevMode = pd.hDevMode;
-            m_devMode = (void*)(long) hDevMode;
+            m_devMode = hDevMode;
             pd.hDevMode = NULL;
 
             // We'll create a new DEVNAMEs structure below.
             pd.hDevMode = NULL;
 
             // We'll create a new DEVNAMEs structure below.
@@ -387,7 +402,8 @@ bool wxWindowsPrintNativeData::TransferFrom( const wxPrintData &data )
 
     if ( hDevMode )
     {
 
     if ( hDevMode )
     {
-        LPDEVMODE devMode = (LPDEVMODE) GlobalLock(hDevMode);
+        GlobalPtrLock lockDevMode(hDevMode);
+        DEVMODE * const devMode = wx_static_cast(DEVMODE *, lockDevMode.Get());
 
         //// Orientation
         devMode->dmOrientation = (short)data.GetOrientation();
 
         //// Orientation
         devMode->dmOrientation = (short)data.GetOrientation();
@@ -404,9 +420,12 @@ bool wxWindowsPrintNativeData::TransferFrom( const wxPrintData &data )
         wxString name = data.GetPrinterName();
         if (!name.empty())
         {
         wxString name = data.GetPrinterName();
         if (!name.empty())
         {
-            //int len = wxMin(31, m_printerName.Len());
-            wxStrncpy((wxChar*)devMode->dmDeviceName,name.c_str(),31);
-            devMode->dmDeviceName[31] = wxT('\0');
+            // NB: the cast is needed in the ANSI build, strangely enough
+            //     dmDeviceName is BYTE[] and not char[] there
+            wxStrncpy(wx_reinterpret_cast(wxChar *, devMode->dmDeviceName),
+                      name.wx_str(),
+                      WXSIZEOF(devMode->dmDeviceName) - 1);
+            devMode->dmDeviceName[WXSIZEOF(devMode->dmDeviceName) - 1] = wxT('\0');
         }
 
         //// Colour
         }
 
         //// Colour
@@ -417,38 +436,40 @@ bool wxWindowsPrintNativeData::TransferFrom( const wxPrintData &data )
         devMode->dmFields |= DM_COLOR;
 
         //// Paper size
         devMode->dmFields |= DM_COLOR;
 
         //// Paper size
-        if (data.GetPaperId() == wxPAPER_NONE)
+
+        // Paper id has priority over paper size. If id is specified, then size
+        // is ignored (as it can be filled in even for standard paper sizes)
+
+        wxPrintPaperType *paperType = NULL;
+
+        const wxPaperSize paperId = data.GetPaperId();
+        if ( paperId != wxPAPER_NONE && wxThePrintPaperDatabase )
         {
         {
-            // DEVMODE is in tenths of a milimeter
-            devMode->dmPaperWidth = (short)(data.GetPaperSize().x * 10);
-            devMode->dmPaperLength = (short)(data.GetPaperSize().y * 10);
-            if(m_customWindowsPaperId != 0)
-                devMode->dmPaperSize = m_customWindowsPaperId;
-            else
-                devMode->dmPaperSize = DMPAPER_USER;
-            devMode->dmFields |= DM_PAPERWIDTH;
-            devMode->dmFields |= DM_PAPERLENGTH;
+            paperType = wxThePrintPaperDatabase->FindPaperType(paperId);
         }
         }
-        else
+
+        if ( paperType )
+        {
+            devMode->dmPaperSize = (short)paperType->GetPlatformId();
+            devMode->dmFields |= DM_PAPERSIZE;
+        }
+        else // custom (or no) paper size
         {
         {
-            if (wxThePrintPaperDatabase)
+            const wxSize paperSize = data.GetPaperSize();
+            if ( paperSize != wxDefaultSize )
             {
             {
-                wxPrintPaperType* paper = wxThePrintPaperDatabase->FindPaperType( data.GetPaperId() );
-                if (paper)
-                {
-                    devMode->dmPaperSize = (short)paper->GetPlatformId();
-                    devMode->dmFields |= DM_PAPERSIZE;
-                }
+                // Fall back on specifying the paper size explicitly
+                if(m_customWindowsPaperId != 0)
+                    devMode->dmPaperSize = m_customWindowsPaperId;
                 else
                 else
-                {
-                    // Fall back on specifying the paper size explicitly
-                    devMode->dmPaperWidth = (short)(data.GetPaperSize().x * 10);
-                    devMode->dmPaperLength = (short)(data.GetPaperSize().y * 10);
                     devMode->dmPaperSize = DMPAPER_USER;
                     devMode->dmPaperSize = DMPAPER_USER;
-                    devMode->dmFields |= DM_PAPERWIDTH;
-                    devMode->dmFields |= DM_PAPERLENGTH;
-                }
+                devMode->dmPaperWidth = (short)(paperSize.x * 10);
+                devMode->dmPaperLength = (short)(paperSize.y * 10);
+                devMode->dmFields |= DM_PAPERWIDTH;
+                devMode->dmFields |= DM_PAPERLENGTH;
             }
             }
+            //else: neither paper type nor size specified, don't fill DEVMODE
+            //      at all so that the system defaults are used
         }
 
         //// Duplex
         }
 
         //// Duplex
@@ -518,23 +539,26 @@ bool wxWindowsPrintNativeData::TransferFrom( const wxPrintData &data )
                 case wxPRINTBIN_FORMSOURCE:     devMode->dmDefaultSource = DMBIN_FORMSOURCE;    break;
 
                 default:
                 case wxPRINTBIN_FORMSOURCE:     devMode->dmDefaultSource = DMBIN_FORMSOURCE;    break;
 
                 default:
-                    devMode->dmDefaultSource = (short)(DMBIN_USER + data.GetBin() - wxPRINTBIN_USER);
+                    devMode->dmDefaultSource = (short)(DMBIN_USER + data.GetBin() - wxPRINTBIN_USER); // 256 + data.GetBin() - 14 = 242 + data.GetBin()
                     break;
             }
 
             devMode->dmFields |= DM_DEFAULTSOURCE;
         }
                     break;
             }
 
             devMode->dmFields |= DM_DEFAULTSOURCE;
         }
-
-        GlobalUnlock(hDevMode);
+        if (data.GetMedia() != wxPRINTMEDIA_DEFAULT)
+        {
+            devMode->dmMediaType = data.GetMedia();
+            devMode->dmFields |= DM_MEDIATYPE;
+        }
     }
 
     }
 
-    if ( hDevNames )
+    if ( m_devNames )
     {
     {
-        GlobalFree(hDevNames);
+        ::GlobalFree(wx_static_cast(HGLOBAL, m_devNames));
     }
 
     // TODO: I hope it's OK to pass some empty strings to DEVNAMES.
     }
 
     // TODO: I hope it's OK to pass some empty strings to DEVNAMES.
-    m_devNames = (void*) (long) wxCreateDevNames(wxEmptyString, data.GetPrinterName(), wxEmptyString);
+    m_devNames = wxCreateDevNames(wxEmptyString, data.GetPrinterName(), wxEmptyString);
 
     return true;
 }
 
     return true;
 }
@@ -603,9 +627,9 @@ int wxWindowsPrintDialog::ShowModal()
 
     pd->hwndOwner = 0;
 
 
     pd->hwndOwner = 0;
 
-    if ( ret != false && (pd->hDC) )
+    if ( ret && (pd->hDC) )
     {
     {
-        wxPrinterDC *pdc = new wxPrinterDC( (WXHDC) pd->hDC );
+        wxPrinterDC *pdc = new wxPrinterDCFromHDC( (WXHDC) pd->hDC );
         m_printerDC = pdc;
         ConvertFromNative( m_printDialogData );
         return wxID_OK;
         m_printerDC = pdc;
         ConvertFromNative( m_printDialogData );
         return wxID_OK;
@@ -624,7 +648,7 @@ wxDC *wxWindowsPrintDialog::GetPrintDC()
         return m_printerDC;
     }
     else
         return m_printerDC;
     }
     else
-        return (wxDC*) NULL;
+        return (wxPrinterDC*) NULL;
 }
 
 bool wxWindowsPrintDialog::ConvertToNative( wxPrintDialogData &data )
 }
 
 bool wxWindowsPrintDialog::ConvertToNative( wxPrintDialogData &data )
@@ -666,14 +690,14 @@ bool wxWindowsPrintDialog::ConvertToNative( wxPrintDialogData &data )
     if (pd->hDevNames)
         GlobalFree(pd->hDevNames);
 
     if (pd->hDevNames)
         GlobalFree(pd->hDevNames);
 
-    pd->hDevMode = (HGLOBAL)(DWORD) native_data->GetDevMode();
-    native_data->SetDevMode( (void*) NULL);
+    pd->hDevMode = wx_static_cast(HGLOBAL, native_data->GetDevMode());
+    native_data->SetDevMode(NULL);
 
     // Shouldn't assert; we should be able to test Ok-ness at a higher level
     //wxASSERT_MSG( (pd->hDevMode), wxT("hDevMode must be non-NULL in ConvertToNative!"));
 
 
     // Shouldn't assert; we should be able to test Ok-ness at a higher level
     //wxASSERT_MSG( (pd->hDevMode), wxT("hDevMode must be non-NULL in ConvertToNative!"));
 
-    pd->hDevNames = (HGLOBAL)(DWORD) native_data->GetDevNames();
-    native_data->SetDevNames( (void*) NULL);
+    pd->hDevNames = wx_static_cast(HGLOBAL, native_data->GetDevNames());
+    native_data->SetDevNames(NULL);
 
 
     pd->hDC = (HDC) NULL;
 
 
     pd->hDC = (HDC) NULL;
@@ -720,10 +744,6 @@ bool wxWindowsPrintDialog::ConvertToNative( wxPrintDialogData &data )
         pd->Flags |= PD_PAGENUMS;
     if ( data.GetEnableHelp() )
         pd->Flags |= PD_SHOWHELP;
         pd->Flags |= PD_PAGENUMS;
     if ( data.GetEnableHelp() )
         pd->Flags |= PD_SHOWHELP;
-#if WXWIN_COMPATIBILITY_2_4
-    if ( data.GetSetupDialog() )
-        pd->Flags |= PD_PRINTSETUP;
-#endif
 
     return true;
 }
 
     return true;
 }
@@ -742,10 +762,9 @@ bool wxWindowsPrintDialog::ConvertFromNative( wxPrintDialogData &data )
     {
         if (native_data->GetDevMode())
         {
     {
         if (native_data->GetDevMode())
         {
-            // Make sure we don't leak memory
-            GlobalFree( (HGLOBAL)(DWORD) native_data->GetDevMode() );
+            ::GlobalFree(wx_static_cast(HGLOBAL, native_data->GetDevMode()));
         }
         }
-        native_data->SetDevMode( (void*)(long) pd->hDevMode );
+        native_data->SetDevMode(pd->hDevMode);
         pd->hDevMode = NULL;
     }
 
         pd->hDevMode = NULL;
     }
 
@@ -754,10 +773,9 @@ bool wxWindowsPrintDialog::ConvertFromNative( wxPrintDialogData &data )
     {
         if (native_data->GetDevNames())
         {
     {
         if (native_data->GetDevNames())
         {
-            // Make sure we don't leak memory
-            GlobalFree((HGLOBAL)(DWORD) native_data->GetDevNames());
+            ::GlobalFree(wx_static_cast(HGLOBAL, native_data->GetDevNames()));
         }
         }
-        native_data->SetDevNames((void*)(long) pd->hDevNames);
+        native_data->SetDevNames(pd->hDevNames);
         pd->hDevNames = NULL;
     }
 
         pd->hDevNames = NULL;
     }
 
@@ -779,9 +797,7 @@ bool wxWindowsPrintDialog::ConvertFromNative( wxPrintDialogData &data )
     data.EnableSelection( ((pd->Flags & PD_NOSELECTION) != PD_NOSELECTION) );
     data.EnablePageNumbers( ((pd->Flags & PD_NOPAGENUMS) != PD_NOPAGENUMS) );
     data.EnableHelp( ((pd->Flags & PD_SHOWHELP) == PD_SHOWHELP) );
     data.EnableSelection( ((pd->Flags & PD_NOSELECTION) != PD_NOSELECTION) );
     data.EnablePageNumbers( ((pd->Flags & PD_NOPAGENUMS) != PD_NOPAGENUMS) );
     data.EnableHelp( ((pd->Flags & PD_SHOWHELP) == PD_SHOWHELP) );
-#if WXWIN_COMPATIBILITY_2_4
-    data.SetSetupDialog( ((pd->Flags & PD_PRINTSETUP) == PD_PRINTSETUP) );
-#endif
+
     return true;
 }
 
     return true;
 }
 
@@ -999,7 +1015,10 @@ bool wxWindowsPageSetupDialog::ConvertFromNative( wxPageSetupDialogData &data )
     data.EnableHelp( ((pd->Flags & PSD_SHOWHELP) == PSD_SHOWHELP) );
 
     //   PAGESETUPDLG is in hundreds of a mm
     data.EnableHelp( ((pd->Flags & PSD_SHOWHELP) == PSD_SHOWHELP) );
 
     //   PAGESETUPDLG is in hundreds of a mm
-    data.SetPaperSize( wxSize(pd->ptPaperSize.x / 100, pd->ptPaperSize.y / 100) );
+    if (data.GetPrintData().GetOrientation() == wxLANDSCAPE)
+        data.SetPaperSize( wxSize(pd->ptPaperSize.y / 100, pd->ptPaperSize.x / 100) );
+    else
+        data.SetPaperSize( wxSize(pd->ptPaperSize.x / 100, pd->ptPaperSize.y / 100) );
 
     data.SetMinMarginTopLeft( wxPoint(pd->rtMinMargin.left / 100, pd->rtMinMargin.top / 100) );
     data.SetMinMarginBottomRight( wxPoint(pd->rtMinMargin.right / 100, pd->rtMinMargin.bottom / 100) );
 
     data.SetMinMarginTopLeft( wxPoint(pd->rtMinMargin.left / 100, pd->rtMinMargin.top / 100) );
     data.SetMinMarginBottomRight( wxPoint(pd->rtMinMargin.right / 100, pd->rtMinMargin.bottom / 100) );