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