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 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 23 DropTargetWin::~DropTargetWin() { 24 } 25 26 // static 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 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 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 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 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 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 111 ULONG DropTargetWin::AddRef() { 112 return ++ref_count_; 113 } 114 115 ULONG DropTargetWin::Release() { 116 if (--ref_count_ == 0) { 117 delete this; 118 return 0U; 119 } 120 return ref_count_; 121 } 122 123 DWORD DropTargetWin::OnDragEnter(IDataObject* data_object, 124 DWORD key_state, 125 POINT cursor_position, 126 DWORD effect) { 127 return DROPEFFECT_NONE; 128 } 129 130 DWORD DropTargetWin::OnDragOver(IDataObject* data_object, 131 DWORD key_state, 132 POINT cursor_position, 133 DWORD effect) { 134 return DROPEFFECT_NONE; 135 } 136 137 void DropTargetWin::OnDragLeave(IDataObject* data_object) { 138 } 139 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