1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        src/msw/printdlg.cpp
3 // Purpose:     wxPrintDialog, wxPageSetupDialog
4 // Author:      Julian Smart
5 // Modified by:
6 // Created:     04/01/98
7 // RCS-ID:      $Id: printdlg.cpp 62959 2009-12-21 10:04:31Z CE $
8 // Copyright:   (c) Julian Smart
9 // Licence:     wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11 
12 // ===========================================================================
13 // declarations
14 // ===========================================================================
15 
16 // ---------------------------------------------------------------------------
17 // headers
18 // ---------------------------------------------------------------------------
19 
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
22 
23 #ifdef __BORLANDC__
24     #pragma hdrstop
25 #endif
26 
27 // Don't use the Windows print dialog if we're in wxUniv mode and using
28 // the PostScript architecture
29 #if wxUSE_PRINTING_ARCHITECTURE && (!defined(__WXUNIVERSAL__) || !wxUSE_POSTSCRIPT_ARCHITECTURE_IN_MSW)
30 
31 #ifndef WX_PRECOMP
32     #include "wx/msw/wrapcdlg.h"
33     #include "wx/app.h"
34     #include "wx/dcprint.h"
35     #include "wx/cmndata.h"
36 #endif
37 
38 #include "wx/printdlg.h"
39 #include "wx/msw/printdlg.h"
40 #include "wx/paper.h"
41 #include "wx/msgdlg.h"
42 
43 #include <stdlib.h>
44 
45 #ifndef __WIN32__
46     #include <print.h>
47 #endif
48 
49 // smart pointer like class using OpenPrinter and ClosePrinter
50 class WinPrinter
51 {
52 public:
53     // default ctor
WinPrinter()54     WinPrinter()
55     {
56         m_hPrinter = (HANDLE)NULL;
57     }
58 
WinPrinter(const wxString & printerName)59     WinPrinter( const wxString& printerName )
60     {
61         Open( printerName );
62     }
63 
~WinPrinter()64     ~WinPrinter()
65     {
66         Close();
67     }
68 
Open(const wxString & printerName,LPPRINTER_DEFAULTS pDefault=(LPPRINTER_DEFAULTS)NULL)69     BOOL Open( const wxString& printerName, LPPRINTER_DEFAULTS pDefault=(LPPRINTER_DEFAULTS)NULL )
70     {
71         Close();
72         return OpenPrinter( (LPTSTR)printerName.wx_str(), &m_hPrinter, pDefault );
73     }
74 
Close()75     BOOL Close()
76     {
77         BOOL result = TRUE;
78         if( m_hPrinter )
79         {
80             result = ClosePrinter( m_hPrinter );
81             m_hPrinter = (HANDLE)NULL;
82         }
83         return result;
84     }
85 
operator HANDLE()86     operator HANDLE() { return m_hPrinter; }
operator bool()87     operator bool() { return m_hPrinter != (HANDLE)NULL; }
88 
89 private:
90     HANDLE m_hPrinter;
91 
92     DECLARE_NO_COPY_CLASS(WinPrinter)
93 };
94 
95 //----------------------------------------------------------------------------
96 // wxWindowsPrintNativeData
97 //----------------------------------------------------------------------------
98 
99 #ifdef __WXDEBUG__
wxGetPrintDlgError()100 static wxString wxGetPrintDlgError()
101 {
102     DWORD err = CommDlgExtendedError();
103     wxString msg = wxT("Unknown");
104     switch (err)
105     {
106         case CDERR_FINDRESFAILURE: msg = wxT("CDERR_FINDRESFAILURE"); break;
107         case CDERR_INITIALIZATION: msg = wxT("CDERR_INITIALIZATION"); break;
108         case CDERR_LOADRESFAILURE: msg = wxT("CDERR_LOADRESFAILURE"); break;
109         case CDERR_LOADSTRFAILURE: msg = wxT("CDERR_LOADSTRFAILURE"); break;
110         case CDERR_LOCKRESFAILURE: msg = wxT("CDERR_LOCKRESFAILURE"); break;
111         case CDERR_MEMALLOCFAILURE: msg = wxT("CDERR_MEMALLOCFAILURE"); break;
112         case CDERR_MEMLOCKFAILURE: msg = wxT("CDERR_MEMLOCKFAILURE"); break;
113         case CDERR_NOHINSTANCE: msg = wxT("CDERR_NOHINSTANCE"); break;
114         case CDERR_NOHOOK: msg = wxT("CDERR_NOHOOK"); break;
115         case CDERR_NOTEMPLATE: msg = wxT("CDERR_NOTEMPLATE"); break;
116         case CDERR_STRUCTSIZE: msg = wxT("CDERR_STRUCTSIZE"); break;
117         case  PDERR_RETDEFFAILURE: msg = wxT("PDERR_RETDEFFAILURE"); break;
118         case  PDERR_PRINTERNOTFOUND: msg = wxT("PDERR_PRINTERNOTFOUND"); break;
119         case  PDERR_PARSEFAILURE: msg = wxT("PDERR_PARSEFAILURE"); break;
120         case  PDERR_NODEVICES: msg = wxT("PDERR_NODEVICES"); break;
121         case  PDERR_NODEFAULTPRN: msg = wxT("PDERR_NODEFAULTPRN"); break;
122         case  PDERR_LOADDRVFAILURE: msg = wxT("PDERR_LOADDRVFAILURE"); break;
123         case  PDERR_INITFAILURE: msg = wxT("PDERR_INITFAILURE"); break;
124         case  PDERR_GETDEVMODEFAIL: msg = wxT("PDERR_GETDEVMODEFAIL"); break;
125         case  PDERR_DNDMMISMATCH: msg = wxT("PDERR_DNDMMISMATCH"); break;
126         case  PDERR_DEFAULTDIFFERENT: msg = wxT("PDERR_DEFAULTDIFFERENT"); break;
127         case  PDERR_CREATEICFAILURE: msg = wxT("PDERR_CREATEICFAILURE"); break;
128         default: break;
129     }
130     return msg;
131 }
132 #endif
133 
wxCreateDevNames(const wxString & driverName,const wxString & printerName,const wxString & portName)134 static HGLOBAL wxCreateDevNames(const wxString& driverName, const wxString& printerName, const wxString& portName)
135 {
136     HGLOBAL hDev = NULL;
137     // if (!driverName.empty() && !printerName.empty() && !portName.empty())
138     if (driverName.empty() && printerName.empty() && portName.empty())
139     {
140     }
141     else
142     {
143         hDev = GlobalAlloc(GPTR, 4*sizeof(WORD)+
144                            ( driverName.length() + 1 +
145             printerName.length() + 1 +
146                              portName.length()+1 ) * sizeof(wxChar) );
147         LPDEVNAMES lpDev = (LPDEVNAMES)GlobalLock(hDev);
148         lpDev->wDriverOffset = sizeof(WORD) * 4 / sizeof(wxChar);
149         wxStrcpy((wxChar*)lpDev + lpDev->wDriverOffset, driverName);
150 
151         lpDev->wDeviceOffset = (WORD)( lpDev->wDriverOffset +
152                                        driverName.length() + 1 );
153         wxStrcpy((wxChar*)lpDev + lpDev->wDeviceOffset, printerName);
154 
155         lpDev->wOutputOffset = (WORD)( lpDev->wDeviceOffset +
156                                        printerName.length() + 1 );
157         wxStrcpy((wxChar*)lpDev + lpDev->wOutputOffset, portName);
158 
159         lpDev->wDefault = 0;
160 
161         GlobalUnlock(hDev);
162     }
163 
164     return hDev;
165 }
166 
IMPLEMENT_CLASS(wxWindowsPrintNativeData,wxPrintNativeDataBase)167 IMPLEMENT_CLASS(wxWindowsPrintNativeData, wxPrintNativeDataBase)
168 
169 wxWindowsPrintNativeData::wxWindowsPrintNativeData()
170 {
171     m_devMode = (void*) NULL;
172     m_devNames = (void*) NULL;
173     m_customWindowsPaperId = 0;
174 }
175 
~wxWindowsPrintNativeData()176 wxWindowsPrintNativeData::~wxWindowsPrintNativeData()
177 {
178     HGLOBAL hDevMode = (HGLOBAL)(DWORD) m_devMode;
179     if ( hDevMode )
180         GlobalFree(hDevMode);
181     HGLOBAL hDevNames = (HGLOBAL)(DWORD) m_devNames;
182     if ( hDevNames )
183         GlobalFree(hDevNames);
184 }
185 
IsOk() const186 bool wxWindowsPrintNativeData::IsOk() const
187 {
188     return (m_devMode != NULL) ;
189 }
190 
TransferTo(wxPrintData & data)191 bool wxWindowsPrintNativeData::TransferTo( wxPrintData &data )
192 {
193     HGLOBAL hDevMode = (HGLOBAL)(DWORD) m_devMode;
194     HGLOBAL hDevNames = (HGLOBAL)(DWORD) m_devNames;
195 
196     if (!hDevMode)
197     {
198         return false;
199     }
200     else
201     {
202         LPDEVMODE devMode = (LPDEVMODE)GlobalLock(hDevMode);
203 
204         //// Orientation
205         if (devMode->dmFields & DM_ORIENTATION)
206             data.SetOrientation( devMode->dmOrientation );
207 
208         //// Collation
209         if (devMode->dmFields & DM_COLLATE)
210         {
211             if (devMode->dmCollate == DMCOLLATE_TRUE)
212                 data.SetCollate( true );
213             else
214                 data.SetCollate( false );
215         }
216 
217         //// Number of copies
218         if (devMode->dmFields & DM_COPIES)
219             data.SetNoCopies( devMode->dmCopies );
220 
221         //// Bin
222         if (devMode->dmFields & DM_DEFAULTSOURCE) {
223             switch (devMode->dmDefaultSource) {
224                 case DMBIN_ONLYONE        : data.SetBin(wxPRINTBIN_ONLYONE       ); break;
225                 case DMBIN_LOWER          : data.SetBin(wxPRINTBIN_LOWER         ); break;
226                 case DMBIN_MIDDLE         : data.SetBin(wxPRINTBIN_MIDDLE        ); break;
227                 case DMBIN_MANUAL         : data.SetBin(wxPRINTBIN_MANUAL        ); break;
228                 case DMBIN_ENVELOPE       : data.SetBin(wxPRINTBIN_ENVELOPE      ); break;
229                 case DMBIN_ENVMANUAL      : data.SetBin(wxPRINTBIN_ENVMANUAL     ); break;
230                 case DMBIN_AUTO           : data.SetBin(wxPRINTBIN_AUTO          ); break;
231                 case DMBIN_TRACTOR        : data.SetBin(wxPRINTBIN_TRACTOR       ); break;
232                 case DMBIN_SMALLFMT       : data.SetBin(wxPRINTBIN_SMALLFMT      ); break;
233                 case DMBIN_LARGEFMT       : data.SetBin(wxPRINTBIN_LARGEFMT      ); break;
234                 case DMBIN_LARGECAPACITY  : data.SetBin(wxPRINTBIN_LARGECAPACITY ); break;
235                 case DMBIN_CASSETTE       : data.SetBin(wxPRINTBIN_CASSETTE      ); break;
236                 case DMBIN_FORMSOURCE     : data.SetBin(wxPRINTBIN_FORMSOURCE    ); break;
237                 default:
238                     if (devMode->dmDefaultSource>=DMBIN_USER) {
239                         data.SetBin((wxPrintBin)((devMode->dmDefaultSource)-DMBIN_USER+(int)wxPRINTBIN_USER));
240                     } else {
241                         data.SetBin(wxPRINTBIN_DEFAULT);
242                     }
243                     break;
244             }
245         } else {
246             data.SetBin(wxPRINTBIN_DEFAULT);
247         }
248         if (devMode->dmFields & DM_MEDIATYPE)
249         {
250             wxASSERT( (int)devMode->dmMediaType != wxPRINTMEDIA_DEFAULT );
251             data.SetMedia(devMode->dmMediaType);
252         }
253         //// Printer name
254         if (devMode->dmDeviceName[0] != 0)
255             // This syntax fixes a crash when using VS 7.1
256             data.SetPrinterName( wxString(devMode->dmDeviceName, CCHDEVICENAME) );
257 
258         //// Colour
259         if (devMode->dmFields & DM_COLOR)
260         {
261             if (devMode->dmColor == DMCOLOR_COLOR)
262                 data.SetColour( true );
263             else
264                 data.SetColour( false );
265         }
266         else
267             data.SetColour( true );
268 
269         //// Paper size
270         // We don't know size of user defined paper and some buggy drivers
271         // set both DM_PAPERSIZE and DM_PAPERWIDTH & DM_PAPERLENGTH. Since
272         // dmPaperSize >= DMPAPER_USER wouldn't be in wxWin's database, this
273         // code wouldn't set m_paperSize correctly.
274 
275         bool foundPaperSize = false;
276         if ((devMode->dmFields & DM_PAPERSIZE) && (devMode->dmPaperSize < DMPAPER_USER))
277         {
278             if (wxThePrintPaperDatabase)
279             {
280                 wxPrintPaperType* paper = wxThePrintPaperDatabase->FindPaperTypeByPlatformId(devMode->dmPaperSize);
281                 if (paper)
282                 {
283                     data.SetPaperId( paper->GetId() );
284                     data.SetPaperSize( wxSize(paper->GetWidth() / 10,paper->GetHeight() / 10) );
285                     m_customWindowsPaperId = 0;
286                     foundPaperSize = true;
287                 }
288             }
289             else
290             {
291                 // Shouldn't really get here
292                 wxFAIL_MSG(wxT("Paper database wasn't initialized in wxPrintData::ConvertFromNative."));
293                 data.SetPaperId( wxPAPER_NONE );
294                 data.SetPaperSize( wxSize(0,0) );
295                 m_customWindowsPaperId = 0;
296 
297                 GlobalUnlock(hDevMode);
298                 return false;
299             }
300         }
301 
302         if (!foundPaperSize)
303         {
304             if ((devMode->dmFields & DM_PAPERWIDTH) && (devMode->dmFields & DM_PAPERLENGTH))
305             {
306                 // DEVMODE is in tenths of a millimeter
307                 data.SetPaperSize( wxSize(devMode->dmPaperWidth / 10, devMode->dmPaperLength / 10) );
308                 data.SetPaperId( wxPAPER_NONE );
309                 m_customWindowsPaperId = devMode->dmPaperSize;
310             }
311             else
312             {
313                 // Often will reach this for non-standard paper sizes (sizes which
314                 // wouldn't be in wxWidget's paper database). Setting
315                 // m_customWindowsPaperId to devMode->dmPaperSize should be enough
316                 // to get this paper size working.
317                 data.SetPaperSize( wxSize(0,0) );
318                 data.SetPaperId( wxPAPER_NONE );
319                 m_customWindowsPaperId = devMode->dmPaperSize;
320             }
321         }
322 
323         //// Duplex
324 
325         if (devMode->dmFields & DM_DUPLEX)
326         {
327             switch (devMode->dmDuplex)
328             {
329                 case DMDUP_HORIZONTAL:   data.SetDuplex( wxDUPLEX_HORIZONTAL ); break;
330                 case DMDUP_VERTICAL:     data.SetDuplex( wxDUPLEX_VERTICAL ); break;
331                 default:
332                 case DMDUP_SIMPLEX:      data.SetDuplex( wxDUPLEX_SIMPLEX ); break;
333             }
334         }
335         else
336             data.SetDuplex( wxDUPLEX_SIMPLEX );
337 
338         //// Quality
339 
340         if (devMode->dmFields & DM_PRINTQUALITY)
341         {
342             switch (devMode->dmPrintQuality)
343             {
344                 case DMRES_MEDIUM:  data.SetQuality( wxPRINT_QUALITY_MEDIUM ); break;
345                 case DMRES_LOW:     data.SetQuality( wxPRINT_QUALITY_LOW ); break;
346                 case DMRES_DRAFT:   data.SetQuality( wxPRINT_QUALITY_DRAFT ); break;
347                 case DMRES_HIGH:    data.SetQuality( wxPRINT_QUALITY_HIGH ); break;
348                 default:
349                 {
350                     // TODO: if the printer fills in the resolution in DPI, how
351                     // will the application know if it's high, low, draft etc.??
352                     //                    wxFAIL_MSG("Warning: DM_PRINTQUALITY was not one of the standard values.");
353                     data.SetQuality( devMode->dmPrintQuality );
354                     break;
355 
356                 }
357             }
358         }
359         else
360             data.SetQuality( wxPRINT_QUALITY_HIGH );
361 
362         if (devMode->dmDriverExtra > 0)
363             data.SetPrivData( (char *)devMode+devMode->dmSize, devMode->dmDriverExtra );
364         else
365             data.SetPrivData( NULL, 0 );
366 
367         GlobalUnlock(hDevMode);
368     }
369 
370     if (hDevNames)
371     {
372         LPDEVNAMES lpDevNames = (LPDEVNAMES)GlobalLock(hDevNames);
373         if (lpDevNames)
374         {
375             // TODO: Unicode-ification
376 
377             // Get the port name
378             // port is obsolete in WIN32
379             // m_printData.SetPortName((LPSTR)lpDevNames + lpDevNames->wDriverOffset);
380 
381             // Get the printer name
382             wxString printerName = (LPTSTR)lpDevNames + lpDevNames->wDeviceOffset;
383 
384             // Not sure if we should check for this mismatch
385 //            wxASSERT_MSG( (m_printerName.empty() || (devName == m_printerName)), "Printer name obtained from DEVMODE and DEVNAMES were different!");
386 
387             if (!printerName.empty())
388                 data.SetPrinterName( printerName );
389 
390             GlobalUnlock(hDevNames);
391         }
392     }
393 
394     return true;
395 }
396 
TransferFrom(const wxPrintData & data)397 bool wxWindowsPrintNativeData::TransferFrom( const wxPrintData &data )
398 {
399     HGLOBAL hDevMode = (HGLOBAL)(DWORD) m_devMode;
400     HGLOBAL hDevNames = (HGLOBAL)(DWORD) m_devNames;
401     WinPrinter printer;
402     LPTSTR szPrinterName = (LPTSTR)data.GetPrinterName().wx_str();
403 
404     // From MSDN: How To Modify Printer Settings with the DocumentProperties() Function
405     // The purpose of this is to fill the DEVMODE with privdata from printer driver.
406     // If we have a printer name and OpenPrinter sucessfully returns
407     // this replaces the PrintDlg function which creates the DEVMODE filled only with data from default printer.
408     if ( !m_devMode && !data.GetPrinterName().IsEmpty() )
409     {
410         // Open printer
411         if ( printer.Open( data.GetPrinterName() ) == TRUE )
412         {
413             DWORD dwNeeded, dwRet;
414 
415             // Step 1:
416             // Allocate a buffer of the correct size.
417             dwNeeded = DocumentProperties( NULL,
418                 printer,         // Handle to our printer.
419                 szPrinterName,   // Name of the printer.
420                 NULL,            // Asking for size, so
421                 NULL,            // these are not used.
422                 0 );             // Zero returns buffer size.
423 
424             LPDEVMODE tempDevMode = static_cast<LPDEVMODE>( GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT, dwNeeded ) );
425 
426             // Step 2:
427             // Get the default DevMode for the printer
428             dwRet = DocumentProperties( NULL,
429                 printer,
430                 szPrinterName,
431                 tempDevMode,     // The address of the buffer to fill.
432                 NULL,            // Not using the input buffer.
433                 DM_OUT_BUFFER ); // Have the output buffer filled.
434 
435             if ( dwRet != IDOK )
436             {
437                 // If failure, cleanup
438                 GlobalFree( tempDevMode );
439                 printer.Close();
440             }
441             else
442             {
443                 hDevMode = tempDevMode;
444                 m_devMode = hDevMode;
445                 tempDevMode = NULL;
446             }
447         }
448     }
449 
450     if (!hDevMode)
451     {
452         // Use PRINTDLG as a way of creating a DEVMODE object
453         PRINTDLG pd;
454 
455         // GNU-WIN32 has the wrong size PRINTDLG - can't work out why.
456 #ifdef __GNUWIN32__
457         memset(&pd, 0, 66);
458         pd.lStructSize    = 66;
459 #else
460         memset(&pd, 0, sizeof(PRINTDLG));
461 #ifdef __WXWINCE__
462         pd.cbStruct    = sizeof(PRINTDLG);
463 #else
464         pd.lStructSize    = sizeof(PRINTDLG);
465 #endif
466 #endif
467 
468         pd.hwndOwner      = (HWND)NULL;
469         pd.hDevMode       = NULL; // Will be created by PrintDlg
470         pd.hDevNames      = NULL; // Ditto
471         //pd.hInstance      = (HINSTANCE) wxGetInstance();
472 
473         pd.Flags          = PD_RETURNDEFAULT;
474         pd.nCopies        = 1;
475 
476         // Fill out the DEVMODE structure
477         // so we can use it as input in the 'real' PrintDlg
478         if (!PrintDlg(&pd))
479         {
480             if ( pd.hDevMode )
481                 GlobalFree(pd.hDevMode);
482             if ( pd.hDevNames )
483                 GlobalFree(pd.hDevNames);
484             pd.hDevMode = NULL;
485             pd.hDevNames = NULL;
486 
487 #if defined(__WXDEBUG__) && defined(__WIN32__)
488             wxString str(wxT("Printing error: "));
489             str += wxGetPrintDlgError();
490             wxLogDebug(str);
491 #endif
492         }
493         else
494         {
495             hDevMode = pd.hDevMode;
496             m_devMode = (void*)(long) hDevMode;
497             pd.hDevMode = NULL;
498 
499             // We'll create a new DEVNAMEs structure below.
500             if ( pd.hDevNames )
501                 GlobalFree(pd.hDevNames);
502             pd.hDevNames = NULL;
503 
504             // hDevNames = pd->hDevNames;
505             // m_devNames = (void*)(long) hDevNames;
506             // pd->hDevnames = NULL;
507 
508         }
509     }
510 
511     if ( hDevMode )
512     {
513         LPDEVMODE devMode = (LPDEVMODE) GlobalLock(hDevMode);
514 
515         //// Orientation
516         devMode->dmOrientation = (short)data.GetOrientation();
517 
518         //// Collation
519         devMode->dmCollate = (data.GetCollate() ? DMCOLLATE_TRUE : DMCOLLATE_FALSE);
520         devMode->dmFields |= DM_COLLATE;
521 
522         //// Number of copies
523         devMode->dmCopies = (short)data.GetNoCopies();
524         devMode->dmFields |= DM_COPIES;
525 
526         //// Printer name
527         wxString name = data.GetPrinterName();
528         if (!name.empty())
529         {
530             //int len = wxMin(31, m_printerName.Len());
531             wxStrncpy((wxChar*)devMode->dmDeviceName,name.c_str(),31);
532             devMode->dmDeviceName[31] = wxT('\0');
533         }
534 
535         //// Colour
536         if (data.GetColour())
537             devMode->dmColor = DMCOLOR_COLOR;
538         else
539             devMode->dmColor = DMCOLOR_MONOCHROME;
540         devMode->dmFields |= DM_COLOR;
541 
542         //// Paper size
543 
544         // Paper id has priority over paper size. If id is specified, then size
545         // is ignored (as it can be filled in even for standard paper sizes)
546 
547         wxPrintPaperType *paperType = NULL;
548 
549         const wxPaperSize paperId = data.GetPaperId();
550         if ( paperId != wxPAPER_NONE && wxThePrintPaperDatabase )
551         {
552             paperType = wxThePrintPaperDatabase->FindPaperType(paperId);
553         }
554 
555         if ( paperType )
556         {
557             devMode->dmPaperSize = (short)paperType->GetPlatformId();
558             devMode->dmFields |= DM_PAPERSIZE;
559         }
560         else // custom (or no) paper size
561         {
562             const wxSize paperSize = data.GetPaperSize();
563             if ( paperSize != wxDefaultSize )
564             {
565                 // Fall back on specifying the paper size explicitly
566                 if(m_customWindowsPaperId != 0)
567                     devMode->dmPaperSize = m_customWindowsPaperId;
568                 else
569                     devMode->dmPaperSize = DMPAPER_USER;
570                 devMode->dmPaperWidth = (short)(paperSize.x * 10);
571                 devMode->dmPaperLength = (short)(paperSize.y * 10);
572                 devMode->dmFields |= DM_PAPERWIDTH;
573                 devMode->dmFields |= DM_PAPERLENGTH;
574 
575                 // A printer driver may or may not also want DM_PAPERSIZE to
576                 // be specified. Also, if the printer driver doesn't implement the DMPAPER_USER
577                 // size, then this won't work, and even if you found the correct id by
578                 // enumerating the driver's paper sizes, it probably won't change the actual size,
579                 // it'll just select that custom paper type with its own current setting.
580                 // For a discussion on this, see http://www.codeguru.com/forum/showthread.php?threadid=458617
581                 // Although m_customWindowsPaperId is intended to work around this, it's
582                 // unclear how it can help you set the custom paper size programmatically.
583             }
584             //else: neither paper type nor size specified, don't fill DEVMODE
585             //      at all so that the system defaults are used
586         }
587 
588         //// Duplex
589         short duplex;
590         switch (data.GetDuplex())
591         {
592             case wxDUPLEX_HORIZONTAL:
593                 duplex = DMDUP_HORIZONTAL;
594                 break;
595             case wxDUPLEX_VERTICAL:
596                 duplex = DMDUP_VERTICAL;
597                 break;
598             default:
599             // in fact case wxDUPLEX_SIMPLEX:
600                 duplex = DMDUP_SIMPLEX;
601                 break;
602         }
603         devMode->dmDuplex = duplex;
604         devMode->dmFields |= DM_DUPLEX;
605 
606         //// Quality
607 
608         short quality;
609         switch (data.GetQuality())
610         {
611             case wxPRINT_QUALITY_MEDIUM:
612                 quality = DMRES_MEDIUM;
613                 break;
614             case wxPRINT_QUALITY_LOW:
615                 quality = DMRES_LOW;
616                 break;
617             case wxPRINT_QUALITY_DRAFT:
618                 quality = DMRES_DRAFT;
619                 break;
620             case wxPRINT_QUALITY_HIGH:
621                 quality = DMRES_HIGH;
622                 break;
623             default:
624                 quality = (short)data.GetQuality();
625                 devMode->dmYResolution = quality;
626                 devMode->dmFields |= DM_YRESOLUTION;
627                 break;
628         }
629         devMode->dmPrintQuality = quality;
630         devMode->dmFields |= DM_PRINTQUALITY;
631 
632         if (data.GetPrivDataLen() > 0)
633         {
634             memcpy( (char *)devMode+devMode->dmSize, data.GetPrivData(), data.GetPrivDataLen() );
635             devMode->dmDriverExtra = (WXWORD)data.GetPrivDataLen();
636         }
637 
638         if (data.GetBin() != wxPRINTBIN_DEFAULT)
639         {
640             switch (data.GetBin())
641             {
642                 case wxPRINTBIN_ONLYONE:        devMode->dmDefaultSource = DMBIN_ONLYONE;       break;
643                 case wxPRINTBIN_LOWER:          devMode->dmDefaultSource = DMBIN_LOWER;         break;
644                 case wxPRINTBIN_MIDDLE:         devMode->dmDefaultSource = DMBIN_MIDDLE;        break;
645                 case wxPRINTBIN_MANUAL:         devMode->dmDefaultSource = DMBIN_MANUAL;        break;
646                 case wxPRINTBIN_ENVELOPE:       devMode->dmDefaultSource = DMBIN_ENVELOPE;      break;
647                 case wxPRINTBIN_ENVMANUAL:      devMode->dmDefaultSource = DMBIN_ENVMANUAL;     break;
648                 case wxPRINTBIN_AUTO:           devMode->dmDefaultSource = DMBIN_AUTO;          break;
649                 case wxPRINTBIN_TRACTOR:        devMode->dmDefaultSource = DMBIN_TRACTOR;       break;
650                 case wxPRINTBIN_SMALLFMT:       devMode->dmDefaultSource = DMBIN_SMALLFMT;      break;
651                 case wxPRINTBIN_LARGEFMT:       devMode->dmDefaultSource = DMBIN_LARGEFMT;      break;
652                 case wxPRINTBIN_LARGECAPACITY:  devMode->dmDefaultSource = DMBIN_LARGECAPACITY; break;
653                 case wxPRINTBIN_CASSETTE:       devMode->dmDefaultSource = DMBIN_CASSETTE;      break;
654                 case wxPRINTBIN_FORMSOURCE:     devMode->dmDefaultSource = DMBIN_FORMSOURCE;    break;
655 
656                 default:
657                     devMode->dmDefaultSource = (short)(DMBIN_USER + data.GetBin() - wxPRINTBIN_USER); // 256 + data.GetBin() - 14 = 242 + data.GetBin()
658                     break;
659             }
660 
661             devMode->dmFields |= DM_DEFAULTSOURCE;
662         }
663         if (data.GetMedia() != wxPRINTMEDIA_DEFAULT)
664         {
665             devMode->dmMediaType = data.GetMedia();
666             devMode->dmFields |= DM_MEDIATYPE;
667         }
668         if( printer )
669         {
670             // Step 3:
671             // Merge the new settings with the old.
672             // This gives the driver an opportunity to update any private
673             // portions of the DevMode structure.
674             DocumentProperties( NULL,
675                 printer,
676                 szPrinterName,
677                 (LPDEVMODE)hDevMode, // Reuse our buffer for output.
678                 (LPDEVMODE)hDevMode, // Pass the driver our changes
679                 DM_IN_BUFFER |       // Commands to Merge our changes and
680                 DM_OUT_BUFFER );     // write the result.
681         }
682         GlobalUnlock(hDevMode);
683     }
684 
685     if ( hDevNames )
686     {
687         GlobalFree(hDevNames);
688     }
689 
690     // TODO: I hope it's OK to pass some empty strings to DEVNAMES.
691     m_devNames = (void*) (long) wxCreateDevNames(wxEmptyString, data.GetPrinterName(), wxEmptyString);
692 
693     return true;
694 }
695 
696 // ---------------------------------------------------------------------------
697 // wxPrintDialog
698 // ---------------------------------------------------------------------------
699 
IMPLEMENT_CLASS(wxWindowsPrintDialog,wxPrintDialogBase)700 IMPLEMENT_CLASS(wxWindowsPrintDialog, wxPrintDialogBase)
701 
702 wxWindowsPrintDialog::wxWindowsPrintDialog(wxWindow *p, wxPrintDialogData* data)
703 {
704     Create(p, data);
705 }
706 
wxWindowsPrintDialog(wxWindow * p,wxPrintData * data)707 wxWindowsPrintDialog::wxWindowsPrintDialog(wxWindow *p, wxPrintData* data)
708 {
709     wxPrintDialogData data2;
710     if ( data )
711         data2 = *data;
712 
713     Create(p, &data2);
714 }
715 
Create(wxWindow * p,wxPrintDialogData * data)716 bool wxWindowsPrintDialog::Create(wxWindow *p, wxPrintDialogData* data)
717 {
718     m_dialogParent = p;
719     m_printerDC = NULL;
720     m_destroyDC = true;
721 
722     // MSW handle
723     m_printDlg = NULL;
724 
725     if ( data )
726         m_printDialogData = *data;
727 
728     return true;
729 }
730 
~wxWindowsPrintDialog()731 wxWindowsPrintDialog::~wxWindowsPrintDialog()
732 {
733     PRINTDLG *pd = (PRINTDLG *) m_printDlg;
734     if (pd && pd->hDevMode)
735         GlobalFree(pd->hDevMode);
736     if ( pd )
737         delete pd;
738 
739     if (m_destroyDC && m_printerDC)
740         delete m_printerDC;
741 }
742 
ShowModal()743 int wxWindowsPrintDialog::ShowModal()
744 {
745     ConvertToNative( m_printDialogData );
746 
747     PRINTDLG *pd = (PRINTDLG*) m_printDlg;
748 
749     if (m_dialogParent)
750         pd->hwndOwner = (HWND) m_dialogParent->GetHWND();
751     else if (wxTheApp->GetTopWindow())
752         pd->hwndOwner = (HWND) wxTheApp->GetTopWindow()->GetHWND();
753     else
754         pd->hwndOwner = 0;
755 
756     bool ret = (PrintDlg( pd ) != 0);
757 
758     pd->hwndOwner = 0;
759 
760     if ( ret && (pd->hDC) )
761     {
762         wxPrinterDC *pdc = new wxPrinterDC( (WXHDC) pd->hDC );
763         m_printerDC = pdc;
764         ConvertFromNative( m_printDialogData );
765         return wxID_OK;
766     }
767     else
768     {
769         return wxID_CANCEL;
770     }
771 }
772 
GetPrintDC()773 wxDC *wxWindowsPrintDialog::GetPrintDC()
774 {
775     if (m_printerDC)
776     {
777         m_destroyDC = false;
778         return m_printerDC;
779     }
780     else
781         return (wxPrinterDC*) NULL;
782 }
783 
ConvertToNative(wxPrintDialogData & data)784 bool wxWindowsPrintDialog::ConvertToNative( wxPrintDialogData &data )
785 {
786     wxWindowsPrintNativeData *native_data =
787         (wxWindowsPrintNativeData *) data.GetPrintData().GetNativeData();
788     data.GetPrintData().ConvertToNative();
789 
790     PRINTDLG *pd = (PRINTDLG*) m_printDlg;
791 
792     // Shouldn't have been defined anywhere
793     if (pd)
794         return false;
795 
796     pd = new PRINTDLG;
797     memset( pd, 0, sizeof(PRINTDLG) );
798     m_printDlg = (void*) pd;
799 
800     // GNU-WIN32 has the wrong size PRINTDLG - can't work out why.
801 #ifdef __GNUWIN32__
802     pd->lStructSize    = 66;
803 #else
804     pd->lStructSize    = sizeof(PRINTDLG);
805 #endif
806     pd->hwndOwner      = (HWND)NULL;
807     pd->hDevMode       = NULL; // Will be created by PrintDlg
808     pd->hDevNames      = NULL; // Ditto
809 
810     pd->Flags          = PD_RETURNDEFAULT;
811     pd->nCopies        = 1;
812 
813     // Pass the devmode data to the PRINTDLG structure, since it'll
814     // be needed when PrintDlg is called.
815     if (pd->hDevMode)
816         GlobalFree(pd->hDevMode);
817 
818     // Pass the devnames data to the PRINTDLG structure, since it'll
819     // be needed when PrintDlg is called.
820     if (pd->hDevNames)
821         GlobalFree(pd->hDevNames);
822 
823     pd->hDevMode = (HGLOBAL)(DWORD) native_data->GetDevMode();
824     native_data->SetDevMode( (void*) NULL);
825 
826     // Shouldn't assert; we should be able to test Ok-ness at a higher level
827     //wxASSERT_MSG( (pd->hDevMode), wxT("hDevMode must be non-NULL in ConvertToNative!"));
828 
829     pd->hDevNames = (HGLOBAL)(DWORD) native_data->GetDevNames();
830     native_data->SetDevNames( (void*) NULL);
831 
832 
833     pd->hDC = (HDC) NULL;
834     pd->nFromPage = (WORD)data.GetFromPage();
835     pd->nToPage = (WORD)data.GetToPage();
836     pd->nMinPage = (WORD)data.GetMinPage();
837     pd->nMaxPage = (WORD)data.GetMaxPage();
838     pd->nCopies = (WORD)data.GetNoCopies();
839 
840     pd->Flags = PD_RETURNDC;
841 
842 #ifdef __GNUWIN32__
843     pd->lStructSize = 66;
844 #else
845     pd->lStructSize = sizeof( PRINTDLG );
846 #endif
847 
848     pd->hwndOwner=(HWND)NULL;
849 //    pd->hDevNames=(HANDLE)NULL;
850     pd->hInstance=(HINSTANCE)NULL;
851     pd->lCustData = (LPARAM) NULL;
852     pd->lpfnPrintHook = NULL;
853     pd->lpfnSetupHook = NULL;
854     pd->lpPrintTemplateName = NULL;
855     pd->lpSetupTemplateName = NULL;
856     pd->hPrintTemplate = (HGLOBAL) NULL;
857     pd->hSetupTemplate = (HGLOBAL) NULL;
858 
859     if ( data.GetAllPages() )
860         pd->Flags |= PD_ALLPAGES;
861     if ( data.GetSelection() )
862         pd->Flags |= PD_SELECTION;
863     if ( data.GetCollate() )
864         pd->Flags |= PD_COLLATE;
865     if ( data.GetPrintToFile() )
866         pd->Flags |= PD_PRINTTOFILE;
867     if ( !data.GetEnablePrintToFile() )
868         pd->Flags |= PD_DISABLEPRINTTOFILE;
869     if ( !data.GetEnableSelection() )
870         pd->Flags |= PD_NOSELECTION;
871     if ( !data.GetEnablePageNumbers() )
872         pd->Flags |= PD_NOPAGENUMS;
873     else if ( (!data.GetAllPages()) && (!data.GetSelection()) && (data.GetFromPage() != 0) && (data.GetToPage() != 0))
874         pd->Flags |= PD_PAGENUMS;
875     if ( data.GetEnableHelp() )
876         pd->Flags |= PD_SHOWHELP;
877 #if WXWIN_COMPATIBILITY_2_4
878     if ( data.GetSetupDialog() )
879         pd->Flags |= PD_PRINTSETUP;
880 #endif
881 
882     return true;
883 }
884 
ConvertFromNative(wxPrintDialogData & data)885 bool wxWindowsPrintDialog::ConvertFromNative( wxPrintDialogData &data )
886 {
887     PRINTDLG *pd = (PRINTDLG*) m_printDlg;
888     if ( pd == NULL )
889         return false;
890 
891     wxWindowsPrintNativeData *native_data =
892         (wxWindowsPrintNativeData *) data.GetPrintData().GetNativeData();
893 
894     // Pass the devmode data back to the wxPrintData structure where it really belongs.
895     if (pd->hDevMode)
896     {
897         if (native_data->GetDevMode())
898         {
899             // Make sure we don't leak memory
900             GlobalFree( (HGLOBAL)(DWORD) native_data->GetDevMode() );
901         }
902         native_data->SetDevMode( (void*)(long) pd->hDevMode );
903         pd->hDevMode = NULL;
904     }
905 
906     // Pass the devnames data back to the wxPrintData structure where it really belongs.
907     if (pd->hDevNames)
908     {
909         if (native_data->GetDevNames())
910         {
911             // Make sure we don't leak memory
912             GlobalFree((HGLOBAL)(DWORD) native_data->GetDevNames());
913         }
914         native_data->SetDevNames((void*)(long) pd->hDevNames);
915         pd->hDevNames = NULL;
916     }
917 
918     // Now convert the DEVMODE object, passed down from the PRINTDLG object,
919     // into wxWidgets form.
920     native_data->TransferTo( data.GetPrintData() );
921 
922     data.SetFromPage( pd->nFromPage );
923     data.SetToPage( pd->nToPage );
924     data.SetMinPage( pd->nMinPage );
925     data.SetMaxPage( pd->nMaxPage );
926     data.SetNoCopies( pd->nCopies );
927 
928     data.SetAllPages( (((pd->Flags & PD_PAGENUMS) != PD_PAGENUMS) && ((pd->Flags & PD_SELECTION) != PD_SELECTION)) );
929     data.SetSelection( ((pd->Flags & PD_SELECTION) == PD_SELECTION) );
930     data.SetCollate( ((pd->Flags & PD_COLLATE) == PD_COLLATE) );
931     data.SetPrintToFile( ((pd->Flags & PD_PRINTTOFILE) == PD_PRINTTOFILE) );
932     data.EnablePrintToFile( ((pd->Flags & PD_DISABLEPRINTTOFILE) != PD_DISABLEPRINTTOFILE) );
933     data.EnableSelection( ((pd->Flags & PD_NOSELECTION) != PD_NOSELECTION) );
934     data.EnablePageNumbers( ((pd->Flags & PD_NOPAGENUMS) != PD_NOPAGENUMS) );
935     data.EnableHelp( ((pd->Flags & PD_SHOWHELP) == PD_SHOWHELP) );
936 #if WXWIN_COMPATIBILITY_2_4
937     data.SetSetupDialog( ((pd->Flags & PD_PRINTSETUP) == PD_PRINTSETUP) );
938 #endif
939 
940     return true;
941 }
942 
943 // ---------------------------------------------------------------------------
944 // wxWidnowsPageSetupDialog
945 // ---------------------------------------------------------------------------
946 
IMPLEMENT_CLASS(wxWindowsPageSetupDialog,wxPageSetupDialogBase)947 IMPLEMENT_CLASS(wxWindowsPageSetupDialog, wxPageSetupDialogBase)
948 
949 wxWindowsPageSetupDialog::wxWindowsPageSetupDialog()
950 {
951     m_dialogParent = NULL;
952     m_pageDlg = NULL;
953 }
954 
wxWindowsPageSetupDialog(wxWindow * p,wxPageSetupDialogData * data)955 wxWindowsPageSetupDialog::wxWindowsPageSetupDialog(wxWindow *p, wxPageSetupDialogData *data)
956 {
957     Create(p, data);
958 }
959 
Create(wxWindow * p,wxPageSetupDialogData * data)960 bool wxWindowsPageSetupDialog::Create(wxWindow *p, wxPageSetupDialogData *data)
961 {
962     m_dialogParent = p;
963     m_pageDlg = NULL;
964 
965     if (data)
966         m_pageSetupData = (*data);
967 
968     return true;
969 }
970 
~wxWindowsPageSetupDialog()971 wxWindowsPageSetupDialog::~wxWindowsPageSetupDialog()
972 {
973     PAGESETUPDLG *pd = (PAGESETUPDLG *)m_pageDlg;
974     if ( pd && pd->hDevMode )
975         GlobalFree(pd->hDevMode);
976     if ( pd && pd->hDevNames )
977         GlobalFree(pd->hDevNames);
978     if ( pd )
979         delete pd;
980 }
981 
ShowModal()982 int wxWindowsPageSetupDialog::ShowModal()
983 {
984     ConvertToNative( m_pageSetupData );
985 
986     PAGESETUPDLG *pd = (PAGESETUPDLG *) m_pageDlg;
987     if (m_dialogParent)
988         pd->hwndOwner = (HWND) m_dialogParent->GetHWND();
989     else if (wxTheApp->GetTopWindow())
990         pd->hwndOwner = (HWND) wxTheApp->GetTopWindow()->GetHWND();
991     else
992         pd->hwndOwner = 0;
993 
994     BOOL retVal = PageSetupDlg( pd ) ;
995     pd->hwndOwner = 0;
996 
997     if (retVal)
998     {
999         ConvertFromNative( m_pageSetupData );
1000 
1001         return wxID_OK;
1002     }
1003 
1004     return wxID_CANCEL;
1005 }
1006 
ConvertToNative(wxPageSetupDialogData & data)1007 bool wxWindowsPageSetupDialog::ConvertToNative( wxPageSetupDialogData &data )
1008 {
1009     wxWindowsPrintNativeData *native_data =
1010         (wxWindowsPrintNativeData *) data.GetPrintData().GetNativeData();
1011     data.GetPrintData().ConvertToNative();
1012 
1013     PAGESETUPDLG *pd = (PAGESETUPDLG*) m_pageDlg;
1014 
1015     // Shouldn't have been defined anywhere
1016     if (pd)
1017         return false;
1018 
1019     pd = new PAGESETUPDLG;
1020     pd->hDevMode = NULL;
1021     pd->hDevNames = NULL;
1022     m_pageDlg = (void *)pd;
1023 
1024     // Pass the devmode data (created in m_printData.ConvertToNative)
1025     // to the PRINTDLG structure, since it'll
1026     // be needed when PrintDlg is called.
1027 
1028     if (pd->hDevMode)
1029     {
1030         GlobalFree(pd->hDevMode);
1031         pd->hDevMode = NULL;
1032     }
1033     pd->hDevMode = (HGLOBAL) native_data->GetDevMode();
1034     native_data->SetDevMode( (void*) NULL );
1035 
1036     // Shouldn't assert; we should be able to test Ok-ness at a higher level
1037     //wxASSERT_MSG( (pd->hDevMode), wxT("hDevMode must be non-NULL in ConvertToNative!"));
1038 
1039     // Pass the devnames data (created in m_printData.ConvertToNative)
1040     // to the PRINTDLG structure, since it'll
1041     // be needed when PrintDlg is called.
1042 
1043     if (pd->hDevNames)
1044     {
1045         GlobalFree(pd->hDevNames);
1046         pd->hDevNames = NULL;
1047     }
1048     pd->hDevNames = (HGLOBAL) native_data->GetDevNames();
1049     native_data->SetDevNames((void*) NULL);
1050 
1051 //        pd->hDevMode = GlobalAlloc(GMEM_MOVEABLE, sizeof(DEVMODE));
1052 
1053     pd->Flags = PSD_MARGINS|PSD_MINMARGINS;
1054 
1055     if ( data.GetDefaultMinMargins() )
1056         pd->Flags |= PSD_DEFAULTMINMARGINS;
1057     if ( !data.GetEnableMargins() )
1058         pd->Flags |= PSD_DISABLEMARGINS;
1059     if ( !data.GetEnableOrientation() )
1060         pd->Flags |= PSD_DISABLEORIENTATION;
1061     if ( !data.GetEnablePaper() )
1062         pd->Flags |= PSD_DISABLEPAPER;
1063     if ( !data.GetEnablePrinter() )
1064         pd->Flags |= PSD_DISABLEPRINTER;
1065     if ( data.GetDefaultInfo() )
1066         pd->Flags |= PSD_RETURNDEFAULT;
1067     if ( data.GetEnableHelp() )
1068         pd->Flags |= PSD_SHOWHELP;
1069 
1070     // We want the units to be in hundredths of a millimetre
1071     pd->Flags |= PSD_INHUNDREDTHSOFMILLIMETERS;
1072 
1073     pd->lStructSize = sizeof( PAGESETUPDLG );
1074     pd->hwndOwner=(HWND)NULL;
1075 //    pd->hDevNames=(HWND)NULL;
1076     pd->hInstance=(HINSTANCE)NULL;
1077     //   PAGESETUPDLG is in hundreds of a mm
1078     pd->ptPaperSize.x = data.GetPaperSize().x * 100;
1079     pd->ptPaperSize.y = data.GetPaperSize().y * 100;
1080 
1081     pd->rtMinMargin.left = data.GetMinMarginTopLeft().x * 100;
1082     pd->rtMinMargin.top = data.GetMinMarginTopLeft().y * 100;
1083     pd->rtMinMargin.right = data.GetMinMarginBottomRight().x * 100;
1084     pd->rtMinMargin.bottom = data.GetMinMarginBottomRight().y * 100;
1085 
1086     pd->rtMargin.left = data.GetMarginTopLeft().x * 100;
1087     pd->rtMargin.top = data.GetMarginTopLeft().y * 100;
1088     pd->rtMargin.right = data.GetMarginBottomRight().x * 100;
1089     pd->rtMargin.bottom = data.GetMarginBottomRight().y * 100;
1090 
1091     pd->lCustData = 0;
1092     pd->lpfnPageSetupHook = NULL;
1093     pd->lpfnPagePaintHook = NULL;
1094     pd->hPageSetupTemplate = NULL;
1095     pd->lpPageSetupTemplateName = NULL;
1096 
1097 /*
1098     if ( pd->hDevMode )
1099     {
1100         DEVMODE *devMode = (DEVMODE*) GlobalLock(pd->hDevMode);
1101         memset(devMode, 0, sizeof(DEVMODE));
1102         devMode->dmSize = sizeof(DEVMODE);
1103         devMode->dmOrientation = m_orientation;
1104         devMode->dmFields = DM_ORIENTATION;
1105         GlobalUnlock(pd->hDevMode);
1106     }
1107 */
1108     return true;
1109 }
1110 
ConvertFromNative(wxPageSetupDialogData & data)1111 bool wxWindowsPageSetupDialog::ConvertFromNative( wxPageSetupDialogData &data )
1112 {
1113     PAGESETUPDLG *pd = (PAGESETUPDLG *) m_pageDlg;
1114     if ( !pd )
1115         return false;
1116 
1117     wxWindowsPrintNativeData *native_data =
1118         (wxWindowsPrintNativeData *) data.GetPrintData().GetNativeData();
1119 
1120     // Pass the devmode data back to the wxPrintData structure where it really belongs.
1121     if (pd->hDevMode)
1122     {
1123         if (native_data->GetDevMode())
1124         {
1125             // Make sure we don't leak memory
1126             GlobalFree((HGLOBAL) native_data->GetDevMode());
1127         }
1128         native_data->SetDevMode( (void*) pd->hDevMode );
1129         pd->hDevMode = NULL;
1130     }
1131 
1132     // Isn't this superfluous? It's called again below.
1133     // data.GetPrintData().ConvertFromNative();
1134 
1135     // Pass the devnames data back to the wxPrintData structure where it really belongs.
1136     if (pd->hDevNames)
1137     {
1138         if (native_data->GetDevNames())
1139         {
1140             // Make sure we don't leak memory
1141             GlobalFree((HGLOBAL) native_data->GetDevNames());
1142         }
1143         native_data->SetDevNames((void*) pd->hDevNames);
1144         pd->hDevNames = NULL;
1145     }
1146 
1147     data.GetPrintData().ConvertFromNative();
1148 
1149     pd->Flags = PSD_MARGINS|PSD_MINMARGINS;
1150 
1151     data.SetDefaultMinMargins( ((pd->Flags & PSD_DEFAULTMINMARGINS) == PSD_DEFAULTMINMARGINS) );
1152     data.EnableMargins( ((pd->Flags & PSD_DISABLEMARGINS) != PSD_DISABLEMARGINS) );
1153     data.EnableOrientation( ((pd->Flags & PSD_DISABLEORIENTATION) != PSD_DISABLEORIENTATION) );
1154     data.EnablePaper( ((pd->Flags & PSD_DISABLEPAPER) != PSD_DISABLEPAPER) );
1155     data.EnablePrinter( ((pd->Flags & PSD_DISABLEPRINTER) != PSD_DISABLEPRINTER) );
1156     data.SetDefaultInfo( ((pd->Flags & PSD_RETURNDEFAULT) == PSD_RETURNDEFAULT) );
1157     data.EnableHelp( ((pd->Flags & PSD_SHOWHELP) == PSD_SHOWHELP) );
1158 
1159     //   PAGESETUPDLG is in hundreds of a mm
1160     if (data.GetPrintData().GetOrientation() == wxLANDSCAPE)
1161         data.SetPaperSize( wxSize(pd->ptPaperSize.y / 100, pd->ptPaperSize.x / 100) );
1162     else
1163         data.SetPaperSize( wxSize(pd->ptPaperSize.x / 100, pd->ptPaperSize.y / 100) );
1164 
1165     data.SetMinMarginTopLeft( wxPoint(pd->rtMinMargin.left / 100, pd->rtMinMargin.top / 100) );
1166     data.SetMinMarginBottomRight( wxPoint(pd->rtMinMargin.right / 100, pd->rtMinMargin.bottom / 100) );
1167 
1168     data.SetMarginTopLeft( wxPoint(pd->rtMargin.left / 100, pd->rtMargin.top / 100) );
1169     data.SetMarginBottomRight( wxPoint(pd->rtMargin.right / 100, pd->rtMargin.bottom / 100) );
1170 
1171     return true;
1172 }
1173 
1174 #endif
1175     // wxUSE_PRINTING_ARCHITECTURE
1176