1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/msw/ole/dropsrc.cpp
3 // Purpose: implementation of wxIDropSource and wxDropSource
4 // Author: Vadim Zeitlin
7 // Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
11 // ============================================================================
13 // ============================================================================
15 // ----------------------------------------------------------------------------
17 // ----------------------------------------------------------------------------
19 // For compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
22 #if defined(__BORLANDC__)
26 #if wxUSE_OLE && wxUSE_DRAG_AND_DROP
29 #include "wx/window.h"
35 #include "wx/msw/private.h"
37 // for some compilers, the entire ole2.h must be included, not only oleauto.h
38 #if wxUSE_NORLANDER_HEADERS || defined(__WATCOMC__) || defined(__WXWINCE__)
44 #include "wx/msw/ole/oleutils.h"
46 // ----------------------------------------------------------------------------
47 // wxIDropSource implementation of IDropSource interface
48 // ----------------------------------------------------------------------------
50 class wxIDropSource
: public IDropSource
53 wxIDropSource(wxDropSource
*pDropSource
);
54 virtual ~wxIDropSource() { }
57 STDMETHODIMP
QueryContinueDrag(BOOL fEscapePressed
, DWORD grfKeyState
);
58 STDMETHODIMP
GiveFeedback(DWORD dwEffect
);
60 DECLARE_IUNKNOWN_METHODS
;
63 DWORD m_grfInitKeyState
; // button which started the d&d operation
64 wxDropSource
*m_pDropSource
; // pointer to C++ class we belong to
66 wxDECLARE_NO_COPY_CLASS(wxIDropSource
);
69 // ============================================================================
71 // ============================================================================
73 // ----------------------------------------------------------------------------
74 // wxIDropSource implementation
75 // ----------------------------------------------------------------------------
76 BEGIN_IID_TABLE(wxIDropSource
)
81 IMPLEMENT_IUNKNOWN_METHODS(wxIDropSource
)
83 wxIDropSource::wxIDropSource(wxDropSource
*pDropSource
)
85 wxASSERT( pDropSource
!= NULL
);
87 m_pDropSource
= pDropSource
;
88 m_grfInitKeyState
= 0;
91 // Name : wxIDropSource::QueryContinueDrag
92 // Purpose : decide if drag operation must be continued or not
93 // Returns : HRESULT: S_OK if we should continue
94 // DRAGDROP_S_DROP to drop right now
95 // DRAGDROP_S_CANCEL to cancel everything
96 // Params : [in] BOOL fEscapePressed <Esc> pressed since last call?
97 // [in] DWORD grfKeyState mask containing state of kbd keys
98 // Notes : as there is no reasonably simple portable way to implement this
99 // function, we currently don't give the possibility to override the
100 // default behaviour implemented here
101 STDMETHODIMP
wxIDropSource::QueryContinueDrag(BOOL fEscapePressed
,
104 if ( fEscapePressed
)
105 return DRAGDROP_S_CANCEL
;
107 // initialize ourself with the drag begin button
108 if ( m_grfInitKeyState
== 0 ) {
109 m_grfInitKeyState
= grfKeyState
& (MK_LBUTTON
| MK_RBUTTON
| MK_MBUTTON
);
112 if ( !(grfKeyState
& m_grfInitKeyState
) ) {
113 // button which started d&d released, go!
114 return DRAGDROP_S_DROP
;
120 // Name : wxIDropSource::GiveFeedback
121 // Purpose : give UI feedback according to current state of operation
122 // Returns : STDMETHODIMP
123 // Params : [in] DWORD dwEffect - what would happen if we dropped now
124 // Notes : default implementation is ok in more than 99% of cases
125 STDMETHODIMP
wxIDropSource::GiveFeedback(DWORD dwEffect
)
128 if ( dwEffect
& DROPEFFECT_COPY
)
130 else if ( dwEffect
& DROPEFFECT_MOVE
)
135 if ( m_pDropSource
->GiveFeedback(effect
) )
138 return DRAGDROP_S_USEDEFAULTCURSORS
;
141 // ----------------------------------------------------------------------------
142 // wxDropSource implementation
143 // ----------------------------------------------------------------------------
147 // common part of all ctors
148 void wxDropSource::Init()
150 m_pIDropSource
= new wxIDropSource(this);
151 m_pIDropSource
->AddRef();
154 wxDropSource::wxDropSource(wxWindow
* WXUNUSED(win
),
155 const wxCursor
&cursorCopy
,
156 const wxCursor
&cursorMove
,
157 const wxCursor
&cursorStop
)
158 : wxDropSourceBase(cursorCopy
, cursorMove
, cursorStop
)
163 wxDropSource::wxDropSource(wxDataObject
& data
,
164 wxWindow
* WXUNUSED(win
),
165 const wxCursor
&cursorCopy
,
166 const wxCursor
&cursorMove
,
167 const wxCursor
&cursorStop
)
168 : wxDropSourceBase(cursorCopy
, cursorMove
, cursorStop
)
174 wxDropSource::~wxDropSource()
176 m_pIDropSource
->Release();
180 // Purpose : start drag and drop operation
181 // Returns : wxDragResult - the code of performed operation
182 // Params : [in] int flags: specifies if moving is allowe (or only copying)
183 // Notes : you must call SetData() before if you had used def ctor
184 wxDragResult
wxDropSource::DoDragDrop(int flags
)
186 wxCHECK_MSG( m_data
!= NULL
, wxDragNone
, wxT("No data in wxDropSource!") );
189 HRESULT hr
= ::DoDragDrop(m_data
->GetInterface(),
191 (flags
& wxDrag_AllowMove
)
192 ? DROPEFFECT_COPY
| DROPEFFECT_MOVE
196 if ( hr
== DRAGDROP_S_CANCEL
) {
199 else if ( hr
== DRAGDROP_S_DROP
) {
200 if ( dwEffect
& DROPEFFECT_COPY
) {
203 else if ( dwEffect
& DROPEFFECT_MOVE
) {
204 // consistency check: normally, we shouldn't get "move" at all
205 // here if we don't allow it, but in practice it does happen quite often
206 return (flags
& wxDrag_AllowMove
) ? wxDragMove
: wxDragCopy
;
215 wxLogApiError(wxT("DoDragDrop"), hr
);
216 wxLogError(wxT("Drag & drop operation failed."));
219 wxLogDebug(wxT("Unexpected success return code %08lx from DoDragDrop."),
227 // Name : wxDropSource::GiveFeedback
228 // Purpose : visually inform the user about d&d operation state
229 // Returns : bool: true if we do all ourselves or false for default feedback
230 // Params : [in] DragResult effect - what would happen if we dropped now
231 // Notes : here we just leave this stuff for default implementation
232 bool wxDropSource::GiveFeedback(wxDragResult effect
)
234 const wxCursor
& cursor
= GetCursor(effect
);
237 ::SetCursor((HCURSOR
)cursor
.GetHCURSOR());
247 #endif // wxUSE_OLE && wxUSE_DRAG_AND_DROP