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