1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     wxPrintDialog, wxPageSetupDialog 
   4 // Author:      Julian Smart 
   8 // Copyright:   (c) Julian Smart 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // =========================================================================== 
  14 // =========================================================================== 
  16 // --------------------------------------------------------------------------- 
  18 // --------------------------------------------------------------------------- 
  20 // For compilers that support precompilation, includes "wx.h". 
  21 #include "wx/wxprec.h" 
  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) 
  35 #include "wx/cmndata.h" 
  36 #include "wx/printdlg.h" 
  37 #include "wx/msw/printdlg.h" 
  38 #include "wx/dcprint.h" 
  43 #include "wx/msw/wrapcdlg.h" 
  49 //---------------------------------------------------------------------------- 
  50 // wxWindowsPrintNativeData 
  51 //---------------------------------------------------------------------------- 
  54 static wxString 
wxGetPrintDlgError() 
  56     DWORD err 
= CommDlgExtendedError(); 
  57     wxString msg 
= wxT("Unknown"); 
  60         case CDERR_FINDRESFAILURE
: msg 
= wxT("CDERR_FINDRESFAILURE"); break; 
  61         case CDERR_INITIALIZATION
: msg 
= wxT("CDERR_INITIALIZATION"); break; 
  62         case CDERR_LOADRESFAILURE
: msg 
= wxT("CDERR_LOADRESFAILURE"); break; 
  63         case CDERR_LOADSTRFAILURE
: msg 
= wxT("CDERR_LOADSTRFAILURE"); break; 
  64         case CDERR_LOCKRESFAILURE
: msg 
= wxT("CDERR_LOCKRESFAILURE"); break; 
  65         case CDERR_MEMALLOCFAILURE
: msg 
= wxT("CDERR_MEMALLOCFAILURE"); break; 
  66         case CDERR_MEMLOCKFAILURE
: msg 
= wxT("CDERR_MEMLOCKFAILURE"); break; 
  67         case CDERR_NOHINSTANCE
: msg 
= wxT("CDERR_NOHINSTANCE"); break; 
  68         case CDERR_NOHOOK
: msg 
= wxT("CDERR_NOHOOK"); break; 
  69         case CDERR_NOTEMPLATE
: msg 
= wxT("CDERR_NOTEMPLATE"); break; 
  70         case CDERR_STRUCTSIZE
: msg 
= wxT("CDERR_STRUCTSIZE"); break; 
  71         case  PDERR_RETDEFFAILURE
: msg 
= wxT("PDERR_RETDEFFAILURE"); break; 
  72         case  PDERR_PRINTERNOTFOUND
: msg 
= wxT("PDERR_PRINTERNOTFOUND"); break; 
  73         case  PDERR_PARSEFAILURE
: msg 
= wxT("PDERR_PARSEFAILURE"); break; 
  74         case  PDERR_NODEVICES
: msg 
= wxT("PDERR_NODEVICES"); break; 
  75         case  PDERR_NODEFAULTPRN
: msg 
= wxT("PDERR_NODEFAULTPRN"); break; 
  76         case  PDERR_LOADDRVFAILURE
: msg 
= wxT("PDERR_LOADDRVFAILURE"); break; 
  77         case  PDERR_INITFAILURE
: msg 
= wxT("PDERR_INITFAILURE"); break; 
  78         case  PDERR_GETDEVMODEFAIL
: msg 
= wxT("PDERR_GETDEVMODEFAIL"); break; 
  79         case  PDERR_DNDMMISMATCH
: msg 
= wxT("PDERR_DNDMMISMATCH"); break; 
  80         case  PDERR_DEFAULTDIFFERENT
: msg 
= wxT("PDERR_DEFAULTDIFFERENT"); break; 
  81         case  PDERR_CREATEICFAILURE
: msg 
= wxT("PDERR_CREATEICFAILURE"); break; 
  88 static HGLOBAL 
wxCreateDevNames(const wxString
& driverName
, const wxString
& printerName
, const wxString
& portName
) 
  91     // if (!driverName.empty() && !printerName.empty() && !portName.empty()) 
  92     if (driverName
.empty() && printerName
.empty() && portName
.empty()) 
  97         hDev 
= GlobalAlloc(GPTR
, 4*sizeof(WORD
)+ 
  98                            ( driverName
.Length() + 1 + 
  99             printerName
.Length() + 1 + 
 100                              portName
.Length()+1 ) * sizeof(wxChar
) ); 
 101         LPDEVNAMES lpDev 
= (LPDEVNAMES
)GlobalLock(hDev
); 
 102         lpDev
->wDriverOffset 
= sizeof(WORD
) * 4 / sizeof(wxChar
); 
 103         wxStrcpy((wxChar
*)lpDev 
+ lpDev
->wDriverOffset
, driverName
); 
 105         lpDev
->wDeviceOffset 
= (WORD
)( lpDev
->wDriverOffset 
+ 
 106                                        driverName
.Length() + 1 ); 
 107         wxStrcpy((wxChar
*)lpDev 
+ lpDev
->wDeviceOffset
, printerName
); 
 109         lpDev
->wOutputOffset 
= (WORD
)( lpDev
->wDeviceOffset 
+ 
 110                                        printerName
.Length() + 1 ); 
 111         wxStrcpy((wxChar
*)lpDev 
+ lpDev
->wOutputOffset
, portName
); 
 121 IMPLEMENT_CLASS(wxWindowsPrintNativeData
, wxPrintNativeDataBase
) 
 123 wxWindowsPrintNativeData::wxWindowsPrintNativeData() 
 125     m_devMode 
= (void*) NULL
; 
 126     m_devNames 
= (void*) NULL
; 
 127     m_customWindowsPaperId 
= 0; 
 130 wxWindowsPrintNativeData::~wxWindowsPrintNativeData() 
 132     HGLOBAL hDevMode 
= (HGLOBAL
)(DWORD
) m_devMode
; 
 134         GlobalFree(hDevMode
); 
 135     HGLOBAL hDevNames 
= (HGLOBAL
)(DWORD
) m_devNames
; 
 137         GlobalFree(hDevNames
); 
 140 bool wxWindowsPrintNativeData::Ok() const 
 142     return (m_devMode 
!= NULL
) ; 
 145 bool wxWindowsPrintNativeData::TransferTo( wxPrintData 
&data 
) 
 147     HGLOBAL hDevMode 
= (HGLOBAL
)(DWORD
) m_devMode
; 
 148     HGLOBAL hDevNames 
= (HGLOBAL
)(DWORD
) m_devNames
; 
 156         LPDEVMODE devMode 
= (LPDEVMODE
)GlobalLock(hDevMode
); 
 159         if (devMode
->dmFields 
& DM_ORIENTATION
) 
 160             data
.SetOrientation( devMode
->dmOrientation 
); 
 163         if (devMode
->dmFields 
& DM_COLLATE
) 
 165             if (devMode
->dmCollate 
== DMCOLLATE_TRUE
) 
 166                 data
.SetCollate( true ); 
 168                 data
.SetCollate( false ); 
 171         //// Number of copies 
 172         if (devMode
->dmFields 
& DM_COPIES
) 
 173             data
.SetNoCopies( devMode
->dmCopies 
); 
 176         if (devMode
->dmFields 
& DM_DEFAULTSOURCE
) { 
 177             switch (devMode
->dmDefaultSource
) { 
 178                 case DMBIN_ONLYONE        
: data
.SetBin(wxPRINTBIN_ONLYONE       
); break; 
 179                 case DMBIN_LOWER          
: data
.SetBin(wxPRINTBIN_LOWER         
); break; 
 180                 case DMBIN_MIDDLE         
: data
.SetBin(wxPRINTBIN_MIDDLE        
); break; 
 181                 case DMBIN_MANUAL         
: data
.SetBin(wxPRINTBIN_MANUAL        
); break; 
 182                 case DMBIN_ENVELOPE       
: data
.SetBin(wxPRINTBIN_ENVELOPE      
); break; 
 183                 case DMBIN_ENVMANUAL      
: data
.SetBin(wxPRINTBIN_ENVMANUAL     
); break; 
 184                 case DMBIN_AUTO           
: data
.SetBin(wxPRINTBIN_AUTO          
); break; 
 185                 case DMBIN_TRACTOR        
: data
.SetBin(wxPRINTBIN_TRACTOR       
); break; 
 186                 case DMBIN_SMALLFMT       
: data
.SetBin(wxPRINTBIN_SMALLFMT      
); break; 
 187                 case DMBIN_LARGEFMT       
: data
.SetBin(wxPRINTBIN_LARGEFMT      
); break; 
 188                 case DMBIN_LARGECAPACITY  
: data
.SetBin(wxPRINTBIN_LARGECAPACITY 
); break; 
 189                 case DMBIN_CASSETTE       
: data
.SetBin(wxPRINTBIN_CASSETTE      
); break; 
 190                 case DMBIN_FORMSOURCE     
: data
.SetBin(wxPRINTBIN_FORMSOURCE    
); break; 
 192                     if (devMode
->dmDefaultSource
>=DMBIN_USER
) { 
 193                         data
.SetBin((wxPrintBin
)((devMode
->dmDefaultSource
)-DMBIN_USER
+(int)wxPRINTBIN_USER
)); 
 195                         data
.SetBin(wxPRINTBIN_DEFAULT
); 
 200             data
.SetBin(wxPRINTBIN_DEFAULT
); 
 204         if (devMode
->dmDeviceName
[0] != 0) 
 205             // This syntax fixes a crash when using VS 7.1 
 206             data
.SetPrinterName( wxString(devMode
->dmDeviceName
, CCHDEVICENAME
) ); 
 209         if (devMode
->dmFields 
& DM_COLOR
) 
 211             if (devMode
->dmColor 
== DMCOLOR_COLOR
) 
 212                 data
.SetColour( true ); 
 214                 data
.SetColour( false ); 
 217             data
.SetColour( true ); 
 221         // We don't know size of user defined paper and some buggy drivers 
 222         // set both DM_PAPERSIZE and DM_PAPERWIDTH & DM_PAPERLENGTH. Since 
 223         // dmPaperSize >= DMPAPER_USER wouldn't be in wxWin's database, this 
 224         // code wouldn't set m_paperSize correctly. 
 226         bool foundPaperSize 
= false; 
 227         if ((devMode
->dmFields 
& DM_PAPERSIZE
) && (devMode
->dmPaperSize 
< DMPAPER_USER
)) 
 229             if (wxThePrintPaperDatabase
) 
 231                 wxPrintPaperType
* paper 
= wxThePrintPaperDatabase
->FindPaperTypeByPlatformId(devMode
->dmPaperSize
); 
 234                     data
.SetPaperId( paper
->GetId() ); 
 235                     data
.SetPaperSize( wxSize(paper
->GetWidth() / 10,paper
->GetHeight() / 10) ); 
 236                     m_customWindowsPaperId 
= 0; 
 237                     foundPaperSize 
= true; 
 242                 // Shouldn't really get here 
 243                 wxFAIL_MSG(wxT("Paper database wasn't initialized in wxPrintData::ConvertFromNative.")); 
 244                 data
.SetPaperId( wxPAPER_NONE 
); 
 245                 data
.SetPaperSize( wxSize(0,0) ); 
 246                 m_customWindowsPaperId 
= 0; 
 248                 GlobalUnlock(hDevMode
); 
 253         if (!foundPaperSize
) { 
 254             if ((devMode
->dmFields 
& DM_PAPERWIDTH
) && (devMode
->dmFields 
& DM_PAPERLENGTH
)) 
 256                 // DEVMODE is in tenths of a millimeter 
 257                 data
.SetPaperSize( wxSize(devMode
->dmPaperWidth 
/ 10, devMode
->dmPaperLength 
/ 10) ); 
 258                 data
.SetPaperId( wxPAPER_NONE 
); 
 259                 m_customWindowsPaperId 
= devMode
->dmPaperSize
; 
 263                 // Often will reach this for non-standard paper sizes (sizes which 
 264                 // wouldn't be in wxWidget's paper database). Setting 
 265                 // m_customWindowsPaperId to devMode->dmPaperSize should be enough 
 266                 // to get this paper size working. 
 267                 data
.SetPaperSize( wxSize(0,0) ); 
 268                 data
.SetPaperId( wxPAPER_NONE 
); 
 269                 m_customWindowsPaperId 
= devMode
->dmPaperSize
; 
 275         if (devMode
->dmFields 
& DM_DUPLEX
) 
 277             switch (devMode
->dmDuplex
) 
 279                 case DMDUP_HORIZONTAL
:   data
.SetDuplex( wxDUPLEX_HORIZONTAL 
); break; 
 280                 case DMDUP_VERTICAL
:     data
.SetDuplex( wxDUPLEX_VERTICAL 
); break; 
 282                 case DMDUP_SIMPLEX
:      data
.SetDuplex( wxDUPLEX_SIMPLEX 
); break; 
 286             data
.SetDuplex( wxDUPLEX_SIMPLEX 
); 
 290         if (devMode
->dmFields 
& DM_PRINTQUALITY
) 
 292             switch (devMode
->dmPrintQuality
) 
 294                 case DMRES_MEDIUM
:  data
.SetQuality( wxPRINT_QUALITY_MEDIUM 
); break; 
 295                 case DMRES_LOW
:     data
.SetQuality( wxPRINT_QUALITY_LOW 
); break; 
 296                 case DMRES_DRAFT
:   data
.SetQuality( wxPRINT_QUALITY_DRAFT 
); break; 
 297                 case DMRES_HIGH
:    data
.SetQuality( wxPRINT_QUALITY_HIGH 
); break; 
 300                     // TODO: if the printer fills in the resolution in DPI, how 
 301                     // will the application know if it's high, low, draft etc.?? 
 302                     //                    wxFAIL_MSG("Warning: DM_PRINTQUALITY was not one of the standard values."); 
 303                     data
.SetQuality( devMode
->dmPrintQuality 
); 
 310             data
.SetQuality( wxPRINT_QUALITY_HIGH 
); 
 312         if (devMode
->dmDriverExtra 
> 0) 
 313             data
.SetPrivData( (char *)devMode
+devMode
->dmSize
, devMode
->dmDriverExtra 
); 
 315             data
.SetPrivData( NULL
, 0 ); 
 317         GlobalUnlock(hDevMode
); 
 322         LPDEVNAMES lpDevNames 
= (LPDEVNAMES
)GlobalLock(hDevNames
); 
 325             // TODO: Unicode-ification 
 328             // port is obsolete in WIN32 
 329             // m_printData.SetPortName((LPSTR)lpDevNames + lpDevNames->wDriverOffset); 
 331             // Get the printer name 
 332             wxString printerName 
= (LPTSTR
)lpDevNames 
+ lpDevNames
->wDeviceOffset
; 
 334             // Not sure if we should check for this mismatch 
 335 //            wxASSERT_MSG( (m_printerName.empty() || (devName == m_printerName)), "Printer name obtained from DEVMODE and DEVNAMES were different!"); 
 337             if (!printerName
.empty()) 
 338                 data
.SetPrinterName( printerName 
); 
 340             GlobalUnlock(hDevNames
); 
 347 bool wxWindowsPrintNativeData::TransferFrom( const wxPrintData 
&data 
) 
 349     HGLOBAL hDevMode 
= (HGLOBAL
)(DWORD
) m_devMode
; 
 350     HGLOBAL hDevNames 
= (HGLOBAL
)(DWORD
) m_devNames
; 
 353         // Use PRINTDLG as a way of creating a DEVMODE object 
 356         // GNU-WIN32 has the wrong size PRINTDLG - can't work out why. 
 361         memset(&pd
, 0, sizeof(PRINTDLG
)); 
 363         pd
.cbStruct    
= sizeof(PRINTDLG
); 
 365         pd
.lStructSize    
= sizeof(PRINTDLG
); 
 369         pd
.hwndOwner      
= (HWND
)NULL
; 
 370         pd
.hDevMode       
= NULL
; // Will be created by PrintDlg 
 371         pd
.hDevNames      
= NULL
; // Ditto 
 372         //pd.hInstance      = (HINSTANCE) wxGetInstance(); 
 374         pd
.Flags          
= PD_RETURNDEFAULT
; 
 377         // Fill out the DEVMODE structure 
 378         // so we can use it as input in the 'real' PrintDlg 
 382                 GlobalFree(pd
.hDevMode
); 
 384                 GlobalFree(pd
.hDevNames
); 
 388 #if defined(__WXDEBUG__) && defined(__WIN32__) 
 389             wxString 
str(wxT("Printing error: ")); 
 390             str 
+= wxGetPrintDlgError(); 
 396             hDevMode 
= pd
.hDevMode
; 
 397             m_devMode 
= (void*)(long) hDevMode
; 
 400             // We'll create a new DEVNAMEs structure below. 
 402                 GlobalFree(pd
.hDevNames
); 
 405             // hDevNames = pd->hDevNames; 
 406             // m_devNames = (void*)(long) hDevNames; 
 407             // pd->hDevnames = NULL; 
 414         LPDEVMODE devMode 
= (LPDEVMODE
) GlobalLock(hDevMode
); 
 417         devMode
->dmOrientation 
= (short)data
.GetOrientation(); 
 420         devMode
->dmCollate 
= (data
.GetCollate() ? DMCOLLATE_TRUE 
: DMCOLLATE_FALSE
); 
 421         devMode
->dmFields 
|= DM_COLLATE
; 
 423         //// Number of copies 
 424         devMode
->dmCopies 
= (short)data
.GetNoCopies(); 
 425         devMode
->dmFields 
|= DM_COPIES
; 
 428         wxString name 
= data
.GetPrinterName(); 
 431             //int len = wxMin(31, m_printerName.Len()); 
 432             wxStrncpy((wxChar
*)devMode
->dmDeviceName
,name
.c_str(),31); 
 433             devMode
->dmDeviceName
[31] = wxT('\0'); 
 437         if (data
.GetColour()) 
 438             devMode
->dmColor 
= DMCOLOR_COLOR
; 
 440             devMode
->dmColor 
= DMCOLOR_MONOCHROME
; 
 441         devMode
->dmFields 
|= DM_COLOR
; 
 444         if (data
.GetPaperId() == wxPAPER_NONE
) 
 446             // DEVMODE is in tenths of a milimeter 
 447             devMode
->dmPaperWidth 
= (short)(data
.GetPaperSize().x 
* 10); 
 448             devMode
->dmPaperLength 
= (short)(data
.GetPaperSize().y 
* 10); 
 449             if(m_customWindowsPaperId 
!= 0) 
 450                 devMode
->dmPaperSize 
= m_customWindowsPaperId
; 
 452                 devMode
->dmPaperSize 
= DMPAPER_USER
; 
 453             devMode
->dmFields 
|= DM_PAPERWIDTH
; 
 454             devMode
->dmFields 
|= DM_PAPERLENGTH
; 
 458             if (wxThePrintPaperDatabase
) 
 460                 wxPrintPaperType
* paper 
= wxThePrintPaperDatabase
->FindPaperType( data
.GetPaperId() ); 
 463                     devMode
->dmPaperSize 
= (short)paper
->GetPlatformId(); 
 464                     devMode
->dmFields 
|= DM_PAPERSIZE
; 
 468                     // Fall back on specifying the paper size explicitly 
 469                     devMode
->dmPaperWidth 
= (short)(data
.GetPaperSize().x 
* 10); 
 470                     devMode
->dmPaperLength 
= (short)(data
.GetPaperSize().y 
* 10); 
 471                     devMode
->dmPaperSize 
= DMPAPER_USER
; 
 472                     devMode
->dmFields 
|= DM_PAPERWIDTH
; 
 473                     devMode
->dmFields 
|= DM_PAPERLENGTH
; 
 480         switch (data
.GetDuplex()) 
 482             case wxDUPLEX_HORIZONTAL
: 
 483                 duplex 
= DMDUP_HORIZONTAL
; 
 485             case wxDUPLEX_VERTICAL
: 
 486                 duplex 
= DMDUP_VERTICAL
; 
 489             // in fact case wxDUPLEX_SIMPLEX: 
 490                 duplex 
= DMDUP_SIMPLEX
; 
 493         devMode
->dmDuplex 
= duplex
; 
 494         devMode
->dmFields 
|= DM_DUPLEX
; 
 499         switch (data
.GetQuality()) 
 501             case wxPRINT_QUALITY_MEDIUM
: 
 502                 quality 
= DMRES_MEDIUM
; 
 504             case wxPRINT_QUALITY_LOW
: 
 507             case wxPRINT_QUALITY_DRAFT
: 
 508                 quality 
= DMRES_DRAFT
; 
 510             case wxPRINT_QUALITY_HIGH
: 
 511                 quality 
= DMRES_HIGH
; 
 514                 quality 
= (short)data
.GetQuality(); 
 517         devMode
->dmPrintQuality 
= quality
; 
 518         devMode
->dmFields 
|= DM_PRINTQUALITY
; 
 520         if (data
.GetPrivDataLen() > 0) 
 522             memcpy( (char *)devMode
+devMode
->dmSize
, data
.GetPrivData(), data
.GetPrivDataLen() ); 
 523             devMode
->dmDriverExtra 
= (WXWORD
)data
.GetPrivDataLen(); 
 526         if (data
.GetBin() != wxPRINTBIN_DEFAULT
) 
 528             switch (data
.GetBin()) 
 530                 case wxPRINTBIN_ONLYONE
:        devMode
->dmDefaultSource 
= DMBIN_ONLYONE
;       break; 
 531                 case wxPRINTBIN_LOWER
:          devMode
->dmDefaultSource 
= DMBIN_LOWER
;         break; 
 532                 case wxPRINTBIN_MIDDLE
:         devMode
->dmDefaultSource 
= DMBIN_MIDDLE
;        break; 
 533                 case wxPRINTBIN_MANUAL
:         devMode
->dmDefaultSource 
= DMBIN_MANUAL
;        break; 
 534                 case wxPRINTBIN_ENVELOPE
:       devMode
->dmDefaultSource 
= DMBIN_ENVELOPE
;      break; 
 535                 case wxPRINTBIN_ENVMANUAL
:      devMode
->dmDefaultSource 
= DMBIN_ENVMANUAL
;     break; 
 536                 case wxPRINTBIN_AUTO
:           devMode
->dmDefaultSource 
= DMBIN_AUTO
;          break; 
 537                 case wxPRINTBIN_TRACTOR
:        devMode
->dmDefaultSource 
= DMBIN_TRACTOR
;       break; 
 538                 case wxPRINTBIN_SMALLFMT
:       devMode
->dmDefaultSource 
= DMBIN_SMALLFMT
;      break; 
 539                 case wxPRINTBIN_LARGEFMT
:       devMode
->dmDefaultSource 
= DMBIN_LARGEFMT
;      break; 
 540                 case wxPRINTBIN_LARGECAPACITY
:  devMode
->dmDefaultSource 
= DMBIN_LARGECAPACITY
; break; 
 541                 case wxPRINTBIN_CASSETTE
:       devMode
->dmDefaultSource 
= DMBIN_CASSETTE
;      break; 
 542                 case wxPRINTBIN_FORMSOURCE
:     devMode
->dmDefaultSource 
= DMBIN_FORMSOURCE
;    break; 
 545                     devMode
->dmDefaultSource 
= (short)(DMBIN_USER 
+ data
.GetBin() - wxPRINTBIN_USER
); // 256 + data.GetBin() - 14 = 242 + data.GetBin() 
 549             devMode
->dmFields 
|= DM_DEFAULTSOURCE
; 
 552         GlobalUnlock(hDevMode
); 
 557         GlobalFree(hDevNames
); 
 560     // TODO: I hope it's OK to pass some empty strings to DEVNAMES. 
 561     m_devNames 
= (void*) (long) wxCreateDevNames(wxEmptyString
, data
.GetPrinterName(), wxEmptyString
); 
 566 // --------------------------------------------------------------------------- 
 568 // --------------------------------------------------------------------------- 
 570 IMPLEMENT_CLASS(wxWindowsPrintDialog
, wxPrintDialogBase
) 
 572 wxWindowsPrintDialog::wxWindowsPrintDialog(wxWindow 
*p
, wxPrintDialogData
* data
) 
 577 wxWindowsPrintDialog::wxWindowsPrintDialog(wxWindow 
*p
, wxPrintData
* data
) 
 579     wxPrintDialogData data2
; 
 586 bool wxWindowsPrintDialog::Create(wxWindow 
*p
, wxPrintDialogData
* data
) 
 596         m_printDialogData 
= *data
; 
 601 wxWindowsPrintDialog::~wxWindowsPrintDialog() 
 603     PRINTDLG 
*pd 
= (PRINTDLG 
*) m_printDlg
; 
 604     if (pd 
&& pd
->hDevMode
) 
 605         GlobalFree(pd
->hDevMode
); 
 609     if (m_destroyDC 
&& m_printerDC
) 
 613 int wxWindowsPrintDialog::ShowModal() 
 615     ConvertToNative( m_printDialogData 
); 
 617     PRINTDLG 
*pd 
= (PRINTDLG
*) m_printDlg
; 
 620         pd
->hwndOwner 
= (HWND
) m_dialogParent
->GetHWND(); 
 621     else if (wxTheApp
->GetTopWindow()) 
 622         pd
->hwndOwner 
= (HWND
) wxTheApp
->GetTopWindow()->GetHWND(); 
 626     bool ret 
= (PrintDlg( pd 
) != 0); 
 630     if ( ret 
&& (pd
->hDC
) ) 
 632         wxPrinterDC 
*pdc 
= new wxPrinterDC( (WXHDC
) pd
->hDC 
); 
 634         ConvertFromNative( m_printDialogData 
); 
 643 wxDC 
*wxWindowsPrintDialog::GetPrintDC() 
 654 bool wxWindowsPrintDialog::ConvertToNative( wxPrintDialogData 
&data 
) 
 656     wxWindowsPrintNativeData 
*native_data 
= 
 657         (wxWindowsPrintNativeData 
*) data
.GetPrintData().GetNativeData(); 
 658     data
.GetPrintData().ConvertToNative(); 
 660     PRINTDLG 
*pd 
= (PRINTDLG
*) m_printDlg
; 
 662     // Shouldn't have been defined anywhere 
 667     memset( pd
, 0, sizeof(PRINTDLG
) ); 
 668     m_printDlg 
= (void*) pd
; 
 670     // GNU-WIN32 has the wrong size PRINTDLG - can't work out why. 
 672     pd
->lStructSize    
= 66; 
 674     pd
->lStructSize    
= sizeof(PRINTDLG
); 
 676     pd
->hwndOwner      
= (HWND
)NULL
; 
 677     pd
->hDevMode       
= NULL
; // Will be created by PrintDlg 
 678     pd
->hDevNames      
= NULL
; // Ditto 
 680     pd
->Flags          
= PD_RETURNDEFAULT
; 
 683     // Pass the devmode data to the PRINTDLG structure, since it'll 
 684     // be needed when PrintDlg is called. 
 686         GlobalFree(pd
->hDevMode
); 
 688     // Pass the devnames data to the PRINTDLG structure, since it'll 
 689     // be needed when PrintDlg is called. 
 691         GlobalFree(pd
->hDevNames
); 
 693     pd
->hDevMode 
= (HGLOBAL
)(DWORD
) native_data
->GetDevMode(); 
 694     native_data
->SetDevMode( (void*) NULL
); 
 696     // Shouldn't assert; we should be able to test Ok-ness at a higher level 
 697     //wxASSERT_MSG( (pd->hDevMode), wxT("hDevMode must be non-NULL in ConvertToNative!")); 
 699     pd
->hDevNames 
= (HGLOBAL
)(DWORD
) native_data
->GetDevNames(); 
 700     native_data
->SetDevNames( (void*) NULL
); 
 703     pd
->hDC 
= (HDC
) NULL
; 
 704     pd
->nFromPage 
= (WORD
)data
.GetFromPage(); 
 705     pd
->nToPage 
= (WORD
)data
.GetToPage(); 
 706     pd
->nMinPage 
= (WORD
)data
.GetMinPage(); 
 707     pd
->nMaxPage 
= (WORD
)data
.GetMaxPage(); 
 708     pd
->nCopies 
= (WORD
)data
.GetNoCopies(); 
 710     pd
->Flags 
= PD_RETURNDC
; 
 713     pd
->lStructSize 
= 66; 
 715     pd
->lStructSize 
= sizeof( PRINTDLG 
); 
 718     pd
->hwndOwner
=(HWND
)NULL
; 
 719 //    pd->hDevNames=(HANDLE)NULL; 
 720     pd
->hInstance
=(HINSTANCE
)NULL
; 
 721     pd
->lCustData 
= (LPARAM
) NULL
; 
 722     pd
->lpfnPrintHook 
= NULL
; 
 723     pd
->lpfnSetupHook 
= NULL
; 
 724     pd
->lpPrintTemplateName 
= NULL
; 
 725     pd
->lpSetupTemplateName 
= NULL
; 
 726     pd
->hPrintTemplate 
= (HGLOBAL
) NULL
; 
 727     pd
->hSetupTemplate 
= (HGLOBAL
) NULL
; 
 729     if ( data
.GetAllPages() ) 
 730         pd
->Flags 
|= PD_ALLPAGES
; 
 731     if ( data
.GetSelection() ) 
 732         pd
->Flags 
|= PD_SELECTION
; 
 733     if ( data
.GetCollate() ) 
 734         pd
->Flags 
|= PD_COLLATE
; 
 735     if ( data
.GetPrintToFile() ) 
 736         pd
->Flags 
|= PD_PRINTTOFILE
; 
 737     if ( !data
.GetEnablePrintToFile() ) 
 738         pd
->Flags 
|= PD_DISABLEPRINTTOFILE
; 
 739     if ( !data
.GetEnableSelection() ) 
 740         pd
->Flags 
|= PD_NOSELECTION
; 
 741     if ( !data
.GetEnablePageNumbers() ) 
 742         pd
->Flags 
|= PD_NOPAGENUMS
; 
 743     else if ( (!data
.GetAllPages()) && (!data
.GetSelection()) && (data
.GetFromPage() != 0) && (data
.GetToPage() != 0)) 
 744         pd
->Flags 
|= PD_PAGENUMS
; 
 745     if ( data
.GetEnableHelp() ) 
 746         pd
->Flags 
|= PD_SHOWHELP
; 
 747 #if WXWIN_COMPATIBILITY_2_4 
 748     if ( data
.GetSetupDialog() ) 
 749         pd
->Flags 
|= PD_PRINTSETUP
; 
 755 bool wxWindowsPrintDialog::ConvertFromNative( wxPrintDialogData 
&data 
) 
 757     PRINTDLG 
*pd 
= (PRINTDLG
*) m_printDlg
; 
 761     wxWindowsPrintNativeData 
*native_data 
= 
 762         (wxWindowsPrintNativeData 
*) data
.GetPrintData().GetNativeData(); 
 764     // Pass the devmode data back to the wxPrintData structure where it really belongs. 
 767         if (native_data
->GetDevMode()) 
 769             // Make sure we don't leak memory 
 770             GlobalFree( (HGLOBAL
)(DWORD
) native_data
->GetDevMode() ); 
 772         native_data
->SetDevMode( (void*)(long) pd
->hDevMode 
); 
 776     // Pass the devnames data back to the wxPrintData structure where it really belongs. 
 779         if (native_data
->GetDevNames()) 
 781             // Make sure we don't leak memory 
 782             GlobalFree((HGLOBAL
)(DWORD
) native_data
->GetDevNames()); 
 784         native_data
->SetDevNames((void*)(long) pd
->hDevNames
); 
 785         pd
->hDevNames 
= NULL
; 
 788     // Now convert the DEVMODE object, passed down from the PRINTDLG object, 
 789     // into wxWidgets form. 
 790     native_data
->TransferTo( data
.GetPrintData() ); 
 792     data
.SetFromPage( pd
->nFromPage 
); 
 793     data
.SetToPage( pd
->nToPage 
); 
 794     data
.SetMinPage( pd
->nMinPage 
); 
 795     data
.SetMaxPage( pd
->nMaxPage 
); 
 796     data
.SetNoCopies( pd
->nCopies 
); 
 798     data
.SetAllPages( (((pd
->Flags 
& PD_PAGENUMS
) != PD_PAGENUMS
) && ((pd
->Flags 
& PD_SELECTION
) != PD_SELECTION
)) ); 
 799     data
.SetSelection( ((pd
->Flags 
& PD_SELECTION
) == PD_SELECTION
) ); 
 800     data
.SetCollate( ((pd
->Flags 
& PD_COLLATE
) == PD_COLLATE
) ); 
 801     data
.SetPrintToFile( ((pd
->Flags 
& PD_PRINTTOFILE
) == PD_PRINTTOFILE
) ); 
 802     data
.EnablePrintToFile( ((pd
->Flags 
& PD_DISABLEPRINTTOFILE
) != PD_DISABLEPRINTTOFILE
) ); 
 803     data
.EnableSelection( ((pd
->Flags 
& PD_NOSELECTION
) != PD_NOSELECTION
) ); 
 804     data
.EnablePageNumbers( ((pd
->Flags 
& PD_NOPAGENUMS
) != PD_NOPAGENUMS
) ); 
 805     data
.EnableHelp( ((pd
->Flags 
& PD_SHOWHELP
) == PD_SHOWHELP
) ); 
 806 #if WXWIN_COMPATIBILITY_2_4 
 807     data
.SetSetupDialog( ((pd
->Flags 
& PD_PRINTSETUP
) == PD_PRINTSETUP
) ); 
 812 // --------------------------------------------------------------------------- 
 813 // wxWidnowsPageSetupDialog 
 814 // --------------------------------------------------------------------------- 
 816 IMPLEMENT_CLASS(wxWindowsPageSetupDialog
, wxPageSetupDialogBase
) 
 818 wxWindowsPageSetupDialog::wxWindowsPageSetupDialog() 
 820     m_dialogParent 
= NULL
; 
 824 wxWindowsPageSetupDialog::wxWindowsPageSetupDialog(wxWindow 
*p
, wxPageSetupDialogData 
*data
) 
 829 bool wxWindowsPageSetupDialog::Create(wxWindow 
*p
, wxPageSetupDialogData 
*data
) 
 835         m_pageSetupData 
= (*data
); 
 840 wxWindowsPageSetupDialog::~wxWindowsPageSetupDialog() 
 842     PAGESETUPDLG 
*pd 
= (PAGESETUPDLG 
*)m_pageDlg
; 
 843     if ( pd 
&& pd
->hDevMode 
) 
 844         GlobalFree(pd
->hDevMode
); 
 845     if ( pd 
&& pd
->hDevNames 
) 
 846         GlobalFree(pd
->hDevNames
); 
 851 int wxWindowsPageSetupDialog::ShowModal() 
 853     ConvertToNative( m_pageSetupData 
); 
 855     PAGESETUPDLG 
*pd 
= (PAGESETUPDLG 
*) m_pageDlg
; 
 857         pd
->hwndOwner 
= (HWND
) m_dialogParent
->GetHWND(); 
 858     else if (wxTheApp
->GetTopWindow()) 
 859         pd
->hwndOwner 
= (HWND
) wxTheApp
->GetTopWindow()->GetHWND(); 
 862     BOOL retVal 
= PageSetupDlg( pd 
) ; 
 866         ConvertFromNative( m_pageSetupData 
); 
 873 bool wxWindowsPageSetupDialog::ConvertToNative( wxPageSetupDialogData 
&data 
) 
 875     wxWindowsPrintNativeData 
*native_data 
= 
 876         (wxWindowsPrintNativeData 
*) data
.GetPrintData().GetNativeData(); 
 877     data
.GetPrintData().ConvertToNative(); 
 879     PAGESETUPDLG 
*pd 
= (PAGESETUPDLG
*) m_pageDlg
; 
 881     // Shouldn't have been defined anywhere 
 885     pd 
= new PAGESETUPDLG
; 
 887     pd
->hDevNames 
= NULL
; 
 888     m_pageDlg 
= (void *)pd
; 
 890     // Pass the devmode data (created in m_printData.ConvertToNative) 
 891     // to the PRINTDLG structure, since it'll 
 892     // be needed when PrintDlg is called. 
 896         GlobalFree(pd
->hDevMode
); 
 899     pd
->hDevMode 
= (HGLOBAL
) native_data
->GetDevMode(); 
 900     native_data
->SetDevMode( (void*) NULL 
); 
 902     // Shouldn't assert; we should be able to test Ok-ness at a higher level 
 903     //wxASSERT_MSG( (pd->hDevMode), wxT("hDevMode must be non-NULL in ConvertToNative!")); 
 905     // Pass the devnames data (created in m_printData.ConvertToNative) 
 906     // to the PRINTDLG structure, since it'll 
 907     // be needed when PrintDlg is called. 
 911         GlobalFree(pd
->hDevNames
); 
 912         pd
->hDevNames 
= NULL
; 
 914     pd
->hDevNames 
= (HGLOBAL
) native_data
->GetDevNames(); 
 915     native_data
->SetDevNames((void*) NULL
); 
 917 //        pd->hDevMode = GlobalAlloc(GMEM_MOVEABLE, sizeof(DEVMODE)); 
 919     pd
->Flags 
= PSD_MARGINS
|PSD_MINMARGINS
; 
 921     if ( data
.GetDefaultMinMargins() ) 
 922         pd
->Flags 
|= PSD_DEFAULTMINMARGINS
; 
 923     if ( !data
.GetEnableMargins() ) 
 924         pd
->Flags 
|= PSD_DISABLEMARGINS
; 
 925     if ( !data
.GetEnableOrientation() ) 
 926         pd
->Flags 
|= PSD_DISABLEORIENTATION
; 
 927     if ( !data
.GetEnablePaper() ) 
 928         pd
->Flags 
|= PSD_DISABLEPAPER
; 
 929     if ( !data
.GetEnablePrinter() ) 
 930         pd
->Flags 
|= PSD_DISABLEPRINTER
; 
 931     if ( data
.GetDefaultInfo() ) 
 932         pd
->Flags 
|= PSD_RETURNDEFAULT
; 
 933     if ( data
.GetEnableHelp() ) 
 934         pd
->Flags 
|= PSD_SHOWHELP
; 
 936     // We want the units to be in hundredths of a millimetre 
 937     pd
->Flags 
|= PSD_INHUNDREDTHSOFMILLIMETERS
; 
 939     pd
->lStructSize 
= sizeof( PAGESETUPDLG 
); 
 940     pd
->hwndOwner
=(HWND
)NULL
; 
 941 //    pd->hDevNames=(HWND)NULL; 
 942     pd
->hInstance
=(HINSTANCE
)NULL
; 
 943     //   PAGESETUPDLG is in hundreds of a mm 
 944     pd
->ptPaperSize
.x 
= data
.GetPaperSize().x 
* 100; 
 945     pd
->ptPaperSize
.y 
= data
.GetPaperSize().y 
* 100; 
 947     pd
->rtMinMargin
.left 
= data
.GetMinMarginTopLeft().x 
* 100; 
 948     pd
->rtMinMargin
.top 
= data
.GetMinMarginTopLeft().y 
* 100; 
 949     pd
->rtMinMargin
.right 
= data
.GetMinMarginBottomRight().x 
* 100; 
 950     pd
->rtMinMargin
.bottom 
= data
.GetMinMarginBottomRight().y 
* 100; 
 952     pd
->rtMargin
.left 
= data
.GetMarginTopLeft().x 
* 100; 
 953     pd
->rtMargin
.top 
= data
.GetMarginTopLeft().y 
* 100; 
 954     pd
->rtMargin
.right 
= data
.GetMarginBottomRight().x 
* 100; 
 955     pd
->rtMargin
.bottom 
= data
.GetMarginBottomRight().y 
* 100; 
 958     pd
->lpfnPageSetupHook 
= NULL
; 
 959     pd
->lpfnPagePaintHook 
= NULL
; 
 960     pd
->hPageSetupTemplate 
= NULL
; 
 961     pd
->lpPageSetupTemplateName 
= NULL
; 
 966         DEVMODE *devMode = (DEVMODE*) GlobalLock(pd->hDevMode); 
 967         memset(devMode, 0, sizeof(DEVMODE)); 
 968         devMode->dmSize = sizeof(DEVMODE); 
 969         devMode->dmOrientation = m_orientation; 
 970         devMode->dmFields = DM_ORIENTATION; 
 971         GlobalUnlock(pd->hDevMode); 
 977 bool wxWindowsPageSetupDialog::ConvertFromNative( wxPageSetupDialogData 
&data 
) 
 979     PAGESETUPDLG 
*pd 
= (PAGESETUPDLG 
*) m_pageDlg
; 
 983     wxWindowsPrintNativeData 
*native_data 
= 
 984         (wxWindowsPrintNativeData 
*) data
.GetPrintData().GetNativeData(); 
 986     // Pass the devmode data back to the wxPrintData structure where it really belongs. 
 989         if (native_data
->GetDevMode()) 
 991             // Make sure we don't leak memory 
 992             GlobalFree((HGLOBAL
) native_data
->GetDevMode()); 
 994         native_data
->SetDevMode( (void*) pd
->hDevMode 
); 
 998     // Isn't this superfluous? It's called again below. 
 999     // data.GetPrintData().ConvertFromNative(); 
1001     // Pass the devnames data back to the wxPrintData structure where it really belongs. 
1004         if (native_data
->GetDevNames()) 
1006             // Make sure we don't leak memory 
1007             GlobalFree((HGLOBAL
) native_data
->GetDevNames()); 
1009         native_data
->SetDevNames((void*) pd
->hDevNames
); 
1010         pd
->hDevNames 
= NULL
; 
1013     data
.GetPrintData().ConvertFromNative(); 
1015     pd
->Flags 
= PSD_MARGINS
|PSD_MINMARGINS
; 
1017     data
.SetDefaultMinMargins( ((pd
->Flags 
& PSD_DEFAULTMINMARGINS
) == PSD_DEFAULTMINMARGINS
) ); 
1018     data
.EnableMargins( ((pd
->Flags 
& PSD_DISABLEMARGINS
) != PSD_DISABLEMARGINS
) ); 
1019     data
.EnableOrientation( ((pd
->Flags 
& PSD_DISABLEORIENTATION
) != PSD_DISABLEORIENTATION
) ); 
1020     data
.EnablePaper( ((pd
->Flags 
& PSD_DISABLEPAPER
) != PSD_DISABLEPAPER
) ); 
1021     data
.EnablePrinter( ((pd
->Flags 
& PSD_DISABLEPRINTER
) != PSD_DISABLEPRINTER
) ); 
1022     data
.SetDefaultInfo( ((pd
->Flags 
& PSD_RETURNDEFAULT
) == PSD_RETURNDEFAULT
) ); 
1023     data
.EnableHelp( ((pd
->Flags 
& PSD_SHOWHELP
) == PSD_SHOWHELP
) ); 
1025     //   PAGESETUPDLG is in hundreds of a mm 
1026     data
.SetPaperSize( wxSize(pd
->ptPaperSize
.x 
/ 100, pd
->ptPaperSize
.y 
/ 100) ); 
1028     data
.SetMinMarginTopLeft( wxPoint(pd
->rtMinMargin
.left 
/ 100, pd
->rtMinMargin
.top 
/ 100) ); 
1029     data
.SetMinMarginBottomRight( wxPoint(pd
->rtMinMargin
.right 
/ 100, pd
->rtMinMargin
.bottom 
/ 100) ); 
1031     data
.SetMarginTopLeft( wxPoint(pd
->rtMargin
.left 
/ 100, pd
->rtMargin
.top 
/ 100) ); 
1032     data
.SetMarginBottomRight( wxPoint(pd
->rtMargin
.right 
/ 100, pd
->rtMargin
.bottom 
/ 100) ); 
1038     // wxUSE_PRINTING_ARCHITECTURE