]>
git.saurik.com Git - wxWidgets.git/blob - src/msw/printwin.cpp
   1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/msw/printwin.cpp 
   3 // Purpose:     wxWindowsPrinter framework 
   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 printer if we're in wxUniv mode and using 
  28 // the PostScript architecture 
  29 #if wxUSE_PRINTING_ARCHITECTURE && (!defined(__WXUNIVERSAL__) || !wxUSE_POSTSCRIPT_ARCHITECTURE_IN_MSW) 
  32     #include "wx/window.h" 
  33     #include "wx/msw/private.h" 
  37     #include "wx/msgdlg.h" 
  40     #include "wx/dcprint.h" 
  43 #include "wx/msw/printwin.h" 
  44 #include "wx/printdlg.h" 
  45 #include "wx/msw/private.h" 
  49 #include "wx/msw/wrapcdlg.h" 
  54 // --------------------------------------------------------------------------- 
  56 // --------------------------------------------------------------------------- 
  58 LONG APIENTRY _EXPORT 
wxAbortProc(HDC hPr
, int Code
); 
  60 // --------------------------------------------------------------------------- 
  62 // --------------------------------------------------------------------------- 
  64     IMPLEMENT_DYNAMIC_CLASS(wxWindowsPrinter
, wxPrinterBase
) 
  65     IMPLEMENT_CLASS(wxWindowsPrintPreview
, wxPrintPreviewBase
) 
  67 // =========================================================================== 
  69 // =========================================================================== 
  71 // --------------------------------------------------------------------------- 
  73 // --------------------------------------------------------------------------- 
  75 wxWindowsPrinter::wxWindowsPrinter(wxPrintDialogData 
*data
) 
  78     m_lpAbortProc 
= (WXFARPROC
) MakeProcInstance((FARPROC
) wxAbortProc
, wxGetInstance()); 
  81 wxWindowsPrinter::~wxWindowsPrinter() 
  83     // avoids warning about statement with no effect (FreeProcInstance 
  84     // doesn't do anything under Win32) 
  85 #if !defined(__WIN32__) && !defined(__NT__) 
  86     FreeProcInstance((FARPROC
) m_lpAbortProc
); 
  90 bool wxWindowsPrinter::Print(wxWindow 
*parent
, wxPrintout 
*printout
, bool prompt
) 
  93     sm_abortWindow 
= NULL
; 
  97         sm_lastError 
= wxPRINTER_ERROR
; 
 101     printout
->SetIsPreview(false); 
 103     if (m_printDialogData
.GetMinPage() < 1) 
 104         m_printDialogData
.SetMinPage(1); 
 105     if (m_printDialogData
.GetMaxPage() < 1) 
 106         m_printDialogData
.SetMaxPage(9999); 
 108     // Create a suitable device context 
 109     wxDC 
*dc 
wxDUMMY_INITIALIZE(NULL
); 
 112         dc 
= PrintDialog(parent
); 
 118         dc 
= new wxPrinterDC(m_printDialogData
.GetPrintData()); 
 121     // May have pressed cancel. 
 122     if (!dc 
|| !dc
->Ok()) 
 128     HDC hdc 
= ::GetDC(NULL
); 
 129     int logPPIScreenX 
= ::GetDeviceCaps(hdc
, LOGPIXELSX
); 
 130     int logPPIScreenY 
= ::GetDeviceCaps(hdc
, LOGPIXELSY
); 
 131     ::ReleaseDC(NULL
, hdc
); 
 133     int logPPIPrinterX 
= ::GetDeviceCaps((HDC
) dc
->GetHDC(), LOGPIXELSX
); 
 134     int logPPIPrinterY 
= ::GetDeviceCaps((HDC
) dc
->GetHDC(), LOGPIXELSY
); 
 135     if (logPPIPrinterX 
== 0 || logPPIPrinterY 
== 0) 
 138         sm_lastError 
= wxPRINTER_ERROR
; 
 142     printout
->SetPPIScreen(logPPIScreenX
, logPPIScreenY
); 
 143     printout
->SetPPIPrinter(logPPIPrinterX
, logPPIPrinterY
); 
 145     // Set printout parameters 
 150     printout
->SetPageSizePixels((int)w
, (int)h
); 
 152     dc
->GetSizeMM(&w
, &h
); 
 153     printout
->SetPageSizeMM((int)w
, (int)h
); 
 155     // Create an abort window 
 156     wxBusyCursor busyCursor
; 
 158     printout
->OnPreparePrinting(); 
 160     // Get some parameters from the printout, if defined 
 161     int fromPage
, toPage
; 
 162     int minPage
, maxPage
; 
 163     printout
->GetPageInfo(&minPage
, &maxPage
, &fromPage
, &toPage
); 
 167         sm_lastError 
= wxPRINTER_ERROR
; 
 171     // Only set min and max, because from and to have been 
 173     m_printDialogData
.SetMinPage(minPage
); 
 174     m_printDialogData
.SetMaxPage(maxPage
); 
 176     wxWindow 
*win 
= CreateAbortWindow(parent
, printout
); 
 179 #if defined(__WATCOMC__) || defined(__BORLANDC__) || defined(__GNUWIN32__) || defined(__SALFORDC__) || !defined(__WIN32__) 
 181     ::SetAbortProc((HDC
) dc
->GetHDC(), (ABORTPROC
) m_lpAbortProc
); 
 183     ::SetAbortProc((HDC
) dc
->GetHDC(), (FARPROC
) m_lpAbortProc
); 
 186     ::SetAbortProc((HDC
) dc
->GetHDC(), (int (_stdcall 
*) 
 187         // cast it to right type only if required 
 188         // FIXME it's really cdecl and we're casting it to stdcall - either there is 
 189         //       something I don't understand or it will crash at first usage 
 200         wxLogDebug(wxT("Could not create an abort dialog.")); 
 201         sm_lastError 
= wxPRINTER_ERROR
; 
 206     sm_abortWindow 
= win
; 
 207     sm_abortWindow
->Show(); 
 210     printout
->OnBeginPrinting(); 
 212     sm_lastError 
= wxPRINTER_NO_ERROR
; 
 214     int minPageNum 
= minPage
, maxPageNum 
= maxPage
; 
 216     if ( !m_printDialogData
.GetAllPages() ) 
 218         minPageNum 
= m_printDialogData
.GetFromPage(); 
 219         maxPageNum 
= m_printDialogData
.GetToPage(); 
 224           copyCount 
<= m_printDialogData
.GetNoCopies(); 
 227         if ( !printout
->OnBeginDocument(minPageNum
, maxPageNum
) ) 
 229             wxLogError(_("Could not start printing.")); 
 230             sm_lastError 
= wxPRINTER_ERROR
; 
 235             sm_lastError 
= wxPRINTER_CANCELLED
; 
 241         for ( pn 
= minPageNum
; 
 242               pn 
<= maxPageNum 
&& printout
->HasPage(pn
); 
 247                 sm_lastError 
= wxPRINTER_CANCELLED
; 
 252             bool cont 
= printout
->OnPrintPage(pn
); 
 257                 sm_lastError 
= wxPRINTER_CANCELLED
; 
 262         printout
->OnEndDocument(); 
 265     printout
->OnEndPrinting(); 
 269         sm_abortWindow
->Show(false); 
 270         delete sm_abortWindow
; 
 271         sm_abortWindow 
= NULL
; 
 276     return sm_lastError 
== wxPRINTER_NO_ERROR
; 
 279 wxDC
* wxWindowsPrinter::PrintDialog(wxWindow 
*parent
) 
 281     wxDC
* dc 
= (wxDC
*) NULL
; 
 283     wxPrintDialog 
dialog(parent
, & m_printDialogData
); 
 284     int ret 
= dialog
.ShowModal(); 
 288         dc 
= dialog
.GetPrintDC(); 
 289         m_printDialogData 
= dialog
.GetPrintDialogData(); 
 291             sm_lastError 
= wxPRINTER_ERROR
; 
 293             sm_lastError 
= wxPRINTER_NO_ERROR
; 
 296         sm_lastError 
= wxPRINTER_CANCELLED
; 
 301 bool wxWindowsPrinter::Setup(wxWindow 
*WXUNUSED(parent
)) 
 304     // We no longer expose that dialog 
 305     wxPrintDialog 
dialog(parent
, & m_printDialogData
); 
 306     dialog
.GetPrintDialogData().SetSetupDialog(true); 
 308     int ret 
= dialog
.ShowModal(); 
 312         m_printDialogData 
= dialog
.GetPrintDialogData(); 
 315     return (ret 
== wxID_OK
); 
 325 wxWindowsPrintPreview::wxWindowsPrintPreview(wxPrintout 
*printout
, 
 326                                              wxPrintout 
*printoutForPrinting
, 
 327                                              wxPrintDialogData 
*data
) 
 328                      : wxPrintPreviewBase(printout
, printoutForPrinting
, data
) 
 333 wxWindowsPrintPreview::wxWindowsPrintPreview(wxPrintout 
*printout
, 
 334                                              wxPrintout 
*printoutForPrinting
, 
 336                      : wxPrintPreviewBase(printout
, printoutForPrinting
, data
) 
 341 wxWindowsPrintPreview::~wxWindowsPrintPreview() 
 345 bool wxWindowsPrintPreview::Print(bool interactive
) 
 347     if (!m_printPrintout
) 
 349     wxWindowsPrinter 
printer(&m_printDialogData
); 
 350     return printer
.Print(m_previewFrame
, m_printPrintout
, interactive
); 
 353 void wxWindowsPrintPreview::DetermineScaling() 
 355     HDC dc 
= ::GetDC(NULL
); 
 356     int screenWidth 
= ::GetDeviceCaps(dc
, HORZSIZE
); 
 357     int screenYRes 
= ::GetDeviceCaps(dc
, VERTRES
); 
 358     int logPPIScreenX 
= ::GetDeviceCaps(dc
, LOGPIXELSX
); 
 359     int logPPIScreenY 
= ::GetDeviceCaps(dc
, LOGPIXELSY
); 
 360     m_previewPrintout
->SetPPIScreen(logPPIScreenX
, logPPIScreenY
); 
 362     ::ReleaseDC(NULL
, dc
); 
 364     // Get a device context for the currently selected printer 
 365     wxPrinterDC 
printerDC(m_printDialogData
.GetPrintData()); 
 367     int printerWidth 
= 150; 
 368     int printerHeight 
wxDUMMY_INITIALIZE(250); 
 369     int printerXRes 
= 1500; 
 370     int printerYRes 
= 2500; 
 372     dc 
= GetHdcOf(printerDC
); 
 375         printerWidth 
= ::GetDeviceCaps(dc
, HORZSIZE
); 
 376         printerHeight 
= ::GetDeviceCaps(dc
, VERTSIZE
); 
 377         printerXRes 
= ::GetDeviceCaps(dc
, HORZRES
); 
 378         printerYRes 
= ::GetDeviceCaps(dc
, VERTRES
); 
 380         int logPPIPrinterX 
= ::GetDeviceCaps(dc
, LOGPIXELSX
); 
 381         int logPPIPrinterY 
= ::GetDeviceCaps(dc
, LOGPIXELSY
); 
 383         m_previewPrintout
->SetPPIPrinter(logPPIPrinterX
, logPPIPrinterY
); 
 384         m_previewPrintout
->SetPageSizeMM(printerWidth
, printerHeight
); 
 386         if (logPPIPrinterX 
== 0 || logPPIPrinterY 
== 0 || printerWidth 
== 0 || printerHeight 
== 0) 
 392     m_pageWidth 
= printerXRes
; 
 393     m_pageHeight 
= printerYRes
; 
 395     // At 100%, the page should look about page-size on the screen. 
 396     m_previewScale 
= (float)((float)screenWidth
/(float)printerWidth
); 
 397     m_previewScale 
= m_previewScale 
* (float)((float)screenYRes
/(float)printerYRes
); 
 400 /**************************************************************************** 
 402   FUNCTION: wxAbortProc() 
 404     PURPOSE:  Processes messages for the Abort Dialog box 
 406 ****************************************************************************/ 
 408 LONG APIENTRY _EXPORT 
wxAbortProc(HDC 
WXUNUSED(hPr
), int WXUNUSED(Code
)) 
 412     if (!wxPrinterBase::sm_abortWindow
)              /* If the abort dialog isn't up yet */ 
 415     /* Process messages intended for the abort dialog box */ 
 417     while (!wxPrinterBase::sm_abortIt 
&& ::PeekMessage(&msg
, 0, 0, 0, TRUE
)) 
 418         if (!IsDialogMessage((HWND
) wxPrinterBase::sm_abortWindow
->GetHWND(), &msg
)) { 
 419             TranslateMessage(&msg
); 
 420             DispatchMessage(&msg
); 
 423     /* bAbort is TRUE (return is FALSE) if the user has aborted */ 
 425     return !wxPrinterBase::sm_abortIt
; 
 429     // wxUSE_PRINTING_ARCHITECTURE