]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/msw/enhmeta.cpp
Rework IE virtual file system support to use new syntax. Remove now unused code for...
[wxWidgets.git] / src / msw / enhmeta.cpp
... / ...
CommitLineData
1///////////////////////////////////////////////////////////////////////////////
2// Name: src/msw/enhmeta.cpp
3// Purpose: implementation of wxEnhMetaFileXXX classes
4// Author: Vadim Zeitlin
5// Modified by:
6// Created: 13.01.00
7// RCS-ID: $Id$
8// Copyright: (c) 2000 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9// Licence: wxWindows licence
10///////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
24 #pragma hdrstop
25#endif
26
27#if wxUSE_ENH_METAFILE
28
29#ifndef WX_PRECOMP
30 #include "wx/string.h"
31 #include "wx/log.h"
32 #include "wx/intl.h"
33#endif //WX_PRECOMP
34
35#include "wx/dc.h"
36#include "wx/msw/dc.h"
37
38#include "wx/metafile.h"
39#include "wx/clipbrd.h"
40
41#include "wx/msw/private.h"
42
43// ----------------------------------------------------------------------------
44// wxWin macros
45// ----------------------------------------------------------------------------
46
47IMPLEMENT_DYNAMIC_CLASS(wxEnhMetaFile, wxObject)
48
49// ----------------------------------------------------------------------------
50// macros
51// ----------------------------------------------------------------------------
52
53#define GetEMF() ((HENHMETAFILE)m_hMF)
54#define GetEMFOf(mf) ((HENHMETAFILE)((mf).m_hMF))
55
56// ----------------------------------------------------------------------------
57// private functions
58// ----------------------------------------------------------------------------
59
60// we must pass NULL if the string is empty to metafile functions
61static inline const wxChar *GetMetaFileName(const wxString& fn)
62 { return !fn ? (const wxChar *)NULL : (const wxChar*)fn.wx_str(); }
63
64// ============================================================================
65// implementation
66// ============================================================================
67
68// ----------------------------------------------------------------------------
69// wxEnhMetaFile
70// ----------------------------------------------------------------------------
71
72wxGDIRefData *wxEnhMetaFile::CreateGDIRefData() const
73{
74 wxFAIL_MSG( wxT("must be implemented if used") );
75
76 return NULL;
77}
78
79wxGDIRefData *
80wxEnhMetaFile::CloneGDIRefData(const wxGDIRefData *WXUNUSED(data)) const
81{
82 wxFAIL_MSG( wxT("must be implemented if used") );
83
84 return NULL;
85}
86
87void wxEnhMetaFile::Init()
88{
89 if ( m_filename.empty() )
90 {
91 m_hMF = 0;
92 }
93 else // have valid file name, load metafile from it
94 {
95 m_hMF = (WXHANDLE)::GetEnhMetaFile(m_filename.t_str());
96 if ( !m_hMF )
97 {
98 wxLogSysError(_("Failed to load metafile from file \"%s\"."),
99 m_filename.c_str());
100 }
101 }
102}
103
104void wxEnhMetaFile::Assign(const wxEnhMetaFile& mf)
105{
106 if ( &mf == this )
107 return;
108
109 if ( mf.m_hMF )
110 {
111 m_hMF = (WXHANDLE)::CopyEnhMetaFile(GetEMFOf(mf),
112 GetMetaFileName(m_filename));
113 if ( !m_hMF )
114 {
115 wxLogLastError(wxT("CopyEnhMetaFile"));
116 }
117 }
118 else
119 {
120 m_hMF = 0;
121 }
122}
123
124void wxEnhMetaFile::Free()
125{
126 if ( m_hMF )
127 {
128 if ( !::DeleteEnhMetaFile(GetEMF()) )
129 {
130 wxLogLastError(wxT("DeleteEnhMetaFile"));
131 }
132 }
133}
134
135bool wxEnhMetaFile::Play(wxDC *dc, wxRect *rectBound)
136{
137 wxCHECK_MSG( IsOk(), false, wxT("can't play invalid enhanced metafile") );
138 wxCHECK_MSG( dc, false, wxT("invalid wxDC in wxEnhMetaFile::Play") );
139
140 RECT rect;
141 if ( rectBound )
142 {
143 rect.top = rectBound->y;
144 rect.left = rectBound->x;
145 rect.right = rectBound->x + rectBound->width;
146 rect.bottom = rectBound->y + rectBound->height;
147 }
148 else
149 {
150 wxSize size = GetSize();
151
152 rect.top =
153 rect.left = 0;
154 rect.right = size.x;
155 rect.bottom = size.y;
156 }
157
158 wxDCImpl *impl = dc->GetImpl();
159 wxMSWDCImpl *msw_impl = wxDynamicCast( impl, wxMSWDCImpl );
160 if (!msw_impl)
161 return false;
162
163 if ( !::PlayEnhMetaFile(GetHdcOf(*msw_impl), GetEMF(), &rect) )
164 {
165 wxLogLastError(wxT("PlayEnhMetaFile"));
166
167 return false;
168 }
169
170 return true;
171}
172
173wxSize wxEnhMetaFile::GetSize() const
174{
175 wxSize size = wxDefaultSize;
176
177 if ( IsOk() )
178 {
179 ENHMETAHEADER hdr;
180 if ( !::GetEnhMetaFileHeader(GetEMF(), sizeof(hdr), &hdr) )
181 {
182 wxLogLastError(wxT("GetEnhMetaFileHeader"));
183 }
184 else
185 {
186 // the width and height are in HIMETRIC (0.01mm) units, transform
187 // them to pixels
188 LONG w = hdr.rclFrame.right,
189 h = hdr.rclFrame.bottom;
190
191 HIMETRICToPixel(&w, &h);
192
193 size.x = w;
194 size.y = h;
195 }
196 }
197
198 return size;
199}
200
201bool wxEnhMetaFile::SetClipboard(int WXUNUSED(width), int WXUNUSED(height))
202{
203#if wxUSE_DRAG_AND_DROP && wxUSE_CLIPBOARD
204 wxCHECK_MSG( m_hMF, false, wxT("can't copy invalid metafile to clipboard") );
205
206 return wxTheClipboard->AddData(new wxEnhMetaFileDataObject(*this));
207#else // !wxUSE_DRAG_AND_DROP
208 wxFAIL_MSG(wxT("not implemented"));
209 return false;
210#endif // wxUSE_DRAG_AND_DROP/!wxUSE_DRAG_AND_DROP
211}
212
213// ----------------------------------------------------------------------------
214// wxEnhMetaFileDCImpl
215// ----------------------------------------------------------------------------
216
217class wxEnhMetaFileDCImpl : public wxMSWDCImpl
218{
219public:
220 wxEnhMetaFileDCImpl( wxEnhMetaFileDC *owner,
221 const wxString& filename, int width, int height,
222 const wxString& description );
223 wxEnhMetaFileDCImpl( wxEnhMetaFileDC *owner,
224 const wxDC& referenceDC,
225 const wxString& filename, int width, int height,
226 const wxString& description );
227 virtual ~wxEnhMetaFileDCImpl();
228
229 // obtain a pointer to the new metafile (caller should delete it)
230 wxEnhMetaFile *Close();
231
232protected:
233 virtual void DoGetSize(int *width, int *height) const;
234
235private:
236 void Create(HDC hdcRef,
237 const wxString& filename, int width, int height,
238 const wxString& description);
239
240 // size passed to ctor and returned by DoGetSize()
241 int m_width,
242 m_height;
243};
244
245
246wxEnhMetaFileDCImpl::wxEnhMetaFileDCImpl( wxEnhMetaFileDC* owner,
247 const wxString& filename,
248 int width, int height,
249 const wxString& description )
250 : wxMSWDCImpl( owner )
251{
252 Create(ScreenHDC(), filename, width, height, description);
253}
254
255wxEnhMetaFileDCImpl::wxEnhMetaFileDCImpl( wxEnhMetaFileDC* owner,
256 const wxDC& referenceDC,
257 const wxString& filename,
258 int width, int height,
259 const wxString& description )
260 : wxMSWDCImpl( owner )
261{
262 Create(GetHdcOf(referenceDC), filename, width, height, description);
263}
264
265void wxEnhMetaFileDCImpl::Create(HDC hdcRef,
266 const wxString& filename,
267 int width, int height,
268 const wxString& description)
269{
270 m_width = width;
271 m_height = height;
272
273 RECT rect;
274 RECT *pRect;
275 if ( width && height )
276 {
277 rect.top =
278 rect.left = 0;
279 rect.right = width;
280 rect.bottom = height;
281
282 // CreateEnhMetaFile() wants them in HIMETRIC
283 PixelToHIMETRIC(&rect.right, &rect.bottom, hdcRef);
284
285 pRect = &rect;
286 }
287 else
288 {
289 // GDI will try to find out the size for us (not recommended)
290 pRect = (LPRECT)NULL;
291 }
292
293 m_hDC = (WXHDC)::CreateEnhMetaFile(hdcRef, GetMetaFileName(filename),
294 pRect, description.wx_str());
295 if ( !m_hDC )
296 {
297 wxLogLastError(wxT("CreateEnhMetaFile"));
298 }
299}
300
301void wxEnhMetaFileDCImpl::DoGetSize(int *width, int *height) const
302{
303 if ( width )
304 *width = m_width;
305 if ( height )
306 *height = m_height;
307}
308
309wxEnhMetaFile *wxEnhMetaFileDCImpl::Close()
310{
311 wxCHECK_MSG( IsOk(), NULL, wxT("invalid wxEnhMetaFileDC") );
312
313 HENHMETAFILE hMF = ::CloseEnhMetaFile(GetHdc());
314 if ( !hMF )
315 {
316 wxLogLastError(wxT("CloseEnhMetaFile"));
317
318 return NULL;
319 }
320
321 wxEnhMetaFile *mf = new wxEnhMetaFile;
322 mf->SetHENHMETAFILE((WXHANDLE)hMF);
323 return mf;
324}
325
326wxEnhMetaFileDCImpl::~wxEnhMetaFileDCImpl()
327{
328 // avoid freeing it in the base class dtor
329 m_hDC = 0;
330}
331
332// ----------------------------------------------------------------------------
333// wxEnhMetaFileDC
334// ----------------------------------------------------------------------------
335
336IMPLEMENT_ABSTRACT_CLASS(wxEnhMetaFileDC, wxDC)
337
338wxEnhMetaFileDC::wxEnhMetaFileDC(const wxString& filename,
339 int width, int height,
340 const wxString& description)
341 : wxDC(new wxEnhMetaFileDCImpl(this,
342 filename,
343 width, height,
344 description))
345{
346}
347
348wxEnhMetaFileDC::wxEnhMetaFileDC(const wxDC& referenceDC,
349 const wxString& filename,
350 int width, int height,
351 const wxString& description)
352 : wxDC(new wxEnhMetaFileDCImpl(this,
353 referenceDC,
354 filename,
355 width, height,
356 description))
357{
358}
359
360wxEnhMetaFile *wxEnhMetaFileDC::Close()
361{
362 wxEnhMetaFileDCImpl * const
363 impl = static_cast<wxEnhMetaFileDCImpl *>(GetImpl());
364 wxCHECK_MSG( impl, NULL, wxT("no wxEnhMetaFileDC implementation") );
365
366 return impl->Close();
367}
368
369#if wxUSE_DRAG_AND_DROP
370
371// ----------------------------------------------------------------------------
372// wxEnhMetaFileDataObject
373// ----------------------------------------------------------------------------
374
375wxDataFormat
376wxEnhMetaFileDataObject::GetPreferredFormat(Direction WXUNUSED(dir)) const
377{
378 return wxDF_ENHMETAFILE;
379}
380
381size_t wxEnhMetaFileDataObject::GetFormatCount(Direction WXUNUSED(dir)) const
382{
383 // wxDF_ENHMETAFILE and wxDF_METAFILE
384 return 2;
385}
386
387void wxEnhMetaFileDataObject::GetAllFormats(wxDataFormat *formats,
388 Direction WXUNUSED(dir)) const
389{
390 formats[0] = wxDF_ENHMETAFILE;
391 formats[1] = wxDF_METAFILE;
392}
393
394size_t wxEnhMetaFileDataObject::GetDataSize(const wxDataFormat& format) const
395{
396 if ( format == wxDF_ENHMETAFILE )
397 {
398 // we pass data by handle and not HGLOBAL
399 return 0u;
400 }
401 else
402 {
403 wxASSERT_MSG( format == wxDF_METAFILE, wxT("unsupported format") );
404
405 return sizeof(METAFILEPICT);
406 }
407}
408
409bool wxEnhMetaFileDataObject::GetDataHere(const wxDataFormat& format, void *buf) const
410{
411 wxCHECK_MSG( m_metafile.IsOk(), false, wxT("copying invalid enh metafile") );
412
413 HENHMETAFILE hEMF = (HENHMETAFILE)m_metafile.GetHENHMETAFILE();
414
415 if ( format == wxDF_ENHMETAFILE )
416 {
417 HENHMETAFILE hEMFCopy = ::CopyEnhMetaFile(hEMF, NULL);
418 if ( !hEMFCopy )
419 {
420 wxLogLastError(wxT("CopyEnhMetaFile"));
421
422 return false;
423 }
424
425 *(HENHMETAFILE *)buf = hEMFCopy;
426 }
427 else
428 {
429 wxASSERT_MSG( format == wxDF_METAFILE, wxT("unsupported format") );
430
431 // convert to WMF
432
433 ScreenHDC hdc;
434
435 // first get the buffer size and alloc memory
436 size_t size = ::GetWinMetaFileBits(hEMF, 0, NULL, MM_ANISOTROPIC, hdc);
437 wxCHECK_MSG( size, false, wxT("GetWinMetaFileBits() failed") );
438
439 BYTE *bits = (BYTE *)malloc(size);
440
441 // then get the enh metafile bits
442 if ( !::GetWinMetaFileBits(hEMF, size, bits, MM_ANISOTROPIC, hdc) )
443 {
444 wxLogLastError(wxT("GetWinMetaFileBits"));
445
446 free(bits);
447
448 return false;
449 }
450
451 // and finally convert them to the WMF
452 HMETAFILE hMF = ::SetMetaFileBitsEx(size, bits);
453 free(bits);
454 if ( !hMF )
455 {
456 wxLogLastError(wxT("SetMetaFileBitsEx"));
457
458 return false;
459 }
460
461 METAFILEPICT *mfpict = (METAFILEPICT *)buf;
462
463 wxSize sizeMF = m_metafile.GetSize();
464 mfpict->hMF = hMF;
465 mfpict->mm = MM_ANISOTROPIC;
466 mfpict->xExt = sizeMF.x;
467 mfpict->yExt = sizeMF.y;
468
469 PixelToHIMETRIC(&mfpict->xExt, &mfpict->yExt);
470 }
471
472 return true;
473}
474
475bool wxEnhMetaFileDataObject::SetData(const wxDataFormat& format,
476 size_t WXUNUSED(len),
477 const void *buf)
478{
479 HENHMETAFILE hEMF;
480
481 if ( format == wxDF_ENHMETAFILE )
482 {
483 hEMF = *(HENHMETAFILE *)buf;
484
485 wxCHECK_MSG( hEMF, false, wxT("pasting invalid enh metafile") );
486 }
487 else
488 {
489 wxASSERT_MSG( format == wxDF_METAFILE, wxT("unsupported format") );
490
491 // convert from WMF
492 const METAFILEPICT *mfpict = (const METAFILEPICT *)buf;
493
494 // first get the buffer size
495 size_t size = ::GetMetaFileBitsEx(mfpict->hMF, 0, NULL);
496 wxCHECK_MSG( size, false, wxT("GetMetaFileBitsEx() failed") );
497
498 // then get metafile bits
499 BYTE *bits = (BYTE *)malloc(size);
500 if ( !::GetMetaFileBitsEx(mfpict->hMF, size, bits) )
501 {
502 wxLogLastError(wxT("GetMetaFileBitsEx"));
503
504 free(bits);
505
506 return false;
507 }
508
509 ScreenHDC hdcRef;
510
511 // and finally create an enhanced metafile from them
512 hEMF = ::SetWinMetaFileBits(size, bits, hdcRef, mfpict);
513 free(bits);
514 if ( !hEMF )
515 {
516 wxLogLastError(wxT("SetWinMetaFileBits"));
517
518 return false;
519 }
520 }
521
522 m_metafile.SetHENHMETAFILE((WXHANDLE)hEMF);
523
524 return true;
525}
526
527// ----------------------------------------------------------------------------
528// wxEnhMetaFileSimpleDataObject
529// ----------------------------------------------------------------------------
530
531size_t wxEnhMetaFileSimpleDataObject::GetDataSize() const
532{
533 // we pass data by handle and not HGLOBAL
534 return 0u;
535}
536
537bool wxEnhMetaFileSimpleDataObject::GetDataHere(void *buf) const
538{
539 wxCHECK_MSG( m_metafile.IsOk(), false, wxT("copying invalid enh metafile") );
540
541 HENHMETAFILE hEMF = (HENHMETAFILE)m_metafile.GetHENHMETAFILE();
542
543 HENHMETAFILE hEMFCopy = ::CopyEnhMetaFile(hEMF, NULL);
544 if ( !hEMFCopy )
545 {
546 wxLogLastError(wxT("CopyEnhMetaFile"));
547
548 return false;
549 }
550
551 *(HENHMETAFILE *)buf = hEMFCopy;
552 return true;
553}
554
555bool wxEnhMetaFileSimpleDataObject::SetData(size_t WXUNUSED(len),
556 const void *buf)
557{
558 HENHMETAFILE hEMF = *(HENHMETAFILE *)buf;
559
560 wxCHECK_MSG( hEMF, false, wxT("pasting invalid enh metafile") );
561 m_metafile.SetHENHMETAFILE((WXHANDLE)hEMF);
562
563 return true;
564}
565
566
567#endif // wxUSE_DRAG_AND_DROP
568
569#endif // wxUSE_ENH_METAFILE