-
Notifications
You must be signed in to change notification settings - Fork 6
/
TrackDropSource.cpp
79 lines (67 loc) · 2.23 KB
/
TrackDropSource.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include "TrackDropSource.h"
TrackDropSource::TrackDropSource(HWND p_hWnd) : m_refcount(1), m_hWnd(p_hWnd) {}
pfc::com_ptr_t<IDropSource> TrackDropSource::g_create(HWND hWnd) {
return {new TrackDropSource(hWnd)};
}
/////////////////////////////////////////////////////////
// IUnknown methods
// We support the IUnknown and IDropSource interfaces.
STDMETHODIMP TrackDropSource::QueryInterface(REFIID iid, void** ppvObject) {
if (ppvObject == nullptr) {
return E_INVALIDARG;
} else if (iid == IID_IUnknown) {
AddRef();
*ppvObject = static_cast<IUnknown*>(this);
return S_OK;
} else if (iid == IID_IDropSource) {
AddRef();
*ppvObject = static_cast<IDropSource*>(this);
return S_OK;
} else
return E_NOINTERFACE;
}
// Increase reference count.
STDMETHODIMP_(ULONG) TrackDropSource::AddRef() {
return ++m_refcount;
}
// Decrease reference count.
// Delete object, if reference count reaches zero.
STDMETHODIMP_(ULONG) TrackDropSource::Release() {
LONG rv = --m_refcount;
if (rv == 0)
delete this;
return rv;
}
// IDropSource methods
// Determine whether the drag operation should be continued.
// Return S_OK to continue, DRAGDROP_S_CANCEL to cancel the operation,
// or DRAGDROP_S_DROP to perform a drop.
STDMETHODIMP TrackDropSource::QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState) {
// Cancel if escape was pressed.
if (fEscapePressed) {
return DRAGDROP_S_CANCEL;
// Cancel if right mouse button was pressed.
} else if (grfKeyState & MK_RBUTTON) {
return DRAGDROP_S_CANCEL;
// Drop or cancel if left mouse button was released.
} else if (!(grfKeyState & MK_LBUTTON)) {
DWORD pts = GetMessagePos();
POINT pt = {LOWORD(pts), HIWORD(pts)};
HWND pwnd = WindowFromPoint(pt);
// If the mouse button was released over our window, cancel the operation.
if (pwnd == m_hWnd || GetParent(pwnd) == m_hWnd) {
return DRAGDROP_S_CANCEL;
// Perform a drop otherwise.
} else {
return DRAGDROP_S_DROP;
}
}
// Continue otherwise.
else
return S_OK;
}
// Provide visual feedback (through mouse pointer) about the state of the
// drag operation.
STDMETHODIMP TrackDropSource::GiveFeedback(DWORD /*dwEffect*/) {
return DRAGDROP_S_USEDEFAULTCURSORS;
}