OLD | NEW |
| (Empty) |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "app/win/drop_target.h" | |
6 | |
7 #include <shlobj.h> | |
8 | |
9 #include "base/logging.h" | |
10 | |
11 namespace app { | |
12 namespace win { | |
13 | |
14 IDropTargetHelper* DropTarget::cached_drop_target_helper_ = NULL; | |
15 int32 DropTarget::drag_identity_ = 0; | |
16 | |
17 DropTarget::DropTarget(HWND hwnd) | |
18 : hwnd_(hwnd), | |
19 suspended_(false), | |
20 ref_count_(0) { | |
21 DCHECK(hwnd); | |
22 HRESULT result = RegisterDragDrop(hwnd, this); | |
23 DCHECK(SUCCEEDED(result)); | |
24 } | |
25 | |
26 DropTarget::~DropTarget() { | |
27 } | |
28 | |
29 // static | |
30 IDropTargetHelper* DropTarget::DropHelper() { | |
31 if (!cached_drop_target_helper_) { | |
32 CoCreateInstance(CLSID_DragDropHelper, 0, CLSCTX_INPROC_SERVER, | |
33 IID_IDropTargetHelper, | |
34 reinterpret_cast<void**>(&cached_drop_target_helper_)); | |
35 } | |
36 return cached_drop_target_helper_; | |
37 } | |
38 | |
39 /////////////////////////////////////////////////////////////////////////////// | |
40 // DropTarget, IDropTarget implementation: | |
41 | |
42 HRESULT DropTarget::DragEnter(IDataObject* data_object, | |
43 DWORD key_state, | |
44 POINTL cursor_position, | |
45 DWORD* effect) { | |
46 // Tell the helper that we entered so it can update the drag image. | |
47 IDropTargetHelper* drop_helper = DropHelper(); | |
48 if (drop_helper) { | |
49 drop_helper->DragEnter(GetHWND(), data_object, | |
50 reinterpret_cast<POINT*>(&cursor_position), *effect); | |
51 } | |
52 | |
53 // You can't drag and drop within the same HWND. | |
54 if (suspended_) { | |
55 *effect = DROPEFFECT_NONE; | |
56 return S_OK; | |
57 } | |
58 | |
59 // Update the drag identity, skipping 0. | |
60 if (++drag_identity_ == 0) | |
61 ++drag_identity_; | |
62 | |
63 current_data_object_ = data_object; | |
64 POINT screen_pt = { cursor_position.x, cursor_position.y }; | |
65 *effect = OnDragEnter(current_data_object_, key_state, screen_pt, *effect); | |
66 return S_OK; | |
67 } | |
68 | |
69 HRESULT DropTarget::DragOver(DWORD key_state, | |
70 POINTL cursor_position, | |
71 DWORD* effect) { | |
72 // Tell the helper that we moved over it so it can update the drag image. | |
73 IDropTargetHelper* drop_helper = DropHelper(); | |
74 if (drop_helper) | |
75 drop_helper->DragOver(reinterpret_cast<POINT*>(&cursor_position), *effect); | |
76 | |
77 if (suspended_) { | |
78 *effect = DROPEFFECT_NONE; | |
79 return S_OK; | |
80 } | |
81 | |
82 POINT screen_pt = { cursor_position.x, cursor_position.y }; | |
83 *effect = OnDragOver(current_data_object_, key_state, screen_pt, *effect); | |
84 return S_OK; | |
85 } | |
86 | |
87 HRESULT DropTarget::DragLeave() { | |
88 // Tell the helper that we moved out of it so it can update the drag image. | |
89 IDropTargetHelper* drop_helper = DropHelper(); | |
90 if (drop_helper) | |
91 drop_helper->DragLeave(); | |
92 | |
93 if (suspended_) | |
94 return S_OK; | |
95 | |
96 OnDragLeave(current_data_object_); | |
97 | |
98 current_data_object_ = NULL; | |
99 return S_OK; | |
100 } | |
101 | |
102 HRESULT DropTarget::Drop(IDataObject* data_object, | |
103 DWORD key_state, | |
104 POINTL cursor_position, | |
105 DWORD* effect) { | |
106 // Tell the helper that we dropped onto it so it can update the drag image. | |
107 IDropTargetHelper* drop_helper = DropHelper(); | |
108 if (drop_helper) { | |
109 drop_helper->Drop(current_data_object_, | |
110 reinterpret_cast<POINT*>(&cursor_position), *effect); | |
111 } | |
112 | |
113 if (suspended_) { | |
114 *effect = DROPEFFECT_NONE; | |
115 return S_OK; | |
116 } | |
117 | |
118 POINT screen_pt = { cursor_position.x, cursor_position.y }; | |
119 *effect = OnDrop(current_data_object_, key_state, screen_pt, *effect); | |
120 return S_OK; | |
121 } | |
122 | |
123 /////////////////////////////////////////////////////////////////////////////// | |
124 // DropTarget, IUnknown implementation: | |
125 | |
126 HRESULT DropTarget::QueryInterface(const IID& iid, void** object) { | |
127 *object = NULL; | |
128 if (IsEqualIID(iid, IID_IUnknown) || IsEqualIID(iid, IID_IDropTarget)) { | |
129 *object = this; | |
130 } else { | |
131 return E_NOINTERFACE; | |
132 } | |
133 AddRef(); | |
134 return S_OK; | |
135 } | |
136 | |
137 ULONG DropTarget::AddRef() { | |
138 return ++ref_count_; | |
139 } | |
140 | |
141 ULONG DropTarget::Release() { | |
142 if (--ref_count_ == 0) { | |
143 delete this; | |
144 return 0U; | |
145 } | |
146 return ref_count_; | |
147 } | |
148 | |
149 DWORD DropTarget::OnDragEnter(IDataObject* data_object, | |
150 DWORD key_state, | |
151 POINT cursor_position, | |
152 DWORD effect) { | |
153 return DROPEFFECT_NONE; | |
154 } | |
155 | |
156 DWORD DropTarget::OnDragOver(IDataObject* data_object, | |
157 DWORD key_state, | |
158 POINT cursor_position, | |
159 DWORD effect) { | |
160 return DROPEFFECT_NONE; | |
161 } | |
162 | |
163 void DropTarget::OnDragLeave(IDataObject* data_object) { | |
164 } | |
165 | |
166 DWORD DropTarget::OnDrop(IDataObject* data_object, | |
167 DWORD key_state, | |
168 POINT cursor_position, | |
169 DWORD effect) { | |
170 return DROPEFFECT_NONE; | |
171 } | |
172 | |
173 } // namespace win | |
174 } // namespace app | |
OLD | NEW |