// Created: 10.05.98
// RCS-ID: $Id$
// Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
-// Licence: wxWindows license
+// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
// ============================================================================
#include "wx/msw/private.h" // includes <windows.h>
-#if wxUSE_NORLANDER_HEADERS
- #include <ole2.h>
+#ifdef __WXWINCE__
+#include <winreg.h>
#endif
-#include <oleauto.h>
-#ifndef __WIN32__
+// for some compilers, the entire ole2.h must be included, not only oleauto.h
+#if wxUSE_NORLANDER_HEADERS || defined(__WATCOMC__) || defined(__WXWINCE__)
#include <ole2.h>
- #include <olestd.h>
#endif
+#include <oleauto.h>
#include <shlobj.h>
#include "wx/msw/ole/oleutils.h"
#ifdef __WXDEBUG__
static const wxChar *GetTymedName(DWORD tymed);
#else // !Debug
- #define GetTymedName(tymed) _T("")
+ #define GetTymedName(tymed) wxEmptyString
#endif // Debug/!Debug
// ----------------------------------------------------------------------------
CLIPFORMAT *m_formats; // formats we can provide data in
ULONG m_nCount, // number of formats we support
m_nCurrent; // current enum position
+
+ DECLARE_NO_COPY_CLASS(wxIEnumFORMATETC)
};
// ----------------------------------------------------------------------------
wxDataObject *m_pDataObject; // pointer to C++ class we belong to
bool m_mustDelete;
+
+ DECLARE_NO_COPY_CLASS(wxIDataObject)
};
// ============================================================================
STDMETHODIMP wxIEnumFORMATETC::Next(ULONG celt,
FORMATETC *rgelt,
- ULONG *WXUNUSED(pceltFetched))
+ ULONG *pceltFetched)
{
wxLogTrace(wxTRACE_OleCalls, wxT("wxIEnumFORMATETC::Next"));
- if ( celt > 1 ) {
- // we only return 1 element at a time - mainly because I'm too lazy to
- // implement something which you're never asked for anyhow
- return S_FALSE;
- }
-
- if ( m_nCurrent < m_nCount ) {
+ ULONG numFetched = 0;
+ while (m_nCurrent < m_nCount && numFetched < celt) {
FORMATETC format;
format.cfFormat = m_formats[m_nCurrent++];
format.ptd = NULL;
format.dwAspect = DVASPECT_CONTENT;
format.lindex = -1;
format.tymed = TYMED_HGLOBAL;
- *rgelt = format;
- return S_OK;
- }
- else {
- // bad index
- return S_FALSE;
+ *rgelt++ = format;
+ numFetched++;
}
+
+ if (pceltFetched)
+ *pceltFetched = numFetched;
+
+ return numFetched == celt ? S_OK : S_FALSE;
}
STDMETHODIMP wxIEnumFORMATETC::Skip(ULONG celt)
pmedium->tymed = TYMED_ENHMF;
break;
+#ifndef __WXWINCE__
case wxDF_METAFILE:
pmedium->hGlobal = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE,
sizeof(METAFILEPICT));
}
pmedium->tymed = TYMED_MFPICT;
break;
-
+#endif
default:
// alloc memory
size_t size = m_pDataObject->GetDataSize(format);
return S_OK;
}
+
// set data functions
STDMETHODIMP wxIDataObject::SetData(FORMATETC *pformatetc,
STGMEDIUM *pmedium,
// as we can't fix this bug in explorer (it's a bug because it
// should only use formats returned by EnumFormatEtc), do the
// check here
- if ( !m_pDataObject->IsSupportedFormat(format) ) {
+ if ( !m_pDataObject->IsSupported(format, wxDataObject::Set) ) {
// go away!
return DV_E_FORMATETC;
}
|| ( defined(__MWERKS__) && defined(__WXMSW__) )
size = std::wcslen((const wchar_t *)pBuf) * sizeof(wchar_t);
#else
- size = ::wcslen((const wchar_t *)pBuf) * sizeof(wchar_t);
+ size = wxWcslen((const wchar_t *)pBuf) * sizeof(wchar_t);
#endif
break;
#endif
case CF_BITMAP:
+#ifndef __WXWINCE__
case CF_HDROP:
// these formats don't use size at all, anyhow (but
// pass data by handle, which is always a single DWORD)
size = 0;
break;
+#endif
case CF_DIB:
// the handler will calculate size itself (it's too
size = 0;
break;
+#ifndef __WXWINCE__
case CF_METAFILEPICT:
size = sizeof(METAFILEPICT);
break;
-
+#endif
default:
{
// we suppose that the size precedes the data
size_t wxBitmapDataObject::GetDataSize() const
{
- return wxConvertBitmapToDIB(NULL, GetBitmap());
+#if wxUSE_WXDIB
+ return wxDIB::ConvertFromBitmap(NULL, GetHbitmapOf(GetBitmap()));
+#else
+ return 0;
+#endif
}
bool wxBitmapDataObject::GetDataHere(void *buf) const
{
- return wxConvertBitmapToDIB((LPBITMAPINFO)buf, GetBitmap()) != 0;
+#if wxUSE_WXDIB
+ BITMAPINFO * const pbi = (BITMAPINFO *)buf;
+
+ return wxDIB::ConvertFromBitmap(pbi, GetHbitmapOf(GetBitmap())) != 0;
+#else
+ return FALSE;
+#endif
}
bool wxBitmapDataObject::SetData(size_t WXUNUSED(len), const void *buf)
{
- wxBitmap bitmap(wxConvertDIBToBitmap((const LPBITMAPINFO)buf));
+#if wxUSE_WXDIB
+ const BITMAPINFO * const pbmi = (const BITMAPINFO *)buf;
- if ( !bitmap.Ok() ) {
- wxFAIL_MSG(wxT("pasting/dropping invalid bitmap"));
+ HBITMAP hbmp = wxDIB::ConvertToBitmap(pbmi);
- return FALSE;
- }
+ wxCHECK_MSG( hbmp, FALSE, wxT("pasting/dropping invalid bitmap") );
+
+ const BITMAPINFOHEADER * const pbmih = &pbmi->bmiHeader;
+ wxBitmap bitmap(pbmih->biWidth, pbmih->biHeight, pbmih->biBitCount);
+ bitmap.SetHBITMAP((WXHBITMAP)hbmp);
+
+ // TODO: create wxPalette if the bitmap has any
SetBitmap(bitmap);
return TRUE;
+#else
+ return FALSE;
+#endif
}
// ----------------------------------------------------------------------------
bool wxFileDataObject::SetData(size_t WXUNUSED(size), const void *pData)
{
+#ifndef __WXWINCE__
m_filenames.Empty();
// the documentation states that the first member of DROPFILES structure is
}
return TRUE;
+#else
+ return FALSE;
+#endif
}
void wxFileDataObject::AddFile(const wxString& file)
size_t wxFileDataObject::GetDataSize() const
{
+#ifndef __WXWINCE__
// size returned will be the size of the DROPFILES structure,
// plus the list of filesnames (null byte separated), plus
// a double null at the end
}
return sz;
+#else
+ return 0;
+#endif
}
bool wxFileDataObject::GetDataHere(void *pData) const
{
+#ifndef __WXWINCE__
// pData points to an externally allocated memory block
// created using the size returned by GetDataSize()
*pbuf = wxT('\0');
return TRUE;
+#else
+ return FALSE;
+#endif
}
// ----------------------------------------------------------------------------
// wxURLDataObject
// ----------------------------------------------------------------------------
-
class CFSTR_SHELLURLDataObject : public wxCustomDataObject
{
public:
// CFSTR_SHELLURL is _always_ ANSI!
wxCharBuffer char_buffer( GetDataSize() );
wxCustomDataObject::GetDataHere( (void*)char_buffer.data() );
- wxString unicode_buffer( char_buffer );
+ wxString unicode_buffer( char_buffer, wxConvLibc );
memcpy( buffer, unicode_buffer.c_str(),
( unicode_buffer.length() + 1 ) * sizeof(wxChar) );
// private functions
// ----------------------------------------------------------------------------
-static size_t wxGetNumOfBitmapColors(size_t bitsPerPixel)
-{
- switch ( bitsPerPixel )
- {
- case 1:
- // monochrome bitmap, 2 entries
- return 2;
-
- case 4:
- return 16;
-
- case 8:
- return 256;
-
- case 24:
- // may be used with 24bit bitmaps, but we don't use it here - fall
- // through
-
- case 16:
- case 32:
- // bmiColors not used at all with these bitmaps
- return 0;
-
- default:
- wxFAIL_MSG( wxT("unknown bitmap format") );
- return 0;
- }
-}
-
-size_t wxConvertBitmapToDIB(LPBITMAPINFO pbi, const wxBitmap& bitmap)
-{
- wxASSERT_MSG( bitmap.Ok(), wxT("invalid bmp can't be converted to DIB") );
-
- // shouldn't be selected into a DC or GetDIBits() would fail
- wxASSERT_MSG( !bitmap.GetSelectedInto(),
- wxT("can't copy bitmap selected into wxMemoryDC") );
-
- // prepare all the info we need
- BITMAP bm;
- HBITMAP hbmp = (HBITMAP)bitmap.GetHBITMAP();
- if ( !GetObject(hbmp, sizeof(bm), &bm) )
- {
- wxLogLastError(wxT("GetObject(bitmap)"));
-
- return 0;
- }
-
- // calculate the number of bits per pixel and the number of items in
- // bmiColors array (whose meaning depends on the bitmap format)
- WORD biBits = bm.bmPlanes * bm.bmBitsPixel;
- WORD biColors = (WORD)wxGetNumOfBitmapColors(biBits);
-
- BITMAPINFO bi2;
-
- bool wantSizeOnly = pbi == NULL;
- if ( wantSizeOnly )
- pbi = &bi2;
-
- // just for convenience
- BITMAPINFOHEADER& bi = pbi->bmiHeader;
-
- bi.biSize = sizeof(BITMAPINFOHEADER);
- bi.biWidth = bm.bmWidth;
- bi.biHeight = bm.bmHeight;
- bi.biPlanes = 1;
- bi.biBitCount = biBits;
- bi.biCompression = BI_RGB;
- bi.biSizeImage = 0;
- bi.biXPelsPerMeter = 0;
- bi.biYPelsPerMeter = 0;
- bi.biClrUsed = 0;
- bi.biClrImportant = 0;
-
- // memory we need for BITMAPINFO only
- DWORD dwLen = bi.biSize + biColors * sizeof(RGBQUAD);
-
- // first get the image size
- ScreenHDC hdc;
- if ( !GetDIBits(hdc, hbmp, 0, bi.biHeight, NULL, pbi, DIB_RGB_COLORS) )
- {
- wxLogLastError(wxT("GetDIBits(NULL)"));
-
- return 0;
- }
-
- if ( wantSizeOnly )
- {
- // size of the header + size of the image
- return dwLen + bi.biSizeImage;
- }
-
- // and now copy the bits
- void *image = (char *)pbi + dwLen;
- if ( !GetDIBits(hdc, hbmp, 0, bi.biHeight, image, pbi, DIB_RGB_COLORS) )
- {
- wxLogLastError(wxT("GetDIBits"));
-
- return 0;
- }
-
- return dwLen + bi.biSizeImage;
-}
-
-wxBitmap wxConvertDIBToBitmap(const LPBITMAPINFO pbmi)
-{
- // here we get BITMAPINFO struct followed by the actual bitmap bits and
- // BITMAPINFO starts with BITMAPINFOHEADER followed by colour info
- const BITMAPINFOHEADER *pbmih = &pbmi->bmiHeader;
-
- // biClrUsed has the number of colors, unless it's 0
- int numColors = pbmih->biClrUsed;
- if (numColors==0)
- {
- numColors = wxGetNumOfBitmapColors(pbmih->biBitCount);
- }
-
- // offset of image from the beginning of the header
- DWORD ofs = numColors * sizeof(RGBQUAD);
- void *image = (char *)pbmih + sizeof(BITMAPINFOHEADER) + ofs;
-
- ScreenHDC hdc;
- HBITMAP hbmp = CreateDIBitmap(hdc, pbmih, CBM_INIT,
- image, pbmi, DIB_RGB_COLORS);
- if ( !hbmp )
- {
- wxLogLastError(wxT("CreateDIBitmap"));
- }
-
- wxBitmap bitmap(pbmih->biWidth, pbmih->biHeight, pbmih->biBitCount);
- bitmap.SetHBITMAP((WXHBITMAP)hbmp);
-
- return bitmap;
-}
-
#ifdef __WXDEBUG__
static const wxChar *GetTymedName(DWORD tymed)