]>
git.saurik.com Git - wxWidgets.git/blob - src/msw/enhmeta.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: 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 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
21 #pragma implementation "enhmeta.h"
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
31 #if wxUSE_ENH_METAFILE
34 #include "wx/string.h"
39 #include "wx/metafile.h"
40 #include "wx/clipbrd.h"
42 #include "wx/msw/private.h"
44 // ----------------------------------------------------------------------------
46 // ----------------------------------------------------------------------------
48 IMPLEMENT_DYNAMIC_CLASS(wxEnhMetaFile
, wxObject
)
49 IMPLEMENT_ABSTRACT_CLASS(wxEnhMetaFileDC
, wxDC
)
51 // ----------------------------------------------------------------------------
53 // ----------------------------------------------------------------------------
55 #define GetEMF() ((HENHMETAFILE)m_hMF)
56 #define GetEMFOf(mf) ((HENHMETAFILE)((mf).m_hMF))
58 // ----------------------------------------------------------------------------
60 // ----------------------------------------------------------------------------
62 // we must pass NULL if the string is empty to metafile functions
63 static inline const wxChar
*GetMetaFileName(const wxString
& fn
)
64 { return !fn
? (wxChar
*)NULL
: fn
.c_str(); }
66 // ============================================================================
68 // ============================================================================
70 // ----------------------------------------------------------------------------
72 // ----------------------------------------------------------------------------
74 void wxEnhMetaFile::Init()
76 if ( m_filename
.empty() )
80 else // have valid file name, load metafile from it
82 m_hMF
= GetEnhMetaFile(m_filename
);
84 wxLogSysError(_("Failed to load metafile from file \"%s\"."),
89 void wxEnhMetaFile::Assign(const wxEnhMetaFile
& mf
)
96 m_hMF
= (WXHANDLE
)::CopyEnhMetaFile(GetEMFOf(mf
),
97 GetMetaFileName(m_filename
));
100 wxLogLastError(_T("CopyEnhMetaFile"));
109 void wxEnhMetaFile::Free()
113 if ( !::DeleteEnhMetaFile(GetEMF()) )
115 wxLogLastError(_T("DeleteEnhMetaFile"));
120 bool wxEnhMetaFile::Play(wxDC
*dc
, wxRect
*rectBound
)
122 wxCHECK_MSG( Ok(), false, _T("can't play invalid enhanced metafile") );
123 wxCHECK_MSG( dc
, FALSE
, _T("invalid wxDC in wxEnhMetaFile::Play") );
128 rect
.top
= rectBound
->y
;
129 rect
.left
= rectBound
->x
;
130 rect
.right
= rectBound
->x
+ rectBound
->width
;
131 rect
.bottom
= rectBound
->y
+ rectBound
->height
;
135 wxSize size
= GetSize();
140 rect
.bottom
= size
.y
;
143 if ( !::PlayEnhMetaFile(GetHdcOf(*dc
), GetEMF(), &rect
) )
145 wxLogLastError(_T("PlayEnhMetaFile"));
153 wxSize
wxEnhMetaFile::GetSize() const
155 wxSize size
= wxDefaultSize
;
160 if ( !::GetEnhMetaFileHeader(GetEMF(), sizeof(hdr
), &hdr
) )
162 wxLogLastError(_T("GetEnhMetaFileHeader"));
166 // the width and height are in HIMETRIC (0.01mm) units, transform
168 LONG w
= hdr
.rclFrame
.right
,
169 h
= hdr
.rclFrame
.bottom
;
171 HIMETRICToPixel(&w
, &h
);
181 bool wxEnhMetaFile::SetClipboard(int WXUNUSED(width
), int WXUNUSED(height
))
183 #if wxUSE_DRAG_AND_DROP
184 wxCHECK_MSG( m_hMF
, FALSE
, _T("can't copy invalid metafile to clipboard") );
186 return wxTheClipboard
->AddData(new wxEnhMetaFileDataObject(*this));
187 #else // !wxUSE_DRAG_AND_DROP
188 wxFAIL_MSG(_T("not implemented"));
190 #endif // wxUSE_DRAG_AND_DROP/!wxUSE_DRAG_AND_DROP
193 // ----------------------------------------------------------------------------
195 // ----------------------------------------------------------------------------
197 wxEnhMetaFileDC::wxEnhMetaFileDC(const wxString
& filename
,
198 int width
, int height
,
199 const wxString
& description
)
204 if ( width
&& height
)
209 rect
.bottom
= height
;
211 // CreateEnhMetaFile() wants them in HIMETRIC
212 PixelToHIMETRIC(&rect
.right
, &rect
.bottom
);
218 // GDI will try to find out the size for us (not recommended)
219 pRect
= (LPRECT
)NULL
;
222 m_hDC
= (WXHDC
)::CreateEnhMetaFile(hdcRef
, GetMetaFileName(filename
),
226 wxLogLastError(_T("CreateEnhMetaFile"));
230 wxEnhMetaFile
*wxEnhMetaFileDC::Close()
232 wxCHECK_MSG( Ok(), NULL
, _T("invalid wxEnhMetaFileDC") );
234 HENHMETAFILE hMF
= ::CloseEnhMetaFile(GetHdc());
237 wxLogLastError(_T("CloseEnhMetaFile"));
242 wxEnhMetaFile
*mf
= new wxEnhMetaFile
;
243 mf
->SetHENHMETAFILE((WXHANDLE
)hMF
);
247 wxEnhMetaFileDC::~wxEnhMetaFileDC()
249 // avoid freeing it in the base class dtor
253 #if wxUSE_DRAG_AND_DROP
255 // ----------------------------------------------------------------------------
256 // wxEnhMetaFileDataObject
257 // ----------------------------------------------------------------------------
260 wxEnhMetaFileDataObject::GetPreferredFormat(Direction
WXUNUSED(dir
)) const
262 return wxDF_ENHMETAFILE
;
265 size_t wxEnhMetaFileDataObject::GetFormatCount(Direction
WXUNUSED(dir
)) const
267 // wxDF_ENHMETAFILE and wxDF_METAFILE
271 void wxEnhMetaFileDataObject::GetAllFormats(wxDataFormat
*formats
,
272 Direction
WXUNUSED(dir
)) const
274 formats
[0] = wxDF_ENHMETAFILE
;
275 formats
[1] = wxDF_METAFILE
;
278 size_t wxEnhMetaFileDataObject::GetDataSize(const wxDataFormat
& format
) const
280 if ( format
== wxDF_ENHMETAFILE
)
282 // we pass data by handle and not HGLOBAL
287 wxASSERT_MSG( format
== wxDF_METAFILE
, _T("unsupported format") );
289 return sizeof(METAFILEPICT
);
293 bool wxEnhMetaFileDataObject::GetDataHere(const wxDataFormat
& format
, void *buf
) const
295 wxCHECK_MSG( m_metafile
.Ok(), false, _T("copying invalid enh metafile") );
297 HENHMETAFILE hEMF
= (HENHMETAFILE
)m_metafile
.GetHENHMETAFILE();
299 if ( format
== wxDF_ENHMETAFILE
)
301 HENHMETAFILE hEMFCopy
= ::CopyEnhMetaFile(hEMF
, NULL
);
304 wxLogLastError(_T("CopyEnhMetaFile"));
309 *(HENHMETAFILE
*)buf
= hEMFCopy
;
313 wxASSERT_MSG( format
== wxDF_METAFILE
, _T("unsupported format") );
319 // first get the buffer size and alloc memory
320 size_t size
= ::GetWinMetaFileBits(hEMF
, 0, NULL
, MM_ANISOTROPIC
, hdc
);
321 wxCHECK_MSG( size
, FALSE
, _T("GetWinMetaFileBits() failed") );
323 BYTE
*bits
= (BYTE
*)malloc(size
);
325 // then get the enh metafile bits
326 if ( !::GetWinMetaFileBits(hEMF
, size
, bits
, MM_ANISOTROPIC
, hdc
) )
328 wxLogLastError(_T("GetWinMetaFileBits"));
335 // and finally convert them to the WMF
336 HMETAFILE hMF
= ::SetMetaFileBitsEx(size
, bits
);
340 wxLogLastError(_T("SetMetaFileBitsEx"));
345 METAFILEPICT
*mfpict
= (METAFILEPICT
*)buf
;
347 wxSize sizeMF
= m_metafile
.GetSize();
349 mfpict
->mm
= MM_ANISOTROPIC
;
350 mfpict
->xExt
= sizeMF
.x
;
351 mfpict
->yExt
= sizeMF
.y
;
353 PixelToHIMETRIC(&mfpict
->xExt
, &mfpict
->yExt
);
359 bool wxEnhMetaFileDataObject::SetData(const wxDataFormat
& format
,
360 size_t WXUNUSED(len
),
365 if ( format
== wxDF_ENHMETAFILE
)
367 hEMF
= *(HENHMETAFILE
*)buf
;
369 wxCHECK_MSG( hEMF
, FALSE
, _T("pasting invalid enh metafile") );
373 wxASSERT_MSG( format
== wxDF_METAFILE
, _T("unsupported format") );
376 const METAFILEPICT
*mfpict
= (const METAFILEPICT
*)buf
;
378 // first get the buffer size
379 size_t size
= ::GetMetaFileBitsEx(mfpict
->hMF
, 0, NULL
);
380 wxCHECK_MSG( size
, FALSE
, _T("GetMetaFileBitsEx() failed") );
382 // then get metafile bits
383 BYTE
*bits
= (BYTE
*)malloc(size
);
384 if ( !::GetMetaFileBitsEx(mfpict
->hMF
, size
, bits
) )
386 wxLogLastError(_T("GetMetaFileBitsEx"));
395 // and finally create an enhanced metafile from them
396 hEMF
= ::SetWinMetaFileBits(size
, bits
, hdcRef
, mfpict
);
400 wxLogLastError(_T("SetWinMetaFileBits"));
406 m_metafile
.SetHENHMETAFILE((WXHANDLE
)hEMF
);
411 // ----------------------------------------------------------------------------
412 // wxEnhMetaFileSimpleDataObject
413 // ----------------------------------------------------------------------------
415 size_t wxEnhMetaFileSimpleDataObject::GetDataSize() const
417 // we pass data by handle and not HGLOBAL
421 bool wxEnhMetaFileSimpleDataObject::GetDataHere(void *buf
) const
423 wxCHECK_MSG( m_metafile
.Ok(), false, _T("copying invalid enh metafile") );
425 HENHMETAFILE hEMF
= (HENHMETAFILE
)m_metafile
.GetHENHMETAFILE();
427 HENHMETAFILE hEMFCopy
= ::CopyEnhMetaFile(hEMF
, NULL
);
430 wxLogLastError(_T("CopyEnhMetaFile"));
435 *(HENHMETAFILE
*)buf
= hEMFCopy
;
439 bool wxEnhMetaFileSimpleDataObject::SetData(size_t WXUNUSED(len
),
442 HENHMETAFILE hEMF
= *(HENHMETAFILE
*)buf
;
444 wxCHECK_MSG( hEMF
, FALSE
, _T("pasting invalid enh metafile") );
445 m_metafile
.SetHENHMETAFILE((WXHANDLE
)hEMF
);
451 #endif // wxUSE_DRAG_AND_DROP
453 #endif // wxUSE_ENH_METAFILE