Provide support for storing PNG files on the clipboard (wxMSW)
PNG is a custom clipboard format but images stored in this format are supported by e.g. MS Excel, MS PowerPoint, GIMP (including image transparency). See #17631.
This commit is contained in:
@@ -2153,6 +2153,7 @@ enum wxDataFormatId
|
||||
wxDF_LOCALE = 16,
|
||||
wxDF_PRIVATE = 20,
|
||||
wxDF_HTML = 30, /* Note: does not correspond to CF_ constant */
|
||||
wxDF_PNG = 31, /* Note: does not correspond to CF_ constant */
|
||||
wxDF_MAX
|
||||
};
|
||||
|
||||
|
@@ -34,6 +34,8 @@
|
||||
A list of filenames.}
|
||||
@itemdef{wxDF_HTML,
|
||||
An HTML string. This is currently only valid on Mac and MSW.}
|
||||
@itemdef{wxDF_PNG,
|
||||
A PNG file. This is valid only on MSW.}
|
||||
@endDefList
|
||||
|
||||
As mentioned above, these standard formats may be passed to any function
|
||||
|
@@ -73,6 +73,7 @@
|
||||
|
||||
static bool gs_wxClipboardIsOpen = false;
|
||||
static int gs_htmlcfid = 0;
|
||||
static int gs_pngcfid = 0;
|
||||
|
||||
bool wxOpenClipboard()
|
||||
{
|
||||
@@ -136,6 +137,8 @@ bool wxIsClipboardFormatAvailable(wxDataFormat dataFormat)
|
||||
wxDataFormat::NativeFormat cf = dataFormat.GetFormatId();
|
||||
if (cf == wxDF_HTML)
|
||||
cf = gs_htmlcfid;
|
||||
else if ( cf == wxDF_PNG )
|
||||
cf = gs_pngcfid;
|
||||
|
||||
if ( ::IsClipboardFormatAvailable(cf) )
|
||||
{
|
||||
@@ -162,6 +165,15 @@ bool wxIsClipboardFormatAvailable(wxDataFormat dataFormat)
|
||||
|
||||
|
||||
#if !wxUSE_OLE_CLIPBOARD
|
||||
namespace
|
||||
{
|
||||
struct wxRawImageData
|
||||
{
|
||||
size_t m_size;
|
||||
void* m_data;
|
||||
};
|
||||
}
|
||||
|
||||
bool wxSetClipboardData(wxDataFormat dataFormat,
|
||||
const void *data,
|
||||
int width, int height)
|
||||
@@ -414,6 +426,16 @@ bool wxSetClipboardData(wxDataFormat dataFormat,
|
||||
delete [] buf;
|
||||
break;
|
||||
}
|
||||
|
||||
case wxDF_PNG:
|
||||
{
|
||||
const wxRawImageData* imgData = reinterpret_cast<const wxRawImageData*>(data);
|
||||
|
||||
GlobalPtr hImage(imgData->m_size, GMEM_MOVEABLE | GMEM_DDESHARE);
|
||||
memcpy(GlobalPtrLock(hImage).Get(), imgData->m_data, imgData->m_size);
|
||||
handle = ::SetClipboardData(gs_pngcfid, hImage);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( handle == 0 )
|
||||
@@ -515,9 +537,11 @@ bool wxClipboard::Flush()
|
||||
|
||||
bool wxClipboard::Open()
|
||||
{
|
||||
// Get clipboard id for HTML format...
|
||||
// Get clipboard id for HTML and PNG formats...
|
||||
if(!gs_htmlcfid)
|
||||
gs_htmlcfid = RegisterClipboardFormat(wxT("HTML Format"));
|
||||
if ( !gs_pngcfid )
|
||||
gs_pngcfid = ::RegisterClipboardFormat(wxT("PNG"));
|
||||
|
||||
// OLE opens clipboard for us
|
||||
m_isOpened = true;
|
||||
@@ -636,6 +660,16 @@ bool wxClipboard::AddData( wxDataObject *data )
|
||||
}
|
||||
break;
|
||||
|
||||
case wxDF_PNG:
|
||||
{
|
||||
wxCustomDataObject* imageDataObject = reinterpret_cast<wxCustomDataObject*>(data);
|
||||
wxRawImageData imgData;
|
||||
imgData.m_size = imageDataObject->GetDataSize();
|
||||
imgData.m_data = imageDataObject->GetData();
|
||||
bRet = wxSetClipboardData(format, &imgData);
|
||||
}
|
||||
break;
|
||||
|
||||
#if wxUSE_METAFILE
|
||||
case wxDF_METAFILE:
|
||||
{
|
||||
@@ -768,6 +802,8 @@ bool wxClipboard::GetData( wxDataObject& data )
|
||||
|
||||
if (cf == wxDF_HTML)
|
||||
cf = gs_htmlcfid;
|
||||
else if ( cf == wxDF_PNG )
|
||||
cf = gs_pngcfid;
|
||||
// if the format is not available, try the next one
|
||||
// this test includes implicit / sythetic formats
|
||||
if ( !::IsClipboardFormatAvailable(cf) )
|
||||
|
@@ -64,15 +64,15 @@
|
||||
namespace
|
||||
{
|
||||
|
||||
wxDataFormat HtmlFormatFixup(wxDataFormat format)
|
||||
wxDataFormat NonStandardFormatsFixup(wxDataFormat format)
|
||||
{
|
||||
// Since the HTML format is dynamically registered, the wxDF_HTML
|
||||
// format does not match the native constant in the way other formats do,
|
||||
// Since the HTML and PNG formats are dynamically registered, the wxDF_HTML and wxDF_PNG
|
||||
// formats do not match the native constants in the way other formats do,
|
||||
// so for the format checks below to work, we must change the native
|
||||
// id to the wxDF_HTML constant.
|
||||
// id to the wxDF_HTML or wxDF_PNG constant.
|
||||
//
|
||||
// But skip this for the standard constants which are never going to match
|
||||
// wxDF_HTML anyhow.
|
||||
// wxDF_HTML or wxDF_PNG anyhow.
|
||||
if ( !format.IsStandard() )
|
||||
{
|
||||
wxChar szBuf[256];
|
||||
@@ -80,6 +80,8 @@ wxDataFormat HtmlFormatFixup(wxDataFormat format)
|
||||
{
|
||||
if ( wxStrcmp(szBuf, wxT("HTML Format")) == 0 )
|
||||
format = wxDF_HTML;
|
||||
else if ( wxStrcmp(szBuf, wxT("PNG")) == 0 )
|
||||
format = wxDF_PNG;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -347,7 +349,7 @@ wxIDataObject::SaveSystemData(FORMATETC *pformatetc,
|
||||
|
||||
bool wxDataFormat::operator==(wxDataFormatId format) const
|
||||
{
|
||||
return HtmlFormatFixup(*this).m_format == (NativeFormat)format;
|
||||
return NonStandardFormatsFixup(*this).m_format == (NativeFormat)format;
|
||||
}
|
||||
|
||||
bool wxDataFormat::operator!=(wxDataFormatId format) const
|
||||
@@ -357,7 +359,7 @@ bool wxDataFormat::operator!=(wxDataFormatId format) const
|
||||
|
||||
bool wxDataFormat::operator==(const wxDataFormat& format) const
|
||||
{
|
||||
return HtmlFormatFixup(*this).m_format == HtmlFormatFixup(format).m_format;
|
||||
return NonStandardFormatsFixup(*this).m_format == NonStandardFormatsFixup(format).m_format;
|
||||
}
|
||||
|
||||
bool wxDataFormat::operator!=(const wxDataFormat& format) const
|
||||
@@ -367,7 +369,7 @@ bool wxDataFormat::operator!=(const wxDataFormat& format) const
|
||||
|
||||
bool wxDataFormat::operator==(NativeFormat format) const
|
||||
{
|
||||
return HtmlFormatFixup(*this).m_format == format;
|
||||
return NonStandardFormatsFixup(*this).m_format == format;
|
||||
}
|
||||
|
||||
bool wxDataFormat::operator!=(NativeFormat format) const
|
||||
@@ -422,10 +424,12 @@ wxIEnumFORMATETC::wxIEnumFORMATETC(const wxDataFormat *formats, ULONG nCount)
|
||||
m_nCount = nCount;
|
||||
m_formats = new CLIPFORMAT[nCount];
|
||||
for ( ULONG n = 0; n < nCount; n++ ) {
|
||||
if (formats[n].GetFormatId() != wxDF_HTML)
|
||||
m_formats[n] = formats[n].GetFormatId();
|
||||
else
|
||||
if ( formats[n].GetFormatId() == wxDF_HTML )
|
||||
m_formats[n] = ::RegisterClipboardFormat(wxT("HTML Format"));
|
||||
else if ( formats[n].GetFormatId() == wxDF_PNG )
|
||||
m_formats[n] = ::RegisterClipboardFormat(wxT("PNG"));
|
||||
else
|
||||
m_formats[n] = formats[n].GetFormatId();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -540,7 +544,7 @@ STDMETHODIMP wxIDataObject::GetData(FORMATETC *pformatetcIn, STGMEDIUM *pmedium)
|
||||
// for the bitmaps and metafiles we use the handles instead of global memory
|
||||
// to pass the data
|
||||
wxDataFormat format = (wxDataFormat::NativeFormat)pformatetcIn->cfFormat;
|
||||
format = HtmlFormatFixup(format);
|
||||
format = NonStandardFormatsFixup(format);
|
||||
|
||||
// is this system data?
|
||||
if ( GetSystemData(format, pmedium) )
|
||||
@@ -690,7 +694,7 @@ STDMETHODIMP wxIDataObject::SetData(FORMATETC *pformatetc,
|
||||
{
|
||||
wxDataFormat format = pformatetc->cfFormat;
|
||||
|
||||
format = HtmlFormatFixup(format);
|
||||
format = NonStandardFormatsFixup(format);
|
||||
|
||||
// check if this format is supported
|
||||
if ( !m_pDataObject->IsSupported(format, wxDataObject::Set) ) {
|
||||
@@ -737,6 +741,9 @@ STDMETHODIMP wxIDataObject::SetData(FORMATETC *pformatetc,
|
||||
size = sizeof(METAFILEPICT);
|
||||
break;
|
||||
|
||||
case wxDF_PNG:
|
||||
wxFALLTHROUGH;
|
||||
|
||||
default:
|
||||
size = ptr.GetSize();
|
||||
|
||||
@@ -816,7 +823,7 @@ STDMETHODIMP wxIDataObject::QueryGetData(FORMATETC *pformatetc)
|
||||
|
||||
// and now check the type of data requested
|
||||
wxDataFormat format = pformatetc->cfFormat;
|
||||
format = HtmlFormatFixup(format);
|
||||
format = NonStandardFormatsFixup(format);
|
||||
|
||||
if ( m_pDataObject->IsSupportedFormat(format) ) {
|
||||
wxLogTrace(wxTRACE_OleCalls, wxT("wxIDataObject::QueryGetData: %s ok"),
|
||||
|
Reference in New Issue
Block a user