]> git.saurik.com Git - wxWidgets.git/blob - src/msw/dcprint.cpp
96a461eaaf127b255045b6d5ed9f51fecafc886e
[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/dcprint.h"
27 #include "wx/log.h"
28 #include "math.h"
29
30 #include <windows.h>
31
32 #if wxUSE_COMMON_DIALOGS
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
53 IMPLEMENT_CLASS(wxPrinterDC, wxDC)
54 #endif
55
56 // This form is deprecated
57 wxPrinterDC::wxPrinterDC(const wxString& driver_name, const wxString& device_name, const wxString& file, bool interactive, int orientation)
58 {
59 m_isInteractive = interactive;
60
61 if (!file.IsNull() && file != "")
62 m_printData.SetFilename(file);
63
64 #if wxUSE_COMMON_DIALOGS
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
121 wxPrinterDC::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);
135 }
136
137
138 wxPrinterDC::wxPrinterDC(WXHDC theDC)
139 {
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);
152 }
153
154 wxPrinterDC::~wxPrinterDC(void)
155 {
156 }
157
158 bool 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();
198 wxLogDebug("wxDC::StartDoc failed with error: %d\n", lastError);
199 }
200 #endif
201
202 return (ret > 0);
203 }
204
205 void wxPrinterDC::EndDoc(void)
206 {
207 if (m_hDC) ::EndDoc((HDC) m_hDC);
208 }
209
210 void wxPrinterDC::StartPage(void)
211 {
212 if (m_hDC)
213 ::StartPage((HDC) m_hDC);
214 }
215
216 void wxPrinterDC::EndPage(void)
217 {
218 if (m_hDC)
219 ::EndPage((HDC) m_hDC);
220 }
221
222 // Returns default device and port names
223 static 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.
282 WXHDC wxGetPrinterDC(int orientation)
283 {
284 HDC hDC;
285 LPDEVMODE lpDevMode = NULL;
286 LPDEVNAMES lpDevNames;
287 LPSTR lpszDriverName;
288 LPSTR lpszDeviceName;
289 LPSTR lpszPortName;
290
291 PRINTDLG pd;
292 // __GNUWIN32__ has trouble believing PRINTDLG is 66 bytes - thinks it is 68
293 #ifdef __GNUWIN32__
294 pd.lStructSize = 66; // sizeof(PRINTDLG);
295 #else
296 pd.lStructSize = sizeof(PRINTDLG);
297 #endif
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;
303
304 if (!PrintDlg((LPPRINTDLG)&pd))
305 {
306 if ( pd.hDevMode )
307 GlobalFree(pd.hDevMode);
308 if (pd.hDevNames)
309 GlobalFree(pd.hDevNames);
310
311 return(0);
312 }
313
314 if (!pd.hDevNames)
315 {
316 if ( pd.hDevMode )
317 GlobalFree(pd.hDevMode);
318 }
319
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);
325
326 if ( pd.hDevMode )
327 {
328 lpDevMode = (DEVMODE*) GlobalLock(pd.hDevMode);
329 lpDevMode->dmOrientation = orientation;
330 lpDevMode->dmFields |= DM_ORIENTATION;
331 }
332
333 #ifdef __WIN32__
334 hDC = CreateDC(lpszDriverName, lpszDeviceName, lpszPortName, (DEVMODE *)lpDevMode);
335 #else
336 hDC = CreateDC(lpszDriverName, lpszDeviceName, lpszPortName, (LPSTR)lpDevMode);
337 #endif
338
339 if (pd.hDevMode && lpDevMode)
340 GlobalUnlock(pd.hDevMode);
341
342 if (pd.hDevNames)
343 {
344 GlobalFree(pd.hDevNames);
345 pd.hDevNames=NULL;
346 }
347 if (pd.hDevMode)
348 {
349 GlobalFree(pd.hDevMode);
350 pd.hDevMode=NULL;
351 }
352 return (WXHDC) hDC;
353 }
354 #endif
355
356 // Gets an HDC for the specified printer configuration
357 WXHDC 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." );
387
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 }
402