📄 droptgt.cpp
字号:
if ( !ScreenToClient(m_hwnd, (POINT *)&pt) ) { wxLogLastError(wxT("ScreenToClient")); } // first ask the drop target if it wants data if ( m_pTarget->OnDrop(pt.x, pt.y) ) { // it does, so give it the data source m_pTarget->SetDataSource(pIDataSource); // and now it has the data wxDragResult rc = ConvertDragEffectToResult( GetDropEffect(grfKeyState, m_pTarget->GetDefaultAction())); rc = m_pTarget->OnData(pt.x, pt.y, rc); if ( wxIsDragResultOk(rc) ) { // operation succeeded *pdwEffect = ConvertDragResultToEffect(rc); } //else: *pdwEffect is already DROPEFFECT_NONE } //else: OnDrop() returned false, no need to copy data // release the held object RELEASE_AND_NULL(m_pIDataObject); return S_OK;}// ============================================================================// wxDropTarget implementation// ============================================================================// ----------------------------------------------------------------------------// ctor/dtor// ----------------------------------------------------------------------------wxDropTarget::wxDropTarget(wxDataObject *dataObj) : wxDropTargetBase(dataObj){ // create an IDropTarget implementation which will notify us about d&d // operations. m_pIDropTarget = new wxIDropTarget(this); m_pIDropTarget->AddRef();}wxDropTarget::~wxDropTarget(){ ReleaseInterface(m_pIDropTarget);}// ----------------------------------------------------------------------------// [un]register drop handler// ----------------------------------------------------------------------------bool wxDropTarget::Register(WXHWND hwnd){ // FIXME // RegisterDragDrop not available on Windows CE >= 400? // Or maybe we can dynamically load them from ceshell.dll // or similar.#if defined(__WXWINCE__) && _WIN32_WCE >= 400 wxUnusedVar(hwnd); return false;#else HRESULT hr; // May exist in later WinCE versions#ifndef __WXWINCE__ hr = ::CoLockObjectExternal(m_pIDropTarget, TRUE, FALSE); if ( FAILED(hr) ) { wxLogApiError(wxT("CoLockObjectExternal"), hr); return false; }#endif hr = ::RegisterDragDrop((HWND) hwnd, m_pIDropTarget); if ( FAILED(hr) ) { // May exist in later WinCE versions#ifndef __WXWINCE__ ::CoLockObjectExternal(m_pIDropTarget, FALSE, FALSE);#endif wxLogApiError(wxT("RegisterDragDrop"), hr); return false; } // we will need the window handle for coords transformation later m_pIDropTarget->SetHwnd((HWND)hwnd); return true;#endif}void wxDropTarget::Revoke(WXHWND hwnd){#if defined(__WXWINCE__) && _WIN32_WCE >= 400 // Not available, see note above wxUnusedVar(hwnd);#else HRESULT hr = ::RevokeDragDrop((HWND) hwnd); if ( FAILED(hr) ) { wxLogApiError(wxT("RevokeDragDrop"), hr); } // May exist in later WinCE versions#ifndef __WXWINCE__ ::CoLockObjectExternal(m_pIDropTarget, FALSE, TRUE);#endif m_pIDropTarget->SetHwnd(0);#endif}// ----------------------------------------------------------------------------// base class pure virtuals// ----------------------------------------------------------------------------// OnDrop() is called only if we previously returned true from// IsAcceptedData(), so no need to check anything herebool wxDropTarget::OnDrop(wxCoord WXUNUSED(x), wxCoord WXUNUSED(y)){ return true;}// copy the data from the data source to the target data objectbool wxDropTarget::GetData(){ wxDataFormat format = GetSupportedFormat(m_pIDataSource); if ( format == wxDF_INVALID ) { // this is strange because IsAcceptedData() succeeded previously! wxFAIL_MSG(wxT("strange - did supported formats list change?")); return false; } STGMEDIUM stm; FORMATETC fmtMemory; fmtMemory.cfFormat = format; fmtMemory.ptd = NULL; fmtMemory.dwAspect = DVASPECT_CONTENT; fmtMemory.lindex = -1; fmtMemory.tymed = TYMED_HGLOBAL; // TODO to add other media bool rc = false; HRESULT hr = m_pIDataSource->GetData(&fmtMemory, &stm); if ( SUCCEEDED(hr) ) { IDataObject *dataObject = m_dataObject->GetInterface(); hr = dataObject->SetData(&fmtMemory, &stm, TRUE); if ( SUCCEEDED(hr) ) { rc = true; } else { wxLogApiError(wxT("IDataObject::SetData()"), hr); } } else { wxLogApiError(wxT("IDataObject::GetData()"), hr); } return rc;}// ----------------------------------------------------------------------------// callbacks used by wxIDropTarget// ----------------------------------------------------------------------------// we need a data source, so wxIDropTarget gives it to us using this functionvoid wxDropTarget::SetDataSource(IDataObject *pIDataSource){ m_pIDataSource = pIDataSource;}// determine if we accept data of this typebool wxDropTarget::IsAcceptedData(IDataObject *pIDataSource) const{ return GetSupportedFormat(pIDataSource) != wxDF_INVALID;}// ----------------------------------------------------------------------------// helper functions// ----------------------------------------------------------------------------wxDataFormat wxDropTarget::GetSupportedFormat(IDataObject *pIDataSource) const{ // this strucutre describes a data of any type (first field will be // changing) being passed through global memory block. static FORMATETC s_fmtMemory = { 0, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL // TODO is it worth supporting other tymeds here? }; // get the list of supported formats size_t nFormats = m_dataObject->GetFormatCount(wxDataObject::Set); wxDataFormat format; wxDataFormat *formats; formats = nFormats == 1 ? &format : new wxDataFormat[nFormats]; m_dataObject->GetAllFormats(formats, wxDataObject::Set); // cycle through all supported formats size_t n; for ( n = 0; n < nFormats; n++ ) { s_fmtMemory.cfFormat = formats[n]; // NB: don't use SUCCEEDED macro here: QueryGetData returns S_FALSE // for file drag and drop (format == CF_HDROP) if ( pIDataSource->QueryGetData(&s_fmtMemory) == S_OK ) { format = formats[n]; break; } } if ( formats != &format ) { // free memory if we allocated it delete [] formats; } return n < nFormats ? format : wxFormatInvalid;}// ----------------------------------------------------------------------------// private functions// ----------------------------------------------------------------------------static wxDragResult ConvertDragEffectToResult(DWORD dwEffect){ switch ( dwEffect ) { case DROPEFFECT_COPY: return wxDragCopy; case DROPEFFECT_LINK: return wxDragLink; case DROPEFFECT_MOVE: return wxDragMove; default: wxFAIL_MSG(wxT("invalid value in ConvertDragEffectToResult")); // fall through case DROPEFFECT_NONE: return wxDragNone; }}static DWORD ConvertDragResultToEffect(wxDragResult result){ switch ( result ) { case wxDragCopy: return DROPEFFECT_COPY; case wxDragLink: return DROPEFFECT_LINK; case wxDragMove: return DROPEFFECT_MOVE; default: wxFAIL_MSG(wxT("invalid value in ConvertDragResultToEffect")); // fall through case wxDragNone: return DROPEFFECT_NONE; }}#endif // wxUSE_OLE && wxUSE_DRAG_AND_DROP
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -