1 // 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.
5 #include "base/base_drop_target.h"
9 #include "base/logging.h"
11 ///////////////////////////////////////////////////////////////////////////////
13 IDropTargetHelper
* BaseDropTarget::cached_drop_target_helper_
= NULL
;
14 int32
BaseDropTarget::drag_identity_
= 0;
16 BaseDropTarget::BaseDropTarget(HWND hwnd
)
21 HRESULT result
= RegisterDragDrop(hwnd
, this);
22 DCHECK(SUCCEEDED(result
));
25 BaseDropTarget::~BaseDropTarget() {
29 IDropTargetHelper
* BaseDropTarget::DropHelper() {
30 if (!cached_drop_target_helper_
) {
31 CoCreateInstance(CLSID_DragDropHelper
, 0, CLSCTX_INPROC_SERVER
,
32 IID_IDropTargetHelper
,
33 reinterpret_cast<void**>(&cached_drop_target_helper_
));
35 return cached_drop_target_helper_
;
38 ///////////////////////////////////////////////////////////////////////////////
39 // BaseDropTarget, IDropTarget implementation:
41 HRESULT
BaseDropTarget::DragEnter(IDataObject
* data_object
,
43 POINTL cursor_position
,
45 // Tell the helper that we entered so it can update the drag image.
46 IDropTargetHelper
* drop_helper
= DropHelper();
48 drop_helper
->DragEnter(GetHWND(), data_object
,
49 reinterpret_cast<POINT
*>(&cursor_position
), *effect
);
52 // You can't drag and drop within the same HWND.
54 *effect
= DROPEFFECT_NONE
;
58 // Update the drag identity, skipping 0.
59 if (++drag_identity_
== 0)
62 current_data_object_
= data_object
;
63 POINT screen_pt
= { cursor_position
.x
, cursor_position
.y
};
64 *effect
= OnDragEnter(current_data_object_
, key_state
, screen_pt
, *effect
);
68 HRESULT
BaseDropTarget::DragOver(DWORD key_state
,
69 POINTL cursor_position
,
71 // Tell the helper that we moved over it so it can update the drag image.
72 IDropTargetHelper
* drop_helper
= DropHelper();
74 drop_helper
->DragOver(reinterpret_cast<POINT
*>(&cursor_position
), *effect
);
77 *effect
= DROPEFFECT_NONE
;
81 POINT screen_pt
= { cursor_position
.x
, cursor_position
.y
};
82 *effect
= OnDragOver(current_data_object_
, key_state
, screen_pt
, *effect
);
86 HRESULT
BaseDropTarget::DragLeave() {
87 // Tell the helper that we moved out of it so it can update the drag image.
88 IDropTargetHelper
* drop_helper
= DropHelper();
90 drop_helper
->DragLeave();
95 OnDragLeave(current_data_object_
);
97 current_data_object_
= NULL
;
101 HRESULT
BaseDropTarget::Drop(IDataObject
* data_object
,
103 POINTL cursor_position
,
105 // Tell the helper that we dropped onto it so it can update the drag image.
106 IDropTargetHelper
* drop_helper
= DropHelper();
108 drop_helper
->Drop(current_data_object_
,
109 reinterpret_cast<POINT
*>(&cursor_position
), *effect
);
113 *effect
= DROPEFFECT_NONE
;
117 POINT screen_pt
= { cursor_position
.x
, cursor_position
.y
};
118 *effect
= OnDrop(current_data_object_
, key_state
, screen_pt
, *effect
);
122 ///////////////////////////////////////////////////////////////////////////////
123 // BaseDropTarget, IUnknown implementation:
125 HRESULT
BaseDropTarget::QueryInterface(const IID
& iid
, void** object
) {
127 if (IsEqualIID(iid
, IID_IUnknown
) || IsEqualIID(iid
, IID_IDropTarget
)) {
130 return E_NOINTERFACE
;
136 ULONG
BaseDropTarget::AddRef() {
140 ULONG
BaseDropTarget::Release() {
141 if (--ref_count_
== 0) {
148 DWORD
BaseDropTarget::OnDragEnter(IDataObject
* data_object
,
150 POINT cursor_position
,
152 return DROPEFFECT_NONE
;
155 DWORD
BaseDropTarget::OnDragOver(IDataObject
* data_object
,
157 POINT cursor_position
,
159 return DROPEFFECT_NONE
;
162 void BaseDropTarget::OnDragLeave(IDataObject
* data_object
) {
165 DWORD
BaseDropTarget::OnDrop(IDataObject
* data_object
,
167 POINT cursor_position
,
169 return DROPEFFECT_NONE
;