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