]> git.saurik.com Git - wxWidgets.git/blob - src/msw/dcprint.cpp
Improved wxFileDialog behaviour wrt to remembering filenames
[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 != _T(""))
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 != _T("")) &&
86             (!device_name.IsNull() && device_name != _T("")) &&
87             (!file.IsNull() && file != _T("")))
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(_T("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 != _T("") );
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 == _T(""))
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 == _T(""))
370     {
371         // Retrieve the default device name
372         wxString portName;
373         bool ret = wxGetDefaultDeviceName(devNameStr, portName);
374
375         wxASSERT_MSG( ret, _T("Could not get default device name.") );
376
377         deviceName = WXSTRINGCAST devNameStr;
378     }
379     
380 #ifdef __WIN32__
381     HDC hDC = CreateDC(driverName, deviceName, portName, (DEVMODE *) lpDevMode);
382 #else
383     HDC hDC = CreateDC(driverName, deviceName, portName, (LPSTR) lpDevMode);
384 #endif
385     
386     if (hDevMode && lpDevMode)
387         GlobalUnlock(hDevMode);
388     
389     return (WXHDC) hDC;
390 }
391