• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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 "ui/base/dragdrop/drop_target_win.h"
6 
7 #include <shlobj.h>
8 
9 #include "base/logging.h"
10 
11 namespace ui {
12 
13 IDropTargetHelper* DropTargetWin::cached_drop_target_helper_ = NULL;
14 
DropTargetWin(HWND hwnd)15 DropTargetWin::DropTargetWin(HWND hwnd)
16     : hwnd_(hwnd),
17       ref_count_(0) {
18   DCHECK(hwnd);
19   HRESULT result = RegisterDragDrop(hwnd, this);
20   DCHECK(SUCCEEDED(result));
21 }
22 
~DropTargetWin()23 DropTargetWin::~DropTargetWin() {
24 }
25 
26 // static
DropHelper()27 IDropTargetHelper* DropTargetWin::DropHelper() {
28   if (!cached_drop_target_helper_) {
29     CoCreateInstance(CLSID_DragDropHelper, 0, CLSCTX_INPROC_SERVER,
30                      IID_IDropTargetHelper,
31                      reinterpret_cast<void**>(&cached_drop_target_helper_));
32   }
33   return cached_drop_target_helper_;
34 }
35 
36 ///////////////////////////////////////////////////////////////////////////////
37 // DropTargetWin, IDropTarget implementation:
38 
DragEnter(IDataObject * data_object,DWORD key_state,POINTL cursor_position,DWORD * effect)39 HRESULT DropTargetWin::DragEnter(IDataObject* data_object,
40                                  DWORD key_state,
41                                  POINTL cursor_position,
42                                  DWORD* effect) {
43   // Tell the helper that we entered so it can update the drag image.
44   IDropTargetHelper* drop_helper = DropHelper();
45   if (drop_helper) {
46     drop_helper->DragEnter(GetHWND(), data_object,
47                            reinterpret_cast<POINT*>(&cursor_position), *effect);
48   }
49 
50   current_data_object_ = data_object;
51   POINT screen_pt = { cursor_position.x, cursor_position.y };
52   *effect = OnDragEnter(current_data_object_, key_state, screen_pt, *effect);
53   return S_OK;
54 }
55 
DragOver(DWORD key_state,POINTL cursor_position,DWORD * effect)56 HRESULT DropTargetWin::DragOver(DWORD key_state,
57                                 POINTL cursor_position,
58                                 DWORD* effect) {
59   // Tell the helper that we moved over it so it can update the drag image.
60   IDropTargetHelper* drop_helper = DropHelper();
61   if (drop_helper)
62     drop_helper->DragOver(reinterpret_cast<POINT*>(&cursor_position), *effect);
63 
64   POINT screen_pt = { cursor_position.x, cursor_position.y };
65   *effect = OnDragOver(current_data_object_, key_state, screen_pt, *effect);
66   return S_OK;
67 }
68 
DragLeave()69 HRESULT DropTargetWin::DragLeave() {
70   // Tell the helper that we moved out of it so it can update the drag image.
71   IDropTargetHelper* drop_helper = DropHelper();
72   if (drop_helper)
73     drop_helper->DragLeave();
74 
75   OnDragLeave(current_data_object_);
76 
77   current_data_object_ = NULL;
78   return S_OK;
79 }
80 
Drop(IDataObject * data_object,DWORD key_state,POINTL cursor_position,DWORD * effect)81 HRESULT DropTargetWin::Drop(IDataObject* data_object,
82                             DWORD key_state,
83                             POINTL cursor_position,
84                             DWORD* effect) {
85   // Tell the helper that we dropped onto it so it can update the drag image.
86   IDropTargetHelper* drop_helper = DropHelper();
87   if (drop_helper) {
88     drop_helper->Drop(current_data_object_,
89                       reinterpret_cast<POINT*>(&cursor_position), *effect);
90   }
91 
92   POINT screen_pt = { cursor_position.x, cursor_position.y };
93   *effect = OnDrop(current_data_object_, key_state, screen_pt, *effect);
94   return S_OK;
95 }
96 
97 ///////////////////////////////////////////////////////////////////////////////
98 // DropTargetWin, IUnknown implementation:
99 
QueryInterface(const IID & iid,void ** object)100 HRESULT DropTargetWin::QueryInterface(const IID& iid, void** object) {
101   *object = NULL;
102   if (IsEqualIID(iid, IID_IUnknown) || IsEqualIID(iid, IID_IDropTarget)) {
103     *object = this;
104   } else {
105     return E_NOINTERFACE;
106   }
107   AddRef();
108   return S_OK;
109 }
110 
AddRef()111 ULONG DropTargetWin::AddRef() {
112   return ++ref_count_;
113 }
114 
Release()115 ULONG DropTargetWin::Release() {
116   if (--ref_count_ == 0) {
117     delete this;
118     return 0U;
119   }
120   return ref_count_;
121 }
122 
OnDragEnter(IDataObject * data_object,DWORD key_state,POINT cursor_position,DWORD effect)123 DWORD DropTargetWin::OnDragEnter(IDataObject* data_object,
124                                  DWORD key_state,
125                                  POINT cursor_position,
126                                  DWORD effect) {
127   return DROPEFFECT_NONE;
128 }
129 
OnDragOver(IDataObject * data_object,DWORD key_state,POINT cursor_position,DWORD effect)130 DWORD DropTargetWin::OnDragOver(IDataObject* data_object,
131                                 DWORD key_state,
132                                 POINT cursor_position,
133                                 DWORD effect) {
134   return DROPEFFECT_NONE;
135 }
136 
OnDragLeave(IDataObject * data_object)137 void DropTargetWin::OnDragLeave(IDataObject* data_object) {
138 }
139 
OnDrop(IDataObject * data_object,DWORD key_state,POINT cursor_position,DWORD effect)140 DWORD DropTargetWin::OnDrop(IDataObject* data_object,
141                             DWORD key_state,
142                             POINT cursor_position,
143                             DWORD effect) {
144   return DROPEFFECT_NONE;
145 }
146 
147 }  // namespace ui
148