⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 droptgt.cpp

📁 Wxpython Implemented on Windows CE, Source code
💻 CPP
📖 第 1 页 / 共 2 页
字号:
///////////////////////////////////////////////////////////////////////////////
// Name:        src/msw/ole/droptgt.cpp
// Purpose:     wxDropTarget implementation
// Author:      Vadim Zeitlin
// Modified by:
// Created:
// RCS-ID:      $Id: droptgt.cpp,v 1.45 2006/04/26 08:21:09 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/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
        #if wxCHECK_W32API_VERSION( 1, 0 )
            #include "wx/msw/wrapwin.h"
        #endif
        #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-up
STDMETHODIMP 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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -