]>
git.saurik.com Git - wxWidgets.git/blob - src/msw/enhmeta.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/msw/enhmeta.cpp
3 // Purpose: implementation of wxEnhMetaFileXXX classes
4 // Author: Vadim Zeitlin
8 // Copyright: (c) 2000 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
27 #if wxUSE_ENH_METAFILE
30 #include "wx/string.h"
35 #include "wx/metafile.h"
36 #include "wx/clipbrd.h"
38 #include "wx/msw/private.h"
40 // ----------------------------------------------------------------------------
42 // ----------------------------------------------------------------------------
44 IMPLEMENT_DYNAMIC_CLASS(wxEnhMetaFile
, wxObject
)
45 IMPLEMENT_ABSTRACT_CLASS(wxEnhMetaFileDC
, wxDC
)
47 // ----------------------------------------------------------------------------
49 // ----------------------------------------------------------------------------
51 #define GetEMF() ((HENHMETAFILE)m_hMF)
52 #define GetEMFOf(mf) ((HENHMETAFILE)((mf).m_hMF))
54 // ----------------------------------------------------------------------------
56 // ----------------------------------------------------------------------------
58 // we must pass NULL if the string is empty to metafile functions
59 static inline const wxChar
*GetMetaFileName(const wxString
& fn
)
60 { return !fn
? (const wxChar
*)NULL
: (const wxChar
*)fn
.wx_str(); }
62 // ============================================================================
64 // ============================================================================
66 // ----------------------------------------------------------------------------
68 // ----------------------------------------------------------------------------
70 void wxEnhMetaFile::Init()
72 if ( m_filename
.empty() )
76 else // have valid file name, load metafile from it
78 m_hMF
= (WXHANDLE
)::GetEnhMetaFile(m_filename
.fn_str());
80 wxLogSysError(_("Failed to load metafile from file \"%s\"."),
85 void wxEnhMetaFile::Assign(const wxEnhMetaFile
& mf
)
92 m_hMF
= (WXHANDLE
)::CopyEnhMetaFile(GetEMFOf(mf
),
93 GetMetaFileName(m_filename
));
96 wxLogLastError(_T("CopyEnhMetaFile"));
105 void wxEnhMetaFile::Free()
109 if ( !::DeleteEnhMetaFile(GetEMF()) )
111 wxLogLastError(_T("DeleteEnhMetaFile"));
116 bool wxEnhMetaFile::Play(wxDC
*dc
, wxRect
*rectBound
)
118 wxCHECK_MSG( Ok(), false, _T("can't play invalid enhanced metafile") );
119 wxCHECK_MSG( dc
, false, _T("invalid wxDC in wxEnhMetaFile::Play") );
124 rect
.top
= rectBound
->y
;
125 rect
.left
= rectBound
->x
;
126 rect
.right
= rectBound
->x
+ rectBound
->width
;
127 rect
.bottom
= rectBound
->y
+ rectBound
->height
;
131 wxSize size
= GetSize();
136 rect
.bottom
= size
.y
;
139 if ( !::PlayEnhMetaFile(GetHdcOf(*dc
), GetEMF(), &rect
) )
141 wxLogLastError(_T("PlayEnhMetaFile"));
149 wxSize
wxEnhMetaFile::GetSize() const
151 wxSize size
= wxDefaultSize
;
156 if ( !::GetEnhMetaFileHeader(GetEMF(), sizeof(hdr
), &hdr
) )
158 wxLogLastError(_T("GetEnhMetaFileHeader"));
162 // the width and height are in HIMETRIC (0.01mm) units, transform
164 LONG w
= hdr
.rclFrame
.right
,
165 h
= hdr
.rclFrame
.bottom
;
167 HIMETRICToPixel(&w
, &h
);
177 bool wxEnhMetaFile::SetClipboard(int WXUNUSED(width
), int WXUNUSED(height
))
179 #if wxUSE_DRAG_AND_DROP && wxUSE_CLIPBOARD
180 wxCHECK_MSG( m_hMF
, false, _T("can't copy invalid metafile to clipboard") );
182 return wxTheClipboard
->AddData(new wxEnhMetaFileDataObject(*this));
183 #else // !wxUSE_DRAG_AND_DROP
184 wxFAIL_MSG(_T("not implemented"));
186 #endif // wxUSE_DRAG_AND_DROP/!wxUSE_DRAG_AND_DROP
189 // ----------------------------------------------------------------------------
191 // ----------------------------------------------------------------------------
193 wxEnhMetaFileDC::wxEnhMetaFileDC(const wxString
& filename
,
194 int width
, int height
,
195 const wxString
& description
)
202 if ( width
&& height
)
207 rect
.bottom
= height
;
209 // CreateEnhMetaFile() wants them in HIMETRIC
210 PixelToHIMETRIC(&rect
.right
, &rect
.bottom
);
216 // GDI will try to find out the size for us (not recommended)
217 pRect
= (LPRECT
)NULL
;
221 m_hDC
= (WXHDC
)::CreateEnhMetaFile(hdcRef
, GetMetaFileName(filename
),
222 pRect
, description
.wx_str());
225 wxLogLastError(_T("CreateEnhMetaFile"));
229 void wxEnhMetaFileDC::DoGetSize(int *width
, int *height
) const
237 wxEnhMetaFile
*wxEnhMetaFileDC::Close()
239 wxCHECK_MSG( Ok(), NULL
, _T("invalid wxEnhMetaFileDC") );
241 HENHMETAFILE hMF
= ::CloseEnhMetaFile(GetHdc());
244 wxLogLastError(_T("CloseEnhMetaFile"));
249 wxEnhMetaFile
*mf
= new wxEnhMetaFile
;
250 mf
->SetHENHMETAFILE((WXHANDLE
)hMF
);
254 wxEnhMetaFileDC::~wxEnhMetaFileDC()
256 // avoid freeing it in the base class dtor
260 #if wxUSE_DRAG_AND_DROP
262 // ----------------------------------------------------------------------------
263 // wxEnhMetaFileDataObject
264 // ----------------------------------------------------------------------------
267 wxEnhMetaFileDataObject::GetPreferredFormat(Direction
WXUNUSED(dir
)) const
269 return wxDF_ENHMETAFILE
;
272 size_t wxEnhMetaFileDataObject::GetFormatCount(Direction
WXUNUSED(dir
)) const
274 // wxDF_ENHMETAFILE and wxDF_METAFILE
278 void wxEnhMetaFileDataObject::GetAllFormats(wxDataFormat
*formats
,
279 Direction
WXUNUSED(dir
)) const
281 formats
[0] = wxDF_ENHMETAFILE
;
282 formats
[1] = wxDF_METAFILE
;
285 size_t wxEnhMetaFileDataObject::GetDataSize(const wxDataFormat
& format
) const
287 if ( format
== wxDF_ENHMETAFILE
)
289 // we pass data by handle and not HGLOBAL
294 wxASSERT_MSG( format
== wxDF_METAFILE
, _T("unsupported format") );
296 return sizeof(METAFILEPICT
);
300 bool wxEnhMetaFileDataObject::GetDataHere(const wxDataFormat
& format
, void *buf
) const
302 wxCHECK_MSG( m_metafile
.Ok(), false, _T("copying invalid enh metafile") );
304 HENHMETAFILE hEMF
= (HENHMETAFILE
)m_metafile
.GetHENHMETAFILE();
306 if ( format
== wxDF_ENHMETAFILE
)
308 HENHMETAFILE hEMFCopy
= ::CopyEnhMetaFile(hEMF
, NULL
);
311 wxLogLastError(_T("CopyEnhMetaFile"));
316 *(HENHMETAFILE
*)buf
= hEMFCopy
;
320 wxASSERT_MSG( format
== wxDF_METAFILE
, _T("unsupported format") );
326 // first get the buffer size and alloc memory
327 size_t size
= ::GetWinMetaFileBits(hEMF
, 0, NULL
, MM_ANISOTROPIC
, hdc
);
328 wxCHECK_MSG( size
, false, _T("GetWinMetaFileBits() failed") );
330 BYTE
*bits
= (BYTE
*)malloc(size
);
332 // then get the enh metafile bits
333 if ( !::GetWinMetaFileBits(hEMF
, size
, bits
, MM_ANISOTROPIC
, hdc
) )
335 wxLogLastError(_T("GetWinMetaFileBits"));
342 // and finally convert them to the WMF
343 HMETAFILE hMF
= ::SetMetaFileBitsEx(size
, bits
);
347 wxLogLastError(_T("SetMetaFileBitsEx"));
352 METAFILEPICT
*mfpict
= (METAFILEPICT
*)buf
;
354 wxSize sizeMF
= m_metafile
.GetSize();
356 mfpict
->mm
= MM_ANISOTROPIC
;
357 mfpict
->xExt
= sizeMF
.x
;
358 mfpict
->yExt
= sizeMF
.y
;
360 PixelToHIMETRIC(&mfpict
->xExt
, &mfpict
->yExt
);
366 bool wxEnhMetaFileDataObject::SetData(const wxDataFormat
& format
,
367 size_t WXUNUSED(len
),
372 if ( format
== wxDF_ENHMETAFILE
)
374 hEMF
= *(HENHMETAFILE
*)buf
;
376 wxCHECK_MSG( hEMF
, false, _T("pasting invalid enh metafile") );
380 wxASSERT_MSG( format
== wxDF_METAFILE
, _T("unsupported format") );
383 const METAFILEPICT
*mfpict
= (const METAFILEPICT
*)buf
;
385 // first get the buffer size
386 size_t size
= ::GetMetaFileBitsEx(mfpict
->hMF
, 0, NULL
);
387 wxCHECK_MSG( size
, false, _T("GetMetaFileBitsEx() failed") );
389 // then get metafile bits
390 BYTE
*bits
= (BYTE
*)malloc(size
);
391 if ( !::GetMetaFileBitsEx(mfpict
->hMF
, size
, bits
) )
393 wxLogLastError(_T("GetMetaFileBitsEx"));
402 // and finally create an enhanced metafile from them
403 hEMF
= ::SetWinMetaFileBits(size
, bits
, hdcRef
, mfpict
);
407 wxLogLastError(_T("SetWinMetaFileBits"));
413 m_metafile
.SetHENHMETAFILE((WXHANDLE
)hEMF
);
418 // ----------------------------------------------------------------------------
419 // wxEnhMetaFileSimpleDataObject
420 // ----------------------------------------------------------------------------
422 size_t wxEnhMetaFileSimpleDataObject::GetDataSize() const
424 // we pass data by handle and not HGLOBAL
428 bool wxEnhMetaFileSimpleDataObject::GetDataHere(void *buf
) const
430 wxCHECK_MSG( m_metafile
.Ok(), false, _T("copying invalid enh metafile") );
432 HENHMETAFILE hEMF
= (HENHMETAFILE
)m_metafile
.GetHENHMETAFILE();
434 HENHMETAFILE hEMFCopy
= ::CopyEnhMetaFile(hEMF
, NULL
);
437 wxLogLastError(_T("CopyEnhMetaFile"));
442 *(HENHMETAFILE
*)buf
= hEMFCopy
;
446 bool wxEnhMetaFileSimpleDataObject::SetData(size_t WXUNUSED(len
),
449 HENHMETAFILE hEMF
= *(HENHMETAFILE
*)buf
;
451 wxCHECK_MSG( hEMF
, false, _T("pasting invalid enh metafile") );
452 m_metafile
.SetHENHMETAFILE((WXHANDLE
)hEMF
);
458 #endif // wxUSE_DRAG_AND_DROP
460 #endif // wxUSE_ENH_METAFILE