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