]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/msw/printwin.cpp
applying OSAF patch for "toolbar selection not correct on Mac after calling Realize...
[wxWidgets.git] / src / msw / printwin.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: printwin.cpp
3// Purpose: wxWindowsPrinter framework
4// Author: Julian Smart
5// Modified by:
6// Created: 04/01/98
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12// ===========================================================================
13// declarations
14// ===========================================================================
15
16// ---------------------------------------------------------------------------
17// headers
18// ---------------------------------------------------------------------------
19
20#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
21 #pragma implementation "printwin.h"
22#endif
23
24// For compilers that support precompilation, includes "wx.h".
25#include "wx/wxprec.h"
26
27#ifdef __BORLANDC__
28 #pragma hdrstop
29#endif
30
31#include "wx/defs.h"
32
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)
36
37#ifndef WX_PRECOMP
38 #include "wx/window.h"
39 #include "wx/msw/private.h"
40 #include "wx/utils.h"
41 #include "wx/dc.h"
42 #include "wx/app.h"
43 #include "wx/msgdlg.h"
44 #include "wx/intl.h"
45#endif
46
47#include "wx/msw/printwin.h"
48#include "wx/dcprint.h"
49#include "wx/printdlg.h"
50#include "wx/log.h"
51#include "wx/msw/private.h"
52
53#include <stdlib.h>
54
55#include "wx/msw/wrapcdlg.h"
56#ifndef __WIN32__
57 #include <print.h>
58#endif
59
60// ---------------------------------------------------------------------------
61// private functions
62// ---------------------------------------------------------------------------
63
64LONG APIENTRY _EXPORT wxAbortProc(HDC hPr, int Code);
65
66// ---------------------------------------------------------------------------
67// wxWin macros
68// ---------------------------------------------------------------------------
69
70 IMPLEMENT_DYNAMIC_CLASS(wxWindowsPrinter, wxPrinterBase)
71 IMPLEMENT_CLASS(wxWindowsPrintPreview, wxPrintPreviewBase)
72
73// ===========================================================================
74// implementation
75// ===========================================================================
76
77// ---------------------------------------------------------------------------
78// Printer
79// ---------------------------------------------------------------------------
80
81wxWindowsPrinter::wxWindowsPrinter(wxPrintDialogData *data)
82 : wxPrinterBase(data)
83{
84 m_lpAbortProc = (WXFARPROC) MakeProcInstance((FARPROC) wxAbortProc, wxGetInstance());
85}
86
87wxWindowsPrinter::~wxWindowsPrinter()
88{
89 // avoids warning about statement with no effect (FreeProcInstance
90 // doesn't do anything under Win32)
91#if !defined(__WIN32__) && !defined(__NT__)
92 FreeProcInstance((FARPROC) m_lpAbortProc);
93#endif
94}
95
96bool wxWindowsPrinter::Print(wxWindow *parent, wxPrintout *printout, bool prompt)
97{
98 sm_abortIt = false;
99 sm_abortWindow = NULL;
100
101 if (!printout)
102 {
103 sm_lastError = wxPRINTER_ERROR;
104 return false;
105 }
106
107 printout->SetIsPreview(false);
108
109 if (m_printDialogData.GetMinPage() < 1)
110 m_printDialogData.SetMinPage(1);
111 if (m_printDialogData.GetMaxPage() < 1)
112 m_printDialogData.SetMaxPage(9999);
113
114 // Create a suitable device context
115 wxDC *dc wxDUMMY_INITIALIZE(NULL);
116 if (prompt)
117 {
118 dc = PrintDialog(parent);
119 if (!dc)
120 return false;
121 }
122 else
123 {
124 dc = new wxPrinterDC(m_printDialogData.GetPrintData());
125 }
126
127 // May have pressed cancel.
128 if (!dc || !dc->Ok())
129 {
130 if (dc) delete dc;
131 return false;
132 }
133
134 HDC hdc = ::GetDC(NULL);
135 int logPPIScreenX = ::GetDeviceCaps(hdc, LOGPIXELSX);
136 int logPPIScreenY = ::GetDeviceCaps(hdc, LOGPIXELSY);
137 ::ReleaseDC(NULL, hdc);
138
139 int logPPIPrinterX = ::GetDeviceCaps((HDC) dc->GetHDC(), LOGPIXELSX);
140 int logPPIPrinterY = ::GetDeviceCaps((HDC) dc->GetHDC(), LOGPIXELSY);
141 if (logPPIPrinterX == 0 || logPPIPrinterY == 0)
142 {
143 delete dc;
144 sm_lastError = wxPRINTER_ERROR;
145 return false;
146 }
147
148 printout->SetPPIScreen(logPPIScreenX, logPPIScreenY);
149 printout->SetPPIPrinter(logPPIPrinterX, logPPIPrinterY);
150
151 // Set printout parameters
152 printout->SetDC(dc);
153
154 int w, h;
155 dc->GetSize(&w, &h);
156 printout->SetPageSizePixels((int)w, (int)h);
157
158 dc->GetSizeMM(&w, &h);
159 printout->SetPageSizeMM((int)w, (int)h);
160
161 // Create an abort window
162 wxBusyCursor busyCursor;
163
164 printout->OnPreparePrinting();
165
166 // Get some parameters from the printout, if defined
167 int fromPage, toPage;
168 int minPage, maxPage;
169 printout->GetPageInfo(&minPage, &maxPage, &fromPage, &toPage);
170
171 if (maxPage == 0)
172 {
173 sm_lastError = wxPRINTER_ERROR;
174 return false;
175 }
176
177 // Only set min and max, because from and to have been
178 // set by the user
179 m_printDialogData.SetMinPage(minPage);
180 m_printDialogData.SetMaxPage(maxPage);
181
182 wxWindow *win = CreateAbortWindow(parent, printout);
183 wxYield();
184
185#if defined(__WATCOMC__) || defined(__BORLANDC__) || defined(__GNUWIN32__) || defined(__SALFORDC__) || !defined(__WIN32__)
186#ifdef STRICT
187 ::SetAbortProc((HDC) dc->GetHDC(), (ABORTPROC) m_lpAbortProc);
188#else
189 ::SetAbortProc((HDC) dc->GetHDC(), (FARPROC) m_lpAbortProc);
190#endif
191#else
192 ::SetAbortProc((HDC) dc->GetHDC(), (int (_stdcall *)
193 // cast it to right type only if required
194 // FIXME it's really cdecl and we're casting it to stdcall - either there is
195 // something I don't understand or it will crash at first usage
196#ifdef STRICT
197 (HDC, int)
198#else
199 ()
200#endif
201 )m_lpAbortProc);
202#endif
203
204 if (!win)
205 {
206 wxLogDebug(wxT("Could not create an abort dialog."));
207 sm_lastError = wxPRINTER_ERROR;
208
209 delete dc;
210 return false;
211 }
212 sm_abortWindow = win;
213 sm_abortWindow->Show();
214 wxSafeYield();
215
216 printout->OnBeginPrinting();
217
218 sm_lastError = wxPRINTER_NO_ERROR;
219
220 int minPageNum = minPage, maxPageNum = maxPage;
221
222 if ( !m_printDialogData.GetAllPages() )
223 {
224 minPageNum = m_printDialogData.GetFromPage();
225 maxPageNum = m_printDialogData.GetToPage();
226 }
227
228 int copyCount;
229 for ( copyCount = 1;
230 copyCount <= m_printDialogData.GetNoCopies();
231 copyCount++ )
232 {
233 if ( !printout->OnBeginDocument(minPageNum, maxPageNum) )
234 {
235 wxLogError(_("Could not start printing."));
236 sm_lastError = wxPRINTER_ERROR;
237 break;
238 }
239 if (sm_abortIt)
240 {
241 sm_lastError = wxPRINTER_CANCELLED;
242 break;
243 }
244
245 int pn;
246
247 for ( pn = minPageNum;
248 pn <= maxPageNum && printout->HasPage(pn);
249 pn++ )
250 {
251 if ( sm_abortIt )
252 {
253 sm_lastError = wxPRINTER_CANCELLED;
254 break;
255 }
256
257 dc->StartPage();
258 bool cont = printout->OnPrintPage(pn);
259 dc->EndPage();
260
261 if ( !cont )
262 {
263 sm_lastError = wxPRINTER_CANCELLED;
264 break;
265 }
266 }
267
268 printout->OnEndDocument();
269 }
270
271 printout->OnEndPrinting();
272
273 if (sm_abortWindow)
274 {
275 sm_abortWindow->Show(false);
276 delete sm_abortWindow;
277 sm_abortWindow = NULL;
278 }
279
280 delete dc;
281
282 return sm_lastError == wxPRINTER_NO_ERROR;
283}
284
285wxDC* wxWindowsPrinter::PrintDialog(wxWindow *parent)
286{
287 wxDC* dc = (wxDC*) NULL;
288
289 wxPrintDialog dialog(parent, & m_printDialogData);
290 int ret = dialog.ShowModal();
291
292 if (ret == wxID_OK)
293 {
294 dc = dialog.GetPrintDC();
295 m_printDialogData = dialog.GetPrintDialogData();
296 if (dc == NULL)
297 sm_lastError = wxPRINTER_ERROR;
298 else
299 sm_lastError = wxPRINTER_NO_ERROR;
300 }
301 else
302 sm_lastError = wxPRINTER_CANCELLED;
303
304 return dc;
305}
306
307bool wxWindowsPrinter::Setup(wxWindow *WXUNUSED(parent))
308{
309#if 0
310 // We no longer expose that dialog
311 wxPrintDialog dialog(parent, & m_printDialogData);
312 dialog.GetPrintDialogData().SetSetupDialog(true);
313
314 int ret = dialog.ShowModal();
315
316 if (ret == wxID_OK)
317 {
318 m_printDialogData = dialog.GetPrintDialogData();
319 }
320
321 return (ret == wxID_OK);
322#else
323 return false;
324#endif
325}
326
327/*
328* Print preview
329*/
330
331wxWindowsPrintPreview::wxWindowsPrintPreview(wxPrintout *printout,
332 wxPrintout *printoutForPrinting,
333 wxPrintDialogData *data)
334 : wxPrintPreviewBase(printout, printoutForPrinting, data)
335{
336 DetermineScaling();
337}
338
339wxWindowsPrintPreview::wxWindowsPrintPreview(wxPrintout *printout,
340 wxPrintout *printoutForPrinting,
341 wxPrintData *data)
342 : wxPrintPreviewBase(printout, printoutForPrinting, data)
343{
344 DetermineScaling();
345}
346
347wxWindowsPrintPreview::~wxWindowsPrintPreview()
348{
349}
350
351bool wxWindowsPrintPreview::Print(bool interactive)
352{
353 if (!m_printPrintout)
354 return false;
355 wxWindowsPrinter printer(&m_printDialogData);
356 return printer.Print(m_previewFrame, m_printPrintout, interactive);
357}
358
359void wxWindowsPrintPreview::DetermineScaling()
360{
361 HDC dc = ::GetDC(NULL);
362 int screenWidth = ::GetDeviceCaps(dc, HORZSIZE);
363 int screenYRes = ::GetDeviceCaps(dc, VERTRES);
364 int logPPIScreenX = ::GetDeviceCaps(dc, LOGPIXELSX);
365 int logPPIScreenY = ::GetDeviceCaps(dc, LOGPIXELSY);
366 m_previewPrintout->SetPPIScreen(logPPIScreenX, logPPIScreenY);
367
368 ::ReleaseDC(NULL, dc);
369
370 // Get a device context for the currently selected printer
371 wxPrinterDC printerDC(m_printDialogData.GetPrintData());
372
373 int printerWidth = 150;
374 int printerHeight wxDUMMY_INITIALIZE(250);
375 int printerXRes = 1500;
376 int printerYRes = 2500;
377
378 dc = GetHdcOf(printerDC);
379 if ( dc )
380 {
381 printerWidth = ::GetDeviceCaps(dc, HORZSIZE);
382 printerHeight = ::GetDeviceCaps(dc, VERTSIZE);
383 printerXRes = ::GetDeviceCaps(dc, HORZRES);
384 printerYRes = ::GetDeviceCaps(dc, VERTRES);
385
386 int logPPIPrinterX = ::GetDeviceCaps(dc, LOGPIXELSX);
387 int logPPIPrinterY = ::GetDeviceCaps(dc, LOGPIXELSY);
388
389 m_previewPrintout->SetPPIPrinter(logPPIPrinterX, logPPIPrinterY);
390 m_previewPrintout->SetPageSizeMM(printerWidth, printerHeight);
391
392 if (logPPIPrinterX == 0 || logPPIPrinterY == 0 || printerWidth == 0 || printerHeight == 0)
393 m_isOk = false;
394 }
395 else
396 m_isOk = false;
397
398 m_pageWidth = printerXRes;
399 m_pageHeight = printerYRes;
400
401 // At 100%, the page should look about page-size on the screen.
402 m_previewScale = (float)((float)screenWidth/(float)printerWidth);
403 m_previewScale = m_previewScale * (float)((float)screenYRes/(float)printerYRes);
404}
405
406/****************************************************************************
407
408 FUNCTION: wxAbortProc()
409
410 PURPOSE: Processes messages for the Abort Dialog box
411
412****************************************************************************/
413
414LONG APIENTRY _EXPORT wxAbortProc(HDC WXUNUSED(hPr), int WXUNUSED(Code))
415{
416 MSG msg;
417
418 if (!wxPrinterBase::sm_abortWindow) /* If the abort dialog isn't up yet */
419 return(TRUE);
420
421 /* Process messages intended for the abort dialog box */
422
423 while (!wxPrinterBase::sm_abortIt && ::PeekMessage(&msg, 0, 0, 0, TRUE))
424 if (!IsDialogMessage((HWND) wxPrinterBase::sm_abortWindow->GetHWND(), &msg)) {
425 TranslateMessage(&msg);
426 DispatchMessage(&msg);
427 }
428
429 /* bAbort is TRUE (return is FALSE) if the user has aborted */
430
431 return !wxPrinterBase::sm_abortIt;
432}
433
434#endif
435 // wxUSE_PRINTING_ARCHITECTURE