📄 dataobj.cpp
字号:
BITMAP bmp;
if ( !GetObject(hbmp, sizeof(BITMAP), &bmp) )
{
wxLogLastError(wxT("GetObject(HBITMAP)"));
}
wxBitmap bitmap(bmp.bmWidth, bmp.bmHeight, bmp.bmPlanes);
bitmap.SetHBITMAP((WXHBITMAP)hbmp);
if ( !bitmap.Ok() ) {
wxFAIL_MSG(wxT("pasting/dropping invalid bitmap"));
return false;
}
SetBitmap(bitmap);
return true;
}
#if 0
size_t wxBitmapDataObject::GetDataSize(const wxDataFormat& format) const
{
if ( format.GetFormatId() == CF_DIB )
{
// create the DIB
ScreenHDC hdc;
// shouldn't be selected into a DC or GetDIBits() would fail
wxASSERT_MSG( !m_bitmap.GetSelectedInto(),
wxT("can't copy bitmap selected into wxMemoryDC") );
// first get the info
BITMAPINFO bi;
if ( !GetDIBits(hdc, (HBITMAP)m_bitmap.GetHBITMAP(), 0, 0,
NULL, &bi, DIB_RGB_COLORS) )
{
wxLogLastError(wxT("GetDIBits(NULL)"));
return 0;
}
return sizeof(BITMAPINFO) + bi.bmiHeader.biSizeImage;
}
else // CF_BITMAP
{
// no data to copy - we don't pass HBITMAP via global memory
return 0;
}
}
bool wxBitmapDataObject::GetDataHere(const wxDataFormat& format,
void *pBuf) const
{
wxASSERT_MSG( m_bitmap.Ok(), wxT("copying invalid bitmap") );
HBITMAP hbmp = (HBITMAP)m_bitmap.GetHBITMAP();
if ( format.GetFormatId() == CF_DIB )
{
// create the DIB
ScreenHDC hdc;
// shouldn't be selected into a DC or GetDIBits() would fail
wxASSERT_MSG( !m_bitmap.GetSelectedInto(),
wxT("can't copy bitmap selected into wxMemoryDC") );
// first get the info
BITMAPINFO *pbi = (BITMAPINFO *)pBuf;
if ( !GetDIBits(hdc, hbmp, 0, 0, NULL, pbi, DIB_RGB_COLORS) )
{
wxLogLastError(wxT("GetDIBits(NULL)"));
return 0;
}
// and now copy the bits
if ( !GetDIBits(hdc, hbmp, 0, pbi->bmiHeader.biHeight, pbi + 1,
pbi, DIB_RGB_COLORS) )
{
wxLogLastError(wxT("GetDIBits"));
return false;
}
}
else // CF_BITMAP
{
// we put a bitmap handle into pBuf
*(HBITMAP *)pBuf = hbmp;
}
return true;
}
bool wxBitmapDataObject::SetData(const wxDataFormat& format,
size_t size, const void *pBuf)
{
HBITMAP hbmp;
if ( format.GetFormatId() == CF_DIB )
{
// here we get BITMAPINFO struct followed by the actual bitmap bits and
// BITMAPINFO starts with BITMAPINFOHEADER followed by colour info
ScreenHDC hdc;
BITMAPINFO *pbmi = (BITMAPINFO *)pBuf;
BITMAPINFOHEADER *pbmih = &pbmi->bmiHeader;
hbmp = CreateDIBitmap(hdc, pbmih, CBM_INIT,
pbmi + 1, pbmi, DIB_RGB_COLORS);
if ( !hbmp )
{
wxLogLastError(wxT("CreateDIBitmap"));
}
m_bitmap.SetWidth(pbmih->biWidth);
m_bitmap.SetHeight(pbmih->biHeight);
}
else // CF_BITMAP
{
// it's easy with bitmaps: we pass them by handle
hbmp = *(HBITMAP *)pBuf;
BITMAP bmp;
if ( !GetObject(hbmp, sizeof(BITMAP), &bmp) )
{
wxLogLastError(wxT("GetObject(HBITMAP)"));
}
m_bitmap.SetWidth(bmp.bmWidth);
m_bitmap.SetHeight(bmp.bmHeight);
m_bitmap.SetDepth(bmp.bmPlanes);
}
m_bitmap.SetHBITMAP((WXHBITMAP)hbmp);
wxASSERT_MSG( m_bitmap.Ok(), wxT("pasting invalid bitmap") );
return true;
}
#endif // 0
// ----------------------------------------------------------------------------
// wxFileDataObject
// ----------------------------------------------------------------------------
bool wxFileDataObject::SetData(size_t WXUNUSED(size),
const void *WXUNUSED_IN_WINCE(pData))
{
#ifndef __WXWINCE__
m_filenames.Empty();
// the documentation states that the first member of DROPFILES structure is
// a "DWORD offset of double NUL terminated file list". What they mean by
// this (I wonder if you see it immediately) is that the list starts at
// ((char *)&(pDropFiles.pFiles)) + pDropFiles.pFiles. We're also advised
// to use DragQueryFile to work with this structure, but not told where and
// how to get HDROP.
HDROP hdrop = (HDROP)pData; // NB: it works, but I'm not sure about it
// get number of files (magic value -1)
UINT nFiles = ::DragQueryFile(hdrop, (unsigned)-1, NULL, 0u);
wxCHECK_MSG ( nFiles != (UINT)-1, FALSE, wxT("wrong HDROP handle") );
// for each file get the length, allocate memory and then get the name
wxString str;
UINT len, n;
for ( n = 0; n < nFiles; n++ ) {
// +1 for terminating NUL
len = ::DragQueryFile(hdrop, n, NULL, 0) + 1;
UINT len2 = ::DragQueryFile(hdrop, n, wxStringBuffer(str, len), len);
m_filenames.Add(str);
if ( len2 != len - 1 ) {
wxLogDebug(wxT("In wxFileDropTarget::OnDrop DragQueryFile returned\
%d characters, %d expected."), len2, len - 1);
}
}
return true;
#else
return false;
#endif
}
void wxFileDataObject::AddFile(const wxString& file)
{
// just add file to filenames array
// all useful data (such as DROPFILES struct) will be
// created later as necessary
m_filenames.Add(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
// if no filenames in list, size is 0
if ( m_filenames.GetCount() == 0 )
return 0;
// inital size of DROPFILES struct + null byte
size_t sz = sizeof(DROPFILES) + (1 * sizeof(wxChar));
size_t count = m_filenames.GetCount();
for ( size_t i = 0; i < count; i++ )
{
// add filename length plus null byte
sz += (m_filenames[i].Len() + 1) * sizeof(wxChar);
}
return sz;
#else
return 0;
#endif
}
bool wxFileDataObject::GetDataHere(void *WXUNUSED_IN_WINCE(pData)) const
{
#ifndef __WXWINCE__
// pData points to an externally allocated memory block
// created using the size returned by GetDataSize()
// if pData is NULL, or there are no files, return
if ( !pData || m_filenames.GetCount() == 0 )
return false;
// convert data pointer to a DROPFILES struct pointer
LPDROPFILES pDrop = (LPDROPFILES) pData;
// initialize DROPFILES struct
pDrop->pFiles = sizeof(DROPFILES);
pDrop->fNC = FALSE; // not non-client coords
#if wxUSE_UNICODE
pDrop->fWide = TRUE;
#else // ANSI
pDrop->fWide = FALSE;
#endif // Unicode/Ansi
// set start of filenames list (null separated)
wxChar *pbuf = (wxChar*) ((BYTE *)pDrop + sizeof(DROPFILES));
size_t count = m_filenames.GetCount();
for (size_t i = 0; i < count; i++ )
{
// copy filename to pbuf and add null terminator
size_t len = m_filenames[i].Len();
memcpy(pbuf, m_filenames[i], len*sizeof(wxChar));
pbuf += len;
*pbuf++ = wxT('\0');
}
// add final null terminator
*pbuf = wxT('\0');
return true;
#else
return false;
#endif
}
// ----------------------------------------------------------------------------
// wxURLDataObject
// ----------------------------------------------------------------------------
class CFSTR_SHELLURLDataObject : public wxCustomDataObject
{
public:
CFSTR_SHELLURLDataObject() : wxCustomDataObject(CFSTR_SHELLURL) {}
virtual size_t GetBufferOffset( const wxDataFormat& WXUNUSED(format) )
{
return 0;
}
virtual const void* GetSizeFromBuffer( const void* buffer, size_t* size,
const wxDataFormat& WXUNUSED(format) )
{
// CFSTR_SHELLURL is _always_ ANSI text
*size = strlen( (const char*)buffer );
return buffer;
}
virtual void* SetSizeInBuffer( void* buffer, size_t WXUNUSED(size),
const wxDataFormat& WXUNUSED(format) )
{
return buffer;
}
#if wxUSE_UNICODE
virtual bool GetDataHere( void* buffer ) const
{
// CFSTR_SHELLURL is _always_ ANSI!
wxCharBuffer char_buffer( GetDataSize() );
wxCustomDataObject::GetDataHere( (void*)char_buffer.data() );
wxString unicode_buffer( char_buffer, wxConvLibc );
memcpy( buffer, unicode_buffer.c_str(),
( unicode_buffer.length() + 1 ) * sizeof(wxChar) );
return true;
}
virtual bool GetDataHere(const wxDataFormat& WXUNUSED(format),
void *buf) const
{ return GetDataHere(buf); }
#endif
DECLARE_NO_COPY_CLASS(CFSTR_SHELLURLDataObject)
};
wxURLDataObject::wxURLDataObject()
{
// we support CF_TEXT and CFSTR_SHELLURL formats which are basicly the same
// but it seems that some browsers only provide one of them so we have to
// support both
Add(new wxTextDataObject);
Add(new CFSTR_SHELLURLDataObject());
// we don't have any data yet
m_dataObjectLast = NULL;
}
bool wxURLDataObject::SetData(const wxDataFormat& format,
size_t len,
const void *buf)
{
m_dataObjectLast = GetObject(format);
wxCHECK_MSG( m_dataObjectLast, FALSE,
wxT("unsupported format in wxURLDataObject"));
return m_dataObjectLast->SetData(len, buf);
}
wxString wxURLDataObject::GetURL() const
{
wxString url;
wxCHECK_MSG( m_dataObjectLast, url, _T("no data in wxURLDataObject") );
size_t len = m_dataObjectLast->GetDataSize();
m_dataObjectLast->GetDataHere(wxStringBuffer(url, len));
return url;
}
void wxURLDataObject::SetURL(const wxString& url)
{
SetData(wxDataFormat(wxUSE_UNICODE ? wxDF_UNICODETEXT : wxDF_TEXT),
url.Length()+1, url.c_str());
// CFSTR_SHELLURL is always supposed to be ANSI...
wxWX2MBbuf urlA = (wxWX2MBbuf)url.mbc_str();
size_t len = strlen(urlA);
SetData(wxDataFormat(CFSTR_SHELLURL), len+1, (const char*)urlA);
}
// ----------------------------------------------------------------------------
// private functions
// ----------------------------------------------------------------------------
#ifdef __WXDEBUG__
static const wxChar *GetTymedName(DWORD tymed)
{
static wxChar s_szBuf[128];
switch ( tymed ) {
case TYMED_HGLOBAL: return wxT("TYMED_HGLOBAL");
case TYMED_FILE: return wxT("TYMED_FILE");
case TYMED_ISTREAM: return wxT("TYMED_ISTREAM");
case TYMED_ISTORAGE: return wxT("TYMED_ISTORAGE");
case TYMED_GDI: return wxT("TYMED_GDI");
case TYMED_MFPICT: return wxT("TYMED_MFPICT");
case TYMED_ENHMF: return wxT("TYMED_ENHMF");
default:
wxSprintf(s_szBuf, wxT("type of media format %ld (unknown)"), tymed);
return s_szBuf;
}
}
#endif // Debug
#else // not using OLE at all
// ----------------------------------------------------------------------------
// wxDataObject
// ----------------------------------------------------------------------------
#if wxUSE_DATAOBJ
wxDataObject::wxDataObject()
{
}
wxDataObject::~wxDataObject()
{
}
void wxDataObject::SetAutoDelete()
{
}
#ifdef __WXDEBUG__
const wxChar *wxDataObject::GetFormatName(wxDataFormat WXUNUSED(format))
{
return NULL;
}
#endif // __WXDEBUG__
#endif // wxUSE_DATAOBJ
#endif // wxUSE_OLE/!wxUSE_OLE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -