/////////////////////////////////////////////////////////////////////////////
-// Name: msw/metafile.cpp
+// Name: src/msw/metafile.cpp
// Purpose: wxMetafileDC etc.
// Author: Julian Smart
// 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
+// Copyright: (c) Julian Smart
+// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// ============================================================================
// headers
// ----------------------------------------------------------------------------
-#ifdef __GNUG__
- #pragma implementation "metafile.h"
-#endif
-
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#pragma hdrstop
#endif
-#ifndef WX_PRECOMP
- #include "wx/setup.h"
-#endif
-
-#if wxUSE_METAFILE
-
#ifndef WX_PRECOMP
#include "wx/utils.h"
#include "wx/app.h"
#endif
#include "wx/metafile.h"
+#include "wx/filename.h"
+
+#if wxUSE_METAFILE && !defined(wxMETAFILE_IS_ENH)
+
#include "wx/clipbrd.h"
#include "wx/msw/private.h"
wxMetafileRefData::wxMetafileRefData()
{
m_metafile = 0;
- m_windowsMappingMode = wxMM_ANISOTROPIC;
+ m_windowsMappingMode = MM_ANISOTROPIC;
m_width = m_height = 0;
}
{
m_refData = new wxMetafileRefData;
- M_METAFILEDATA->m_windowsMappingMode = wxMM_ANISOTROPIC;
+ M_METAFILEDATA->m_windowsMappingMode = MM_ANISOTROPIC;
M_METAFILEDATA->m_metafile = 0;
- if (!file.IsNull() && (file.Cmp(wxT("")) == 0))
+ if (!file.empty())
M_METAFILEDATA->m_metafile = (WXHANDLE) GetMetaFile(file);
}
{
}
+wxGDIRefData *wxMetafile::CreateGDIRefData() const
+{
+ return new wxMetafileRefData;
+}
+
+wxGDIRefData *wxMetafile::CloneGDIRefData(const wxGDIRefData *data) const
+{
+ return new wxMetafileRefData(*static_cast<const wxMetafileRefData *>(data));
+}
+
bool wxMetafile::SetClipboard(int width, int height)
{
+#if !wxUSE_CLIPBOARD
+ return false;
+#else
if (!m_refData)
- return FALSE;
+ return false;
bool alreadyOpen = wxClipboardOpen();
if (!alreadyOpen)
{
wxOpenClipboard();
if (!wxEmptyClipboard())
- return FALSE;
+ return false;
}
bool success = wxSetClipboardData(wxDF_METAFILE, this, width,height);
if (!alreadyOpen)
wxCloseClipboard();
return success;
+#endif
}
bool wxMetafile::Play(wxDC *dc)
{
if (!m_refData)
- return FALSE;
-
- dc->BeginDrawing();
+ return false;
if (dc->GetHDC() && M_METAFILEDATA->m_metafile)
- PlayMetaFile(GetHdcOf(*dc), (HMETAFILE) M_METAFILEDATA->m_metafile);
-
- dc->EndDrawing();
+ {
+ if ( !::PlayMetaFile(GetHdcOf(*dc), (HMETAFILE)
+ M_METAFILEDATA->m_metafile) )
+ {
+ wxLogLastError(wxT("PlayMetaFile"));
+ }
+ }
- return TRUE;
+ return true;
}
void wxMetafile::SetHMETAFILE(WXHANDLE mf)
// 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)
+wxMetafileDCImpl::wxMetafileDCImpl(wxDC *owner, const wxString& file)
+ : wxMSWDCImpl(owner)
{
m_metaFile = NULL;
m_minX = 10000;
m_maxY = -10000;
// m_title = NULL;
- if (!file.IsNull() && wxFileExists(file))
+ if ( wxFileExists(file) )
wxRemoveFile(file);
- if (!file.IsNull() && (file != wxT("")))
- m_hDC = (WXHDC) CreateMetaFile(file);
- else
+ if ( file.empty() )
m_hDC = (WXHDC) CreateMetaFile(NULL);
+ else
+ m_hDC = (WXHDC) CreateMetaFile(file);
m_ok = (m_hDC != (WXHDC) 0) ;
// 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)
+wxMetafileDCImpl::wxMetafileDCImpl(wxDC *owner, const wxString& file,
+ int xext, int yext, int xorg, int yorg)
+ : wxMSWDCImpl(owner)
{
m_minX = 10000;
m_minY = 10000;
m_maxX = -10000;
m_maxY = -10000;
- if ( !!file && wxFileExists(file))
+ if ( !file.empty() && wxFileExists(file) )
wxRemoveFile(file);
- m_hDC = (WXHDC) CreateMetaFile(file);
+ m_hDC = (WXHDC) CreateMetaFile(file.empty() ? NULL : wxMSW_CONV_LPCTSTR(file));
- m_ok = TRUE;
+ m_ok = true;
::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;
+ m_windowsMappingMode = MM_ANISOTROPIC;
SetMapMode(wxMM_TEXT); // NOTE: does not set HDC mapmode (this is correct)
}
-wxMetafileDC::~wxMetafileDC()
+wxMetafileDCImpl::~wxMetafileDCImpl()
{
m_hDC = 0;
}
-void wxMetafileDC::GetTextExtent(const wxString& string, long *x, long *y,
- long *descent, long *externalLeading, wxFont *theFont, bool use16bit) const
+void wxMetafileDCImpl::DoGetTextExtent(const wxString& string,
+ wxCoord *x, wxCoord *y,
+ wxCoord *descent, wxCoord *externalLeading,
+ const wxFont *theFont) const
{
- wxFont *fontToUse = theFont;
+ const wxFont *fontToUse = theFont;
if (!fontToUse)
- fontToUse = (wxFont*) &m_font;
+ fontToUse = &m_font;
- HDC dc = GetDC(NULL);
+ ScreenHDC dc;
+ SelectInHDC selFont(dc, GetHfontOf(*fontToUse));
SIZE sizeRect;
TEXTMETRIC tm;
- GetTextExtentPoint(dc, WXSTRINGCAST string, wxStrlen(WXSTRINGCAST string), &sizeRect);
- GetTextMetrics(dc, &tm);
-
- ReleaseDC(NULL, dc);
+ ::GetTextExtentPoint32(dc, WXSTRINGCAST string, wxStrlen(WXSTRINGCAST string), &sizeRect);
+ ::GetTextMetrics(dc, &tm);
if ( x )
*x = sizeRect.cx;
*externalLeading = tm.tmExternalLeading;
}
-wxMetafile *wxMetafileDC::Close()
+void wxMetafileDCImpl::DoGetSize(int *width, int *height) const
+{
+ wxCHECK_RET( m_refData, wxT("invalid wxMetafileDC") );
+
+ if ( width )
+ *width = M_METAFILEDATA->m_width;
+ if ( height )
+ *height = M_METAFILEDATA->m_height;
+}
+
+wxMetafile *wxMetafileDCImpl::Close()
{
SelectOldObjects(m_hDC);
HANDLE mf = CloseMetaFile((HDC) m_hDC);
return NULL;
}
-void wxMetafileDC::SetMapMode(int mode)
+void wxMetafileDCImpl::SetMapMode(wxMappingMode mode)
{
m_mappingMode = mode;
break;
}
}
- m_windowExtX = 100;
- m_windowExtY = 100;
}
// ----------------------------------------------------------------------------
bool wxMakeMetafilePlaceable(const wxString& filename, float scale)
{
- return wxMakeMetafilePlaceable(filename, 0, 0, 0, 0, scale, FALSE);
+ return wxMakeMetafilePlaceable(filename, 0, 0, 0, 0, scale, false);
}
bool wxMakeMetafilePlaceable(const wxString& filename, int x1, int y1, int x2, int y2, float scale, bool useOriginAndExtent)
p < (WORD *)&pMFHead ->checksum; ++p)
pMFHead ->checksum ^= *p;
- FILE *fd = fopen(filename.fn_str(), "rb");
- if (!fd) return FALSE;
+ FILE *fd = wxFopen(filename.fn_str(), wxT("rb"));
+ if (!fd) return false;
- wxChar tempFileBuf[256];
- wxGetTempFileName(wxT("mf"), tempFileBuf);
- FILE *fHandle = fopen(wxConvFile.cWX2MB(tempFileBuf), "wb");
+ wxString tempFileBuf = wxFileName::CreateTempFileName(wxT("mf"));
+ if (tempFileBuf.empty())
+ return false;
+
+ FILE *fHandle = wxFopen(tempFileBuf.fn_str(), wxT("wb"));
if (!fHandle)
- return FALSE;
- fwrite((void *)&header, sizeof(unsigned char), sizeof(mfPLACEABLEHEADER), fHandle);
+ return false;
+ fwrite((void *)&header, 1, sizeof(mfPLACEABLEHEADER), fHandle);
// Calculate origin and extent
int originX = x1;
// Read metafile header and write
METAHEADER metaHeader;
- fread((void *)&metaHeader, sizeof(unsigned char), sizeof(metaHeader), fd);
+ fread((void *)&metaHeader, 1, sizeof(metaHeader), fd);
if (useOriginAndExtent)
metaHeader.mtSize += 15;
else
metaHeader.mtSize += 5;
- fwrite((void *)&metaHeader, sizeof(unsigned char), sizeof(metaHeader), fHandle);
+ fwrite((void *)&metaHeader, 1, sizeof(metaHeader), fHandle);
// Write SetMapMode, SetWindowOrigin and SetWindowExt records
char modeBuffer[8];
extentRecord->rdParm[0] = extentY;
extentRecord->rdParm[1] = extentX;
- fwrite((void *)modeBuffer, sizeof(char), 8, fHandle);
+ fwrite((void *)modeBuffer, 1, 8, fHandle);
if (useOriginAndExtent)
{
- fwrite((void *)originBuffer, sizeof(char), 10, fHandle);
- fwrite((void *)extentBuffer, sizeof(char), 10, fHandle);
+ fwrite((void *)originBuffer, 1, 10, fHandle);
+ fwrite((void *)extentBuffer, 1, 10, fHandle);
}
int ch = -2;
wxRemoveFile(filename);
wxCopyFile(tempFileBuf, filename);
wxRemoveFile(tempFileBuf);
- return TRUE;
+ return true;
}
+
+#if wxUSE_DRAG_AND_DROP
+
// ----------------------------------------------------------------------------
// wxMetafileDataObject
// ----------------------------------------------------------------------------
bool wxMetafileDataObject::GetDataHere(void *buf) const
{
METAFILEPICT *mfpict = (METAFILEPICT *)buf;
- const wxMetafile mf = GetMetafile();
- mfpict->mm = mf.GetWindowsMappingMode();
+ const wxMetafile& mf = GetMetafile();
+
+ wxCHECK_MSG( mf.GetHMETAFILE(), false, wxT("copying invalid metafile") );
+
+ // doesn't seem to work with any other mapping mode...
+ mfpict->mm = MM_ANISOTROPIC; //mf.GetWindowsMappingMode();
mfpict->xExt = mf.GetWidth();
mfpict->yExt = mf.GetHeight();
- mfpict->hMF = (HMETAFILE)mf.GetHMETAFILE();
- wxCHECK_MSG( mfpict->hMF, FALSE, _T("copying invalid metafile") );
+ // transform the picture size to HIMETRIC units (0.01mm) - as we don't know
+ // what DC the picture will be rendered to, use the default display one
+ PixelToHIMETRIC(&mfpict->xExt, &mfpict->yExt);
- return TRUE;
+ mfpict->hMF = CopyMetaFile((HMETAFILE)mf.GetHMETAFILE(), NULL);
+
+ return true;
}
bool wxMetafileDataObject::SetData(size_t WXUNUSED(len), const void *buf)
wxMetafile mf;
mf.SetWindowsMappingMode(mfpict->mm);
- mf.SetWidth(mfpict->xExt);
- mf.SetHeight(mfpict->yExt);
+
+ LONG w = mfpict->xExt,
+ h = mfpict->yExt;
+ if ( mfpict->mm == MM_ANISOTROPIC )
+ {
+ // in this case xExt and yExt contain suggested size in HIMETRIC units
+ // (0.01 mm) - transform this to something more reasonable (pixels)
+ HIMETRICToPixel(&w, &h);
+ }
+
+ mf.SetWidth(w);
+ mf.SetHeight(h);
mf.SetHMETAFILE((WXHANDLE)mfpict->hMF);
- wxCHECK_MSG( mfpict->hMF, FALSE, _T("pasting invalid metafile") );
+ wxCHECK_MSG( mfpict->hMF, false, wxT("pasting invalid metafile") );
SetMetafile(mf);
- return TRUE;
+ return true;
}
-#endif // wxUSE_METAFILE
+#endif // wxUSE_DRAG_AND_DROP
+#endif // wxUSE_METAFILE