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__)
36 #include <wx/msw/ole/oleutils.h>
37 #include <wx/msw/ole/dataobj.h>
38 #include <wx/msw/ole/dropsrc.h>
45 // ----------------------------------------------------------------------------
46 // wxIDropSource implementation of IDropSource interface
47 // ----------------------------------------------------------------------------
49 class wxIDropSource
: public IDropSource
52 wxIDropSource(wxDropSource
*pDropSource
);
54 DECLARE_IUNKNOWN_METHODS
;
57 STDMETHODIMP
QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
);
58 STDMETHODIMP
GiveFeedback(DWORD dwEffect
);
61 DWORD m_grfInitKeyState
; // button which started the d&d operation
62 wxDropSource
*m_pDropSource
; // pointer to C++ class we belong to
65 // ============================================================================
67 // ============================================================================
69 // ----------------------------------------------------------------------------
70 // wxIDropSource implementation
71 // ----------------------------------------------------------------------------
72 BEGIN_IID_TABLE(wxIDropSource
)
77 IMPLEMENT_IUNKNOWN_METHODS(wxIDropSource
)
79 wxIDropSource::wxIDropSource(wxDropSource
*pDropSource
)
81 wxASSERT( pDropSource
!= NULL
);
83 m_pDropSource
= pDropSource
;
84 m_grfInitKeyState
= 0;
88 // Name : wxIDropSource::QueryContinueDrag
89 // Purpose : decide if drag operation must be continued or not
90 // Returns : HRESULT: S_OK if we should continue
91 // DRAGDROP_S_DROP to drop right now
92 // DRAGDROP_S_CANCEL to cancel everything
93 // Params : [in] BOOL fEscapePressed <Esc> pressed since last call?
94 // [in] DWORD grfKeyState mask containing state of kbd keys
95 // Notes : as there is no reasonably simple portable way to implement this
96 // function, we currently don't give the possibility to override the
97 // default behaviour implemented here
98 STDMETHODIMP
wxIDropSource::QueryContinueDrag(BOOL fEscapePressed
,
101 if ( fEscapePressed
)
102 return DRAGDROP_S_CANCEL
;
104 // initialize ourself with the drag begin button
105 if ( m_grfInitKeyState
== 0 ) {
106 m_grfInitKeyState
= grfKeyState
& (MK_LBUTTON
| MK_RBUTTON
| MK_MBUTTON
);
109 if ( !(grfKeyState
& m_grfInitKeyState
) ) {
110 // button which started d&d released, go!
111 return DRAGDROP_S_DROP
;
117 // Name : wxIDropSource::GiveFeedback
118 // Purpose : give UI feedback according to current state of operation
119 // Returns : STDMETHODIMP
120 // Params : [in] DWORD dwEffect - what would happen if we dropped now
121 // Notes : default implementation is ok in more than 99% of cases
122 STDMETHODIMP
wxIDropSource::GiveFeedback(DWORD dwEffect
)
124 wxDropSource::DragResult effect
;
125 if ( dwEffect
& DROPEFFECT_COPY
)
126 effect
= wxDropSource::Copy
;
127 else if ( dwEffect
& DROPEFFECT_MOVE
)
128 effect
= wxDropSource::Move
;
130 effect
= wxDropSource::None
;
132 if ( m_pDropSource
->GiveFeedback(effect
,
133 (dwEffect
& DROPEFFECT_SCROLL
) != 0 ) )
136 return DRAGDROP_S_USEDEFAULTCURSORS
;
139 // ----------------------------------------------------------------------------
140 // wxDropSource implementation
141 // ----------------------------------------------------------------------------
145 // common part of all ctors
146 void wxDropSource::Init()
148 m_pIDropSource
= new wxIDropSource(this);
149 m_pIDropSource
->AddRef();
152 wxDropSource::wxDropSource()
158 wxDropSource::wxDropSource(wxDataObject
& data
)
164 void wxDropSource::SetData(wxDataObject
& data
)
169 wxDropSource::~wxDropSource()
171 m_pIDropSource
->Release();
175 // Purpose : start drag and drop operation
176 // Returns : DragResult - the code of performed operation
177 // Params : [in] bool bAllowMove: if false, only copy is allowed
178 // Notes : you must call SetData() before if you had used def ctor
179 wxDropSource::DragResult
wxDropSource::DoDragDrop(bool bAllowMove
)
181 wxCHECK_MSG( m_pData
!= NULL
, None
, "No data in wxDropSource!" );
184 HRESULT hr
= ::DoDragDrop(m_pData
->GetInterface(),
186 bAllowMove
? DROPEFFECT_COPY
| DROPEFFECT_MOVE
190 if ( hr
== DRAGDROP_S_CANCEL
) {
193 else if ( hr
== DRAGDROP_S_DROP
) {
194 if ( dwEffect
& DROPEFFECT_COPY
) {
197 else if ( dwEffect
& DROPEFFECT_MOVE
) {
198 // consistency check: normally, we shouldn't get "move" at all
199 // here if !bAllowMove, but in practice it does happen quite often
212 wxLogApiError("DoDragDrop", hr
);
213 wxLogError("Drag & drop operation failed.");
216 wxLogDebug("Unexpected success return code %08lx from DoDragDrop.", hr
);
223 // Name : wxDropSource::GiveFeedback
224 // Purpose : visually inform the user about d&d operation state
225 // Returns : bool: true if we do all ourselves or false for default feedback
226 // Params : [in] DragResult effect - what would happen if we dropped now
227 // [in] bool bScrolling - true if target is scrolling
228 // Notes : here we just leave this stuff for default implementation
229 bool wxDropSource::GiveFeedback(DragResult effect
, bool bScrolling
)
234 #endif //USE_DRAG_AND_DROP