📄 dataobj.cpp
字号:
// 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.empty() ) return 0;#if wxUSE_UNICODE_MSLU size_t sizeOfChar; if ( wxGetOsVersion() == wxOS_WINDOWS_9X ) { // Win9x always uses ANSI file names and MSLU doesn't help with this sizeOfChar = sizeof(char); } else { sizeOfChar = sizeof(wxChar); }#else // !wxUSE_UNICODE_MSLU static const size_t sizeOfChar = sizeof(wxChar);#endif // wxUSE_UNICODE_MSLU/!wxUSE_UNICODE_MSLU // inital size of DROPFILES struct + null byte size_t sz = sizeof(DROPFILES) + sizeOfChar; const size_t count = m_filenames.size(); for ( size_t i = 0; i < count; i++ ) { // add filename length plus null byte size_t len;#if wxUSE_UNICODE_MSLU if ( sizeOfChar == sizeof(char) ) len = strlen(wxConvFileName->cWC2MB(m_filenames[i])); else#endif // wxUSE_UNICODE_MSLU len = m_filenames[i].length(); sz += (len + 1) * sizeOfChar; } 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.empty() ) 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_MSLU pDrop->fWide = wxGetOsVersion() != wxOS_WINDOWS_9X ? TRUE : FALSE;#else pDrop->fWide = wxUSE_UNICODE;#endif const size_t sizeOfChar = pDrop->fWide ? sizeof(wchar_t) : sizeof(char); // set start of filenames list (null separated) BYTE *pbuf = (BYTE *)(pDrop + 1); const size_t count = m_filenames.size(); for ( size_t i = 0; i < count; i++ ) { // copy filename to pbuf and add null terminator size_t len;#if wxUSE_UNICODE_MSLU if ( sizeOfChar == sizeof(char) ) { wxCharBuffer buf(wxConvFileName->cWC2MB(m_filenames[i])); len = strlen(buf); memcpy(pbuf, buf, len*sizeOfChar); } else#endif // wxUSE_UNICODE_MSLU { len = m_filenames[i].length(); memcpy(pbuf, m_filenames[i].c_str(), len*sizeOfChar); } pbuf += len*sizeOfChar; memset(pbuf, 0, sizeOfChar); pbuf += sizeOfChar; } // add final null terminator memset(pbuf, 0, sizeOfChar); return true;#else return false;#endif}// ----------------------------------------------------------------------------// wxURLDataObject// ----------------------------------------------------------------------------// Work around bug in Wine headers#if defined(__WINE__) && defined(CFSTR_SHELLURL) && wxUSE_UNICODE#undef CFSTR_SHELLURL#define CFSTR_SHELLURL _T("CFSTR_SHELLURL")#endifclass 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(const wxString& url){ // 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; if ( !url.empty() ) SetURL(url);}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_DATAOBJwxDataObject::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 + -