]> git.saurik.com Git - wxWidgets.git/blame - src/msw/dcprint.cpp
wxWindow::Fit() infinite loop bug fixed
[wxWidgets.git] / src / msw / dcprint.cpp
CommitLineData
2bda0e17
KB
1/////////////////////////////////////////////////////////////////////////////
2// Name: dcprint.cpp
3// Purpose: wxPrinterDC class
4// Author: Julian Smart
5// Modified by:
6// Created: 01/02/97
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart and Markus Holzem
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
2bda0e17
KB
13#pragma implementation "dcprint.h"
14#endif
15
16// For compilers that support precompilation, includes "wx.h".
17#include "wx/wxprec.h"
18
19#ifdef __BORLANDC__
20#pragma hdrstop
21#endif
22
23#ifndef WX_PRECOMP
24#endif
25
0c589ad0 26#include "wx/string.h"
6776a0b2 27#include "wx/log.h"
0c589ad0 28#include "wx/window.h"
42e69d6b 29#include "wx/msw/private.h"
0c589ad0
BM
30#include "wx/dcprint.h"
31#include "math.h"
2bda0e17 32
c455ab93 33#if wxUSE_COMMON_DIALOGS || defined(__WXWINE__)
2bda0e17
KB
34#include <commdlg.h>
35#endif
36
37#ifndef __WIN32__
38#include <print.h>
39#endif
40
2bda0e17
KB
41#if !USE_SHARED_LIBRARY
42IMPLEMENT_CLASS(wxPrinterDC, wxDC)
43#endif
44
7bcb11d3 45// This form is deprecated
debe6624 46wxPrinterDC::wxPrinterDC(const wxString& driver_name, const wxString& device_name, const wxString& file, bool interactive, int orientation)
2bda0e17 47{
7bcb11d3
JS
48 m_isInteractive = interactive;
49
50 if (!file.IsNull() && file != "")
51 m_printData.SetFilename(file);
52
47d67540 53#if wxUSE_COMMON_DIALOGS
7bcb11d3
JS
54 if (interactive)
55 {
56 PRINTDLG pd;
57
58 pd.lStructSize = sizeof( PRINTDLG );
59 pd.hwndOwner=(HWND) NULL;
60 pd.hDevMode=(HANDLE)NULL;
61 pd.hDevNames=(HANDLE)NULL;
62 pd.Flags=PD_RETURNDC | PD_NOSELECTION | PD_NOPAGENUMS;
63 pd.nFromPage=0;
64 pd.nToPage=0;
65 pd.nMinPage=0;
66 pd.nMaxPage=0;
67 pd.nCopies=1;
68 pd.hInstance=(HINSTANCE)NULL;
69
70 if ( PrintDlg( &pd ) != 0 )
71 {
72 m_hDC = (WXHDC) pd.hDC;
73 m_ok = TRUE;
74 }
75 else
76 {
77 m_ok = FALSE;
78 return;
79 }
80
81 // m_dontDelete = TRUE;
82 }
83 else
84#endif
85 if ((!driver_name.IsNull() && driver_name != "") &&
86 (!device_name.IsNull() && device_name != "") &&
87 (!file.IsNull() && file != ""))
88 {
89 m_hDC = (WXHDC) CreateDC((char *) (const char *) driver_name, (char *) (const char *) device_name, (char *) (const char *) file, NULL);
90 m_ok = m_hDC ? TRUE: FALSE;
91 }
92 else
93 {
94 wxPrintData printData;
95 printData.SetOrientation(orientation);
96 m_hDC = wxGetPrinterDC(printData);
97 m_ok = m_hDC ? TRUE: FALSE;
98 }
99
100 if (m_hDC)
101 {
102 // int width = GetDeviceCaps(m_hDC, VERTRES);
103 // int height = GetDeviceCaps(m_hDC, HORZRES);
104 SetMapMode(wxMM_TEXT);
105 }
106 SetBrush(*wxBLACK_BRUSH);
107 SetPen(*wxBLACK_PEN);
108}
109
110wxPrinterDC::wxPrinterDC(const wxPrintData& printData)
111{
112 m_printData = printData;
113
114 m_isInteractive = FALSE;
115
116 m_hDC = wxGetPrinterDC(printData);
117 m_ok = (m_hDC != 0);
118
119 if (m_hDC)
120 SetMapMode(wxMM_TEXT);
121
122 SetBrush(*wxBLACK_BRUSH);
123 SetPen(*wxBLACK_PEN);
2bda0e17
KB
124}
125
7bcb11d3 126
2bda0e17
KB
127wxPrinterDC::wxPrinterDC(WXHDC theDC)
128{
7bcb11d3
JS
129 m_isInteractive = FALSE;
130
131 m_hDC = theDC;
132 m_ok = TRUE;
133 if (m_hDC)
134 {
135 // int width = GetDeviceCaps(m_hDC, VERTRES);
136 // int height = GetDeviceCaps(m_hDC, HORZRES);
137 SetMapMode(wxMM_TEXT);
138 }
139 SetBrush(*wxBLACK_BRUSH);
140 SetPen(*wxBLACK_PEN);
2bda0e17
KB
141}
142
143wxPrinterDC::~wxPrinterDC(void)
144{
145}
146
7bcb11d3
JS
147bool wxPrinterDC::StartDoc(const wxString& message)
148{
149 DOCINFO docinfo;
150 docinfo.cbSize = sizeof(DOCINFO);
151 docinfo.lpszDocName = (const char *)message;
152
153 wxString filename(m_printData.GetFilename());
154
155 if (filename.IsEmpty())
156 docinfo.lpszOutput = NULL;
157 else
158 docinfo.lpszOutput = (const char *) filename;
159
160#if defined(__WIN95__)
161 docinfo.lpszDatatype = NULL;
162 docinfo.fwType = 0;
163#endif
164
165 if (!m_hDC)
166 return FALSE;
167
168 int ret =
169#ifndef __WIN32__
170 ::StartDoc((HDC) m_hDC, &docinfo);
171#else
172#ifdef UNICODE
173 ::StartDocW((HDC) m_hDC, &docinfo);
174#else
175#ifdef __TWIN32__
176 ::StartDoc((HDC) m_hDC, &docinfo);
177#else
178 ::StartDocA((HDC) m_hDC, &docinfo);
179#endif
180#endif
181#endif
182
183#ifndef __WIN16__
184 if (ret <= 0)
185 {
186 DWORD lastError = GetLastError();
6776a0b2 187 wxLogDebug("wxDC::StartDoc failed with error: %d\n", lastError);
7bcb11d3
JS
188 }
189#endif
190
191 return (ret > 0);
192}
193
194void wxPrinterDC::EndDoc(void)
195{
196 if (m_hDC) ::EndDoc((HDC) m_hDC);
197}
198
199void wxPrinterDC::StartPage(void)
200{
201 if (m_hDC)
202 ::StartPage((HDC) m_hDC);
203}
204
205void wxPrinterDC::EndPage(void)
206{
207 if (m_hDC)
208 ::EndPage((HDC) m_hDC);
209}
210
211// Returns default device and port names
212static bool wxGetDefaultDeviceName(wxString& deviceName, wxString& portName)
213{
214 deviceName = "";
215
216 LPDEVNAMES lpDevNames;
217 LPSTR lpszDriverName;
218 LPSTR lpszDeviceName;
219 LPSTR lpszPortName;
220
221 PRINTDLG pd;
222
223 // Cygwin has trouble believing PRINTDLG is 66 bytes - thinks it is 68
224#ifdef __GNUWIN32__
225 pd.lStructSize = 66; // sizeof(PRINTDLG);
226#else
227 pd.lStructSize = sizeof(PRINTDLG);
228#endif
229
230 pd.hwndOwner = (HWND)NULL;
231 pd.hDevMode = NULL; // Will be created by PrintDlg
232 pd.hDevNames = NULL; // Ditto
233 pd.Flags = PD_RETURNDEFAULT;
234 pd.nCopies = 1;
235
236 if (!PrintDlg((LPPRINTDLG)&pd))
237 {
238 if ( pd.hDevMode )
239 GlobalFree(pd.hDevMode);
240 if (pd.hDevNames)
241 GlobalFree(pd.hDevNames);
242
243 return FALSE;
244 }
245
246 if (pd.hDevNames)
247 {
248 lpDevNames = (LPDEVNAMES)GlobalLock(pd.hDevNames);
249 lpszDriverName = (LPSTR)lpDevNames + lpDevNames->wDriverOffset;
250 lpszDeviceName = (LPSTR)lpDevNames + lpDevNames->wDeviceOffset;
251 lpszPortName = (LPSTR)lpDevNames + lpDevNames->wOutputOffset;
252 GlobalUnlock(pd.hDevNames);
253 GlobalFree(pd.hDevNames);
254 pd.hDevNames=NULL;
255
256 deviceName = lpszDeviceName;
257 portName = lpszPortName;
258 }
259
260 if (pd.hDevMode)
261 {
262 GlobalFree(pd.hDevMode);
263 pd.hDevMode=NULL;
264 }
265 return ( deviceName != "" );
266}
267
268#if 0
269// This uses defaults, except for orientation, so we should eliminate this function
270// and use the 2nd form (passing wxPrintData) instead.
2bda0e17
KB
271WXHDC wxGetPrinterDC(int orientation)
272{
273 HDC hDC;
274 LPDEVMODE lpDevMode = NULL;
275 LPDEVNAMES lpDevNames;
276 LPSTR lpszDriverName;
277 LPSTR lpszDeviceName;
278 LPSTR lpszPortName;
7bcb11d3 279
2bda0e17
KB
280 PRINTDLG pd;
281 // __GNUWIN32__ has trouble believing PRINTDLG is 66 bytes - thinks it is 68
7bcb11d3 282#ifdef __GNUWIN32__
2bda0e17 283 pd.lStructSize = 66; // sizeof(PRINTDLG);
7bcb11d3
JS
284#else
285 pd.lStructSize = sizeof(PRINTDLG);
286#endif
2bda0e17
KB
287 pd.hwndOwner = (HWND)NULL;
288 pd.hDevMode = NULL; // Will be created by PrintDlg
289 pd.hDevNames = NULL; // Ditto
290 pd.Flags = PD_RETURNDEFAULT;
291 pd.nCopies = 1;
7bcb11d3 292
2bda0e17
KB
293 if (!PrintDlg((LPPRINTDLG)&pd))
294 {
295 if ( pd.hDevMode )
296 GlobalFree(pd.hDevMode);
297 if (pd.hDevNames)
298 GlobalFree(pd.hDevNames);
7bcb11d3 299
2bda0e17
KB
300 return(0);
301 }
7bcb11d3 302
2bda0e17
KB
303 if (!pd.hDevNames)
304 {
305 if ( pd.hDevMode )
306 GlobalFree(pd.hDevMode);
307 }
7bcb11d3 308
2bda0e17
KB
309 lpDevNames = (LPDEVNAMES)GlobalLock(pd.hDevNames);
310 lpszDriverName = (LPSTR)lpDevNames + lpDevNames->wDriverOffset;
311 lpszDeviceName = (LPSTR)lpDevNames + lpDevNames->wDeviceOffset;
312 lpszPortName = (LPSTR)lpDevNames + lpDevNames->wOutputOffset;
313 GlobalUnlock(pd.hDevNames);
7bcb11d3 314
2bda0e17
KB
315 if ( pd.hDevMode )
316 {
317 lpDevMode = (DEVMODE*) GlobalLock(pd.hDevMode);
318 lpDevMode->dmOrientation = orientation;
319 lpDevMode->dmFields |= DM_ORIENTATION;
320 }
7bcb11d3 321
2bda0e17
KB
322#ifdef __WIN32__
323 hDC = CreateDC(lpszDriverName, lpszDeviceName, lpszPortName, (DEVMODE *)lpDevMode);
324#else
325 hDC = CreateDC(lpszDriverName, lpszDeviceName, lpszPortName, (LPSTR)lpDevMode);
326#endif
7bcb11d3 327
2bda0e17
KB
328 if (pd.hDevMode && lpDevMode)
329 GlobalUnlock(pd.hDevMode);
7bcb11d3 330
2bda0e17
KB
331 if (pd.hDevNames)
332 {
7bcb11d3
JS
333 GlobalFree(pd.hDevNames);
334 pd.hDevNames=NULL;
2bda0e17
KB
335 }
336 if (pd.hDevMode)
337 {
338 GlobalFree(pd.hDevMode);
339 pd.hDevMode=NULL;
340 }
341 return (WXHDC) hDC;
342}
7bcb11d3
JS
343#endif
344
345// Gets an HDC for the specified printer configuration
346WXHDC WXDLLEXPORT wxGetPrinterDC(const wxPrintData& printDataConst)
347{
348 wxPrintData printData = printDataConst;
349 printData.ConvertToNative();
350
351 char* driverName = (char*) NULL;
352
353 wxString devNameStr = printData.GetPrinterName();
354 char* deviceName;
355 char* portName = (char*) NULL; // Obsolete in WIN32
356
357 if (devNameStr == "")
358 deviceName = (char*) NULL;
359 else
360 deviceName = (char*) (const char*) devNameStr;
361
362 LPDEVMODE lpDevMode = (LPDEVMODE) NULL;
363
364 HGLOBAL hDevMode = (HGLOBAL) printData.GetNativeData();
365
366 if ( hDevMode )
367 lpDevMode = (DEVMODE*) GlobalLock(hDevMode);
368
369 if (devNameStr == "")
370 {
371 // Retrieve the default device name
372 wxString portName;
373 bool ret = wxGetDefaultDeviceName(devNameStr, portName);
374
375 wxASSERT_MSG( ret, "Could not get default device name." );
2bda0e17 376
7bcb11d3
JS
377 deviceName = (char*) (const char*) devNameStr;
378 }
379
380#ifdef __WIN32__
381 HDC hDC = CreateDC(driverName, deviceName, portName, (DEVMODE *) lpDevMode);
382#else
383 HDC hDC = CreateDC(driverName, deviceName, portName, (LPSTR) lpDevMode);
384#endif
385
386 if (hDevMode && lpDevMode)
387 GlobalUnlock(hDevMode);
388
389 return (WXHDC) hDC;
390}
2bda0e17 391