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