]>
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" 
  38 #include "wx/metafile.h" 
  39 #include "wx/clipbrd.h" 
  41 #include "wx/msw/private.h" 
  43 // ---------------------------------------------------------------------------- 
  45 // ---------------------------------------------------------------------------- 
  47 IMPLEMENT_DYNAMIC_CLASS(wxEnhMetaFile
, wxObject
) 
  48 IMPLEMENT_ABSTRACT_CLASS(wxEnhMetaFileDC
, wxDC
) 
  50 // ---------------------------------------------------------------------------- 
  52 // ---------------------------------------------------------------------------- 
  54 #define GetEMF()            ((HENHMETAFILE)m_hMF) 
  55 #define GetEMFOf(mf)        ((HENHMETAFILE)((mf).m_hMF)) 
  57 // ---------------------------------------------------------------------------- 
  59 // ---------------------------------------------------------------------------- 
  61 // we must pass NULL if the string is empty to metafile functions 
  62 static inline const wxChar 
*GetMetaFileName(const wxString
& fn
) 
  63     { return !fn 
? (wxChar 
*)NULL 
: fn
.c_str(); } 
  65 // ============================================================================ 
  67 // ============================================================================ 
  69 // ---------------------------------------------------------------------------- 
  71 // ---------------------------------------------------------------------------- 
  73 void wxEnhMetaFile::Assign(const wxEnhMetaFile
& mf
) 
  80         m_hMF 
= (WXHANDLE
)::CopyEnhMetaFile(GetEMFOf(mf
), 
  81                                             GetMetaFileName(m_filename
)); 
  84             wxLogLastError(_T("CopyEnhMetaFile")); 
  93 void wxEnhMetaFile::Free() 
  97         if ( !::DeleteEnhMetaFile(GetEMF()) ) 
  99             wxLogLastError(_T("DeleteEnhMetaFile")); 
 104 bool wxEnhMetaFile::Play(wxDC 
*dc
, wxRect 
*rectBound
) 
 106     wxCHECK_MSG( Ok(), FALSE
, _T("can't play invalid enhanced metafile") ); 
 107     wxCHECK_MSG( dc
, FALSE
, _T("invalid wxDC in wxEnhMetaFile::Play") ); 
 112         rect
.top 
= rectBound
->y
; 
 113         rect
.left 
= rectBound
->x
; 
 114         rect
.right 
= rectBound
->x 
+ rectBound
->width
; 
 115         rect
.bottom 
= rectBound
->y 
+ rectBound
->height
; 
 119         wxSize size 
= GetSize(); 
 124         rect
.bottom 
= size
.y
; 
 127     if ( !::PlayEnhMetaFile(GetHdcOf(*dc
), GetEMF(), &rect
) ) 
 129         wxLogLastError(_T("PlayEnhMetaFile")); 
 137 wxSize 
wxEnhMetaFile::GetSize() const 
 139     wxSize size 
= wxDefaultSize
; 
 144         if ( !::GetEnhMetaFileHeader(GetEMF(), sizeof(hdr
), &hdr
) ) 
 146             wxLogLastError(_T("GetEnhMetaFileHeader")); 
 150             // the width and height are in HIMETRIC (0.01mm) units, transform 
 152             LONG w 
= hdr
.rclFrame
.right
, 
 153                  h 
= hdr
.rclFrame
.bottom
; 
 155             HIMETRICToPixel(&w
, &h
); 
 165 bool wxEnhMetaFile::SetClipboard(int WXUNUSED(width
), int WXUNUSED(height
)) 
 167 #if wxUSE_DRAG_AND_DROP 
 168     wxCHECK_MSG( m_hMF
, FALSE
, _T("can't copy invalid metafile to clipboard") ); 
 170     return wxTheClipboard
->AddData(new wxEnhMetaFileDataObject(*this)); 
 171 #else // !wxUSE_DRAG_AND_DROP 
 172     wxFAIL_MSG(_T("not implemented")); 
 174 #endif // wxUSE_DRAG_AND_DROP/!wxUSE_DRAG_AND_DROP 
 177 // ---------------------------------------------------------------------------- 
 179 // ---------------------------------------------------------------------------- 
 181 wxEnhMetaFileDC::wxEnhMetaFileDC(const wxString
& filename
, 
 182                                  int width
, int height
, 
 183                                  const wxString
& description
) 
 188     if ( width 
&& height 
) 
 193         rect
.bottom 
= height
; 
 195         // CreateEnhMetaFile() wants them in HIMETRIC 
 196         PixelToHIMETRIC(&rect
.right
, &rect
.bottom
); 
 202         // GDI will try to find out the size for us (not recommended) 
 203         pRect 
= (LPRECT
)NULL
; 
 206     m_hDC 
= (WXHDC
)::CreateEnhMetaFile(hdcRef
, GetMetaFileName(filename
), 
 210         wxLogLastError(_T("CreateEnhMetaFile")); 
 214 wxEnhMetaFile 
*wxEnhMetaFileDC::Close() 
 216     wxCHECK_MSG( Ok(), NULL
, _T("invalid wxEnhMetaFileDC") ); 
 218     HENHMETAFILE hMF 
= ::CloseEnhMetaFile(GetHdc()); 
 221         wxLogLastError(_T("CloseEnhMetaFile")); 
 226     wxEnhMetaFile 
*mf 
= new wxEnhMetaFile
; 
 227     mf
->SetHENHMETAFILE((WXHANDLE
)hMF
); 
 231 wxEnhMetaFileDC::~wxEnhMetaFileDC() 
 233     // avoid freeing it in the base class dtor 
 237 #if wxUSE_DRAG_AND_DROP 
 239 // ---------------------------------------------------------------------------- 
 240 // wxEnhMetaFileDataObject 
 241 // ---------------------------------------------------------------------------- 
 244 wxEnhMetaFileDataObject::GetPreferredFormat(Direction 
WXUNUSED(dir
)) const 
 246     return wxDF_ENHMETAFILE
; 
 249 size_t wxEnhMetaFileDataObject::GetFormatCount(Direction 
WXUNUSED(dir
)) const 
 251     // wxDF_ENHMETAFILE and wxDF_METAFILE 
 255 void wxEnhMetaFileDataObject::GetAllFormats(wxDataFormat 
*formats
, 
 256                                             Direction 
WXUNUSED(dir
)) const 
 258     formats
[0] = wxDF_ENHMETAFILE
; 
 259     formats
[1] = wxDF_METAFILE
; 
 262 size_t wxEnhMetaFileDataObject::GetDataSize(const wxDataFormat
& format
) const 
 264     if ( format 
== wxDF_ENHMETAFILE 
) 
 266         // we pass data by handle and not HGLOBAL 
 271         wxASSERT_MSG( format 
== wxDF_METAFILE
, _T("unsupported format") ); 
 273         return sizeof(METAFILEPICT
); 
 277 bool wxEnhMetaFileDataObject::GetDataHere(const wxDataFormat
& format
, void *buf
) const 
 279     wxCHECK_MSG( m_metafile
.Ok(), FALSE
, _T("copying invalid enh metafile") ); 
 281     HENHMETAFILE hEMF 
= (HENHMETAFILE
)m_metafile
.GetHENHMETAFILE(); 
 283     if ( format 
== wxDF_ENHMETAFILE 
) 
 285         HENHMETAFILE hEMFCopy 
= ::CopyEnhMetaFile(hEMF
, NULL
); 
 288             wxLogLastError(_T("CopyEnhMetaFile")); 
 293         *(HENHMETAFILE 
*)buf 
= hEMFCopy
; 
 297         wxASSERT_MSG( format 
== wxDF_METAFILE
, _T("unsupported format") ); 
 303         // first get the buffer size and alloc memory 
 304         size_t size 
= ::GetWinMetaFileBits(hEMF
, 0, NULL
, MM_ANISOTROPIC
, hdc
); 
 305         wxCHECK_MSG( size
, FALSE
, _T("GetWinMetaFileBits() failed") ); 
 307         BYTE 
*bits 
= (BYTE 
*)malloc(size
); 
 309         // then get the enh metafile bits 
 310         if ( !::GetWinMetaFileBits(hEMF
, size
, bits
, MM_ANISOTROPIC
, hdc
) ) 
 312             wxLogLastError(_T("GetWinMetaFileBits")); 
 319         // and finally convert them to the WMF 
 320         HMETAFILE hMF 
= ::SetMetaFileBitsEx(size
, bits
); 
 324             wxLogLastError(_T("SetMetaFileBitsEx")); 
 329         METAFILEPICT 
*mfpict 
= (METAFILEPICT 
*)buf
; 
 331         wxSize sizeMF 
= m_metafile
.GetSize(); 
 333         mfpict
->mm   
= MM_ANISOTROPIC
; 
 334         mfpict
->xExt 
= sizeMF
.x
; 
 335         mfpict
->yExt 
= sizeMF
.y
; 
 337         PixelToHIMETRIC(&mfpict
->xExt
, &mfpict
->yExt
); 
 343 bool wxEnhMetaFileDataObject::SetData(const wxDataFormat
& format
, 
 344                                       size_t WXUNUSED(len
), 
 349     if ( format 
== wxDF_ENHMETAFILE 
) 
 351         hEMF 
= *(HENHMETAFILE 
*)buf
; 
 353         wxCHECK_MSG( hEMF
, FALSE
, _T("pasting invalid enh metafile") ); 
 357         wxASSERT_MSG( format 
== wxDF_METAFILE
, _T("unsupported format") ); 
 360         const METAFILEPICT 
*mfpict 
= (const METAFILEPICT 
*)buf
; 
 362         // first get the buffer size 
 363         size_t size 
= ::GetMetaFileBitsEx(mfpict
->hMF
, 0, NULL
); 
 364         wxCHECK_MSG( size
, FALSE
, _T("GetMetaFileBitsEx() failed") ); 
 366         // then get metafile bits 
 367         BYTE 
*bits 
= (BYTE 
*)malloc(size
); 
 368         if ( !::GetMetaFileBitsEx(mfpict
->hMF
, size
, bits
) ) 
 370             wxLogLastError(_T("GetMetaFileBitsEx")); 
 379         // and finally create an enhanced metafile from them 
 380         hEMF 
= ::SetWinMetaFileBits(size
, bits
, hdcRef
, mfpict
); 
 384             wxLogLastError(_T("SetWinMetaFileBits")); 
 390     m_metafile
.SetHENHMETAFILE((WXHANDLE
)hEMF
); 
 395 // ---------------------------------------------------------------------------- 
 396 // wxEnhMetaFileSimpleDataObject 
 397 // ---------------------------------------------------------------------------- 
 399 size_t wxEnhMetaFileSimpleDataObject::GetDataSize() const 
 401     // we pass data by handle and not HGLOBAL 
 405 bool wxEnhMetaFileSimpleDataObject::GetDataHere(void *buf
) const 
 407     wxCHECK_MSG( m_metafile
.Ok(), FALSE
, _T("copying invalid enh metafile") ); 
 409     HENHMETAFILE hEMF 
= (HENHMETAFILE
)m_metafile
.GetHENHMETAFILE(); 
 411     HENHMETAFILE hEMFCopy 
= ::CopyEnhMetaFile(hEMF
, NULL
); 
 414         wxLogLastError(_T("CopyEnhMetaFile")); 
 419     *(HENHMETAFILE 
*)buf 
= hEMFCopy
; 
 423 bool wxEnhMetaFileSimpleDataObject::SetData(size_t WXUNUSED(len
), 
 426     HENHMETAFILE hEMF 
= *(HENHMETAFILE 
*)buf
; 
 428     wxCHECK_MSG( hEMF
, FALSE
, _T("pasting invalid enh metafile") ); 
 429     m_metafile
.SetHENHMETAFILE((WXHANDLE
)hEMF
); 
 435 #endif // wxUSE_DRAG_AND_DROP 
 437 #endif // wxUSE_ENH_METAFILE