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. 4 5 #ifndef BASE_BASE_DROP_TARGET_H_ 6 #define BASE_BASE_DROP_TARGET_H_ 7 8 #include <objidl.h> 9 10 #include "base/ref_counted.h" 11 12 struct IDropTargetHelper; 13 14 // A DropTarget implementation that takes care of the nitty gritty 15 // of dnd. While this class is concrete, subclasses will most likely 16 // want to override various OnXXX methods. 17 // 18 // Because BaseDropTarget is ref counted you shouldn't delete it directly, 19 // rather wrap it in a scoped_refptr. Be sure and invoke RevokeDragDrop(m_hWnd) 20 // before the HWND is deleted too. 21 // 22 // This class is meant to be used in a STA and is not multithread-safe. 23 class BaseDropTarget : public IDropTarget { 24 public: 25 // Create a new BaseDropTarget associating it with the given HWND. 26 explicit BaseDropTarget(HWND hwnd); 27 virtual ~BaseDropTarget(); 28 29 // When suspended is set to |true|, the drop target does not receive drops 30 // from drags initiated within the owning HWND. 31 // TODO(beng): (http://b/1085385) figure out how we will handle legitimate 32 // drag-drop operations within the same HWND, such as dragging 33 // selected text to an edit field. 34 bool suspended() const { return suspended_; } 35 void set_suspended(bool suspended) { suspended_ = suspended; } 36 37 // IDropTarget implementation: 38 HRESULT __stdcall DragEnter(IDataObject* data_object, 39 DWORD key_state, 40 POINTL cursor_position, 41 DWORD* effect); 42 HRESULT __stdcall DragOver(DWORD key_state, 43 POINTL cursor_position, 44 DWORD* effect); 45 HRESULT __stdcall DragLeave(); 46 HRESULT __stdcall Drop(IDataObject* data_object, 47 DWORD key_state, 48 POINTL cursor_position, 49 DWORD* effect); 50 51 // IUnknown implementation: 52 HRESULT __stdcall QueryInterface(const IID& iid, void** object); 53 ULONG __stdcall AddRef(); 54 ULONG __stdcall Release(); 55 56 protected: 57 // Returns the hosting HWND. 58 HWND GetHWND() { return hwnd_; } 59 60 // Invoked when the cursor first moves over the hwnd during a dnd session. 61 // This should return a bitmask of the supported drop operations: 62 // DROPEFFECT_NONE, DROPEFFECT_COPY, DROPEFFECT_LINK and/or 63 // DROPEFFECT_MOVE. 64 virtual DWORD OnDragEnter(IDataObject* data_object, 65 DWORD key_state, 66 POINT cursor_position, 67 DWORD effect); 68 69 // Invoked when the cursor moves over the window during a dnd session. 70 // This should return a bitmask of the supported drop operations: 71 // DROPEFFECT_NONE, DROPEFFECT_COPY, DROPEFFECT_LINK and/or 72 // DROPEFFECT_MOVE. 73 virtual DWORD OnDragOver(IDataObject* data_object, 74 DWORD key_state, 75 POINT cursor_position, 76 DWORD effect); 77 78 // Invoked when the cursor moves outside the bounds of the hwnd during a 79 // dnd session. 80 virtual void OnDragLeave(IDataObject* data_object); 81 82 // Invoked when the drop ends on the window. This should return the operation 83 // that was taken. 84 virtual DWORD OnDrop(IDataObject* data_object, 85 DWORD key_state, 86 POINT cursor_position, 87 DWORD effect); 88 89 // Return the drag identity. 90 static int32 GetDragIdentity() { return drag_identity_; } 91 92 private: 93 // Returns the cached drop helper, creating one if necessary. The returned 94 // object is not addrefed. May return NULL if the object couldn't be created. 95 static IDropTargetHelper* DropHelper(); 96 97 // The data object currently being dragged over this drop target. 98 scoped_refptr<IDataObject> current_data_object_; 99 100 // A helper object that is used to provide drag image support while the mouse 101 // is dragging over the content area. 102 // 103 // DO NOT ACCESS DIRECTLY! Use DropHelper() instead, which will lazily create 104 // this if it doesn't exist yet. This object can take tens of milliseconds to 105 // create, and we don't want to block any window opening for this, especially 106 // since often, DnD will never be used. Instead, we force this penalty to the 107 // first time it is actually used. 108 static IDropTargetHelper* cached_drop_target_helper_; 109 110 // The drag identity (id). An up-counter that increases when the cursor first 111 // moves over the HWND in a DnD session (OnDragEnter). 0 is reserved to mean 112 // the "no/unknown" identity, and is used for initialization. The identity is 113 // sent to the renderer in drag enter notifications. Note: the identity value 114 // is passed over the renderer NPAPI interface to gears, so use int32 instead 115 // of int here. 116 static int32 drag_identity_; 117 118 // The HWND of the source. This HWND is used to determine coordinates for 119 // mouse events that are sent to the renderer notifying various drag states. 120 HWND hwnd_; 121 122 // Whether or not we are currently processing drag notifications for drags 123 // initiated in this window. 124 bool suspended_; 125 126 LONG ref_count_; 127 128 DISALLOW_EVIL_CONSTRUCTORS(BaseDropTarget); 129 }; 130 131 #endif // BASE_BASE_DROP_TARGET_H_ 132