blob: 7c1790ed198a34e3b8335fd4b6b6caa7b07387d0 [file] [log] [blame]
license.botf003cfe2008-08-24 09:55:55 +09001// Copyright (c) 2006-2008 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.
initial.commit3f4a7322008-07-27 06:49:38 +09004
5#include <windows.h>
6#include <shlobj.h>
7
8#include "base/base_drop_target.h"
9
10#include "base/logging.h"
11
12///////////////////////////////////////////////////////////////////////////////
13
14IDropTargetHelper* BaseDropTarget::cached_drop_target_helper_ = NULL;
15
16BaseDropTarget::BaseDropTarget(HWND hwnd)
17 : suspend_(false),
18 ref_count_(0),
19 hwnd_(hwnd) {
20 DCHECK(hwnd);
21 HRESULT result = RegisterDragDrop(hwnd, this);
22}
23
24BaseDropTarget::~BaseDropTarget() {
25}
26
27// static
28IDropTargetHelper* BaseDropTarget::DropHelper() {
29 if (!cached_drop_target_helper_) {
30 CoCreateInstance(CLSID_DragDropHelper, 0, CLSCTX_INPROC_SERVER,
31 IID_IDropTargetHelper,
32 reinterpret_cast<void**>(&cached_drop_target_helper_));
33 }
34 return cached_drop_target_helper_;
35}
36
37///////////////////////////////////////////////////////////////////////////////
38// BaseDropTarget, IDropTarget implementation:
39
40HRESULT BaseDropTarget::DragEnter(IDataObject* data_object,
41 DWORD key_state,
42 POINTL cursor_position,
43 DWORD* effect) {
44 // Tell the helper that we entered so it can update the drag image.
45 IDropTargetHelper* drop_helper = DropHelper();
46 if (drop_helper) {
47 drop_helper->DragEnter(GetHWND(), data_object,
48 reinterpret_cast<POINT*>(&cursor_position), *effect);
49 }
50
51 // You can't drag and drop within the same HWND.
52 if (suspend_) {
53 *effect = DROPEFFECT_NONE;
54 return S_OK;
55 }
56 current_data_object_ = data_object;
57 POINT screen_pt = { cursor_position.x, cursor_position.y };
58 *effect = OnDragEnter(current_data_object_, key_state, screen_pt, *effect);
59 return S_OK;
60}
61
62HRESULT BaseDropTarget::DragOver(DWORD key_state,
63 POINTL cursor_position,
64 DWORD* effect) {
65 // Tell the helper that we moved over it so it can update the drag image.
66 IDropTargetHelper* drop_helper = DropHelper();
67 if (drop_helper)
68 drop_helper->DragOver(reinterpret_cast<POINT*>(&cursor_position), *effect);
69
70 if (suspend_) {
71 *effect = DROPEFFECT_NONE;
72 return S_OK;
73 }
74
75 POINT screen_pt = { cursor_position.x, cursor_position.y };
76 *effect = OnDragOver(current_data_object_, key_state, screen_pt, *effect);
77 return S_OK;
78}
79
80HRESULT BaseDropTarget::DragLeave() {
81 // Tell the helper that we moved out of it so it can update the drag image.
82 IDropTargetHelper* drop_helper = DropHelper();
83 if (drop_helper)
84 drop_helper->DragLeave();
85
86 OnDragLeave(current_data_object_);
87
88 current_data_object_ = NULL;
89 return S_OK;
90}
91
92HRESULT BaseDropTarget::Drop(IDataObject* data_object,
93 DWORD key_state,
94 POINTL cursor_position,
95 DWORD* effect) {
96 // Tell the helper that we dropped onto it so it can update the drag image.
97 IDropTargetHelper* drop_helper = DropHelper();
98 if (drop_helper) {
99 drop_helper->Drop(current_data_object_,
100 reinterpret_cast<POINT*>(&cursor_position), *effect);
101 }
102
103 if (suspend_) {
104 *effect = DROPEFFECT_NONE;
105 return S_OK;
106 }
107
108 POINT screen_pt = { cursor_position.x, cursor_position.y };
109 *effect = OnDrop(current_data_object_, key_state, screen_pt, *effect);
110 return S_OK;
111}
112
113///////////////////////////////////////////////////////////////////////////////
114// BaseDropTarget, IUnknown implementation:
115
116HRESULT BaseDropTarget::QueryInterface(const IID& iid, void** object) {
117 *object = NULL;
118 if (IsEqualIID(iid, IID_IUnknown) || IsEqualIID(iid, IID_IDropTarget)) {
119 *object = this;
120 } else {
121 return E_NOINTERFACE;
122 }
123 AddRef();
124 return S_OK;
125}
126
127ULONG BaseDropTarget::AddRef() {
128 return InterlockedIncrement(&ref_count_);
129}
130
131ULONG BaseDropTarget::Release() {
132 if (InterlockedDecrement(&ref_count_) == 0) {
133 ULONG copied_refcnt = ref_count_;
134 delete this;
135 return copied_refcnt;
136 }
137 return ref_count_;
138}
139
140DWORD BaseDropTarget::OnDragEnter(IDataObject* data_object,
141 DWORD key_state,
142 POINT cursor_position,
143 DWORD effect) {
144 return DROPEFFECT_NONE;
145}
146
147DWORD BaseDropTarget::OnDragOver(IDataObject* data_object,
148 DWORD key_state,
149 POINT cursor_position,
150 DWORD effect) {
151 return DROPEFFECT_NONE;
152}
153
154void BaseDropTarget::OnDragLeave(IDataObject* data_object) {
155}
156
157DWORD BaseDropTarget::OnDrop(IDataObject* data_object,
158 DWORD key_state,
159 POINT cursor_position,
160 DWORD effect) {
161 return DROPEFFECT_NONE;
162}
license.botf003cfe2008-08-24 09:55:55 +0900163