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