📄 dnd.cpp
字号:
///////////////////////////////////////////////////////////////////////////////// Name: src/mac/carbon/dnd.cpp// Purpose: wxDropTarget, wxDropSource implementations// Author: Stefan Csomor// Modified by:// Created: 1998-01-01// RCS-ID: $Id: dnd.cpp,v 1.56 2006/10/14 16:01:54 SC Exp $// Copyright: (c) 1998 Stefan Csomor// Licence: wxWindows licence///////////////////////////////////////////////////////////////////////////////#include "wx/wxprec.h"#if wxUSE_DRAG_AND_DROP#include "wx/dnd.h"#ifndef WX_PRECOMP #include "wx/app.h" #include "wx/toplevel.h" #include "wx/gdicmn.h"#endif // WX_PRECOMP#include "wx/mac/private.h"#ifndef __DARWIN__ #include <Scrap.h>#endif// ----------------------------------------------------------------------------// globals// ----------------------------------------------------------------------------typedef struct{ wxWindow *m_currentTargetWindow; wxDropTarget *m_currentTarget; wxDropSource *m_currentSource;} MacTrackingGlobals;MacTrackingGlobals gTrackingGlobals;void wxMacEnsureTrackingHandlersInstalled();//----------------------------------------------------------------------------// wxDropTarget//----------------------------------------------------------------------------wxDropTarget::wxDropTarget( wxDataObject *data ) : wxDropTargetBase( data ){ wxMacEnsureTrackingHandlersInstalled();}wxDragResult wxDropTarget::OnDragOver( wxCoord WXUNUSED(x), wxCoord WXUNUSED(y), wxDragResult def ){ return CurrentDragHasSupportedFormat() ? def : wxDragNone;}bool wxDropTarget::OnDrop( wxCoord WXUNUSED(x), wxCoord WXUNUSED(y) ){ if (m_dataObject == NULL) return false; return CurrentDragHasSupportedFormat();}wxDragResult wxDropTarget::OnData( wxCoord WXUNUSED(x), wxCoord WXUNUSED(y), wxDragResult def ){ if (m_dataObject == NULL) return wxDragNone; if (!CurrentDragHasSupportedFormat()) return wxDragNone; return GetData() ? def : wxDragNone;}bool wxDropTarget::CurrentDragHasSupportedFormat(){ bool supported = false; if ( gTrackingGlobals.m_currentSource != NULL ) { wxDataObject* data = gTrackingGlobals.m_currentSource->GetDataObject(); if ( data ) { size_t formatcount = data->GetFormatCount(); wxDataFormat *array = new wxDataFormat[formatcount]; data->GetAllFormats( array ); for (size_t i = 0; !supported && i < formatcount; i++) { wxDataFormat format = array[i]; if ( m_dataObject->IsSupported( format ) ) { supported = true; break; } } delete [] array; } } if ( !supported ) { UInt16 items; ItemReference theItem; FlavorType theType; UInt16 flavors = 0; CountDragItems( (DragReference)m_currentDrag, &items ); for (UInt16 index = 1; index <= items && !supported; ++index) { flavors = 0; GetDragItemReferenceNumber( (DragReference)m_currentDrag, index, &theItem ); CountDragItemFlavors( (DragReference)m_currentDrag, theItem, &flavors ); for ( UInt16 flavor = 1; flavor <= flavors; ++flavor ) { GetFlavorType( (DragReference)m_currentDrag, theItem, flavor, &theType ); if ( m_dataObject->IsSupportedFormat( wxDataFormat( theType ) ) ) { supported = true; break; } } } } return supported;}bool wxDropTarget::GetData(){ if (m_dataObject == NULL) return false; if ( !CurrentDragHasSupportedFormat() ) return false; bool transferred = false; if ( gTrackingGlobals.m_currentSource != NULL ) { wxDataObject* data = gTrackingGlobals.m_currentSource->GetDataObject(); if (data != NULL) { size_t formatcount = data->GetFormatCount(); wxDataFormat *array = new wxDataFormat[formatcount]; data->GetAllFormats( array ); for (size_t i = 0; !transferred && i < formatcount; i++) { wxDataFormat format = array[i]; if ( m_dataObject->IsSupported( format ) ) { int size = data->GetDataSize( format ); transferred = true; if (size == 0) { m_dataObject->SetData( format, 0, 0 ); } else { char *d = new char[size]; data->GetDataHere( format, (void*)d ); m_dataObject->SetData( format, size, d ); delete [] d; } } } delete [] array; } } if ( !transferred ) { UInt16 items; OSErr result; ItemReference theItem; FlavorType theType; FlavorFlags theFlags; UInt16 flavors; wxString filenamesPassed; CountDragItems( (DragReference)m_currentDrag, &items ); for (UInt16 index = 1; index <= items; ++index) { flavors = 0; GetDragItemReferenceNumber( (DragReference)m_currentDrag, index, &theItem ); CountDragItemFlavors( (DragReference)m_currentDrag, theItem, &flavors ); wxDataFormat preferredFormat = m_dataObject->GetPreferredFormat( wxDataObject::Set ); bool hasPreferredFormat = false; for (UInt16 flavor = 1; flavor <= flavors; ++flavor) { result = GetFlavorType( (DragReference)m_currentDrag, theItem, flavor, &theType ); wxDataFormat format( theType ); if (preferredFormat == format) { hasPreferredFormat = true; break; } } for (UInt16 flavor = 1; flavor <= flavors; ++flavor) { result = GetFlavorType( (DragReference)m_currentDrag, theItem, flavor, &theType ); wxDataFormat format( theType ); if ((hasPreferredFormat && format == preferredFormat) || (!hasPreferredFormat && m_dataObject->IsSupportedFormat( format ))) { result = GetFlavorFlags( (DragReference)m_currentDrag, theItem, theType, &theFlags ); if (result == noErr) { Size dataSize; Ptr theData; GetFlavorDataSize( (DragReference)m_currentDrag, theItem, theType, &dataSize ); if (theType == kScrapFlavorTypeText) { // this increment is only valid for allocating: // on the next GetFlavorData call it is reset again to the original value dataSize++; } else if (theType == kScrapFlavorTypeUnicode) { // this increment is only valid for allocating: // on the next GetFlavorData call it is reset again to the original value dataSize++; dataSize++; } if (dataSize > 0) theData = new char[dataSize]; else theData = NULL; GetFlavorData( (DragReference)m_currentDrag, theItem, theType, (void*)theData, &dataSize, 0L ); switch (theType) { case kScrapFlavorTypeText: theData[dataSize] = 0; m_dataObject->SetData( wxDataFormat(wxDF_TEXT), dataSize, theData ); break;#if wxUSE_UNICODE case kScrapFlavorTypeUnicode: theData[dataSize + 0] = theData[dataSize + 1] = 0; m_dataObject->SetData( wxDataFormat(wxDF_UNICODETEXT), dataSize, theData ); break;#endif case kDragFlavorTypeHFS: if (theData != NULL) { HFSFlavor* theFile = (HFSFlavor*)theData;#ifndef __LP64__ wxString name = wxMacFSSpec2MacFilename( &theFile->fileSpec ); if (!name.empty()) filenamesPassed += name + wxT("\n");#endif } break; default: m_dataObject->SetData( format, dataSize, theData ); break; } delete [] theData; } break; } } } if (filenamesPassed.length() > 0) { wxCharBuffer buf = filenamesPassed.fn_str(); m_dataObject->SetData( wxDataFormat(wxDF_FILENAME), strlen( buf ), (const char*)buf ); } } return true;}//-------------------------------------------------------------------------// wxDropSource//-------------------------------------------------------------------------//-----------------------------------------------------------------------------// drag requestwxDropSource::wxDropSource(wxWindow *win, const wxCursor &cursorCopy, const wxCursor &cursorMove, const wxCursor &cursorStop) : wxDropSourceBase(cursorCopy, cursorMove, cursorStop){ wxMacEnsureTrackingHandlersInstalled(); m_window = win;}wxDropSource::wxDropSource(wxDataObject& data, wxWindow *win, const wxCursor &cursorCopy, const wxCursor &cursorMove, const wxCursor &cursorStop) : wxDropSourceBase(cursorCopy, cursorMove, cursorStop){ wxMacEnsureTrackingHandlersInstalled(); SetData( data ); m_window = win;}wxDropSource::~wxDropSource(){}wxDragResult wxDropSource::DoDragDrop(int flags){ wxASSERT_MSG( m_data, wxT("Drop source: no data") ); if ((m_data == NULL) || (m_data->GetFormatCount() == 0)) return (wxDragResult)wxDragNone; DragReference theDrag; RgnHandle dragRegion; if (NewDrag( &theDrag ) != noErr) return wxDragNone; // add data to drag size_t formatCount = m_data->GetFormatCount(); wxDataFormat *formats = new wxDataFormat[formatCount]; m_data->GetAllFormats( formats ); ItemReference theItem = (ItemReference) 1; for ( size_t i = 0; i < formatCount; ++i ) { size_t dataSize = m_data->GetDataSize( formats[i] ); Ptr dataPtr = new char[dataSize]; m_data->GetDataHere( formats[i], dataPtr ); OSType type = formats[i].GetFormatId(); if ( type == 'TEXT' || type == 'utxt' ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -