📄 droptgt.cpp
字号:
///////////////////////////////////////////////////////////////////////////////// Name: src/msw/ole/droptgt.cpp// Purpose: wxDropTarget implementation// Author: Vadim Zeitlin// Modified by:// Created:// RCS-ID: $Id: droptgt.cpp,v 1.46 2006/09/07 19:01:42 ABX Exp $// Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>// Licence: wxWindows licence///////////////////////////////////////////////////////////////////////////////// ============================================================================// Declarations// ============================================================================// ----------------------------------------------------------------------------// headers// ----------------------------------------------------------------------------// For compilers that support precompilation, includes "wx.h".#include "wx/wxprec.h"#if defined(__BORLANDC__) #pragma hdrstop#endif#if wxUSE_OLE && wxUSE_DRAG_AND_DROP#ifndef WX_PRECOMP #include "wx/msw/wrapwin.h" #include "wx/log.h"#endif#include "wx/msw/private.h"#ifdef __WXWINCE__ #include <winreg.h> #include <ole2.h>#endif#ifdef __WIN32__ #if !defined(__GNUWIN32__) || wxUSE_NORLANDER_HEADERS #include <shlobj.h> // for DROPFILES structure #endif#else #include <shellapi.h>#endif#include "wx/dnd.h"#include "wx/msw/ole/oleutils.h"// ----------------------------------------------------------------------------// IDropTarget interface: forward all interesting things to wxDropTarget// (the name is unfortunate, but wx_I_DropTarget is not at all the same thing// as wxDropTarget which is 'public' class, while this one is private)// ----------------------------------------------------------------------------class wxIDropTarget : public IDropTarget{public: wxIDropTarget(wxDropTarget *p); virtual ~wxIDropTarget(); // accessors for wxDropTarget void SetHwnd(HWND hwnd) { m_hwnd = hwnd; } // IDropTarget methods STDMETHODIMP DragEnter(LPDATAOBJECT, DWORD, POINTL, LPDWORD); STDMETHODIMP DragOver(DWORD, POINTL, LPDWORD); STDMETHODIMP DragLeave(); STDMETHODIMP Drop(LPDATAOBJECT, DWORD, POINTL, LPDWORD); DECLARE_IUNKNOWN_METHODS;protected: IDataObject *m_pIDataObject; // !NULL between DragEnter and DragLeave/Drop wxDropTarget *m_pTarget; // the real target (we're just a proxy) HWND m_hwnd; // window we're associated with // get default drop effect for given keyboard flags static inline DWORD GetDropEffect(DWORD flags, wxDragResult defaultAction); DECLARE_NO_COPY_CLASS(wxIDropTarget)};// ----------------------------------------------------------------------------// private functions// ----------------------------------------------------------------------------static wxDragResult ConvertDragEffectToResult(DWORD dwEffect);static DWORD ConvertDragResultToEffect(wxDragResult result);// ============================================================================// wxIDropTarget implementation// ============================================================================// Name : static wxIDropTarget::GetDropEffect// Purpose : determine the drop operation from keyboard/mouse state.// Returns : DWORD combined from DROPEFFECT_xxx constants// Params : [in] DWORD flags kbd & mouse flags as passed to// IDropTarget methods// Notes : We do "move" normally and "copy" if <Ctrl> is pressed,// which is the standard behaviour (currently there is no// way to redefine it)DWORD wxIDropTarget::GetDropEffect(DWORD flags, wxDragResult defaultAction){ if (defaultAction == wxDragCopy) return flags & MK_SHIFT ? DROPEFFECT_MOVE : DROPEFFECT_COPY; return flags & MK_CONTROL ? DROPEFFECT_COPY : DROPEFFECT_MOVE;}wxIDropTarget::wxIDropTarget(wxDropTarget *pTarget){ m_pTarget = pTarget; m_pIDataObject = NULL;}wxIDropTarget::~wxIDropTarget(){}BEGIN_IID_TABLE(wxIDropTarget) ADD_IID(Unknown) ADD_IID(DropTarget)END_IID_TABLE;IMPLEMENT_IUNKNOWN_METHODS(wxIDropTarget)// Name : wxIDropTarget::DragEnter// Purpose : Called when the mouse enters the window (dragging something)// Returns : S_OK// Params : [in] IDataObject *pIDataSource : source data// [in] DWORD grfKeyState : kbd & mouse state// [in] POINTL pt : mouse coordinates// [out]DWORD *pdwEffect : effect flag// Notes :STDMETHODIMP wxIDropTarget::DragEnter(IDataObject *pIDataSource, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect){ wxLogTrace(wxTRACE_OleCalls, wxT("IDropTarget::DragEnter")); wxASSERT_MSG( m_pIDataObject == NULL, _T("drop target must have data object") ); // show the list of formats supported by the source data object for the // debugging purposes, this is quite useful sometimes - please don't remove#if 0 IEnumFORMATETC *penumFmt; if ( SUCCEEDED(pIDataSource->EnumFormatEtc(DATADIR_GET, &penumFmt)) ) { FORMATETC fmt; while ( penumFmt->Next(1, &fmt, NULL) == S_OK ) { wxLogDebug(_T("Drop source supports format %s"), wxDataObject::GetFormatName(fmt.cfFormat)); } penumFmt->Release(); } else { wxLogLastError(_T("IDataObject::EnumFormatEtc")); }#endif // 0 if ( !m_pTarget->IsAcceptedData(pIDataSource) ) { // we don't accept this kind of data *pdwEffect = DROPEFFECT_NONE; return S_OK; } // get hold of the data object m_pIDataObject = pIDataSource; m_pIDataObject->AddRef(); // we need client coordinates to pass to wxWin functions if ( !ScreenToClient(m_hwnd, (POINT *)&pt) ) { wxLogLastError(wxT("ScreenToClient")); } // give some visual feedback *pdwEffect = ConvertDragResultToEffect( m_pTarget->OnEnter(pt.x, pt.y, ConvertDragEffectToResult( GetDropEffect(grfKeyState, m_pTarget->GetDefaultAction())) ) ); return S_OK;}// Name : wxIDropTarget::DragOver// Purpose : Indicates that the mouse was moved inside the window represented// by this drop target.// Returns : S_OK// Params : [in] DWORD grfKeyState kbd & mouse state// [in] POINTL pt mouse coordinates// [out]LPDWORD pdwEffect effect flag// Notes : We're called on every WM_MOUSEMOVE, so this function should be// very efficient.STDMETHODIMP wxIDropTarget::DragOver(DWORD grfKeyState, POINTL pt, LPDWORD pdwEffect){ // there are too many of them... wxLogDebug("IDropTarget::DragOver"); wxDragResult result; if ( m_pIDataObject ) { result = ConvertDragEffectToResult( GetDropEffect(grfKeyState, m_pTarget->GetDefaultAction())); } else { // can't accept data anyhow normally result = wxDragNone; } // we need client coordinates to pass to wxWin functions if ( !ScreenToClient(m_hwnd, (POINT *)&pt) ) { wxLogLastError(wxT("ScreenToClient")); } *pdwEffect = ConvertDragResultToEffect( m_pTarget->OnDragOver(pt.x, pt.y, result) ); return S_OK;}// Name : wxIDropTarget::DragLeave// Purpose : Informs the drop target that the operation has left its window.// Returns : S_OK// Notes : good place to do any clean-upSTDMETHODIMP wxIDropTarget::DragLeave(){ wxLogTrace(wxTRACE_OleCalls, wxT("IDropTarget::DragLeave")); // remove the UI feedback m_pTarget->OnLeave(); // release the held object RELEASE_AND_NULL(m_pIDataObject); return S_OK;}// Name : wxIDropTarget::Drop// Purpose : Instructs the drop target to paste data that was just now// dropped on it.// Returns : S_OK// Params : [in] IDataObject *pIDataSource the data to paste// [in] DWORD grfKeyState kbd & mouse state// [in] POINTL pt where the drop occurred?// [ouy]DWORD *pdwEffect operation effect// Notes :STDMETHODIMP wxIDropTarget::Drop(IDataObject *pIDataSource, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect){ wxLogTrace(wxTRACE_OleCalls, wxT("IDropTarget::Drop")); // TODO I don't know why there is this parameter, but so far I assume // that it's the same we've already got in DragEnter wxASSERT( m_pIDataObject == pIDataSource ); // by default, nothing happens *pdwEffect = DROPEFFECT_NONE; // we need client coordinates to pass to wxWin functions
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -