Fix adding bitmap to clipboard when wxUSE_OLE == 0 (wxMSW)
When CF_DIB object is placed to the clipboard, a handle to the memory object containing a BITMAPINFO structure followed by the bitmap bits should be passed to SetClipboardData(), not a handle to a DIB section. Also, wxClipboard is the owner of the wxDataObject being added, so it should release passed object.
This commit is contained in:
@@ -179,6 +179,7 @@ wxMSW:
|
|||||||
wxMemoryDC (Cairo >= 1.15.4).
|
wxMemoryDC (Cairo >= 1.15.4).
|
||||||
- Fix updating bounding box in wxDC::DrawSpline().
|
- Fix updating bounding box in wxDC::DrawSpline().
|
||||||
- Fix placing 0RGB wxBitmaps on the clipboard.
|
- Fix placing 0RGB wxBitmaps on the clipboard.
|
||||||
|
- Fix adding wxBitmap to clipboard when wxUSE_OLE == 0.
|
||||||
|
|
||||||
wxOSX:
|
wxOSX:
|
||||||
|
|
||||||
|
@@ -219,9 +219,51 @@ bool wxSetClipboardData(wxDataFormat dataFormat,
|
|||||||
if ( bitmap && bitmap->IsOk() )
|
if ( bitmap && bitmap->IsOk() )
|
||||||
{
|
{
|
||||||
wxDIB dib(*bitmap);
|
wxDIB dib(*bitmap);
|
||||||
|
|
||||||
if ( dib.IsOk() )
|
if ( dib.IsOk() )
|
||||||
{
|
{
|
||||||
handle = ::SetClipboardData(CF_DIB, dib.Detach());
|
DIBSECTION ds;
|
||||||
|
int n = ::GetObject(dib.GetHandle(), sizeof(DIBSECTION), &ds);
|
||||||
|
wxASSERT( n == sizeof(DIBSECTION) && ds.dsBm.bmBits );
|
||||||
|
// Number of colours in the palette.
|
||||||
|
int numColors;
|
||||||
|
switch ( ds.dsBmih.biCompression )
|
||||||
|
{
|
||||||
|
case BI_BITFIELDS:
|
||||||
|
numColors = 3;
|
||||||
|
break;
|
||||||
|
case BI_RGB:
|
||||||
|
numColors = ds.dsBmih.biClrUsed;
|
||||||
|
if ( !numColors )
|
||||||
|
{
|
||||||
|
numColors = ds.dsBmih.biBitCount <= 8 ? 1 << ds.dsBmih.biBitCount : 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
numColors = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long bmpSize = wxDIB::GetLineSize(ds.dsBmih.biWidth, ds.dsBmih.biBitCount) *
|
||||||
|
abs(ds.dsBmih.biHeight);
|
||||||
|
HANDLE hMem;
|
||||||
|
hMem = ::GlobalAlloc(GHND, ds.dsBmih.biSize + numColors*sizeof(RGBQUAD) + bmpSize);
|
||||||
|
if ( hMem )
|
||||||
|
{
|
||||||
|
char* pDst = (char*)::GlobalLock(hMem);
|
||||||
|
memcpy(pDst, &ds.dsBmih, ds.dsBmih.biSize);
|
||||||
|
pDst += ds.dsBmih.biSize;
|
||||||
|
if ( numColors > 0 )
|
||||||
|
{
|
||||||
|
// Get colour table.
|
||||||
|
MemoryHDC hDC;
|
||||||
|
SelectInHDC sDC(hDC, dib.GetHandle());
|
||||||
|
::GetDIBColorTable(hDC, 0, numColors, (RGBQUAD*)pDst);
|
||||||
|
pDst += numColors*sizeof(RGBQUAD);
|
||||||
|
}
|
||||||
|
memcpy(pDst, dib.GetData(), bmpSize);
|
||||||
|
::GlobalUnlock(hMem);
|
||||||
|
handle = ::SetClipboardData(CF_DIB, hMem);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -684,6 +726,7 @@ bool wxClipboard::AddData( wxDataObject *data )
|
|||||||
#elif wxUSE_DATAOBJ
|
#elif wxUSE_DATAOBJ
|
||||||
wxCHECK_MSG( wxIsClipboardOpened(), false, wxT("clipboard not open") );
|
wxCHECK_MSG( wxIsClipboardOpened(), false, wxT("clipboard not open") );
|
||||||
|
|
||||||
|
bool bRet = false;
|
||||||
switch ( format )
|
switch ( format )
|
||||||
{
|
{
|
||||||
case wxDF_TEXT:
|
case wxDF_TEXT:
|
||||||
@@ -691,16 +734,18 @@ bool wxClipboard::AddData( wxDataObject *data )
|
|||||||
{
|
{
|
||||||
wxTextDataObject* textDataObject = (wxTextDataObject*) data;
|
wxTextDataObject* textDataObject = (wxTextDataObject*) data;
|
||||||
wxString str(textDataObject->GetText());
|
wxString str(textDataObject->GetText());
|
||||||
return wxSetClipboardData(format, str.c_str());
|
bRet = wxSetClipboardData(format, str.c_str());
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case wxDF_BITMAP:
|
case wxDF_BITMAP:
|
||||||
case wxDF_DIB:
|
case wxDF_DIB:
|
||||||
{
|
{
|
||||||
wxBitmapDataObject* bitmapDataObject = (wxBitmapDataObject*) data;
|
wxBitmapDataObject* bitmapDataObject = (wxBitmapDataObject*) data;
|
||||||
wxBitmap bitmap(bitmapDataObject->GetBitmap());
|
wxBitmap bitmap(bitmapDataObject->GetBitmap());
|
||||||
return wxSetClipboardData(format, &bitmap);
|
bRet = wxSetClipboardData(format, &bitmap);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
#if wxUSE_METAFILE
|
#if wxUSE_METAFILE
|
||||||
case wxDF_METAFILE:
|
case wxDF_METAFILE:
|
||||||
@@ -708,16 +753,16 @@ bool wxClipboard::AddData( wxDataObject *data )
|
|||||||
#if 1
|
#if 1
|
||||||
// TODO
|
// TODO
|
||||||
wxLogError(wxT("Not implemented because wxMetafileDataObject does not contain width and height values."));
|
wxLogError(wxT("Not implemented because wxMetafileDataObject does not contain width and height values."));
|
||||||
return false;
|
|
||||||
#else
|
#else
|
||||||
wxMetafileDataObject* metaFileDataObject =
|
wxMetafileDataObject* metaFileDataObject =
|
||||||
(wxMetafileDataObject*) data;
|
(wxMetafileDataObject*) data;
|
||||||
wxMetafile metaFile = metaFileDataObject->GetMetafile();
|
wxMetafile metaFile = metaFileDataObject->GetMetafile();
|
||||||
return wxSetClipboardData(wxDF_METAFILE, &metaFile,
|
bRet = wxSetClipboardData(wxDF_METAFILE, &metaFile,
|
||||||
metaFileDataObject->GetWidth(),
|
metaFileDataObject->GetWidth(),
|
||||||
metaFileDataObject->GetHeight());
|
metaFileDataObject->GetHeight());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
#endif // wxUSE_METAFILE
|
#endif // wxUSE_METAFILE
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -726,9 +771,11 @@ bool wxClipboard::AddData( wxDataObject *data )
|
|||||||
// return wxSetClipboardData(data);
|
// return wxSetClipboardData(data);
|
||||||
// TODO
|
// TODO
|
||||||
wxLogError(wxT("Not implemented."));
|
wxLogError(wxT("Not implemented."));
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Delete owned, no longer necessary data.
|
||||||
|
delete data;
|
||||||
|
return bRet;
|
||||||
#else // !wxUSE_DATAOBJ
|
#else // !wxUSE_DATAOBJ
|
||||||
return false;
|
return false;
|
||||||
#endif // wxUSE_DATAOBJ/!wxUSE_DATAOBJ
|
#endif // wxUSE_DATAOBJ/!wxUSE_DATAOBJ
|
||||||
|
Reference in New Issue
Block a user