]> git.saurik.com Git - wxWidgets.git/blob - src/msw/dcprint.cpp
1. fixes for DrawRotatedText(), drawing sample extended to show it
[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 #if !USE_SHARED_LIBRARY
42 IMPLEMENT_CLASS(wxPrinterDC, wxDC)
43 #endif
44
45 // This form is deprecated
46 wxPrinterDC::wxPrinterDC(const wxString& driver_name, const wxString& device_name, const wxString& file, bool interactive, int orientation)
47 {
48 m_isInteractive = interactive;
49
50 if (!file.IsNull() && file != wxT(""))
51 m_printData.SetFilename(file);
52
53 #if wxUSE_COMMON_DIALOGS
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 != wxT("")) &&
86 (!device_name.IsNull() && device_name != wxT("")) &&
87 (!file.IsNull() && file != wxT("")))
88 {
89 m_hDC = (WXHDC) CreateDC(WXSTRINGCAST driver_name, WXSTRINGCAST device_name, WXSTRINGCAST 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
110 wxPrinterDC::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);
124 }
125
126
127 wxPrinterDC::wxPrinterDC(WXHDC theDC)
128 {
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);
141 }
142
143 wxPrinterDC::~wxPrinterDC(void)
144 {
145 }
146
147 bool wxPrinterDC::StartDoc(const wxString& message)
148 {
149 DOCINFO docinfo;
150 docinfo.cbSize = sizeof(DOCINFO);
151 docinfo.lpszDocName = (const wxChar*)message;
152
153 wxString filename(m_printData.GetFilename());
154
155 if (filename.IsEmpty())
156 docinfo.lpszOutput = NULL;
157 else
158 docinfo.lpszOutput = (const wxChar *) 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();
187 wxLogDebug(wxT("wxDC::StartDoc failed with error: %d\n"), lastError);
188 }
189 #endif
190
191 return (ret > 0);
192 }
193
194 void wxPrinterDC::EndDoc(void)
195 {
196 if (m_hDC) ::EndDoc((HDC) m_hDC);
197 }
198
199 void wxPrinterDC::StartPage(void)
200 {
201 if (m_hDC)
202 ::StartPage((HDC) m_hDC);
203 }
204
205 void wxPrinterDC::EndPage(void)
206 {
207 if (m_hDC)
208 ::EndPage((HDC) m_hDC);
209 }
210
211 // Returns default device and port names
212 static 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 != wxT("") );
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.
271 WXHDC wxGetPrinterDC(int orientation)
272 {
273 HDC hDC;
274 LPDEVMODE lpDevMode = NULL;
275 LPDEVNAMES lpDevNames;
276 LPSTR lpszDriverName;
277 LPSTR lpszDeviceName;
278 LPSTR lpszPortName;
279
280 PRINTDLG pd;
281 // __GNUWIN32__ has trouble believing PRINTDLG is 66 bytes - thinks it is 68
282 #ifdef __GNUWIN32__
283 pd.lStructSize = 66; // sizeof(PRINTDLG);
284 #else
285 pd.lStructSize = sizeof(PRINTDLG);
286 #endif
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;
292
293 if (!PrintDlg((LPPRINTDLG)&pd))
294 {
295 if ( pd.hDevMode )
296 GlobalFree(pd.hDevMode);
297 if (pd.hDevNames)
298 GlobalFree(pd.hDevNames);
299
300 return(0);
301 }
302
303 if (!pd.hDevNames)
304 {
305 if ( pd.hDevMode )
306 GlobalFree(pd.hDevMode);
307 }
308
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);
314
315 if ( pd.hDevMode )
316 {
317 lpDevMode = (DEVMODE*) GlobalLock(pd.hDevMode);
318 lpDevMode->dmOrientation = orientation;
319 lpDevMode->dmFields |= DM_ORIENTATION;
320 }
321
322 #ifdef __WIN32__
323 hDC = CreateDC(lpszDriverName, lpszDeviceName, lpszPortName, (DEVMODE *)lpDevMode);
324 #else
325 hDC = CreateDC(lpszDriverName, lpszDeviceName, lpszPortName, (LPSTR)lpDevMode);
326 #endif
327
328 if (pd.hDevMode && lpDevMode)
329 GlobalUnlock(pd.hDevMode);
330
331 if (pd.hDevNames)
332 {
333 GlobalFree(pd.hDevNames);
334 pd.hDevNames=NULL;
335 }
336 if (pd.hDevMode)
337 {
338 GlobalFree(pd.hDevMode);
339 pd.hDevMode=NULL;
340 }
341 return (WXHDC) hDC;
342 }
343 #endif
344
345 // Gets an HDC for the specified printer configuration
346 WXHDC WXDLLEXPORT wxGetPrinterDC(const wxPrintData& printDataConst)
347 {
348 wxPrintData printData = printDataConst;
349 printData.ConvertToNative();
350
351 wxChar* driverName = (wxChar*) NULL;
352
353 wxString devNameStr = printData.GetPrinterName();
354 wxChar* deviceName;
355 wxChar* portName = (wxChar*) NULL; // Obsolete in WIN32
356
357 if (devNameStr == wxT(""))
358 deviceName = (wxChar*) NULL;
359 else
360 deviceName = WXSTRINGCAST devNameStr;
361
362 LPDEVMODE lpDevMode = (LPDEVMODE) NULL;
363
364 HGLOBAL hDevMode = (HGLOBAL)(DWORD) printData.GetNativeData();
365
366 if ( hDevMode )
367 lpDevMode = (DEVMODE*) GlobalLock(hDevMode);
368
369 if (devNameStr == wxT(""))
370 {
371 // Retrieve the default device name
372 wxString portName;
373 #ifdef __WXDEBUG__
374 bool ret =
375 #else // !Debug
376 (void)
377 #endif // Debug/Release
378 wxGetDefaultDeviceName(devNameStr, portName);
379
380 wxASSERT_MSG( ret, wxT("Could not get default device name.") );
381
382 deviceName = WXSTRINGCAST devNameStr;
383 }
384
385 #ifdef __WIN32__
386 HDC hDC = CreateDC(driverName, deviceName, portName, (DEVMODE *) lpDevMode);
387 #else
388 HDC hDC = CreateDC(driverName, deviceName, portName, (LPSTR) lpDevMode);
389 #endif
390
391 if (hDevMode && lpDevMode)
392 GlobalUnlock(hDevMode);
393
394 return (WXHDC) hDC;
395 }
396