1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: msw/ole/dropsrc.cpp
3 // Purpose: implementation of wxIDropSource and wxDropSource
4 // Author: Vadim Zeitlin
8 // Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // Licence: wxWindows license
10 ///////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
21 #pragma implementation "dropsrc.h"
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
27 #if defined(__BORLANDC__)
31 #include "wx/window.h"
36 #if wxUSE_DRAG_AND_DROP
39 #include "wx/dataobj.h"
40 #include "wx/msw/ole/dropsrc.h"
43 #ifdef wxUSE_NORLANDER_HEADERS
54 #include "wx/msw/ole/oleutils.h"
56 // ----------------------------------------------------------------------------
57 // wxIDropSource implementation of IDropSource interface
58 // ----------------------------------------------------------------------------
60 class wxIDropSource
: public IDropSource
63 wxIDropSource(wxDropSource
*pDropSource
);
65 DECLARE_IUNKNOWN_METHODS
;
68 STDMETHODIMP
QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
);
69 STDMETHODIMP
GiveFeedback(DWORD dwEffect
);
72 DWORD m_grfInitKeyState
; // button which started the d&d operation
73 wxDropSource
*m_pDropSource
; // pointer to C++ class we belong to
76 // ============================================================================
78 // ============================================================================
80 // ----------------------------------------------------------------------------
81 // wxIDropSource implementation
82 // ----------------------------------------------------------------------------
83 BEGIN_IID_TABLE(wxIDropSource
)
88 IMPLEMENT_IUNKNOWN_METHODS(wxIDropSource
)
90 wxIDropSource::wxIDropSource(wxDropSource
*pDropSource
)
92 wxASSERT( pDropSource
!= NULL
);
94 m_pDropSource
= pDropSource
;
95 m_grfInitKeyState
= 0;
99 // Name : wxIDropSource::QueryContinueDrag
100 // Purpose : decide if drag operation must be continued or not
101 // Returns : HRESULT: S_OK if we should continue
102 // DRAGDROP_S_DROP to drop right now
103 // DRAGDROP_S_CANCEL to cancel everything
104 // Params : [in] BOOL fEscapePressed <Esc> pressed since last call?
105 // [in] DWORD grfKeyState mask containing state of kbd keys
106 // Notes : as there is no reasonably simple portable way to implement this
107 // function, we currently don't give the possibility to override the
108 // default behaviour implemented here
109 STDMETHODIMP
wxIDropSource::QueryContinueDrag(BOOL fEscapePressed
,
112 if ( fEscapePressed
)
113 return DRAGDROP_S_CANCEL
;
115 // initialize ourself with the drag begin button
116 if ( m_grfInitKeyState
== 0 ) {
117 m_grfInitKeyState
= grfKeyState
& (MK_LBUTTON
| MK_RBUTTON
| MK_MBUTTON
);
120 if ( !(grfKeyState
& m_grfInitKeyState
) ) {
121 // button which started d&d released, go!
122 return DRAGDROP_S_DROP
;
128 // Name : wxIDropSource::GiveFeedback
129 // Purpose : give UI feedback according to current state of operation
130 // Returns : STDMETHODIMP
131 // Params : [in] DWORD dwEffect - what would happen if we dropped now
132 // Notes : default implementation is ok in more than 99% of cases
133 STDMETHODIMP
wxIDropSource::GiveFeedback(DWORD dwEffect
)
136 if ( dwEffect
& DROPEFFECT_COPY
)
138 else if ( dwEffect
& DROPEFFECT_MOVE
)
143 if ( m_pDropSource
->GiveFeedback(effect
,
144 (dwEffect
& DROPEFFECT_SCROLL
) != 0 ) )
147 return DRAGDROP_S_USEDEFAULTCURSORS
;
150 // ----------------------------------------------------------------------------
151 // wxDropSource implementation
152 // ----------------------------------------------------------------------------
156 // common part of all ctors
157 void wxDropSource::Init()
159 m_pIDropSource
= new wxIDropSource(this);
160 m_pIDropSource
->AddRef();
163 wxDropSource::wxDropSource(wxWindow
* WXUNUSED(win
))
169 wxDropSource::wxDropSource(wxDataObject
& data
, wxWindow
* WXUNUSED(win
))
175 void wxDropSource::SetData(wxDataObject
& data
)
180 wxDropSource::~wxDropSource()
182 m_pIDropSource
->Release();
186 // Purpose : start drag and drop operation
187 // Returns : wxDragResult - the code of performed operation
188 // Params : [in] bool bAllowMove: if false, only copy is allowed
189 // Notes : you must call SetData() before if you had used def ctor
190 wxDragResult
wxDropSource::DoDragDrop(bool bAllowMove
)
192 wxCHECK_MSG( m_pData
!= NULL
, wxDragNone
, T("No data in wxDropSource!") );
195 HRESULT hr
= ::DoDragDrop(m_pData
->GetInterface(),
197 bAllowMove
? DROPEFFECT_COPY
| DROPEFFECT_MOVE
201 if ( hr
== DRAGDROP_S_CANCEL
) {
204 else if ( hr
== DRAGDROP_S_DROP
) {
205 if ( dwEffect
& DROPEFFECT_COPY
) {
208 else if ( dwEffect
& DROPEFFECT_MOVE
) {
209 // consistency check: normally, we shouldn't get "move" at all
210 // here if !bAllowMove, but in practice it does happen quite often
223 wxLogApiError("DoDragDrop", hr
);
224 wxLogError(T("Drag & drop operation failed."));
227 wxLogDebug(T("Unexpected success return code %08lx from DoDragDrop."), hr
);
234 // Name : wxDropSource::GiveFeedback
235 // Purpose : visually inform the user about d&d operation state
236 // Returns : bool: true if we do all ourselves or false for default feedback
237 // Params : [in] DragResult effect - what would happen if we dropped now
238 // [in] bool bScrolling - true if target is scrolling
239 // Notes : here we just leave this stuff for default implementation
240 bool wxDropSource::GiveFeedback(wxDragResult effect
, bool bScrolling
)
245 #endif //USE_DRAG_AND_DROP