Applied patch [ 851052 ] [msw] Clipboard: Allow automatic format conversions
By Kevin Edwards (ingenuus) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@25131 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -146,14 +146,16 @@ bool wxIsClipboardOpened()
|
|||||||
|
|
||||||
bool wxIsClipboardFormatAvailable(wxDataFormat dataFormat)
|
bool wxIsClipboardFormatAvailable(wxDataFormat dataFormat)
|
||||||
{
|
{
|
||||||
if ( ::IsClipboardFormatAvailable(dataFormat) )
|
CLIPFORMAT cf = dataFormat.GetFormatId();
|
||||||
|
|
||||||
|
if ( ::IsClipboardFormatAvailable(cf) )
|
||||||
{
|
{
|
||||||
// ok from the first try
|
// ok from the first try
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// for several standard formats, we can convert from some other ones too
|
// for several standard formats, we can convert from some other ones too
|
||||||
switch ( dataFormat.GetFormatId() )
|
switch ( cf )
|
||||||
{
|
{
|
||||||
// for bitmaps, DIBs will also do
|
// for bitmaps, DIBs will also do
|
||||||
case CF_BITMAP:
|
case CF_BITMAP:
|
||||||
@@ -730,9 +732,16 @@ bool wxClipboard::GetData( wxDataObject& data )
|
|||||||
|
|
||||||
data.GetAllFormats(formats, wxDataObject::Set);
|
data.GetAllFormats(formats, wxDataObject::Set);
|
||||||
|
|
||||||
// get the format enumerator
|
// get the data for the given formats
|
||||||
|
FORMATETC formatEtc;
|
||||||
|
CLIPFORMAT cf;
|
||||||
bool result = FALSE;
|
bool result = FALSE;
|
||||||
wxArrayInt supportedFormats;
|
|
||||||
|
// enumerate all explicit formats on the clipboard.
|
||||||
|
// note that this does not include implicit / synthetic (automatically
|
||||||
|
// converted) formats.
|
||||||
|
#ifdef __WXDEBUG__
|
||||||
|
// get the format enumerator
|
||||||
IEnumFORMATETC *pEnumFormatEtc = NULL;
|
IEnumFORMATETC *pEnumFormatEtc = NULL;
|
||||||
hr = pDataObject->EnumFormatEtc(DATADIR_GET, &pEnumFormatEtc);
|
hr = pDataObject->EnumFormatEtc(DATADIR_GET, &pEnumFormatEtc);
|
||||||
if ( FAILED(hr) || !pEnumFormatEtc )
|
if ( FAILED(hr) || !pEnumFormatEtc )
|
||||||
@@ -743,7 +752,6 @@ bool wxClipboard::GetData( wxDataObject& data )
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// ask for the supported formats and see if there are any we support
|
// ask for the supported formats and see if there are any we support
|
||||||
FORMATETC formatEtc;
|
|
||||||
for ( ;; )
|
for ( ;; )
|
||||||
{
|
{
|
||||||
ULONG nCount;
|
ULONG nCount;
|
||||||
@@ -756,29 +764,86 @@ bool wxClipboard::GetData( wxDataObject& data )
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
CLIPFORMAT cf = formatEtc.cfFormat;
|
cf = formatEtc.cfFormat;
|
||||||
|
|
||||||
#ifdef __WXDEBUG__
|
|
||||||
wxLogTrace(wxTRACE_OleCalls,
|
wxLogTrace(wxTRACE_OleCalls,
|
||||||
wxT("Object on the clipboard supports format %s."),
|
wxT("Object on the clipboard supports format %s."),
|
||||||
wxDataObject::GetFormatName(cf));
|
wxDataObject::GetFormatName(cf));
|
||||||
#endif // Debug
|
|
||||||
|
|
||||||
// is supported?
|
|
||||||
for ( size_t n = 0; n < nFormats; n++ )
|
|
||||||
{
|
|
||||||
if ( formats[n].GetFormatId() == cf )
|
|
||||||
{
|
|
||||||
if ( supportedFormats.Index(cf) == wxNOT_FOUND )
|
|
||||||
{
|
|
||||||
supportedFormats.Add(cf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pEnumFormatEtc->Release();
|
pEnumFormatEtc->Release();
|
||||||
}
|
}
|
||||||
|
#endif // Debug
|
||||||
|
|
||||||
|
STGMEDIUM medium;
|
||||||
|
// stop at the first valid format found on the clipboard
|
||||||
|
for ( size_t n = 0; !result && (n < nFormats); n++ )
|
||||||
|
{
|
||||||
|
// convert to NativeFormat Id
|
||||||
|
cf = formats[n].GetFormatId();
|
||||||
|
|
||||||
|
// if the format is not available, try the next one
|
||||||
|
// this test includes implicit / sythetic formats
|
||||||
|
if ( !::IsClipboardFormatAvailable(cf) )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
formatEtc.cfFormat = cf;
|
||||||
|
formatEtc.ptd = NULL;
|
||||||
|
formatEtc.dwAspect = DVASPECT_CONTENT;
|
||||||
|
formatEtc.lindex = -1;
|
||||||
|
|
||||||
|
// use the appropriate tymed
|
||||||
|
switch ( formatEtc.cfFormat )
|
||||||
|
{
|
||||||
|
case CF_BITMAP:
|
||||||
|
formatEtc.tymed = TYMED_GDI;
|
||||||
|
break;
|
||||||
|
|
||||||
|
#ifndef __WXWINCE__
|
||||||
|
case CF_METAFILEPICT:
|
||||||
|
formatEtc.tymed = TYMED_MFPICT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CF_ENHMETAFILE:
|
||||||
|
formatEtc.tymed = TYMED_ENHMF;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
default:
|
||||||
|
formatEtc.tymed = TYMED_HGLOBAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// try to get data
|
||||||
|
hr = pDataObject->GetData(&formatEtc, &medium);
|
||||||
|
if ( FAILED(hr) )
|
||||||
|
{
|
||||||
|
// try other tymed for GDI objects
|
||||||
|
if ( formatEtc.cfFormat == CF_BITMAP )
|
||||||
|
{
|
||||||
|
formatEtc.tymed = TYMED_HGLOBAL;
|
||||||
|
hr = pDataObject->GetData(&formatEtc, &medium);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( SUCCEEDED(hr) )
|
||||||
|
{
|
||||||
|
// pass the data to the data object
|
||||||
|
hr = data.GetInterface()->SetData(&formatEtc, &medium, TRUE);
|
||||||
|
if ( FAILED(hr) )
|
||||||
|
{
|
||||||
|
wxLogDebug(wxT("Failed to set data in wxIDataObject"));
|
||||||
|
|
||||||
|
// IDataObject only takes the ownership of data if it
|
||||||
|
// successfully got it - which is not the case here
|
||||||
|
ReleaseStgMedium(&medium);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//else: unsupported tymed?
|
||||||
|
}
|
||||||
|
|
||||||
if ( formats != &format )
|
if ( formats != &format )
|
||||||
{
|
{
|
||||||
@@ -786,72 +851,6 @@ bool wxClipboard::GetData( wxDataObject& data )
|
|||||||
}
|
}
|
||||||
//else: we didn't allocate any memory
|
//else: we didn't allocate any memory
|
||||||
|
|
||||||
if ( !supportedFormats.IsEmpty() )
|
|
||||||
{
|
|
||||||
FORMATETC formatEtc;
|
|
||||||
formatEtc.ptd = NULL;
|
|
||||||
formatEtc.dwAspect = DVASPECT_CONTENT;
|
|
||||||
formatEtc.lindex = -1;
|
|
||||||
|
|
||||||
size_t nSupportedFormats = supportedFormats.GetCount();
|
|
||||||
for ( size_t n = 0; !result && (n < nSupportedFormats); n++ )
|
|
||||||
{
|
|
||||||
STGMEDIUM medium;
|
|
||||||
formatEtc.cfFormat = supportedFormats[n];
|
|
||||||
|
|
||||||
// use the appropriate tymed
|
|
||||||
switch ( formatEtc.cfFormat )
|
|
||||||
{
|
|
||||||
case CF_BITMAP:
|
|
||||||
formatEtc.tymed = TYMED_GDI;
|
|
||||||
break;
|
|
||||||
#ifndef __WXWINCE__
|
|
||||||
case CF_METAFILEPICT:
|
|
||||||
formatEtc.tymed = TYMED_MFPICT;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CF_ENHMETAFILE:
|
|
||||||
formatEtc.tymed = TYMED_ENHMF;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
formatEtc.tymed = TYMED_HGLOBAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// try to get data
|
|
||||||
hr = pDataObject->GetData(&formatEtc, &medium);
|
|
||||||
if ( FAILED(hr) )
|
|
||||||
{
|
|
||||||
// try other tymed for GDI objects
|
|
||||||
if ( formatEtc.cfFormat == CF_BITMAP )
|
|
||||||
{
|
|
||||||
formatEtc.tymed = TYMED_HGLOBAL;
|
|
||||||
hr = pDataObject->GetData(&formatEtc, &medium);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( SUCCEEDED(hr) )
|
|
||||||
{
|
|
||||||
// pass the data to the data object
|
|
||||||
hr = data.GetInterface()->SetData(&formatEtc, &medium, TRUE);
|
|
||||||
if ( FAILED(hr) )
|
|
||||||
{
|
|
||||||
wxLogDebug(wxT("Failed to set data in wxIDataObject"));
|
|
||||||
|
|
||||||
// IDataObject only takes the ownership of data if it
|
|
||||||
// successfully got it - which is not the case here
|
|
||||||
ReleaseStgMedium(&medium);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//else: unsupported tymed?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//else: unsupported format
|
|
||||||
|
|
||||||
// clean up and return
|
// clean up and return
|
||||||
pDataObject->Release();
|
pDataObject->Release();
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user