]>
git.saurik.com Git - wxWidgets.git/blob - src/msw/printwin.cpp
   1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     wxWindowsPrinter framework 
   4 // Author:      Julian Smart 
   8 // Copyright:   (c) Julian Smart 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // =========================================================================== 
  14 // =========================================================================== 
  16 // --------------------------------------------------------------------------- 
  18 // --------------------------------------------------------------------------- 
  20 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) 
  21     #pragma implementation "printwin.h" 
  24 // For compilers that support precompilation, includes "wx.h". 
  25 #include "wx/wxprec.h" 
  33 // Don't use the Windows printer if we're in wxUniv mode and using 
  34 // the PostScript architecture 
  35 #if wxUSE_PRINTING_ARCHITECTURE && (!defined(__WXUNIVERSAL__) || !wxUSE_POSTSCRIPT_ARCHITECTURE_IN_MSW) 
  38     #include "wx/window.h" 
  39     #include "wx/msw/private.h" 
  43     #include "wx/msgdlg.h" 
  47 #include "wx/msw/printwin.h" 
  48 #include "wx/dcprint.h" 
  49 #include "wx/printdlg.h" 
  51 #include "wx/msw/private.h" 
  55 #include "wx/msw/private.h" 
  63 // --------------------------------------------------------------------------- 
  65 // --------------------------------------------------------------------------- 
  67 LONG APIENTRY _EXPORT 
wxAbortProc(HDC hPr
, int Code
); 
  69 // --------------------------------------------------------------------------- 
  71 // --------------------------------------------------------------------------- 
  73     IMPLEMENT_DYNAMIC_CLASS(wxWindowsPrinter
, wxPrinterBase
) 
  74     IMPLEMENT_CLASS(wxWindowsPrintPreview
, wxPrintPreviewBase
) 
  76 // =========================================================================== 
  78 // =========================================================================== 
  80 // --------------------------------------------------------------------------- 
  82 // --------------------------------------------------------------------------- 
  84 wxWindowsPrinter::wxWindowsPrinter(wxPrintDialogData 
*data
) 
  87     m_lpAbortProc 
= (WXFARPROC
) MakeProcInstance((FARPROC
) wxAbortProc
, wxGetInstance()); 
  90 wxWindowsPrinter::~wxWindowsPrinter() 
  92     // avoids warning about statement with no effect (FreeProcInstance 
  93     // doesn't do anything under Win32) 
  94 #if !defined(__WIN32__) && !defined(__NT__) 
  95     FreeProcInstance((FARPROC
) m_lpAbortProc
); 
  99 bool wxWindowsPrinter::Print(wxWindow 
*parent
, wxPrintout 
*printout
, bool prompt
) 
 102     sm_abortWindow 
= NULL
; 
 106         sm_lastError 
= wxPRINTER_ERROR
; 
 110     printout
->SetIsPreview(false); 
 112     if (m_printDialogData
.GetMinPage() < 1) 
 113         m_printDialogData
.SetMinPage(1); 
 114     if (m_printDialogData
.GetMaxPage() < 1) 
 115         m_printDialogData
.SetMaxPage(9999); 
 117     // Create a suitable device context 
 121         dc 
= PrintDialog(parent
); 
 127         dc 
= new wxPrinterDC(m_printDialogData
.GetPrintData()); 
 130     // May have pressed cancel. 
 131     if (!dc 
|| !dc
->Ok()) 
 137     int logPPIScreenX 
= 0; 
 138     int logPPIScreenY 
= 0; 
 139     int logPPIPrinterX 
= 0; 
 140     int logPPIPrinterY 
= 0; 
 142     HDC hdc 
= ::GetDC(NULL
); 
 143     logPPIScreenX 
= ::GetDeviceCaps(hdc
, LOGPIXELSX
); 
 144     logPPIScreenY 
= ::GetDeviceCaps(hdc
, LOGPIXELSY
); 
 145     ::ReleaseDC(NULL
, hdc
); 
 147     logPPIPrinterX 
= ::GetDeviceCaps((HDC
) dc
->GetHDC(), LOGPIXELSX
); 
 148     logPPIPrinterY 
= ::GetDeviceCaps((HDC
) dc
->GetHDC(), LOGPIXELSY
); 
 149     if (logPPIPrinterX 
== 0 || logPPIPrinterY 
== 0) 
 152         sm_lastError 
= wxPRINTER_ERROR
; 
 156     printout
->SetPPIScreen(logPPIScreenX
, logPPIScreenY
); 
 157     printout
->SetPPIPrinter(logPPIPrinterX
, logPPIPrinterY
); 
 159     // Set printout parameters 
 164     printout
->SetPageSizePixels((int)w
, (int)h
); 
 166     dc
->GetSizeMM(&w
, &h
); 
 167     printout
->SetPageSizeMM((int)w
, (int)h
); 
 169     // Create an abort window 
 170     wxBusyCursor busyCursor
; 
 172     printout
->OnPreparePrinting(); 
 174     // Get some parameters from the printout, if defined 
 175     int fromPage
, toPage
; 
 176     int minPage
, maxPage
; 
 177     printout
->GetPageInfo(&minPage
, &maxPage
, &fromPage
, &toPage
); 
 181         sm_lastError 
= wxPRINTER_ERROR
; 
 185     // Only set min and max, because from and to have been 
 187     m_printDialogData
.SetMinPage(minPage
); 
 188     m_printDialogData
.SetMaxPage(maxPage
); 
 190     wxWindow 
*win 
= CreateAbortWindow(parent
, printout
); 
 193 #if defined(__BORLANDC__) || defined(__GNUWIN32__) || defined(__SALFORDC__) || !defined(__WIN32__) 
 195     ::SetAbortProc((HDC
) dc
->GetHDC(), (ABORTPROC
) m_lpAbortProc
); 
 197     ::SetAbortProc((HDC
) dc
->GetHDC(), (FARPROC
) m_lpAbortProc
); 
 200     ::SetAbortProc((HDC
) dc
->GetHDC(), (int (_stdcall 
*) 
 201         // cast it to right type only if required 
 202         // FIXME it's really cdecl and we're casting it to stdcall - either there is 
 203         //       something I don't understand or it will crash at first usage 
 214         wxLogDebug(wxT("Could not create an abort dialog.")); 
 215         sm_lastError 
= wxPRINTER_ERROR
; 
 219     sm_abortWindow 
= win
; 
 220     sm_abortWindow
->Show(); 
 223     printout
->OnBeginPrinting(); 
 225     sm_lastError 
= wxPRINTER_NO_ERROR
; 
 227     int minPageNum 
= minPage
, maxPageNum 
= maxPage
; 
 229     if ( !m_printDialogData
.GetAllPages() ) 
 231         minPageNum 
= m_printDialogData
.GetFromPage(); 
 232         maxPageNum 
= m_printDialogData
.GetToPage(); 
 237           copyCount 
<= m_printDialogData
.GetNoCopies(); 
 240         if ( !printout
->OnBeginDocument(minPageNum
, maxPageNum
) ) 
 242             wxLogError(_("Could not start printing.")); 
 243             sm_lastError 
= wxPRINTER_ERROR
; 
 248             sm_lastError 
= wxPRINTER_CANCELLED
; 
 254         for ( pn 
= minPageNum
; 
 255               pn 
<= maxPageNum 
&& printout
->HasPage(pn
); 
 260                 sm_lastError 
= wxPRINTER_CANCELLED
; 
 265             bool cont 
= printout
->OnPrintPage(pn
); 
 270                 sm_lastError 
= wxPRINTER_CANCELLED
; 
 275         printout
->OnEndDocument(); 
 278     printout
->OnEndPrinting(); 
 282         sm_abortWindow
->Show(false); 
 283         delete sm_abortWindow
; 
 284         sm_abortWindow 
= NULL
; 
 289     return (sm_lastError 
== wxPRINTER_NO_ERROR
); 
 292 wxDC
* wxWindowsPrinter::PrintDialog(wxWindow 
*parent
) 
 294     wxDC
* dc 
= (wxDC
*) NULL
; 
 296     wxPrintDialog 
dialog(parent
, & m_printDialogData
); 
 297     int ret 
= dialog
.ShowModal(); 
 301         dc 
= dialog
.GetPrintDC(); 
 302         m_printDialogData 
= dialog
.GetPrintDialogData(); 
 304             sm_lastError 
= wxPRINTER_ERROR
; 
 306             sm_lastError 
= wxPRINTER_NO_ERROR
; 
 309         sm_lastError 
= wxPRINTER_CANCELLED
; 
 314 bool wxWindowsPrinter::Setup(wxWindow 
*parent
) 
 316     wxPrintDialog 
dialog(parent
, & m_printDialogData
); 
 317     dialog
.GetPrintDialogData().SetSetupDialog(true); 
 319     int ret 
= dialog
.ShowModal(); 
 323         m_printDialogData 
= dialog
.GetPrintDialogData(); 
 326     return (ret 
== wxID_OK
); 
 333 wxWindowsPrintPreview::wxWindowsPrintPreview(wxPrintout 
*printout
, 
 334                                              wxPrintout 
*printoutForPrinting
, 
 335                                              wxPrintDialogData 
*data
) 
 336                      : wxPrintPreviewBase(printout
, printoutForPrinting
, data
) 
 341 wxWindowsPrintPreview::wxWindowsPrintPreview(wxPrintout 
*printout
, 
 342                                              wxPrintout 
*printoutForPrinting
, 
 344                      : wxPrintPreviewBase(printout
, printoutForPrinting
, data
) 
 349 wxWindowsPrintPreview::~wxWindowsPrintPreview() 
 353 bool wxWindowsPrintPreview::Print(bool interactive
) 
 355     if (!m_printPrintout
) 
 357     wxWindowsPrinter 
printer(&m_printDialogData
); 
 358     return printer
.Print(m_previewFrame
, m_printPrintout
, interactive
); 
 361 void wxWindowsPrintPreview::DetermineScaling() 
 363     HDC dc 
= ::GetDC(NULL
); 
 364     int screenWidth 
= ::GetDeviceCaps(dc
, HORZSIZE
); 
 365     int screenYRes 
= ::GetDeviceCaps(dc
, VERTRES
); 
 366     int logPPIScreenX 
= ::GetDeviceCaps(dc
, LOGPIXELSX
); 
 367     int logPPIScreenY 
= ::GetDeviceCaps(dc
, LOGPIXELSY
); 
 368     m_previewPrintout
->SetPPIScreen(logPPIScreenX
, logPPIScreenY
); 
 370     ::ReleaseDC(NULL
, dc
); 
 372     // Get a device context for the currently selected printer 
 373     wxPrinterDC 
printerDC(m_printDialogData
.GetPrintData()); 
 375     int printerWidth 
= 150; 
 376     int printerHeight 
= 250; 
 377     int printerXRes 
= 1500; 
 378     int printerYRes 
= 2500; 
 380     dc 
= GetHdcOf(printerDC
); 
 383         printerWidth 
= ::GetDeviceCaps(dc
, HORZSIZE
); 
 384         printerHeight 
= ::GetDeviceCaps(dc
, VERTSIZE
); 
 385         printerXRes 
= ::GetDeviceCaps(dc
, HORZRES
); 
 386         printerYRes 
= ::GetDeviceCaps(dc
, VERTRES
); 
 388         int logPPIPrinterX 
= ::GetDeviceCaps(dc
, LOGPIXELSX
); 
 389         int logPPIPrinterY 
= ::GetDeviceCaps(dc
, LOGPIXELSY
); 
 391         m_previewPrintout
->SetPPIPrinter(logPPIPrinterX
, logPPIPrinterY
); 
 392         m_previewPrintout
->SetPageSizeMM(printerWidth
, printerHeight
); 
 394         if (logPPIPrinterX 
== 0 || logPPIPrinterY 
== 0 || printerWidth 
== 0 || printerHeight 
== 0) 
 400     m_pageWidth 
= printerXRes
; 
 401     m_pageHeight 
= printerYRes
; 
 403     // At 100%, the page should look about page-size on the screen. 
 404     m_previewScale 
= (float)((float)screenWidth
/(float)printerWidth
); 
 405     m_previewScale 
= m_previewScale 
* (float)((float)screenYRes
/(float)printerYRes
); 
 408 /**************************************************************************** 
 410   FUNCTION: wxAbortProc() 
 412     PURPOSE:  Processes messages for the Abort Dialog box 
 414 ****************************************************************************/ 
 416 LONG APIENTRY _EXPORT 
wxAbortProc(HDC 
WXUNUSED(hPr
), int WXUNUSED(Code
)) 
 420     if (!wxPrinterBase::sm_abortWindow
)              /* If the abort dialog isn't up yet */ 
 423     /* Process messages intended for the abort dialog box */ 
 425     while (!wxPrinterBase::sm_abortIt 
&& PeekMessage(&msg
, 0, 0, 0, TRUE
)) 
 426         if (!IsDialogMessage((HWND
) wxPrinterBase::sm_abortWindow
->GetHWND(), &msg
)) { 
 427             TranslateMessage(&msg
); 
 428             DispatchMessage(&msg
); 
 431         /* bAbort is TRUE (return is FALSE) if the user has aborted */ 
 433         return (!wxPrinterBase::sm_abortIt
); 
 437     // wxUSE_PRINTING_ARCHITECTURE