From 265b0c070b7531a31d79e79fd44142f5a807b23d Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 7 Jan 2000 02:30:29 +0000 Subject: [PATCH] attempts at providing clipboard/dnd support for metafiles - unsuccessful git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@5283 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/msw/metafile.h | 197 +++++++------- src/msw/clipbrd.cpp | 16 +- src/msw/metafile.cpp | 534 +++++++++++++++++++++----------------- src/msw/ole/dataobj.cpp | 38 +-- 4 files changed, 438 insertions(+), 347 deletions(-) diff --git a/include/wx/msw/metafile.h b/include/wx/msw/metafile.h index ec1237bf29..f6381d489e 100644 --- a/include/wx/msw/metafile.h +++ b/include/wx/msw/metafile.h @@ -1,39 +1,42 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: metafile.h -// Purpose: wxMetaFile, wxMetaFileDC classes +// Name: wx/msw/metafile.h +// Purpose: wxMetaFile, wxMetaFileDC and wxMetaFileDataObject classes // Author: Julian Smart -// Modified by: +// Modified by: VZ 07.01.00: implemented wxMetaFileDataObject // Created: 01/02/97 // RCS-ID: $Id$ // Copyright: (c) Julian Smart -// Licence: wxWindows licence +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// - #ifndef _WX_METAFIILE_H_ #define _WX_METAFIILE_H_ #ifdef __GNUG__ -#pragma interface "metafile.h" + #pragma interface "metafile.h" #endif #include "wx/setup.h" #if wxUSE_METAFILE + #include "wx/dc.h" #include "wx/gdiobj.h" #if wxUSE_DRAG_AND_DROP -#include "wx/dataobj.h" + #include "wx/dataobj.h" #endif -/* - * Metafile and metafile device context classes - * - */ - +// provide synonyms for all metafile classes #define wxMetaFile wxMetafile #define wxMetaFileDC wxMetafileDC +#define wxMetaFileDataObject wxMetafileDataObject + +#define wxMakeMetaFilePlaceable wxMakeMetafilePlaceable + +// ---------------------------------------------------------------------------- +// Metafile and metafile device context classes +// ---------------------------------------------------------------------------- class WXDLLEXPORT wxMetafile; @@ -41,79 +44,88 @@ class WXDLLEXPORT wxMetafileRefData: public wxGDIRefData { friend class WXDLLEXPORT wxMetafile; public: - wxMetafileRefData(void); - ~wxMetafileRefData(void); + wxMetafileRefData(); + ~wxMetafileRefData(); public: WXHANDLE m_metafile; int m_windowsMappingMode; + int m_width, m_height; }; #define M_METAFILEDATA ((wxMetafileRefData *)m_refData) class WXDLLEXPORT wxMetafile: public wxGDIObject { - DECLARE_DYNAMIC_CLASS(wxMetafile) - public: - // Copy constructor - inline wxMetafile(const wxMetafile& metafile) - { Ref(metafile); } - - wxMetafile(const wxString& file = ""); - ~wxMetafile(void); - - // After this is called, the metafile cannot be used for anything - // since it is now owned by the clipboard. - virtual bool SetClipboard(int width = 0, int height = 0); - - virtual bool Play(wxDC *dc); - inline bool Ok(void) const { return (M_METAFILEDATA && (M_METAFILEDATA->m_metafile != 0)); }; - - // Implementation - inline WXHANDLE GetHMETAFILE(void) { return M_METAFILEDATA->m_metafile; } - void SetHMETAFILE(WXHANDLE mf) ; - inline int GetWindowsMappingMode(void) { return M_METAFILEDATA->m_windowsMappingMode; } - void SetWindowsMappingMode(int mm); - - // Operators - inline wxMetafile& operator = (const wxMetafile& metafile) { if (*this == metafile) return (*this); Ref(metafile); return *this; } - inline bool operator == (const wxMetafile& metafile) { return m_refData == metafile.m_refData; } - inline bool operator != (const wxMetafile& metafile) { return m_refData != metafile.m_refData; } +public: + wxMetafile(const wxString& file = wxEmptyString); + wxMetafile(const wxMetafile& metafile) { Ref(metafile); } + virtual ~wxMetafile(); + + // After this is called, the metafile cannot be used for anything + // since it is now owned by the clipboard. + virtual bool SetClipboard(int width = 0, int height = 0); + + virtual bool Play(wxDC *dc); + bool Ok() const { return (M_METAFILEDATA && (M_METAFILEDATA->m_metafile != 0)); }; + + // set/get the size of metafile for clipboard operations + int GetWidth() const { return M_METAFILEDATA->m_width; } + int GetHeight() const { return M_METAFILEDATA->m_height; } + + void SetWidth(int width) { M_METAFILEDATA->m_width = width; } + void SetHeight(int height) { M_METAFILEDATA->m_height = height; } + + // Implementation + WXHANDLE GetHMETAFILE() const { return M_METAFILEDATA->m_metafile; } + void SetHMETAFILE(WXHANDLE mf) ; + int GetWindowsMappingMode() const { return M_METAFILEDATA->m_windowsMappingMode; } + void SetWindowsMappingMode(int mm); + + // Operators + wxMetafile& operator=(const wxMetafile& metafile) + { if (*this != metafile) Ref(metafile); return *this; } + bool operator==(const wxMetafile& metafile) const + { return m_refData == metafile.m_refData; } + bool operator!=(const wxMetafile& metafile) const + { return m_refData != metafile.m_refData; } -protected: +private: + DECLARE_DYNAMIC_CLASS(wxMetafile) }; class WXDLLEXPORT wxMetafileDC: public wxDC { - DECLARE_DYNAMIC_CLASS(wxMetafileDC) - - public: - // Don't supply origin and extent - // Supply them to wxMakeMetaFilePlaceable instead. - wxMetafileDC(const wxString& file = ""); +public: + // Don't supply origin and extent + // Supply them to wxMakeMetaFilePlaceable instead. + wxMetafileDC(const wxString& file = ""); - // Supply origin and extent (recommended). - // Then don't need to supply them to wxMakeMetaFilePlaceable. - wxMetafileDC(const wxString& file, int xext, int yext, int xorg, int yorg); + // Supply origin and extent (recommended). + // Then don't need to supply them to wxMakeMetaFilePlaceable. + wxMetafileDC(const wxString& file, int xext, int yext, int xorg, int yorg); - ~wxMetafileDC(void); + virtual ~wxMetafileDC(); - // Should be called at end of drawing - virtual wxMetafile *Close(void); - virtual void SetMapMode(int mode); - virtual void GetTextExtent(const wxString& string, long *x, long *y, - long *descent = NULL, long *externalLeading = NULL, - wxFont *theFont = NULL, bool use16bit = FALSE) const; + // Should be called at end of drawing + virtual wxMetafile *Close(); + virtual void SetMapMode(int mode); + virtual void GetTextExtent(const wxString& string, long *x, long *y, + long *descent = NULL, long *externalLeading = NULL, + wxFont *theFont = NULL, bool use16bit = FALSE) const; - // Implementation - inline wxMetafile *GetMetaFile(void) const { return m_metaFile; } - inline void SetMetaFile(wxMetafile *mf) { m_metaFile = mf; } - inline int GetWindowsMappingMode(void) const { return m_windowsMappingMode; } - inline void SetWindowsMappingMode(int mm) { m_windowsMappingMode = mm; } + // Implementation + wxMetafile *GetMetaFile() const { return m_metaFile; } + void SetMetaFile(wxMetafile *mf) { m_metaFile = mf; } + int GetWindowsMappingMode() const { return m_windowsMappingMode; } + void SetWindowsMappingMode(int mm) { m_windowsMappingMode = mm; } protected: - int m_windowsMappingMode; - wxMetafile* m_metaFile; + int m_windowsMappingMode; + wxMetafile* m_metaFile; + +private: + DECLARE_DYNAMIC_CLASS(wxMetafileDC) }; /* @@ -124,7 +136,6 @@ protected: */ // No origin or extent -#define wxMakeMetaFilePlaceable wxMakeMetafilePlaceable bool WXDLLEXPORT wxMakeMetafilePlaceable(const wxString& filename, float scale = 1.0); // Optional origin and extent @@ -134,44 +145,34 @@ bool WXDLLEXPORT wxMakeMetaFilePlaceable(const wxString& filename, int x1, int y // wxMetafileDataObject is a specialization of wxDataObject for metafile data // ---------------------------------------------------------------------------- -// TODO: implement OLE side of things. At present, it's just for clipboard -// use. - #if wxUSE_DRAG_AND_DROP -class WXDLLEXPORT wxMetafileDataObject : public wxDataObject + +class WXDLLEXPORT wxMetafileDataObject : public wxDataObjectSimple { public: - // ctors - wxMetafileDataObject() { m_width = 0; m_height = 0; }; - wxMetafileDataObject(const wxMetafile& metafile, int width = 0, int height = 0): - m_metafile(metafile), m_width(width), m_height(height) { } - - void SetMetafile(const wxMetafile& metafile, int w = 0, int h = 0) - { m_metafile = metafile; m_width = w; m_height = h; } - wxMetafile GetMetafile() const { return m_metafile; } - int GetWidth() const { return m_width; } - int GetHeight() const { return m_height; } - - virtual wxDataFormat GetFormat() const { return wxDF_METAFILE; } - -/* ?? - // implement base class pure virtuals - virtual wxDataFormat GetPreferredFormat() const - { return (wxDataFormat) wxDataObject::Text; } - virtual bool IsSupportedFormat(wxDataFormat format) const - { return format == wxDataObject::Text || format == wxDataObject::Locale; } - virtual size_t GetDataSize() const - { return m_strText.Len() + 1; } // +1 for trailing '\0'of course - virtual void GetDataHere(void *pBuf) const - { memcpy(pBuf, m_strText.c_str(), GetDataSize()); } -*/ + // ctors + wxMetafileDataObject() : wxDataObjectSimple(wxDF_METAFILE) + { } + wxMetafileDataObject(const wxMetafile& metafile) + : wxDataObjectSimple(wxDF_METAFILE), m_metafile(metafile) { } + + // virtual functions which you may override if you want to provide data on + // demand only - otherwise, the trivial default versions will be used + virtual void SetMetafile(const wxMetafile& metafile) + { m_metafile = metafile; } + virtual wxMetafile GetMetafile() const + { return m_metafile; } + + // implement base class pure virtuals + virtual size_t GetDataSize() const; + virtual bool GetDataHere(void *buf) const; + virtual bool SetData(size_t len, const void *buf); -private: - wxMetafile m_metafile; - int m_width; - int m_height; +protected: + wxMetafile m_metafile; }; -#endif + +#endif // wxUSE_DRAG_AND_DROP #endif // wxUSE_METAFILE #endif diff --git a/src/msw/clipbrd.cpp b/src/msw/clipbrd.cpp index bb12806233..e02807caaa 100644 --- a/src/msw/clipbrd.cpp +++ b/src/msw/clipbrd.cpp @@ -670,7 +670,6 @@ bool wxClipboard::GetData( wxDataObject& data ) formatEtc.ptd = NULL; formatEtc.dwAspect = DVASPECT_CONTENT; formatEtc.lindex = -1; - formatEtc.tymed = TYMED_HGLOBAL; size_t nSupportedFormats = supportedFormats.GetCount(); for ( size_t n = 0; !result && (n < nSupportedFormats); n++ ) @@ -678,6 +677,21 @@ bool wxClipboard::GetData( wxDataObject& data ) STGMEDIUM medium; formatEtc.cfFormat = supportedFormats[n]; + // use the appropriate tymed + switch ( formatEtc.cfFormat ) + { + case CF_BITMAP: + formatEtc.tymed = TYMED_GDI; + break; + + case CF_METAFILEPICT: + formatEtc.tymed = TYMED_MFPICT; + break; + + default: + formatEtc.tymed = TYMED_HGLOBAL; + } + // try to get data hr = pDataObject->GetData(&formatEtc, &medium); if ( FAILED(hr) ) diff --git a/src/msw/metafile.cpp b/src/msw/metafile.cpp index 373a1400fd..a49e59a0ba 100644 --- a/src/msw/metafile.cpp +++ b/src/msw/metafile.cpp @@ -1,34 +1,42 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: metafile.cpp +// Name: msw/metafile.cpp // Purpose: wxMetafileDC etc. // Author: Julian Smart -// Modified by: +// Modified by: VZ 07.01.00: implemented wxMetaFileDataObject // Created: 04/01/98 // RCS-ID: $Id$ // Copyright: (c) Julian Smart and Markus Holzem -// Licence: wxWindows license +// Licence: wxWindows license ///////////////////////////////////////////////////////////////////////////// +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + #ifdef __GNUG__ -#pragma implementation "metafile.h" + #pragma implementation "metafile.h" #endif // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" #ifdef __BORLANDC__ -#pragma hdrstop + #pragma hdrstop #endif #ifndef WX_PRECOMP -#include "wx/setup.h" + #include "wx/setup.h" #endif #if wxUSE_METAFILE #ifndef WX_PRECOMP -#include "wx/utils.h" -#include "wx/app.h" + #include "wx/utils.h" + #include "wx/app.h" #endif #include "wx/metafile.h" @@ -38,24 +46,35 @@ #include #include -extern bool wxClipboardIsOpen; +// ---------------------------------------------------------------------------- +// wxWin macros +// ---------------------------------------------------------------------------- IMPLEMENT_DYNAMIC_CLASS(wxMetafile, wxObject) IMPLEMENT_ABSTRACT_CLASS(wxMetafileDC, wxDC) +// ============================================================================ +// implementation +// ============================================================================ + +// ---------------------------------------------------------------------------- +// wxMetafileRefData +// ---------------------------------------------------------------------------- + /* * Metafiles * Currently, the only purpose for making a metafile is to put * it on the clipboard. */ -wxMetafileRefData::wxMetafileRefData(void) +wxMetafileRefData::wxMetafileRefData() { m_metafile = 0; m_windowsMappingMode = wxMM_ANISOTROPIC; + m_width = m_height = 0; } -wxMetafileRefData::~wxMetafileRefData(void) +wxMetafileRefData::~wxMetafileRefData() { if (m_metafile) { @@ -64,6 +83,10 @@ wxMetafileRefData::~wxMetafileRefData(void) } } +// ---------------------------------------------------------------------------- +// wxMetafile +// ---------------------------------------------------------------------------- + wxMetafile::wxMetafile(const wxString& file) { m_refData = new wxMetafileRefData; @@ -74,7 +97,7 @@ wxMetafile::wxMetafile(const wxString& file) M_METAFILEDATA->m_metafile = (WXHANDLE) GetMetaFile(file); } -wxMetafile::~wxMetafile(void) +wxMetafile::~wxMetafile() { } @@ -83,15 +106,18 @@ bool wxMetafile::SetClipboard(int width, int height) if (!m_refData) return FALSE; - bool alreadyOpen=wxClipboardOpen(); + bool alreadyOpen = wxClipboardOpen(); if (!alreadyOpen) { wxOpenClipboard(); - if (!wxEmptyClipboard()) return FALSE; + if (!wxEmptyClipboard()) + return FALSE; } bool success = wxSetClipboardData(wxDF_METAFILE, this, width,height); - if (!alreadyOpen) wxCloseClipboard(); - return (bool) success; + if (!alreadyOpen) + wxCloseClipboard(); + + return success; } bool wxMetafile::Play(wxDC *dc) @@ -102,7 +128,7 @@ bool wxMetafile::Play(wxDC *dc) dc->BeginDrawing(); if (dc->GetHDC() && M_METAFILEDATA->m_metafile) - PlayMetaFile((HDC) dc->GetHDC(), (HMETAFILE) M_METAFILEDATA->m_metafile); + PlayMetaFile(GetHdcOf(*dc), (HMETAFILE) M_METAFILEDATA->m_metafile); dc->EndDrawing(); @@ -111,7 +137,7 @@ bool wxMetafile::Play(wxDC *dc) void wxMetafile::SetHMETAFILE(WXHANDLE mf) { - if (m_refData) + if (!m_refData) m_refData = new wxMetafileRefData; M_METAFILEDATA->m_metafile = mf; @@ -119,162 +145,166 @@ void wxMetafile::SetHMETAFILE(WXHANDLE mf) void wxMetafile::SetWindowsMappingMode(int mm) { - if (m_refData) + if (!m_refData) m_refData = new wxMetafileRefData; M_METAFILEDATA->m_windowsMappingMode = mm; } -/* - * Metafile device context - * - */ +// ---------------------------------------------------------------------------- +// Metafile device context +// ---------------------------------------------------------------------------- // Original constructor that does not takes origin and extent. If you use this, // *DO* give origin/extent arguments to wxMakeMetafilePlaceable. wxMetafileDC::wxMetafileDC(const wxString& file) { - m_metaFile = NULL; - m_minX = 10000; - m_minY = 10000; - m_maxX = -10000; - m_maxY = -10000; -// m_title = NULL; + m_metaFile = NULL; + m_minX = 10000; + m_minY = 10000; + m_maxX = -10000; + m_maxY = -10000; + // m_title = NULL; - if (!file.IsNull() && wxFileExists(file)) - wxRemoveFile(file); + if (!file.IsNull() && wxFileExists(file)) + wxRemoveFile(file); - if (!file.IsNull() && (file != wxT(""))) - m_hDC = (WXHDC) CreateMetaFile(file); - else - m_hDC = (WXHDC) CreateMetaFile(NULL); + if (!file.IsNull() && (file != wxT(""))) + m_hDC = (WXHDC) CreateMetaFile(file); + else + m_hDC = (WXHDC) CreateMetaFile(NULL); - m_ok = (m_hDC != (WXHDC) 0) ; + m_ok = (m_hDC != (WXHDC) 0) ; - // Actual Windows mapping mode, for future reference. - m_windowsMappingMode = wxMM_TEXT; + // Actual Windows mapping mode, for future reference. + m_windowsMappingMode = wxMM_TEXT; - SetMapMode(wxMM_TEXT); // NOTE: does not set HDC mapmode (this is correct) + SetMapMode(wxMM_TEXT); // NOTE: does not set HDC mapmode (this is correct) } // New constructor that takes origin and extent. If you use this, don't // give origin/extent arguments to wxMakeMetafilePlaceable. wxMetafileDC::wxMetafileDC(const wxString& file, int xext, int yext, int xorg, int yorg) { - m_minX = 10000; - m_minY = 10000; - m_maxX = -10000; - m_maxY = -10000; - if (file != wxT("") && wxFileExists(file)) wxRemoveFile(file); - m_hDC = (WXHDC) CreateMetaFile(file); + m_minX = 10000; + m_minY = 10000; + m_maxX = -10000; + m_maxY = -10000; + if ( !!file && wxFileExists(file)) + wxRemoveFile(file); + m_hDC = (WXHDC) CreateMetaFile(file); - m_ok = TRUE; + m_ok = TRUE; - ::SetWindowOrgEx((HDC) m_hDC,xorg,yorg, NULL); - ::SetWindowExtEx((HDC) m_hDC,xext,yext, NULL); + ::SetWindowOrgEx((HDC) m_hDC,xorg,yorg, NULL); + ::SetWindowExtEx((HDC) m_hDC,xext,yext, NULL); - // Actual Windows mapping mode, for future reference. - m_windowsMappingMode = wxMM_ANISOTROPIC; + // Actual Windows mapping mode, for future reference. + m_windowsMappingMode = wxMM_ANISOTROPIC; - SetMapMode(wxMM_TEXT); // NOTE: does not set HDC mapmode (this is correct) + SetMapMode(wxMM_TEXT); // NOTE: does not set HDC mapmode (this is correct) } -wxMetafileDC::~wxMetafileDC(void) +wxMetafileDC::~wxMetafileDC() { - m_hDC = 0; + m_hDC = 0; } void wxMetafileDC::GetTextExtent(const wxString& string, long *x, long *y, long *descent, long *externalLeading, wxFont *theFont, bool use16bit) const { - wxFont *fontToUse = theFont; - if (!fontToUse) - fontToUse = (wxFont*) &m_font; - - HDC dc = GetDC(NULL); - - SIZE sizeRect; - TEXTMETRIC tm; - GetTextExtentPoint(dc, WXSTRINGCAST string, wxStrlen(WXSTRINGCAST string), &sizeRect); - GetTextMetrics(dc, &tm); - - ReleaseDC(NULL, dc); - - if ( x ) - *x = sizeRect.cx; - if ( y ) - *y = sizeRect.cy; - if ( descent ) - *descent = tm.tmDescent; - if ( externalLeading ) - *externalLeading = tm.tmExternalLeading; + wxFont *fontToUse = theFont; + if (!fontToUse) + fontToUse = (wxFont*) &m_font; + + HDC dc = GetDC(NULL); + + SIZE sizeRect; + TEXTMETRIC tm; + GetTextExtentPoint(dc, WXSTRINGCAST string, wxStrlen(WXSTRINGCAST string), &sizeRect); + GetTextMetrics(dc, &tm); + + ReleaseDC(NULL, dc); + + if ( x ) + *x = sizeRect.cx; + if ( y ) + *y = sizeRect.cy; + if ( descent ) + *descent = tm.tmDescent; + if ( externalLeading ) + *externalLeading = tm.tmExternalLeading; } -wxMetafile *wxMetafileDC::Close(void) +wxMetafile *wxMetafileDC::Close() { - SelectOldObjects(m_hDC); - HANDLE mf = CloseMetaFile((HDC) m_hDC); - m_hDC = 0; - if (mf) - { - wxMetafile *wx_mf = new wxMetafile; - wx_mf->SetHMETAFILE((WXHANDLE) mf); - wx_mf->SetWindowsMappingMode(m_windowsMappingMode); - return wx_mf; - } - return NULL; + SelectOldObjects(m_hDC); + HANDLE mf = CloseMetaFile((HDC) m_hDC); + m_hDC = 0; + if (mf) + { + wxMetafile *wx_mf = new wxMetafile; + wx_mf->SetHMETAFILE((WXHANDLE) mf); + wx_mf->SetWindowsMappingMode(m_windowsMappingMode); + return wx_mf; + } + return NULL; } void wxMetafileDC::SetMapMode(int mode) { - m_mappingMode = mode; + m_mappingMode = mode; -// int pixel_width = 0; -// int pixel_height = 0; -// int mm_width = 0; -// int mm_height = 0; + // int pixel_width = 0; + // int pixel_height = 0; + // int mm_width = 0; + // int mm_height = 0; - float mm2pixelsX = 10.0; - float mm2pixelsY = 10.0; + float mm2pixelsX = 10.0; + float mm2pixelsY = 10.0; - switch (mode) - { - case wxMM_TWIPS: - { - m_logicalScaleX = (float)(twips2mm * mm2pixelsX); - m_logicalScaleY = (float)(twips2mm * mm2pixelsY); - break; - } - case wxMM_POINTS: - { - m_logicalScaleX = (float)(pt2mm * mm2pixelsX); - m_logicalScaleY = (float)(pt2mm * mm2pixelsY); - break; - } - case wxMM_METRIC: - { - m_logicalScaleX = mm2pixelsX; - m_logicalScaleY = mm2pixelsY; - break; - } - case wxMM_LOMETRIC: + switch (mode) { - m_logicalScaleX = (float)(mm2pixelsX/10.0); - m_logicalScaleY = (float)(mm2pixelsY/10.0); - break; + case wxMM_TWIPS: + { + m_logicalScaleX = (float)(twips2mm * mm2pixelsX); + m_logicalScaleY = (float)(twips2mm * mm2pixelsY); + break; + } + case wxMM_POINTS: + { + m_logicalScaleX = (float)(pt2mm * mm2pixelsX); + m_logicalScaleY = (float)(pt2mm * mm2pixelsY); + break; + } + case wxMM_METRIC: + { + m_logicalScaleX = mm2pixelsX; + m_logicalScaleY = mm2pixelsY; + break; + } + case wxMM_LOMETRIC: + { + m_logicalScaleX = (float)(mm2pixelsX/10.0); + m_logicalScaleY = (float)(mm2pixelsY/10.0); + break; + } + default: + case wxMM_TEXT: + { + m_logicalScaleX = 1.0; + m_logicalScaleY = 1.0; + break; + } } - default: - case wxMM_TEXT: - { - m_logicalScaleX = 1.0; - m_logicalScaleY = 1.0; - break; - } - } - m_windowExtX = 100; - m_windowExtY = 100; + m_windowExtX = 100; + m_windowExtY = 100; } +// ---------------------------------------------------------------------------- +// wxMakeMetafilePlaceable +// ---------------------------------------------------------------------------- + #ifdef __WIN32__ struct RECT32 { @@ -285,21 +315,21 @@ struct RECT32 }; struct mfPLACEABLEHEADER { - DWORD key; - short hmf; - RECT32 bbox; - WORD inch; - DWORD reserved; - WORD checksum; + DWORD key; + short hmf; + RECT32 bbox; + WORD inch; + DWORD reserved; + WORD checksum; }; #else struct mfPLACEABLEHEADER { - DWORD key; - HANDLE hmf; - RECT bbox; - WORD inch; - DWORD reserved; - WORD checksum; + DWORD key; + HANDLE hmf; + RECT bbox; + WORD inch; + DWORD reserved; + WORD checksum; }; #endif @@ -309,7 +339,7 @@ struct mfPLACEABLEHEADER { * and sets the window origin and extent to mimic the wxMM_TEXT mapping mode. * */ - + bool wxMakeMetafilePlaceable(const wxString& filename, float scale) { return wxMakeMetafilePlaceable(filename, 0, 0, 0, 0, scale, FALSE); @@ -317,100 +347,140 @@ bool wxMakeMetafilePlaceable(const wxString& filename, float scale) bool wxMakeMetafilePlaceable(const wxString& filename, int x1, int y1, int x2, int y2, float scale, bool useOriginAndExtent) { - // I'm not sure if this is the correct way of suggesting a scale - // to the client application, but it's the only way I can find. - int unitsPerInch = (int)(576/scale); - - mfPLACEABLEHEADER header; - header.key = 0x9AC6CDD7L; - header.hmf = 0; - header.bbox.left = (int)(x1); - header.bbox.top = (int)(y1); - header.bbox.right = (int)(x2); - header.bbox.bottom = (int)(y2); - header.inch = unitsPerInch; - header.reserved = 0; - - // Calculate checksum - WORD *p; - mfPLACEABLEHEADER *pMFHead = &header; - for (p =(WORD *)pMFHead,pMFHead -> checksum = 0; - p < (WORD *)&pMFHead ->checksum; ++p) - pMFHead ->checksum ^= *p; - - FILE *fd = fopen(filename.fn_str(), "rb"); - if (!fd) return FALSE; - - wxChar tempFileBuf[256]; - wxGetTempFileName(wxT("mf"), tempFileBuf); - FILE *fHandle = fopen(wxConvFile.cWX2MB(tempFileBuf), "wb"); - if (!fHandle) - return FALSE; - fwrite((void *)&header, sizeof(unsigned char), sizeof(mfPLACEABLEHEADER), fHandle); - - // Calculate origin and extent - int originX = x1; - int originY = y1; - int extentX = x2 - x1; - int extentY = (y2 - y1); - - // Read metafile header and write - METAHEADER metaHeader; - fread((void *)&metaHeader, sizeof(unsigned char), sizeof(metaHeader), fd); - - if (useOriginAndExtent) - metaHeader.mtSize += 15; - else - metaHeader.mtSize += 5; - - fwrite((void *)&metaHeader, sizeof(unsigned char), sizeof(metaHeader), fHandle); - - // Write SetMapMode, SetWindowOrigin and SetWindowExt records - char modeBuffer[8]; - char originBuffer[10]; - char extentBuffer[10]; - METARECORD *modeRecord = (METARECORD *)&modeBuffer; - - METARECORD *originRecord = (METARECORD *)&originBuffer; - METARECORD *extentRecord = (METARECORD *)&extentBuffer; - - modeRecord->rdSize = 4; - modeRecord->rdFunction = META_SETMAPMODE; - modeRecord->rdParm[0] = MM_ANISOTROPIC; - - originRecord->rdSize = 5; - originRecord->rdFunction = META_SETWINDOWORG; - originRecord->rdParm[0] = originY; - originRecord->rdParm[1] = originX; - - extentRecord->rdSize = 5; - extentRecord->rdFunction = META_SETWINDOWEXT; - extentRecord->rdParm[0] = extentY; - extentRecord->rdParm[1] = extentX; - - fwrite((void *)modeBuffer, sizeof(char), 8, fHandle); - - if (useOriginAndExtent) - { - fwrite((void *)originBuffer, sizeof(char), 10, fHandle); - fwrite((void *)extentBuffer, sizeof(char), 10, fHandle); - } - - int ch = -2; - while (ch != EOF) - { - ch = getc(fd); - if (ch != EOF) + // I'm not sure if this is the correct way of suggesting a scale + // to the client application, but it's the only way I can find. + int unitsPerInch = (int)(576/scale); + + mfPLACEABLEHEADER header; + header.key = 0x9AC6CDD7L; + header.hmf = 0; + header.bbox.left = (int)(x1); + header.bbox.top = (int)(y1); + header.bbox.right = (int)(x2); + header.bbox.bottom = (int)(y2); + header.inch = unitsPerInch; + header.reserved = 0; + + // Calculate checksum + WORD *p; + mfPLACEABLEHEADER *pMFHead = &header; + for (p =(WORD *)pMFHead,pMFHead -> checksum = 0; + p < (WORD *)&pMFHead ->checksum; ++p) + pMFHead ->checksum ^= *p; + + FILE *fd = fopen(filename.fn_str(), "rb"); + if (!fd) return FALSE; + + wxChar tempFileBuf[256]; + wxGetTempFileName(wxT("mf"), tempFileBuf); + FILE *fHandle = fopen(wxConvFile.cWX2MB(tempFileBuf), "wb"); + if (!fHandle) + return FALSE; + fwrite((void *)&header, sizeof(unsigned char), sizeof(mfPLACEABLEHEADER), fHandle); + + // Calculate origin and extent + int originX = x1; + int originY = y1; + int extentX = x2 - x1; + int extentY = (y2 - y1); + + // Read metafile header and write + METAHEADER metaHeader; + fread((void *)&metaHeader, sizeof(unsigned char), sizeof(metaHeader), fd); + + if (useOriginAndExtent) + metaHeader.mtSize += 15; + else + metaHeader.mtSize += 5; + + fwrite((void *)&metaHeader, sizeof(unsigned char), sizeof(metaHeader), fHandle); + + // Write SetMapMode, SetWindowOrigin and SetWindowExt records + char modeBuffer[8]; + char originBuffer[10]; + char extentBuffer[10]; + METARECORD *modeRecord = (METARECORD *)&modeBuffer; + + METARECORD *originRecord = (METARECORD *)&originBuffer; + METARECORD *extentRecord = (METARECORD *)&extentBuffer; + + modeRecord->rdSize = 4; + modeRecord->rdFunction = META_SETMAPMODE; + modeRecord->rdParm[0] = MM_ANISOTROPIC; + + originRecord->rdSize = 5; + originRecord->rdFunction = META_SETWINDOWORG; + originRecord->rdParm[0] = originY; + originRecord->rdParm[1] = originX; + + extentRecord->rdSize = 5; + extentRecord->rdFunction = META_SETWINDOWEXT; + extentRecord->rdParm[0] = extentY; + extentRecord->rdParm[1] = extentX; + + fwrite((void *)modeBuffer, sizeof(char), 8, fHandle); + + if (useOriginAndExtent) { - putc(ch, fHandle); + fwrite((void *)originBuffer, sizeof(char), 10, fHandle); + fwrite((void *)extentBuffer, sizeof(char), 10, fHandle); } - } - fclose(fHandle); - fclose(fd); - wxRemoveFile(filename); - wxCopyFile(tempFileBuf, filename); - wxRemoveFile(tempFileBuf); - return TRUE; + + int ch = -2; + while (ch != EOF) + { + ch = getc(fd); + if (ch != EOF) + { + putc(ch, fHandle); + } + } + fclose(fHandle); + fclose(fd); + wxRemoveFile(filename); + wxCopyFile(tempFileBuf, filename); + wxRemoveFile(tempFileBuf); + return TRUE; +} + +// ---------------------------------------------------------------------------- +// wxMetafileDataObject +// ---------------------------------------------------------------------------- + +size_t wxMetafileDataObject::GetDataSize() const +{ + return sizeof(METAFILEPICT); +} + +bool wxMetafileDataObject::GetDataHere(void *buf) const +{ + METAFILEPICT *mfpict = (METAFILEPICT *)buf; + const wxMetafile mf = GetMetafile(); + mfpict->mm = mf.GetWindowsMappingMode(); + mfpict->xExt = mf.GetWidth(); + mfpict->yExt = mf.GetHeight(); + mfpict->hMF = (HMETAFILE)mf.GetHMETAFILE(); + + wxCHECK_MSG( mfpict->hMF, FALSE, _T("copying invalid metafile") ); + + return TRUE; +} + +bool wxMetafileDataObject::SetData(size_t WXUNUSED(len), const void *buf) +{ + const METAFILEPICT *mfpict = (const METAFILEPICT *)buf; + + wxMetafile mf; + mf.SetWindowsMappingMode(mfpict->mm); + mf.SetWidth(mfpict->xExt); + mf.SetHeight(mfpict->yExt); + mf.SetHMETAFILE((WXHANDLE)mfpict->hMF); + + wxCHECK_MSG( mfpict->hMF, FALSE, _T("pasting invalid metafile") ); + + SetMetafile(mf); + + return TRUE; } #endif // wxUSE_METAFILE diff --git a/src/msw/ole/dataobj.cpp b/src/msw/ole/dataobj.cpp index 72e6a05a9c..14d98afe93 100644 --- a/src/msw/ole/dataobj.cpp +++ b/src/msw/ole/dataobj.cpp @@ -298,6 +298,12 @@ STDMETHODIMP wxIDataObject::GetData(FORMATETC *pformatetcIn, STGMEDIUM *pmedium) break; case wxDF_METAFILE: + pmedium->hGlobal = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, + sizeof(METAFILEPICT)); + if ( !pmedium->hGlobal ) { + wxLogLastError("GlobalAlloc"); + return E_OUTOFMEMORY; + } pmedium->tymed = TYMED_MFPICT; break; @@ -334,7 +340,7 @@ STDMETHODIMP wxIDataObject::GetData(FORMATETC *pformatetcIn, STGMEDIUM *pmedium) hr = GetDataHere(pformatetcIn, pmedium); if ( FAILED(hr) ) { // free resources we allocated - if ( pmedium->tymed == TYMED_HGLOBAL ) { + if ( pmedium->tymed & (TYMED_HGLOBAL | TYMED_MFPICT) ) { GlobalFree(pmedium->hGlobal); } @@ -358,11 +364,6 @@ STDMETHODIMP wxIDataObject::GetDataHere(FORMATETC *pformatetc, break; case TYMED_MFPICT: - // this should be copied on bitmaps - but I don't have time for - // this now - wxFAIL_MSG(wxT("TODO - no support for metafiles in wxDataObject")); - break; - case TYMED_HGLOBAL: { // copy data @@ -409,11 +410,6 @@ STDMETHODIMP wxIDataObject::SetData(FORMATETC *pformatetc, break; case TYMED_MFPICT: - // this should be copied on bitmaps - but I don't have time for - // this now - wxFAIL_MSG(wxT("TODO - no support for metafiles in wxDataObject")); - break; - case TYMED_HGLOBAL: { wxDataFormat format = pformatetc->cfFormat; @@ -467,6 +463,10 @@ STDMETHODIMP wxIDataObject::SetData(FORMATETC *pformatetc, size = 0; break; + case CF_METAFILEPICT: + size = sizeof(METAFILEPICT); + break; + default: { // we suppose that the size precedes the data @@ -491,11 +491,17 @@ STDMETHODIMP wxIDataObject::SetData(FORMATETC *pformatetc, } if ( fRelease ) { - // we own the medium, so we must release it - but do *not* free the - // bitmap handle fi we have it because we have copied it elsewhere - if ( pmedium->tymed == TYMED_GDI ) + // we own the medium, so we must release it - but do *not* free any + // data we pass by handle because we have copied it elsewhere + switch ( pmedium->tymed ) { - pmedium->hBitmap = 0; + case TYMED_GDI: + pmedium->hBitmap = 0; + break; + + case TYMED_MFPICT: + pmedium->hMetaFilePict = 0; + break; } ReleaseStgMedium(pmedium); @@ -759,7 +765,7 @@ bool wxBitmapDataObject2::GetDataHere(void *pBuf) const return TRUE; } -bool wxBitmapDataObject2::SetData(size_t len, const void *pBuf) +bool wxBitmapDataObject2::SetData(size_t WXUNUSED(len), const void *pBuf) { HBITMAP hbmp = *(HBITMAP *)pBuf; -- 2.45.2