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